Commit 159b0104 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://linuxusb.bkbits.net/pci_hp-2.5

into penguin.transmeta.com:/home/penguin/torvalds/repositories/kernel/linux
parents b6a3d01f 441a1393
...@@ -292,16 +292,14 @@ struct controller { ...@@ -292,16 +292,14 @@ struct controller {
struct pci_resource *io_head; struct pci_resource *io_head;
struct pci_resource *bus_head; struct pci_resource *bus_head;
struct pci_dev *pci_dev; struct pci_dev *pci_dev;
struct pci_ops *pci_ops; struct pci_bus *pci_bus;
struct proc_dir_entry* proc_entry; struct proc_dir_entry* proc_entry;
struct proc_dir_entry* proc_entry2; struct proc_dir_entry* proc_entry2;
struct event_info event_queue[10]; struct event_info event_queue[10];
struct slot *slot; struct slot *slot;
u8 next_event; u8 next_event;
u8 interrupt; u8 interrupt;
u8 bus; u8 bus; /* bus number for the pci hotplug controller */
u8 device;
u8 function;
u8 rev; u8 rev;
u8 slot_device_offset; u8 slot_device_offset;
u8 first_slot; u8 first_slot;
...@@ -695,7 +693,8 @@ static inline int cpq_get_latch_status (struct controller *ctrl, struct slot *sl ...@@ -695,7 +693,8 @@ static inline int cpq_get_latch_status (struct controller *ctrl, struct slot *sl
return 1; return 1;
hp_slot = slot->device - ctrl->slot_device_offset; hp_slot = slot->device - ctrl->slot_device_offset;
dbg(__FUNCTION__": slot->device = %d, ctrl->slot_device_offset = %d \n", slot->device, ctrl->slot_device_offset); dbg("%s: slot->device = %d, ctrl->slot_device_offset = %d \n",
__FUNCTION__, slot->device, ctrl->slot_device_offset);
status = (readl(ctrl->hpc_reg + INT_INPUT_CLEAR) & (0x01L << hp_slot)); status = (readl(ctrl->hpc_reg + INT_INPUT_CLEAR) & (0x01L << hp_slot));
...@@ -733,7 +732,7 @@ static inline int wait_for_ctrl_irq (struct controller *ctrl) ...@@ -733,7 +732,7 @@ static inline int wait_for_ctrl_irq (struct controller *ctrl)
DECLARE_WAITQUEUE(wait, current); DECLARE_WAITQUEUE(wait, current);
int retval = 0; int retval = 0;
dbg(__FUNCTION__" - start\n"); dbg("%s - start\n", __FUNCTION__);
add_wait_queue(&ctrl->queue, &wait); add_wait_queue(&ctrl->queue, &wait);
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
/* Sleep for up to 1 second to wait for the LED to change. */ /* Sleep for up to 1 second to wait for the LED to change. */
...@@ -743,7 +742,7 @@ static inline int wait_for_ctrl_irq (struct controller *ctrl) ...@@ -743,7 +742,7 @@ static inline int wait_for_ctrl_irq (struct controller *ctrl)
if (signal_pending(current)) if (signal_pending(current))
retval = -EINTR; retval = -EINTR;
dbg(__FUNCTION__" - end\n"); dbg("%s - end\n", __FUNCTION__);
return retval; return retval;
} }
......
...@@ -314,7 +314,7 @@ static int ctrl_slot_setup (struct controller * ctrl, void *smbios_start, void * ...@@ -314,7 +314,7 @@ static int ctrl_slot_setup (struct controller * ctrl, void *smbios_start, void *
void *slot_entry= NULL; void *slot_entry= NULL;
int result; int result;
dbg(__FUNCTION__"\n"); dbg("%s\n", __FUNCTION__);
tempdword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR); tempdword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);
...@@ -467,7 +467,7 @@ static int ctrl_slot_cleanup (struct controller * ctrl) ...@@ -467,7 +467,7 @@ static int ctrl_slot_cleanup (struct controller * ctrl)
// //
// Output: SUCCESS or FAILURE // Output: SUCCESS or FAILURE
//============================================================================= //=============================================================================
static int get_slot_mapping (struct pci_ops *ops, u8 bus_num, u8 dev_num, u8 *slot) static int get_slot_mapping (struct pci_bus *bus, u8 bus_num, u8 dev_num, u8 *slot)
{ {
struct irq_routing_table *PCIIRQRoutingInfoLength; struct irq_routing_table *PCIIRQRoutingInfoLength;
u32 work; u32 work;
...@@ -476,7 +476,7 @@ static int get_slot_mapping (struct pci_ops *ops, u8 bus_num, u8 dev_num, u8 *sl ...@@ -476,7 +476,7 @@ static int get_slot_mapping (struct pci_ops *ops, u8 bus_num, u8 dev_num, u8 *sl
u8 tbus, tdevice, tslot, bridgeSlot; u8 tbus, tdevice, tslot, bridgeSlot;
dbg(__FUNCTION__" %p, %d, %d, %p\n", ops, bus_num, dev_num, slot); dbg("%s: %p, %d, %d, %p\n", __FUNCTION__, bus, bus_num, dev_num, slot);
bridgeSlot = 0xFF; bridgeSlot = 0xFF;
...@@ -490,7 +490,6 @@ static int get_slot_mapping (struct pci_ops *ops, u8 bus_num, u8 dev_num, u8 *sl ...@@ -490,7 +490,6 @@ static int get_slot_mapping (struct pci_ops *ops, u8 bus_num, u8 dev_num, u8 *sl
return -1; return -1;
} }
for (loop = 0; loop < len; ++loop) { for (loop = 0; loop < len; ++loop) {
tbus = PCIIRQRoutingInfoLength->slots[loop].bus; tbus = PCIIRQRoutingInfoLength->slots[loop].bus;
tdevice = PCIIRQRoutingInfoLength->slots[loop].devfn >> 3; tdevice = PCIIRQRoutingInfoLength->slots[loop].devfn >> 3;
...@@ -499,7 +498,8 @@ static int get_slot_mapping (struct pci_ops *ops, u8 bus_num, u8 dev_num, u8 *sl ...@@ -499,7 +498,8 @@ static int get_slot_mapping (struct pci_ops *ops, u8 bus_num, u8 dev_num, u8 *sl
if ((tbus == bus_num) && (tdevice == dev_num)) { if ((tbus == bus_num) && (tdevice == dev_num)) {
*slot = tslot; *slot = tslot;
if (PCIIRQRoutingInfoLength != NULL) kfree(PCIIRQRoutingInfoLength ); if (PCIIRQRoutingInfoLength != NULL)
kfree(PCIIRQRoutingInfoLength);
return 0; return 0;
} else { } else {
// Didn't get a match on the target PCI device. Check if the // Didn't get a match on the target PCI device. Check if the
...@@ -508,10 +508,11 @@ static int get_slot_mapping (struct pci_ops *ops, u8 bus_num, u8 dev_num, u8 *sl ...@@ -508,10 +508,11 @@ static int get_slot_mapping (struct pci_ops *ops, u8 bus_num, u8 dev_num, u8 *sl
// device, I need to save the bridge's slot number. If I can't // device, I need to save the bridge's slot number. If I can't
// find an entry for the target device, I will have to assume it's // find an entry for the target device, I will have to assume it's
// on the other side of the bridge, and assign it the bridge's slot. // on the other side of the bridge, and assign it the bridge's slot.
pci_read_config_dword_nodev (ops, tbus, tdevice, 0, PCI_REVISION_ID, &work); bus->number = tbus;
pci_bus_read_config_dword (bus, PCI_DEVFN(tdevice, 0), PCI_REVISION_ID, &work);
if ((work >> 8) == PCI_TO_PCI_BRIDGE_CLASS) { if ((work >> 8) == PCI_TO_PCI_BRIDGE_CLASS) {
pci_read_config_dword_nodev (ops, tbus, tdevice, 0, PCI_PRIMARY_BUS, &work); pci_bus_read_config_dword (bus, PCI_DEVFN(tdevice, 0), PCI_PRIMARY_BUS, &work);
// See if bridge's secondary bus matches target bus. // See if bridge's secondary bus matches target bus.
if (((work >> 8) & 0x000000FF) == (long) bus_num) { if (((work >> 8) & 0x000000FF) == (long) bus_num) {
bridgeSlot = tslot; bridgeSlot = tslot;
...@@ -521,7 +522,6 @@ static int get_slot_mapping (struct pci_ops *ops, u8 bus_num, u8 dev_num, u8 *sl ...@@ -521,7 +522,6 @@ static int get_slot_mapping (struct pci_ops *ops, u8 bus_num, u8 dev_num, u8 *sl
} }
// If we got here, we didn't find an entry in the IRQ mapping table // If we got here, we didn't find an entry in the IRQ mapping table
// for the target PCI device. If we did determine that the target // for the target PCI device. If we did determine that the target
// device is on the other side of a PCI-to-PCI bridge, return the // device is on the other side of a PCI-to-PCI bridge, return the
...@@ -592,7 +592,7 @@ static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status) ...@@ -592,7 +592,7 @@ static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status)
if (slot == NULL) if (slot == NULL)
return -ENODEV; return -ENODEV;
dbg(__FUNCTION__" - physical_slot = %s\n", hotplug_slot->name); dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
ctrl = slot->ctrl; ctrl = slot->ctrl;
if (ctrl == NULL) if (ctrl == NULL)
...@@ -627,7 +627,7 @@ static int process_SI (struct hotplug_slot *hotplug_slot) ...@@ -627,7 +627,7 @@ static int process_SI (struct hotplug_slot *hotplug_slot)
if (slot == NULL) if (slot == NULL)
return -ENODEV; return -ENODEV;
dbg(__FUNCTION__" - physical_slot = %s\n", hotplug_slot->name); dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
ctrl = slot->ctrl; ctrl = slot->ctrl;
if (ctrl == NULL) if (ctrl == NULL)
...@@ -667,7 +667,7 @@ static int process_SS (struct hotplug_slot *hotplug_slot) ...@@ -667,7 +667,7 @@ static int process_SS (struct hotplug_slot *hotplug_slot)
if (slot == NULL) if (slot == NULL)
return -ENODEV; return -ENODEV;
dbg(__FUNCTION__" - physical_slot = %s\n", hotplug_slot->name); dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
ctrl = slot->ctrl; ctrl = slot->ctrl;
if (ctrl == NULL) if (ctrl == NULL)
...@@ -695,7 +695,7 @@ static int hardware_test (struct hotplug_slot *hotplug_slot, u32 value) ...@@ -695,7 +695,7 @@ static int hardware_test (struct hotplug_slot *hotplug_slot, u32 value)
struct slot *slot = get_slot (hotplug_slot, __FUNCTION__); struct slot *slot = get_slot (hotplug_slot, __FUNCTION__);
struct controller *ctrl; struct controller *ctrl;
dbg(__FUNCTION__"\n"); dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
if (slot == NULL) if (slot == NULL)
return -ENODEV; return -ENODEV;
...@@ -716,7 +716,7 @@ static int get_power_status (struct hotplug_slot *hotplug_slot, u8 *value) ...@@ -716,7 +716,7 @@ static int get_power_status (struct hotplug_slot *hotplug_slot, u8 *value)
if (slot == NULL) if (slot == NULL)
return -ENODEV; return -ENODEV;
dbg(__FUNCTION__" - physical_slot = %s\n", hotplug_slot->name); dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
ctrl = slot->ctrl; ctrl = slot->ctrl;
if (ctrl == NULL) if (ctrl == NULL)
...@@ -734,7 +734,7 @@ static int get_attention_status (struct hotplug_slot *hotplug_slot, u8 *value) ...@@ -734,7 +734,7 @@ static int get_attention_status (struct hotplug_slot *hotplug_slot, u8 *value)
if (slot == NULL) if (slot == NULL)
return -ENODEV; return -ENODEV;
dbg(__FUNCTION__" - physical_slot = %s\n", hotplug_slot->name); dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
ctrl = slot->ctrl; ctrl = slot->ctrl;
if (ctrl == NULL) if (ctrl == NULL)
...@@ -752,7 +752,7 @@ static int get_latch_status (struct hotplug_slot *hotplug_slot, u8 *value) ...@@ -752,7 +752,7 @@ static int get_latch_status (struct hotplug_slot *hotplug_slot, u8 *value)
if (slot == NULL) if (slot == NULL)
return -ENODEV; return -ENODEV;
dbg(__FUNCTION__" - physical_slot = %s\n", hotplug_slot->name); dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
ctrl = slot->ctrl; ctrl = slot->ctrl;
if (ctrl == NULL) if (ctrl == NULL)
...@@ -770,8 +770,8 @@ static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value) ...@@ -770,8 +770,8 @@ static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value)
if (slot == NULL) if (slot == NULL)
return -ENODEV; return -ENODEV;
dbg(__FUNCTION__" - physical_slot = %s\n", hotplug_slot->name); dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
ctrl = slot->ctrl; ctrl = slot->ctrl;
if (ctrl == NULL) if (ctrl == NULL)
...@@ -820,7 +820,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -820,7 +820,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
// TODO: This code can be made to support non-Compaq or Intel subsystem IDs // TODO: This code can be made to support non-Compaq or Intel subsystem IDs
rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vid); rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vid);
if (rc) { if (rc) {
err(__FUNCTION__" : pci_read_config_word failed\n"); err("%s : pci_read_config_word failed\n", __FUNCTION__);
return rc; return rc;
} }
dbg("Subsystem Vendor ID: %x\n", subsystem_vid); dbg("Subsystem Vendor ID: %x\n", subsystem_vid);
...@@ -831,14 +831,14 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -831,14 +831,14 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
ctrl = (struct controller *) kmalloc(sizeof(struct controller), GFP_KERNEL); ctrl = (struct controller *) kmalloc(sizeof(struct controller), GFP_KERNEL);
if (!ctrl) { if (!ctrl) {
err(__FUNCTION__" : out of memory\n"); err("%s : out of memory\n", __FUNCTION__);
return -ENOMEM; return -ENOMEM;
} }
memset(ctrl, 0, sizeof(struct controller)); memset(ctrl, 0, sizeof(struct controller));
rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsystem_deviceid); rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsystem_deviceid);
if (rc) { if (rc) {
err(__FUNCTION__" : pci_read_config_word failed\n"); err("%s : pci_read_config_word failed\n", __FUNCTION__);
goto err_free_ctrl; goto err_free_ctrl;
} }
...@@ -991,12 +991,20 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -991,12 +991,20 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
dbg (" pcix_support %s\n", ctrl->pcix_support == 0 ? "not supported" : "supported"); dbg (" pcix_support %s\n", ctrl->pcix_support == 0 ? "not supported" : "supported");
ctrl->pci_dev = pdev; ctrl->pci_dev = pdev;
ctrl->pci_ops = pdev->bus->ops;
/* make our own copy of the pci bus structure, as we like tweaking it a lot */
ctrl->pci_bus = kmalloc (sizeof (*ctrl->pci_bus), GFP_KERNEL);
if (!ctrl->pci_bus) {
err("out of memory\n");
rc = -ENOMEM;
goto err_free_ctrl;
}
memcpy (ctrl->pci_bus, pdev->bus, sizeof (*ctrl->pci_bus));
ctrl->bus = pdev->bus->number; ctrl->bus = pdev->bus->number;
ctrl->device = PCI_SLOT(pdev->devfn);
ctrl->function = PCI_FUNC(pdev->devfn);
ctrl->rev = rev; ctrl->rev = rev;
dbg("bus device function rev: %d %d %d %d\n", ctrl->bus, ctrl->device, ctrl->function, ctrl->rev); dbg("bus device function rev: %d %d %d %d\n", ctrl->bus,
PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), ctrl->rev);
init_MUTEX(&ctrl->crit_sect); init_MUTEX(&ctrl->crit_sect);
init_waitqueue_head(&ctrl->queue); init_waitqueue_head(&ctrl->queue);
...@@ -1004,7 +1012,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1004,7 +1012,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* initialize our threads if they haven't already been started up */ /* initialize our threads if they haven't already been started up */
rc = one_time_init(); rc = one_time_init();
if (rc) { if (rc) {
goto err_free_ctrl; goto err_free_bus;
} }
dbg("pdev = %p\n", pdev); dbg("pdev = %p\n", pdev);
...@@ -1015,7 +1023,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1015,7 +1023,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_resource_len(pdev, 0), MY_NAME)) { pci_resource_len(pdev, 0), MY_NAME)) {
err("cannot reserve MMIO region\n"); err("cannot reserve MMIO region\n");
rc = -ENOMEM; rc = -ENOMEM;
goto err_free_ctrl; goto err_free_bus;
} }
ctrl->hpc_reg = ioremap(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); ctrl->hpc_reg = ioremap(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
...@@ -1043,7 +1051,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1043,7 +1051,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
// in this case it will always be called for the "base" // in this case it will always be called for the "base"
// bus/dev/func of a slot. // bus/dev/func of a slot.
// CS: this is leveraging the PCIIRQ routing code from the kernel (pci-pc.c: get_irq_routing_table) // CS: this is leveraging the PCIIRQ routing code from the kernel (pci-pc.c: get_irq_routing_table)
rc = get_slot_mapping(ctrl->pci_ops, pdev->bus->number, (readb(ctrl->hpc_reg + SLOT_MASK) >> 4), &(ctrl->first_slot)); rc = get_slot_mapping(ctrl->pci_bus, pdev->bus->number, (readb(ctrl->hpc_reg + SLOT_MASK) >> 4), &(ctrl->first_slot));
dbg("get_slot_mapping: first_slot = %d, returned = %d\n", ctrl->first_slot, rc); dbg("get_slot_mapping: first_slot = %d, returned = %d\n", ctrl->first_slot, rc);
if (rc) { if (rc) {
err(msg_initialization_err, rc); err(msg_initialization_err, rc);
...@@ -1053,7 +1061,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1053,7 +1061,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
// Store PCI Config Space for all devices on this bus // Store PCI Config Space for all devices on this bus
rc = cpqhp_save_config(ctrl, ctrl->bus, readb(ctrl->hpc_reg + SLOT_MASK)); rc = cpqhp_save_config(ctrl, ctrl->bus, readb(ctrl->hpc_reg + SLOT_MASK));
if (rc) { if (rc) {
err(__FUNCTION__": unable to save PCI configuration data, error %d\n", rc); err("%s: unable to save PCI configuration data, error %d\n", __FUNCTION__, rc);
goto err_iounmap; goto err_iounmap;
} }
...@@ -1080,7 +1088,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1080,7 +1088,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
rc = ctrl_slot_setup(ctrl, smbios_start, smbios_table); rc = ctrl_slot_setup(ctrl, smbios_start, smbios_table);
if (rc) { if (rc) {
err(msg_initialization_err, 6); err(msg_initialization_err, 6);
err(__FUNCTION__": unable to save PCI configuration data, error %d\n", rc); err("%s: unable to save PCI configuration data, error %d\n", __FUNCTION__, rc);
goto err_iounmap; goto err_iounmap;
} }
...@@ -1188,6 +1196,8 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1188,6 +1196,8 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
iounmap(ctrl->hpc_reg); iounmap(ctrl->hpc_reg);
err_free_mem_region: err_free_mem_region:
release_mem_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); release_mem_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
err_free_bus:
kfree(ctrl->pci_bus);
err_free_ctrl: err_free_ctrl:
kfree(ctrl); kfree(ctrl);
return rc; return rc;
...@@ -1328,6 +1338,8 @@ static void unload_cpqphpd(void) ...@@ -1328,6 +1338,8 @@ static void unload_cpqphpd(void)
kfree(tres); kfree(tres);
} }
kfree (ctrl->pci_bus);
tctrl = ctrl; tctrl = ctrl;
ctrl = ctrl->next; ctrl = ctrl->next;
kfree(tctrl); kfree(tctrl);
......
...@@ -772,13 +772,13 @@ static struct pci_resource *get_resource (struct pci_resource **head, u32 size) ...@@ -772,13 +772,13 @@ static struct pci_resource *get_resource (struct pci_resource **head, u32 size)
return(NULL); return(NULL);
for (node = *head; node; node = node->next) { for (node = *head; node; node = node->next) {
dbg(__FUNCTION__": req_size =%x node=%p, base=%x, length=%x\n", dbg("%s: req_size =%x node=%p, base=%x, length=%x\n",
size, node, node->base, node->length); __FUNCTION__, size, node, node->base, node->length);
if (node->length < size) if (node->length < size)
continue; continue;
if (node->base & (size - 1)) { if (node->base & (size - 1)) {
dbg(__FUNCTION__": not aligned\n"); dbg("%s: not aligned\n", __FUNCTION__);
// this one isn't base aligned properly // this one isn't base aligned properly
// so we'll make a new entry and split it up // so we'll make a new entry and split it up
temp_dword = (node->base | (size-1)) + 1; temp_dword = (node->base | (size-1)) + 1;
...@@ -804,7 +804,7 @@ static struct pci_resource *get_resource (struct pci_resource **head, u32 size) ...@@ -804,7 +804,7 @@ static struct pci_resource *get_resource (struct pci_resource **head, u32 size)
// Don't need to check if too small since we already did // Don't need to check if too small since we already did
if (node->length > size) { if (node->length > size) {
dbg(__FUNCTION__": too big\n"); dbg("%s: too big\n", __FUNCTION__);
// this one is longer than we need // this one is longer than we need
// so we'll make a new entry and split it up // so we'll make a new entry and split it up
split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL); split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
...@@ -821,7 +821,7 @@ static struct pci_resource *get_resource (struct pci_resource **head, u32 size) ...@@ -821,7 +821,7 @@ static struct pci_resource *get_resource (struct pci_resource **head, u32 size)
node->next = split_node; node->next = split_node;
} // End of too big on top end } // End of too big on top end
dbg(__FUNCTION__": got one!!!\n"); dbg("%s: got one!!!\n", __FUNCTION__);
// If we got here, then it is the right size // If we got here, then it is the right size
// Now take it out of the list // Now take it out of the list
if (*head == node) { if (*head == node) {
...@@ -856,7 +856,7 @@ int cpqhp_resource_sort_and_combine(struct pci_resource **head) ...@@ -856,7 +856,7 @@ int cpqhp_resource_sort_and_combine(struct pci_resource **head)
struct pci_resource *node2; struct pci_resource *node2;
int out_of_order = 1; int out_of_order = 1;
dbg(__FUNCTION__": head = %p, *head = %p\n", head, *head); dbg("%s: head = %p, *head = %p\n", __FUNCTION__, head, *head);
if (!(*head)) if (!(*head))
return(1); return(1);
...@@ -942,7 +942,7 @@ void cpqhp_ctrl_intr(int IRQ, struct controller * ctrl, struct pt_regs *regs) ...@@ -942,7 +942,7 @@ void cpqhp_ctrl_intr(int IRQ, struct controller * ctrl, struct pt_regs *regs)
// Read to clear posted writes // Read to clear posted writes
misc = readw(ctrl->hpc_reg + MISC); misc = readw(ctrl->hpc_reg + MISC);
dbg (__FUNCTION__" - waking up\n"); dbg ("%s - waking up\n", __FUNCTION__);
wake_up_interruptible(&ctrl->queue); wake_up_interruptible(&ctrl->queue);
} }
...@@ -1382,8 +1382,8 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl) ...@@ -1382,8 +1382,8 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl)
struct resource_lists res_lists; struct resource_lists res_lists;
hp_slot = func->device - ctrl->slot_device_offset; hp_slot = func->device - ctrl->slot_device_offset;
dbg(__FUNCTION__": func->device, slot_offset, hp_slot = %d, %d ,%d\n", dbg("%s: func->device, slot_offset, hp_slot = %d, %d ,%d\n",
func->device, ctrl->slot_device_offset, hp_slot); __FUNCTION__, func->device, ctrl->slot_device_offset, hp_slot);
if (ctrl->speed == 1) { if (ctrl->speed == 1) {
// Wait for exclusive access to hardware // Wait for exclusive access to hardware
...@@ -1430,55 +1430,56 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl) ...@@ -1430,55 +1430,56 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl)
// turn on board and blink green LED // turn on board and blink green LED
// Wait for exclusive access to hardware // Wait for exclusive access to hardware
dbg(__FUNCTION__": before down\n"); dbg("%s: before down\n", __FUNCTION__);
down(&ctrl->crit_sect); down(&ctrl->crit_sect);
dbg(__FUNCTION__": after down\n"); dbg("%s: after down\n", __FUNCTION__);
dbg(__FUNCTION__": before slot_enable\n"); dbg("%s: before slot_enable\n", __FUNCTION__);
slot_enable (ctrl, hp_slot); slot_enable (ctrl, hp_slot);
dbg(__FUNCTION__": before green_LED_blink\n"); dbg("%s: before green_LED_blink\n", __FUNCTION__);
green_LED_blink (ctrl, hp_slot); green_LED_blink (ctrl, hp_slot);
dbg(__FUNCTION__": before amber_LED_blink\n"); dbg("%s: before amber_LED_blink\n", __FUNCTION__);
amber_LED_off (ctrl, hp_slot); amber_LED_off (ctrl, hp_slot);
dbg(__FUNCTION__": before set_SOGO\n"); dbg("%s: before set_SOGO\n", __FUNCTION__);
set_SOGO(ctrl); set_SOGO(ctrl);
// Wait for SOBS to be unset // Wait for SOBS to be unset
dbg(__FUNCTION__": before wait_for_ctrl_irq\n"); dbg("%s: before wait_for_ctrl_irq\n", __FUNCTION__);
wait_for_ctrl_irq (ctrl); wait_for_ctrl_irq (ctrl);
dbg(__FUNCTION__": after wait_for_ctrl_irq\n"); dbg("%s: after wait_for_ctrl_irq\n", __FUNCTION__);
// Done with exclusive hardware access // Done with exclusive hardware access
dbg(__FUNCTION__": before up\n"); dbg("%s: before up\n", __FUNCTION__);
up(&ctrl->crit_sect); up(&ctrl->crit_sect);
dbg(__FUNCTION__": after up\n"); dbg("%s: after up\n", __FUNCTION__);
// Wait for ~1 second because of hot plug spec // Wait for ~1 second because of hot plug spec
dbg(__FUNCTION__": before long_delay\n"); dbg("%s: before long_delay\n", __FUNCTION__);
long_delay(1*HZ); long_delay(1*HZ);
dbg(__FUNCTION__": after long_delay\n"); dbg("%s: after long_delay\n", __FUNCTION__);
dbg(__FUNCTION__": func status = %x\n", func->status); dbg("%s: func status = %x\n", __FUNCTION__, func->status);
// Check for a power fault // Check for a power fault
if (func->status == 0xFF) { if (func->status == 0xFF) {
// power fault occurred, but it was benign // power fault occurred, but it was benign
temp_register = 0xFFFFFFFF; temp_register = 0xFFFFFFFF;
dbg(__FUNCTION__": temp register set to %x by power fault\n", temp_register); dbg("%s: temp register set to %x by power fault\n", __FUNCTION__, temp_register);
rc = POWER_FAILURE; rc = POWER_FAILURE;
func->status = 0; func->status = 0;
} else { } else {
// Get vendor/device ID u32 // Get vendor/device ID u32
rc = pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_VENDOR_ID, &temp_register); ctrl->pci_bus->number = func->bus;
dbg(__FUNCTION__": pci_read_config_dword returns %d\n", rc); rc = pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(func->device, func->function), PCI_VENDOR_ID, &temp_register);
dbg(__FUNCTION__": temp_register is %x\n", temp_register); dbg("%s: pci_read_config_dword returns %d\n", __FUNCTION__, rc);
dbg("%s: temp_register is %x\n", __FUNCTION__, temp_register);
if (rc != 0) { if (rc != 0) {
// Something's wrong here // Something's wrong here
temp_register = 0xFFFFFFFF; temp_register = 0xFFFFFFFF;
dbg(__FUNCTION__": temp register set to %x by error\n", temp_register); dbg("%s: temp register set to %x by error\n", __FUNCTION__, temp_register);
} }
// Preset return code. It will be changed later if things go okay. // Preset return code. It will be changed later if things go okay.
rc = NO_ADAPTER_PRESENT; rc = NO_ADAPTER_PRESENT;
...@@ -1494,7 +1495,7 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl) ...@@ -1494,7 +1495,7 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl)
rc = configure_new_device(ctrl, func, 0, &res_lists); rc = configure_new_device(ctrl, func, 0, &res_lists);
dbg(__FUNCTION__": back from configure_new_device\n"); dbg("%s: back from configure_new_device\n", __FUNCTION__);
ctrl->io_head = res_lists.io_head; ctrl->io_head = res_lists.io_head;
ctrl->mem_head = res_lists.mem_head; ctrl->mem_head = res_lists.mem_head;
ctrl->p_mem_head = res_lists.p_mem_head; ctrl->p_mem_head = res_lists.p_mem_head;
...@@ -1531,7 +1532,7 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl) ...@@ -1531,7 +1532,7 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl)
func->is_a_board = 0x01; func->is_a_board = 0x01;
//next, we will instantiate the linux pci_dev structures (with appropriate driver notification, if already present) //next, we will instantiate the linux pci_dev structures (with appropriate driver notification, if already present)
dbg(__FUNCTION__": configure linux pci_dev structure\n"); dbg("%s: configure linux pci_dev structure\n", __FUNCTION__);
index = 0; index = 0;
do { do {
new_slot = cpqhp_slot_find(ctrl->bus, func->device, index++); new_slot = cpqhp_slot_find(ctrl->bus, func->device, index++);
...@@ -1598,7 +1599,7 @@ static u32 remove_board(struct pci_func * func, u32 replace_flag, struct control ...@@ -1598,7 +1599,7 @@ static u32 remove_board(struct pci_func * func, u32 replace_flag, struct control
device = func->device; device = func->device;
hp_slot = func->device - ctrl->slot_device_offset; hp_slot = func->device - ctrl->slot_device_offset;
dbg("In "__FUNCTION__", hp_slot = %d\n", hp_slot); dbg("In %s, hp_slot = %d\n", __FUNCTION__, hp_slot);
// When we get here, it is safe to change base Address Registers. // When we get here, it is safe to change base Address Registers.
// We will attempt to save the base Address Register Lengths // We will attempt to save the base Address Register Lengths
...@@ -1927,7 +1928,7 @@ void cpqhp_pushbutton_thread (unsigned long slot) ...@@ -1927,7 +1928,7 @@ void cpqhp_pushbutton_thread (unsigned long slot)
func = cpqhp_slot_find(p_slot->bus, p_slot->device, 0); func = cpqhp_slot_find(p_slot->bus, p_slot->device, 0);
dbg("In power_down_board, func = %p, ctrl = %p\n", func, ctrl); dbg("In power_down_board, func = %p, ctrl = %p\n", func, ctrl);
if (!func) { if (!func) {
dbg("Error! func NULL in "__FUNCTION__"\n"); dbg("Error! func NULL in %s\n", __FUNCTION__);
return ; return ;
} }
...@@ -1951,7 +1952,7 @@ void cpqhp_pushbutton_thread (unsigned long slot) ...@@ -1951,7 +1952,7 @@ void cpqhp_pushbutton_thread (unsigned long slot)
func = cpqhp_slot_find(p_slot->bus, p_slot->device, 0); func = cpqhp_slot_find(p_slot->bus, p_slot->device, 0);
dbg("In add_board, func = %p, ctrl = %p\n", func, ctrl); dbg("In add_board, func = %p, ctrl = %p\n", func, ctrl);
if (!func) { if (!func) {
dbg("Error! func NULL in "__FUNCTION__"\n"); dbg("Error! func NULL in %s\n", __FUNCTION__);
return ; return ;
} }
...@@ -2066,7 +2067,7 @@ int cpqhp_process_SI (struct controller *ctrl, struct pci_func *func) ...@@ -2066,7 +2067,7 @@ int cpqhp_process_SI (struct controller *ctrl, struct pci_func *func)
} }
if (rc) { if (rc) {
dbg(__FUNCTION__": rc = %d\n", rc); dbg("%s: rc = %d\n", __FUNCTION__, rc);
} }
if (p_slot) if (p_slot)
...@@ -2082,7 +2083,9 @@ int cpqhp_process_SS (struct controller *ctrl, struct pci_func *func) ...@@ -2082,7 +2083,9 @@ int cpqhp_process_SS (struct controller *ctrl, struct pci_func *func)
u8 index = 0; u8 index = 0;
u8 replace_flag; u8 replace_flag;
u32 rc = 0; u32 rc = 0;
unsigned int devfn;
struct slot* p_slot; struct slot* p_slot;
struct pci_bus *pci_bus = ctrl->pci_bus;
int physical_slot=0; int physical_slot=0;
device = func->device; device = func->device;
...@@ -2094,8 +2097,11 @@ int cpqhp_process_SS (struct controller *ctrl, struct pci_func *func) ...@@ -2094,8 +2097,11 @@ int cpqhp_process_SS (struct controller *ctrl, struct pci_func *func)
// Make sure there are no video controllers here // Make sure there are no video controllers here
while (func && !rc) { while (func && !rc) {
pci_bus->number = func->bus;
devfn = PCI_DEVFN(func->device, func->function);
// Check the Class Code // Check the Class Code
rc = pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, 0x0B, &class_code); rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
if (rc) if (rc)
return rc; return rc;
...@@ -2104,13 +2110,13 @@ int cpqhp_process_SS (struct controller *ctrl, struct pci_func *func) ...@@ -2104,13 +2110,13 @@ int cpqhp_process_SS (struct controller *ctrl, struct pci_func *func)
rc = REMOVE_NOT_SUPPORTED; rc = REMOVE_NOT_SUPPORTED;
} else { } else {
// See if it's a bridge // See if it's a bridge
rc = pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_HEADER_TYPE, &header_type); rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
if (rc) if (rc)
return rc; return rc;
// If it's a bridge, check the VGA Enable bit // If it's a bridge, check the VGA Enable bit
if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
rc = pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_BRIDGE_CONTROL, &BCR); rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_BRIDGE_CONTROL, &BCR);
if (rc) if (rc)
return rc; return rc;
...@@ -2332,11 +2338,12 @@ static u32 configure_new_device (struct controller * ctrl, struct pci_func * fun ...@@ -2332,11 +2338,12 @@ static u32 configure_new_device (struct controller * ctrl, struct pci_func * fun
new_slot = func; new_slot = func;
dbg(__FUNCTION__"\n"); dbg("%s\n", __FUNCTION__);
// Check for Multi-function device // Check for Multi-function device
rc = pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, 0x0E, &temp_byte); ctrl->pci_bus->number = func->bus;
rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(func->device, func->function), 0x0E, &temp_byte);
if (rc) { if (rc) {
dbg(__FUNCTION__": rc = %d\n", rc); dbg("%s: rc = %d\n", __FUNCTION__, rc);
return rc; return rc;
} }
...@@ -2372,7 +2379,7 @@ static u32 configure_new_device (struct controller * ctrl, struct pci_func * fun ...@@ -2372,7 +2379,7 @@ static u32 configure_new_device (struct controller * ctrl, struct pci_func * fun
// and creates a board structure // and creates a board structure
while ((function < max_functions) && (!stop_it)) { while ((function < max_functions) && (!stop_it)) {
pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, function, 0x00, &ID); pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(func->device, function), 0x00, &ID);
if (ID == 0xFFFFFFFF) { // There's nothing there. if (ID == 0xFFFFFFFF) { // There's nothing there.
function++; function++;
...@@ -2435,6 +2442,7 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f ...@@ -2435,6 +2442,7 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
u32 temp_register; u32 temp_register;
u32 base; u32 base;
u32 ID; u32 ID;
unsigned int devfn;
struct pci_resource *mem_node; struct pci_resource *mem_node;
struct pci_resource *p_mem_node; struct pci_resource *p_mem_node;
struct pci_resource *io_node; struct pci_resource *io_node;
...@@ -2445,17 +2453,22 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f ...@@ -2445,17 +2453,22 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
struct pci_resource *hold_bus_node; struct pci_resource *hold_bus_node;
struct irq_mapping irqs; struct irq_mapping irqs;
struct pci_func *new_slot; struct pci_func *new_slot;
struct pci_bus *pci_bus;
struct resource_lists temp_resources; struct resource_lists temp_resources;
pci_bus = ctrl->pci_bus;
pci_bus->number = func->bus;
devfn = PCI_DEVFN(func->device, func->function);
// Check for Bridge // Check for Bridge
rc = pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_HEADER_TYPE, &temp_byte); rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &temp_byte);
if (rc) if (rc)
return rc; return rc;
if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge
// set Primary bus // set Primary bus
dbg("set Primary bus = %d\n", func->bus); dbg("set Primary bus = %d\n", func->bus);
rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_PRIMARY_BUS, func->bus); rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_PRIMARY_BUS, func->bus);
if (rc) if (rc)
return rc; return rc;
...@@ -2470,29 +2483,29 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f ...@@ -2470,29 +2483,29 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
// set Secondary bus // set Secondary bus
temp_byte = bus_node->base; temp_byte = bus_node->base;
dbg("set Secondary bus = %d\n", bus_node->base); dbg("set Secondary bus = %d\n", bus_node->base);
rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_SECONDARY_BUS, temp_byte); rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_SECONDARY_BUS, temp_byte);
if (rc) if (rc)
return rc; return rc;
// set subordinate bus // set subordinate bus
temp_byte = bus_node->base + bus_node->length - 1; temp_byte = bus_node->base + bus_node->length - 1;
dbg("set subordinate bus = %d\n", bus_node->base + bus_node->length - 1); dbg("set subordinate bus = %d\n", bus_node->base + bus_node->length - 1);
rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_SUBORDINATE_BUS, temp_byte); rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_SUBORDINATE_BUS, temp_byte);
if (rc) if (rc)
return rc; return rc;
// set subordinate Latency Timer and base Latency Timer // set subordinate Latency Timer and base Latency Timer
temp_byte = 0x40; temp_byte = 0x40;
rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_SEC_LATENCY_TIMER, temp_byte); rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_SEC_LATENCY_TIMER, temp_byte);
if (rc) if (rc)
return rc; return rc;
rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_LATENCY_TIMER, temp_byte); rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_LATENCY_TIMER, temp_byte);
if (rc) if (rc)
return rc; return rc;
// set Cache Line size // set Cache Line size
temp_byte = 0x08; temp_byte = 0x08;
rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_CACHE_LINE_SIZE, temp_byte); rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_CACHE_LINE_SIZE, temp_byte);
if (rc) if (rc)
return rc; return rc;
...@@ -2568,10 +2581,10 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f ...@@ -2568,10 +2581,10 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
// set IO base and Limit registers // set IO base and Limit registers
temp_byte = io_node->base >> 8; temp_byte = io_node->base >> 8;
rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_IO_BASE, temp_byte); rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_BASE, temp_byte);
temp_byte = (io_node->base + io_node->length - 1) >> 8; temp_byte = (io_node->base + io_node->length - 1) >> 8;
rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_IO_LIMIT, temp_byte); rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
} else { } else {
kfree(hold_IO_node); kfree(hold_IO_node);
hold_IO_node = NULL; hold_IO_node = NULL;
...@@ -2586,16 +2599,16 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f ...@@ -2586,16 +2599,16 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
// set Mem base and Limit registers // set Mem base and Limit registers
temp_word = mem_node->base >> 16; temp_word = mem_node->base >> 16;
rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_MEMORY_BASE, temp_word); rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_BASE, temp_word);
temp_word = (mem_node->base + mem_node->length - 1) >> 16; temp_word = (mem_node->base + mem_node->length - 1) >> 16;
rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_MEMORY_LIMIT, temp_word); rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
} else { } else {
temp_word = 0xFFFF; temp_word = 0xFFFF;
rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_MEMORY_BASE, temp_word); rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_BASE, temp_word);
temp_word = 0x0000; temp_word = 0x0000;
rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_MEMORY_LIMIT, temp_word); rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
kfree(hold_mem_node); kfree(hold_mem_node);
hold_mem_node = NULL; hold_mem_node = NULL;
...@@ -2610,16 +2623,16 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f ...@@ -2610,16 +2623,16 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
// set Pre Mem base and Limit registers // set Pre Mem base and Limit registers
temp_word = p_mem_node->base >> 16; temp_word = p_mem_node->base >> 16;
rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_PREF_MEMORY_BASE, temp_word); rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
temp_word = (p_mem_node->base + p_mem_node->length - 1) >> 16; temp_word = (p_mem_node->base + p_mem_node->length - 1) >> 16;
rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_PREF_MEMORY_LIMIT, temp_word); rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
} else { } else {
temp_word = 0xFFFF; temp_word = 0xFFFF;
rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_PREF_MEMORY_BASE, temp_word); rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
temp_word = 0x0000; temp_word = 0x0000;
rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_PREF_MEMORY_LIMIT, temp_word); rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
kfree(hold_p_mem_node); kfree(hold_p_mem_node);
hold_p_mem_node = NULL; hold_p_mem_node = NULL;
...@@ -2635,7 +2648,9 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f ...@@ -2635,7 +2648,9 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
irqs.barber_pole = (irqs.barber_pole + 1) & 0x03; irqs.barber_pole = (irqs.barber_pole + 1) & 0x03;
ID = 0xFFFFFFFF; ID = 0xFFFFFFFF;
pci_read_config_dword_nodev (ctrl->pci_ops, hold_bus_node->base, device, 0, 0x00, &ID); pci_bus->number = hold_bus_node->base;
pci_bus_read_config_dword (pci_bus, PCI_DEVFN(device, 0), 0x00, &ID);
pci_bus->number = func->bus;
if (ID != 0xFFFFFFFF) { // device Present if (ID != 0xFFFFFFFF) { // device Present
// Setup slot structure. // Setup slot structure.
...@@ -2703,7 +2718,7 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f ...@@ -2703,7 +2718,7 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
temp_byte = temp_resources.bus_head->base - 1; temp_byte = temp_resources.bus_head->base - 1;
// set subordinate bus // set subordinate bus
rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_SUBORDINATE_BUS, temp_byte); rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_SUBORDINATE_BUS, temp_byte);
if (temp_resources.bus_head->length == 0) { if (temp_resources.bus_head->length == 0) {
kfree(temp_resources.bus_head); kfree(temp_resources.bus_head);
...@@ -2724,7 +2739,7 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f ...@@ -2724,7 +2739,7 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
hold_IO_node->base = io_node->base + io_node->length; hold_IO_node->base = io_node->base + io_node->length;
temp_byte = (hold_IO_node->base) >> 8; temp_byte = (hold_IO_node->base) >> 8;
rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_IO_BASE, temp_byte); rc = pci_bus_write_config_word (pci_bus, devfn, PCI_IO_BASE, temp_byte);
return_resource(&(resources->io_head), io_node); return_resource(&(resources->io_head), io_node);
} }
...@@ -2742,13 +2757,13 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f ...@@ -2742,13 +2757,13 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
func->io_head = hold_IO_node; func->io_head = hold_IO_node;
temp_byte = (io_node->base - 1) >> 8; temp_byte = (io_node->base - 1) >> 8;
rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_IO_LIMIT, temp_byte); rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
return_resource(&(resources->io_head), io_node); return_resource(&(resources->io_head), io_node);
} else { } else {
// it doesn't need any IO // it doesn't need any IO
temp_word = 0x0000; temp_word = 0x0000;
pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_IO_LIMIT, temp_word); rc = pci_bus_write_config_word (pci_bus, devfn, PCI_IO_LIMIT, temp_word);
return_resource(&(resources->io_head), io_node); return_resource(&(resources->io_head), io_node);
kfree(hold_IO_node); kfree(hold_IO_node);
...@@ -2774,7 +2789,7 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f ...@@ -2774,7 +2789,7 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
hold_mem_node->base = mem_node->base + mem_node->length; hold_mem_node->base = mem_node->base + mem_node->length;
temp_word = (hold_mem_node->base) >> 16; temp_word = (hold_mem_node->base) >> 16;
rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_MEMORY_BASE, temp_word); rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_BASE, temp_word);
return_resource(&(resources->mem_head), mem_node); return_resource(&(resources->mem_head), mem_node);
} }
...@@ -2792,14 +2807,14 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f ...@@ -2792,14 +2807,14 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
// configure end address // configure end address
temp_word = (mem_node->base - 1) >> 16; temp_word = (mem_node->base - 1) >> 16;
rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_MEMORY_LIMIT, temp_word); rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
// Return unused resources to the pool // Return unused resources to the pool
return_resource(&(resources->mem_head), mem_node); return_resource(&(resources->mem_head), mem_node);
} else { } else {
// it doesn't need any Mem // it doesn't need any Mem
temp_word = 0x0000; temp_word = 0x0000;
rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_MEMORY_LIMIT, temp_word); rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
return_resource(&(resources->mem_head), mem_node); return_resource(&(resources->mem_head), mem_node);
kfree(hold_mem_node); kfree(hold_mem_node);
...@@ -2825,7 +2840,7 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f ...@@ -2825,7 +2840,7 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
hold_p_mem_node->base = p_mem_node->base + p_mem_node->length; hold_p_mem_node->base = p_mem_node->base + p_mem_node->length;
temp_word = (hold_p_mem_node->base) >> 16; temp_word = (hold_p_mem_node->base) >> 16;
rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_PREF_MEMORY_BASE, temp_word); rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
return_resource(&(resources->p_mem_head), p_mem_node); return_resource(&(resources->p_mem_head), p_mem_node);
} }
...@@ -2843,13 +2858,13 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f ...@@ -2843,13 +2858,13 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
func->p_mem_head = hold_p_mem_node; func->p_mem_head = hold_p_mem_node;
temp_word = (p_mem_node->base - 1) >> 16; temp_word = (p_mem_node->base - 1) >> 16;
rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_PREF_MEMORY_LIMIT, temp_word); rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
return_resource(&(resources->p_mem_head), p_mem_node); return_resource(&(resources->p_mem_head), p_mem_node);
} else { } else {
// it doesn't need any PMem // it doesn't need any PMem
temp_word = 0x0000; temp_word = 0x0000;
rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_PREF_MEMORY_LIMIT, temp_word); rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
return_resource(&(resources->p_mem_head), p_mem_node); return_resource(&(resources->p_mem_head), p_mem_node);
kfree(hold_p_mem_node); kfree(hold_p_mem_node);
...@@ -2870,14 +2885,14 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f ...@@ -2870,14 +2885,14 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
// enable card // enable card
command = 0x0157; // = PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR command = 0x0157; // = PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR
rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_COMMAND, command); rc = pci_bus_write_config_word (pci_bus, devfn, PCI_COMMAND, command);
// set Bridge Control Register // set Bridge Control Register
command = 0x07; // = PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR | PCI_BRIDGE_CTL_NO_ISA command = 0x07; // = PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR | PCI_BRIDGE_CTL_NO_ISA
rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_BRIDGE_CONTROL, command); rc = pci_bus_write_config_word (pci_bus, devfn, PCI_BRIDGE_CONTROL, command);
} else if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_NORMAL) { } else if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
// Standard device // Standard device
rc = pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, 0x0B, &class_code); rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
if (class_code == PCI_BASE_CLASS_DISPLAY) { if (class_code == PCI_BASE_CLASS_DISPLAY) {
// Display (video) adapter (not supported) // Display (video) adapter (not supported)
...@@ -2887,10 +2902,10 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f ...@@ -2887,10 +2902,10 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
for (cloop = 0x10; cloop <= 0x24; cloop += 4) { for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
temp_register = 0xFFFFFFFF; temp_register = 0xFFFFFFFF;
dbg("CND: bus=%d, device=%d, func=%d, offset=%d\n", func->bus, func->device, func->function, cloop); dbg("CND: bus=%d, devfn=%d, offset=%d\n", pci_bus->number, devfn, cloop);
rc = pci_write_config_dword_nodev(ctrl->pci_ops, func->bus, func->device, func->function, cloop, temp_register); rc = pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
rc = pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, cloop, &temp_register); rc = pci_bus_read_config_dword (pci_bus, devfn, cloop, &temp_register);
dbg("CND: base = 0x%x\n", temp_register); dbg("CND: base = 0x%x\n", temp_register);
if (temp_register) { // If this register is implemented if (temp_register) { // If this register is implemented
...@@ -2971,7 +2986,7 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f ...@@ -2971,7 +2986,7 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
return(NOT_ENOUGH_RESOURCES); return(NOT_ENOUGH_RESOURCES);
} }
rc = pci_write_config_dword_nodev(ctrl->pci_ops, func->bus, func->device, func->function, cloop, base); rc = pci_bus_write_config_dword (pci_bus, devfn, cloop, base);
// Check for 64-bit base // Check for 64-bit base
if ((temp_register & 0x07L) == 0x04) { if ((temp_register & 0x07L) == 0x04) {
...@@ -2980,13 +2995,13 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f ...@@ -2980,13 +2995,13 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
// Upper 32 bits of address always zero on today's systems // Upper 32 bits of address always zero on today's systems
// FIXME this is probably not true on Alpha and ia64??? // FIXME this is probably not true on Alpha and ia64???
base = 0; base = 0;
rc = pci_write_config_dword_nodev(ctrl->pci_ops, func->bus, func->device, func->function, cloop, base); rc = pci_bus_write_config_dword (pci_bus, devfn, cloop, base);
} }
} }
} // End of base register loop } // End of base register loop
// Figure out which interrupt pin this function uses // Figure out which interrupt pin this function uses
rc = pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_INTERRUPT_PIN, &temp_byte); rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_INTERRUPT_PIN, &temp_byte);
// If this function needs an interrupt and we are behind a bridge // If this function needs an interrupt and we are behind a bridge
// and the pin is tied to something that's alread mapped, // and the pin is tied to something that's alread mapped,
...@@ -2998,7 +3013,7 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f ...@@ -2998,7 +3013,7 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
IRQ = resources->irqs->interrupt[(temp_byte + resources->irqs->barber_pole - 1) & 0x03]; IRQ = resources->irqs->interrupt[(temp_byte + resources->irqs->barber_pole - 1) & 0x03];
} else { } else {
// Program IRQ based on card type // Program IRQ based on card type
rc = pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, 0x0B, &class_code); rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code);
if (class_code == PCI_BASE_CLASS_STORAGE) { if (class_code == PCI_BASE_CLASS_STORAGE) {
IRQ = cpqhp_disk_irq; IRQ = cpqhp_disk_irq;
...@@ -3008,7 +3023,7 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f ...@@ -3008,7 +3023,7 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
} }
// IRQ Line // IRQ Line
rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_INTERRUPT_LINE, IRQ); rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_INTERRUPT_LINE, IRQ);
if (!behind_bridge) { if (!behind_bridge) {
rc = cpqhp_set_irq(func->bus, func->device, temp_byte + 0x09, IRQ); rc = cpqhp_set_irq(func->bus, func->device, temp_byte + 0x09, IRQ);
...@@ -3022,19 +3037,19 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f ...@@ -3022,19 +3037,19 @@ static int configure_new_function (struct controller * ctrl, struct pci_func * f
// Latency Timer // Latency Timer
temp_byte = 0x40; temp_byte = 0x40;
rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_LATENCY_TIMER, temp_byte); rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_LATENCY_TIMER, temp_byte);
// Cache Line size // Cache Line size
temp_byte = 0x08; temp_byte = 0x08;
rc = pci_write_config_byte_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_CACHE_LINE_SIZE, temp_byte); rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_CACHE_LINE_SIZE, temp_byte);
// disable ROM base Address // disable ROM base Address
temp_dword = 0x00L; temp_dword = 0x00L;
rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_ROM_ADDRESS, temp_dword); rc = pci_bus_write_config_word (pci_bus, devfn, PCI_ROM_ADDRESS, temp_dword);
// enable card // enable card
temp_word = 0x0157; // = PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR temp_word = 0x0157; // = PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR
rc = pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_COMMAND, temp_word); rc = pci_bus_write_config_word (pci_bus, devfn, PCI_COMMAND, temp_word);
} // End of Not-A-Bridge else } // End of Not-A-Bridge else
else { else {
// It's some strange type of PCI adapter (Cardbus?) // It's some strange type of PCI adapter (Cardbus?)
......
...@@ -161,7 +161,7 @@ static int check_for_compaq_ROM (void *rom_start) ...@@ -161,7 +161,7 @@ static int check_for_compaq_ROM (void *rom_start)
(temp6 == 'Q')) { (temp6 == 'Q')) {
result = 1; result = 1;
} }
dbg (__FUNCTION__" - returned %d\n", result); dbg ("%s - returned %d\n", __FUNCTION__, result);
return result; return result;
} }
...@@ -286,12 +286,12 @@ static u32 store_HRT (void *rom_start) ...@@ -286,12 +286,12 @@ static u32 store_HRT (void *rom_start)
return(rc); return(rc);
// The device Number // The device Number
rc = add_byte( &pFill, ctrl->device, &usedbytes, &available); rc = add_byte( &pFill, PCI_SLOT(ctrl->pci_dev->devfn), &usedbytes, &available);
if (rc) if (rc)
return(rc); return(rc);
// The function Number // The function Number
rc = add_byte( &pFill, ctrl->function, &usedbytes, &available); rc = add_byte( &pFill, PCI_FUNC(ctrl->pci_dev->devfn), &usedbytes, &available);
if (rc) if (rc)
return(rc); return(rc);
...@@ -479,8 +479,9 @@ int compaq_nvram_load (void *rom_start, struct controller *ctrl) ...@@ -479,8 +479,9 @@ int compaq_nvram_load (void *rom_start, struct controller *ctrl)
device = p_ev_ctrl->device; device = p_ev_ctrl->device;
function = p_ev_ctrl->function; function = p_ev_ctrl->function;
while ((bus != ctrl->bus) || (device != ctrl->device) while ((bus != ctrl->bus) ||
|| (function != ctrl->function)) { (device != PCI_SLOT(ctrl->pci_dev->devfn)) ||
(function != PCI_FUNC(ctrl->pci_dev->devfn))) {
nummem = p_ev_ctrl->mem_avail; nummem = p_ev_ctrl->mem_avail;
numpmem = p_ev_ctrl->p_mem_avail; numpmem = p_ev_ctrl->p_mem_avail;
numio = p_ev_ctrl->io_avail; numio = p_ev_ctrl->io_avail;
......
...@@ -140,7 +140,7 @@ static int configure_visit_pci_dev (struct pci_dev_wrapped *wrapped_dev, struct ...@@ -140,7 +140,7 @@ static int configure_visit_pci_dev (struct pci_dev_wrapped *wrapped_dev, struct
//We did not even find a hotplug rep of the function, create it //We did not even find a hotplug rep of the function, create it
//This code might be taken out if we can guarantee the creation of functions //This code might be taken out if we can guarantee the creation of functions
//in parallel (hotplug and Linux at the same time). //in parallel (hotplug and Linux at the same time).
dbg("@@@@@@@@@@@ cpqhp_slot_create in "__FUNCTION__"\n"); dbg("@@@@@@@@@@@ cpqhp_slot_create in %s\n", __FUNCTION__);
temp_func = cpqhp_slot_create(bus->number); temp_func = cpqhp_slot_create(bus->number);
if (temp_func == NULL) if (temp_func == NULL)
return -ENOMEM; return -ENOMEM;
...@@ -150,8 +150,9 @@ static int configure_visit_pci_dev (struct pci_dev_wrapped *wrapped_dev, struct ...@@ -150,8 +150,9 @@ static int configure_visit_pci_dev (struct pci_dev_wrapped *wrapped_dev, struct
//Create /proc/bus/pci proc entry for this device and bus device is on //Create /proc/bus/pci proc entry for this device and bus device is on
//Notify the drivers of the change //Notify the drivers of the change
if (temp_func->pci_dev) { if (temp_func->pci_dev) {
pci_proc_attach_device(temp_func->pci_dev); // pci_insert_device (temp_func->pci_dev, bus);
pci_announce_device_to_drivers(temp_func->pci_dev); // pci_proc_attach_device(temp_func->pci_dev);
// pci_announce_device_to_drivers(temp_func->pci_dev);
} }
return 0; return 0;
...@@ -307,7 +308,7 @@ int cpqhp_unconfigure_device(struct pci_func* func) ...@@ -307,7 +308,7 @@ int cpqhp_unconfigure_device(struct pci_func* func)
memset(&wrapped_dev, 0, sizeof(struct pci_dev_wrapped)); memset(&wrapped_dev, 0, sizeof(struct pci_dev_wrapped));
memset(&wrapped_bus, 0, sizeof(struct pci_bus_wrapped)); memset(&wrapped_bus, 0, sizeof(struct pci_bus_wrapped));
dbg(__FUNCTION__": bus/dev/func = %x/%x/%x\n",func->bus, func->device, func->function); dbg("%s: bus/dev/func = %x/%x/%x\n", __FUNCTION__, func->bus, func->device, func->function);
for (j=0; j<8 ; j++) { for (j=0; j<8 ; j++) {
struct pci_dev* temp = pci_find_slot(func->bus, (func->device << 3) | j); struct pci_dev* temp = pci_find_slot(func->bus, (func->device << 3) | j);
...@@ -326,15 +327,15 @@ int cpqhp_unconfigure_device(struct pci_func* func) ...@@ -326,15 +327,15 @@ int cpqhp_unconfigure_device(struct pci_func* func)
return rc; return rc;
} }
static int PCI_RefinedAccessConfig(struct pci_ops *ops, u8 bus, u8 device, u8 function, u8 offset, u32 *value) static int PCI_RefinedAccessConfig(struct pci_bus *bus, unsigned int devfn, u8 offset, u32 *value)
{ {
u32 vendID = 0; u32 vendID = 0;
if (pci_read_config_dword_nodev (ops, bus, device, function, PCI_VENDOR_ID, &vendID) == -1) if (pci_bus_read_config_dword (bus, devfn, PCI_VENDOR_ID, &vendID) == -1)
return -1; return -1;
if (vendID == 0xffffffff) if (vendID == 0xffffffff)
return -1; return -1;
return pci_read_config_dword_nodev (ops, bus, device, function, offset, value); return pci_bus_read_config_dword (bus, devfn, offset, value);
} }
...@@ -355,10 +356,10 @@ int cpqhp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num) ...@@ -355,10 +356,10 @@ int cpqhp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num)
fakedev.devfn = dev_num << 3; fakedev.devfn = dev_num << 3;
fakedev.bus = &fakebus; fakedev.bus = &fakebus;
fakebus.number = bus_num; fakebus.number = bus_num;
dbg(__FUNCTION__": dev %d, bus %d, pin %d, num %d\n", dbg("%s: dev %d, bus %d, pin %d, num %d\n",
dev_num, bus_num, int_pin, irq_num); __FUNCTION__, dev_num, bus_num, int_pin, irq_num);
rc = pcibios_set_irq_routing(&fakedev, int_pin - 0x0a, irq_num); rc = pcibios_set_irq_routing(&fakedev, int_pin - 0x0a, irq_num);
dbg(__FUNCTION__":rc %d\n", rc); dbg("%s: rc %d\n", __FUNCTION__, rc);
if (rc) if (rc)
return rc; return rc;
...@@ -392,9 +393,11 @@ static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 * dev ...@@ -392,9 +393,11 @@ static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 * dev
u32 work; u32 work;
u8 tbus; u8 tbus;
ctrl->pci_bus->number = bus_num;
for (tdevice = 0; tdevice < 0x100; tdevice++) { for (tdevice = 0; tdevice < 0x100; tdevice++) {
//Scan for access first //Scan for access first
if (PCI_RefinedAccessConfig(ctrl->pci_ops, bus_num, tdevice >> 3, tdevice & 0x7, 0x08, &work) == -1) if (PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work) == -1)
continue; continue;
dbg("Looking for nonbridge bus_num %d dev_num %d\n", bus_num, tdevice); dbg("Looking for nonbridge bus_num %d dev_num %d\n", bus_num, tdevice);
//Yep we got one. Not a bridge ? //Yep we got one. Not a bridge ?
...@@ -406,12 +409,12 @@ static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 * dev ...@@ -406,12 +409,12 @@ static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 * dev
} }
for (tdevice = 0; tdevice < 0x100; tdevice++) { for (tdevice = 0; tdevice < 0x100; tdevice++) {
//Scan for access first //Scan for access first
if (PCI_RefinedAccessConfig(ctrl->pci_ops, bus_num, tdevice >> 3, tdevice & 0x7, 0x08, &work) == -1) if (PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work) == -1)
continue; continue;
dbg("Looking for bridge bus_num %d dev_num %d\n", bus_num, tdevice); dbg("Looking for bridge bus_num %d dev_num %d\n", bus_num, tdevice);
//Yep we got one. bridge ? //Yep we got one. bridge ?
if ((work >> 8) == PCI_TO_PCI_BRIDGE_CLASS) { if ((work >> 8) == PCI_TO_PCI_BRIDGE_CLASS) {
pci_read_config_byte_nodev (ctrl->pci_ops, tbus, tdevice, 0, PCI_SECONDARY_BUS, &tbus); pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(tdevice, 0), PCI_SECONDARY_BUS, &tbus);
dbg("Recurse on bus_num %d tdevice %d\n", tbus, tdevice); dbg("Recurse on bus_num %d tdevice %d\n", tbus, tdevice);
if (PCI_ScanBusNonBridge(tbus, tdevice) == 0) if (PCI_ScanBusNonBridge(tbus, tdevice) == 0)
return 0; return 0;
...@@ -450,19 +453,20 @@ static int PCI_GetBusDevHelper(struct controller *ctrl, u8 *bus_num, u8 *dev_num ...@@ -450,19 +453,20 @@ static int PCI_GetBusDevHelper(struct controller *ctrl, u8 *bus_num, u8 *dev_num
if (tslot == slot) { if (tslot == slot) {
*bus_num = tbus; *bus_num = tbus;
*dev_num = tdevice; *dev_num = tdevice;
pci_read_config_dword_nodev (ctrl->pci_ops, *bus_num, *dev_num >> 3, *dev_num & 0x7, PCI_VENDOR_ID, &work); ctrl->pci_bus->number = tbus;
pci_bus_read_config_dword (ctrl->pci_bus, *dev_num, PCI_VENDOR_ID, &work);
if (!nobridge || (work == 0xffffffff)) { if (!nobridge || (work == 0xffffffff)) {
if (PCIIRQRoutingInfoLength != NULL) if (PCIIRQRoutingInfoLength != NULL)
kfree(PCIIRQRoutingInfoLength ); kfree(PCIIRQRoutingInfoLength );
return 0; return 0;
} }
dbg("bus_num %d dev_num %d func_num %d\n", *bus_num, *dev_num >> 3, *dev_num & 0x7); dbg("bus_num %d devfn %d\n", *bus_num, *dev_num);
pci_read_config_dword_nodev (ctrl->pci_ops, *bus_num, *dev_num >> 3, *dev_num & 0x7, PCI_CLASS_REVISION, &work); pci_bus_read_config_dword (ctrl->pci_bus, *dev_num, PCI_CLASS_REVISION, &work);
dbg("work >> 8 (%x) = BRIDGE (%x)\n", work >> 8, PCI_TO_PCI_BRIDGE_CLASS); dbg("work >> 8 (%x) = BRIDGE (%x)\n", work >> 8, PCI_TO_PCI_BRIDGE_CLASS);
if ((work >> 8) == PCI_TO_PCI_BRIDGE_CLASS) { if ((work >> 8) == PCI_TO_PCI_BRIDGE_CLASS) {
pci_read_config_byte_nodev (ctrl->pci_ops, *bus_num, *dev_num >> 3, *dev_num & 0x7, PCI_SECONDARY_BUS, &tbus); pci_bus_read_config_byte (ctrl->pci_bus, *dev_num, PCI_SECONDARY_BUS, &tbus);
dbg("Scan bus for Non Bridge: bus %d\n", tbus); dbg("Scan bus for Non Bridge: bus %d\n", tbus);
if (PCI_ScanBusForNonBridge(ctrl, tbus, dev_num) == 0) { if (PCI_ScanBusForNonBridge(ctrl, tbus, dev_num) == 0) {
*bus_num = tbus; *bus_num = tbus;
...@@ -535,17 +539,17 @@ int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug) ...@@ -535,17 +539,17 @@ int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug)
} }
// Save PCI configuration space for all devices in supported slots // Save PCI configuration space for all devices in supported slots
ctrl->pci_bus->number = busnumber;
for (device = FirstSupported; device <= LastSupported; device++) { for (device = FirstSupported; device <= LastSupported; device++) {
ID = 0xFFFFFFFF; ID = 0xFFFFFFFF;
rc = pci_read_config_dword_nodev (ctrl->pci_ops, busnumber, device, 0, PCI_VENDOR_ID, &ID); rc = pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(device, 0), PCI_VENDOR_ID, &ID);
if (ID != 0xFFFFFFFF) { // device in slot if (ID != 0xFFFFFFFF) { // device in slot
rc = pci_read_config_byte_nodev (ctrl->pci_ops, busnumber, device, 0, 0x0B, &class_code); rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, 0), 0x0B, &class_code);
if (rc) if (rc)
return rc; return rc;
rc = pci_read_config_byte_nodev (ctrl->pci_ops, busnumber, device, 0, PCI_HEADER_TYPE, &header_type); rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, 0), PCI_HEADER_TYPE, &header_type);
if (rc) if (rc)
return rc; return rc;
...@@ -563,7 +567,7 @@ int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug) ...@@ -563,7 +567,7 @@ int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug)
if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // P-P Bridge if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // P-P Bridge
// Recurse the subordinate bus // Recurse the subordinate bus
// get the subordinate bus number // get the subordinate bus number
rc = pci_read_config_byte_nodev (ctrl->pci_ops, busnumber, device, function, PCI_SECONDARY_BUS, &secondary_bus); rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, function), PCI_SECONDARY_BUS, &secondary_bus);
if (rc) { if (rc) {
return rc; return rc;
} else { } else {
...@@ -572,9 +576,9 @@ int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug) ...@@ -572,9 +576,9 @@ int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug)
// Save secondary bus cfg spc // Save secondary bus cfg spc
// with this recursive call. // with this recursive call.
rc = cpqhp_save_config(ctrl, sub_bus, 0); rc = cpqhp_save_config(ctrl, sub_bus, 0);
if (rc) if (rc)
return rc; return rc;
ctrl->pci_bus->number = busnumber;
} }
} }
...@@ -602,7 +606,7 @@ int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug) ...@@ -602,7 +606,7 @@ int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug)
new_slot->pci_dev = pci_find_slot(new_slot->bus, (new_slot->device << 3) | new_slot->function); new_slot->pci_dev = pci_find_slot(new_slot->bus, (new_slot->device << 3) | new_slot->function);
for (cloop = 0; cloop < 0x20; cloop++) { for (cloop = 0; cloop < 0x20; cloop++) {
rc = pci_read_config_dword_nodev (ctrl->pci_ops, busnumber, device, function, cloop << 2, (u32 *) & (new_slot-> config_space [cloop])); rc = pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(device, function), cloop << 2, (u32 *) & (new_slot-> config_space [cloop]));
if (rc) if (rc)
return rc; return rc;
} }
...@@ -615,15 +619,15 @@ int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug) ...@@ -615,15 +619,15 @@ int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug)
// reading in Class Code and Header type. // reading in Class Code and Header type.
while ((function < max_functions)&&(!stop_it)) { while ((function < max_functions)&&(!stop_it)) {
rc = pci_read_config_dword_nodev (ctrl->pci_ops, busnumber, device, function, PCI_VENDOR_ID, &ID); rc = pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(device, function), PCI_VENDOR_ID, &ID);
if (ID == 0xFFFFFFFF) { // nothing there. if (ID == 0xFFFFFFFF) { // nothing there.
function++; function++;
} else { // Something there } else { // Something there
rc = pci_read_config_byte_nodev (ctrl->pci_ops, busnumber, device, function, 0x0B, &class_code); rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, function), 0x0B, &class_code);
if (rc) if (rc)
return rc; return rc;
rc = pci_read_config_byte_nodev (ctrl->pci_ops, busnumber, device, function, PCI_HEADER_TYPE, &header_type); rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, function), PCI_HEADER_TYPE, &header_type);
if (rc) if (rc)
return rc; return rc;
...@@ -677,12 +681,12 @@ int cpqhp_save_slot_config (struct controller *ctrl, struct pci_func * new_slot) ...@@ -677,12 +681,12 @@ int cpqhp_save_slot_config (struct controller *ctrl, struct pci_func * new_slot)
ID = 0xFFFFFFFF; ID = 0xFFFFFFFF;
pci_read_config_dword_nodev (ctrl->pci_ops, new_slot->bus, new_slot->device, 0, PCI_VENDOR_ID, &ID); ctrl->pci_bus->number = new_slot->bus;
pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), PCI_VENDOR_ID, &ID);
if (ID != 0xFFFFFFFF) { // device in slot if (ID != 0xFFFFFFFF) { // device in slot
pci_read_config_byte_nodev (ctrl->pci_ops, new_slot->bus, new_slot->device, 0, 0x0B, &class_code); pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), 0x0B, &class_code);
pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), PCI_HEADER_TYPE, &header_type);
pci_read_config_byte_nodev (ctrl->pci_ops, new_slot->bus, new_slot->device, 0, PCI_HEADER_TYPE, &header_type);
if (header_type & 0x80) // Multi-function device if (header_type & 0x80) // Multi-function device
max_functions = 8; max_functions = 8;
...@@ -694,22 +698,22 @@ int cpqhp_save_slot_config (struct controller *ctrl, struct pci_func * new_slot) ...@@ -694,22 +698,22 @@ int cpqhp_save_slot_config (struct controller *ctrl, struct pci_func * new_slot)
do { do {
if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge
// Recurse the subordinate bus // Recurse the subordinate bus
pci_read_config_byte_nodev (ctrl->pci_ops, new_slot->bus, new_slot->device, function, PCI_SECONDARY_BUS, &secondary_bus); pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_SECONDARY_BUS, &secondary_bus);
sub_bus = (int) secondary_bus; sub_bus = (int) secondary_bus;
// Save the config headers for the secondary bus. // Save the config headers for the secondary bus.
rc = cpqhp_save_config(ctrl, sub_bus, 0); rc = cpqhp_save_config(ctrl, sub_bus, 0);
if (rc) if (rc)
return(rc); return(rc);
ctrl->pci_bus->number = new_slot->bus;
} // End of IF } // End of IF
new_slot->status = 0; new_slot->status = 0;
for (cloop = 0; cloop < 0x20; cloop++) { for (cloop = 0; cloop < 0x20; cloop++) {
pci_read_config_dword_nodev (ctrl->pci_ops, new_slot->bus, new_slot->device, function, cloop << 2, (u32 *) & (new_slot-> config_space [cloop])); pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), cloop << 2, (u32 *) & (new_slot-> config_space [cloop]));
} }
function++; function++;
...@@ -720,14 +724,14 @@ int cpqhp_save_slot_config (struct controller *ctrl, struct pci_func * new_slot) ...@@ -720,14 +724,14 @@ int cpqhp_save_slot_config (struct controller *ctrl, struct pci_func * new_slot)
// reading in the Class Code and the Header type. // reading in the Class Code and the Header type.
while ((function < max_functions) && (!stop_it)) { while ((function < max_functions) && (!stop_it)) {
pci_read_config_dword_nodev (ctrl->pci_ops, new_slot->bus, new_slot->device, function, PCI_VENDOR_ID, &ID); pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_VENDOR_ID, &ID);
if (ID == 0xFFFFFFFF) { // nothing there. if (ID == 0xFFFFFFFF) { // nothing there.
function++; function++;
} else { // Something there } else { // Something there
pci_read_config_byte_nodev (ctrl->pci_ops, new_slot->bus, new_slot->device, function, 0x0B, &class_code); pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), 0x0B, &class_code);
pci_read_config_byte_nodev (ctrl->pci_ops, new_slot->bus, new_slot->device, function, PCI_HEADER_TYPE, &header_type); pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_HEADER_TYPE, &header_type);
stop_it++; stop_it++;
} }
...@@ -763,17 +767,21 @@ int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func * func) ...@@ -763,17 +767,21 @@ int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func * func)
u32 rc; u32 rc;
struct pci_func *next; struct pci_func *next;
int index = 0; int index = 0;
struct pci_bus *pci_bus = ctrl->pci_bus;
unsigned int devfn;
func = cpqhp_slot_find(func->bus, func->device, index++); func = cpqhp_slot_find(func->bus, func->device, index++);
while (func != NULL) { while (func != NULL) {
pci_bus->number = func->bus;
devfn = PCI_DEVFN(func->device, func->function);
// Check for Bridge // Check for Bridge
pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_HEADER_TYPE, &header_type); pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) {
// PCI-PCI Bridge // PCI-PCI Bridge
pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_SECONDARY_BUS, &secondary_bus); pci_bus_read_config_byte (pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
sub_bus = (int) secondary_bus; sub_bus = (int) secondary_bus;
...@@ -787,13 +795,14 @@ int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func * func) ...@@ -787,13 +795,14 @@ int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func * func)
next = next->next; next = next->next;
} }
pci_bus->number = func->bus;
//FIXME: this loop is duplicated in the non-bridge case. The two could be rolled together //FIXME: this loop is duplicated in the non-bridge case. The two could be rolled together
// Figure out IO and memory base lengths // Figure out IO and memory base lengths
for (cloop = 0x10; cloop <= 0x14; cloop += 4) { for (cloop = 0x10; cloop <= 0x14; cloop += 4) {
temp_register = 0xFFFFFFFF; temp_register = 0xFFFFFFFF;
pci_write_config_dword_nodev(ctrl->pci_ops, func->bus, func->device, func->function, cloop, temp_register); pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, cloop, &base); pci_bus_read_config_dword (pci_bus, devfn, cloop, &base);
if (base) { // If this register is implemented if (base) { // If this register is implemented
if (base & 0x01L) { if (base & 0x01L) {
...@@ -827,8 +836,8 @@ int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func * func) ...@@ -827,8 +836,8 @@ int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func * func)
// Figure out IO and memory base lengths // Figure out IO and memory base lengths
for (cloop = 0x10; cloop <= 0x24; cloop += 4) { for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
temp_register = 0xFFFFFFFF; temp_register = 0xFFFFFFFF;
pci_write_config_dword_nodev(ctrl->pci_ops, func->bus, func->device, func->function, cloop, temp_register); pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, cloop, &base); pci_bus_read_config_dword (pci_bus, devfn, cloop, &base);
if (base) { // If this register is implemented if (base) { // If this register is implemented
if (base & 0x01L) { if (base & 0x01L) {
...@@ -897,28 +906,31 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func) ...@@ -897,28 +906,31 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)
struct pci_resource *p_mem_node; struct pci_resource *p_mem_node;
struct pci_resource *io_node; struct pci_resource *io_node;
struct pci_resource *bus_node; struct pci_resource *bus_node;
struct pci_bus *pci_bus = ctrl->pci_bus;
unsigned int devfn;
func = cpqhp_slot_find(func->bus, func->device, index++); func = cpqhp_slot_find(func->bus, func->device, index++);
while ((func != NULL) && func->is_a_board) { while ((func != NULL) && func->is_a_board) {
pci_bus->number = func->bus;
devfn = PCI_DEVFN(func->device, func->function);
// Save the command register // Save the command register
pci_read_config_word_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_COMMAND, &save_command); pci_bus_read_config_word (pci_bus, devfn, PCI_COMMAND, &save_command);
// disable card // disable card
command = 0x00; command = 0x00;
pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_COMMAND, command); pci_bus_write_config_word (pci_bus, devfn, PCI_COMMAND, command);
// Check for Bridge // Check for Bridge
pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_HEADER_TYPE, &header_type); pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge
// Clear Bridge Control Register // Clear Bridge Control Register
command = 0x00; command = 0x00;
pci_write_config_word_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_BRIDGE_CONTROL, command); pci_bus_write_config_word (pci_bus, devfn, PCI_BRIDGE_CONTROL, command);
pci_bus_read_config_byte (pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_SECONDARY_BUS, &secondary_bus); pci_bus_read_config_byte (pci_bus, devfn, PCI_SUBORDINATE_BUS, &temp_byte);
pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_SUBORDINATE_BUS, &temp_byte);
bus_node =(struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL); bus_node =(struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
if (!bus_node) if (!bus_node)
...@@ -931,9 +943,8 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func) ...@@ -931,9 +943,8 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)
func->bus_head = bus_node; func->bus_head = bus_node;
// Save IO base and Limit registers // Save IO base and Limit registers
pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_IO_BASE, &b_base); pci_bus_read_config_byte (pci_bus, devfn, PCI_IO_BASE, &b_base);
pci_bus_read_config_byte (pci_bus, devfn, PCI_IO_LIMIT, &b_length);
pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_IO_LIMIT, &b_length);
if ((b_base <= b_length) && (save_command & 0x01)) { if ((b_base <= b_length) && (save_command & 0x01)) {
io_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL); io_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
...@@ -946,10 +957,10 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func) ...@@ -946,10 +957,10 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)
io_node->next = func->io_head; io_node->next = func->io_head;
func->io_head = io_node; func->io_head = io_node;
} }
// Save memory base and Limit registers
pci_read_config_word_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_MEMORY_BASE, &w_base);
pci_read_config_word_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_MEMORY_LIMIT, &w_length); // Save memory base and Limit registers
pci_bus_read_config_word (pci_bus, devfn, PCI_MEMORY_BASE, &w_base);
pci_bus_read_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, &w_length);
if ((w_base <= w_length) && (save_command & 0x02)) { if ((w_base <= w_length) && (save_command & 0x02)) {
mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL); mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
...@@ -962,10 +973,10 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func) ...@@ -962,10 +973,10 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)
mem_node->next = func->mem_head; mem_node->next = func->mem_head;
func->mem_head = mem_node; func->mem_head = mem_node;
} }
// Save prefetchable memory base and Limit registers
pci_read_config_word_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_PREF_MEMORY_BASE, &w_base);
pci_read_config_word_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_PREF_MEMORY_LIMIT, &w_length); // Save prefetchable memory base and Limit registers
pci_bus_read_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, &w_base);
pci_bus_read_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, &w_length);
if ((w_base <= w_length) && (save_command & 0x02)) { if ((w_base <= w_length) && (save_command & 0x02)) {
p_mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL); p_mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
...@@ -980,12 +991,11 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func) ...@@ -980,12 +991,11 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)
} }
// Figure out IO and memory base lengths // Figure out IO and memory base lengths
for (cloop = 0x10; cloop <= 0x14; cloop += 4) { for (cloop = 0x10; cloop <= 0x14; cloop += 4) {
pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, cloop, &save_base); pci_bus_read_config_dword (pci_bus, devfn, cloop, &save_base);
temp_register = 0xFFFFFFFF; temp_register = 0xFFFFFFFF;
pci_write_config_dword_nodev(ctrl->pci_ops, func->bus, func->device, func->function, cloop, temp_register); pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
pci_bus_read_config_dword (pci_bus, devfn, cloop, &base);
pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, cloop, &base);
temp_register = base; temp_register = base;
...@@ -1046,12 +1056,11 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func) ...@@ -1046,12 +1056,11 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func)
} else if ((header_type & 0x7F) == 0x00) { // Standard header } else if ((header_type & 0x7F) == 0x00) { // Standard header
// Figure out IO and memory base lengths // Figure out IO and memory base lengths
for (cloop = 0x10; cloop <= 0x24; cloop += 4) { for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, cloop, &save_base); pci_bus_read_config_dword (pci_bus, devfn, cloop, &save_base);
temp_register = 0xFFFFFFFF; temp_register = 0xFFFFFFFF;
pci_write_config_dword_nodev(ctrl->pci_ops, func->bus, func->device, func->function, cloop, temp_register); pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
pci_bus_read_config_dword (pci_bus, devfn, cloop, &base);
pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, cloop, &base);
temp_register = base; temp_register = base;
...@@ -1138,21 +1147,26 @@ int cpqhp_configure_board(struct controller *ctrl, struct pci_func * func) ...@@ -1138,21 +1147,26 @@ int cpqhp_configure_board(struct controller *ctrl, struct pci_func * func)
u32 temp; u32 temp;
u32 rc; u32 rc;
int index = 0; int index = 0;
struct pci_bus *pci_bus = ctrl->pci_bus;
unsigned int devfn;
func = cpqhp_slot_find(func->bus, func->device, index++); func = cpqhp_slot_find(func->bus, func->device, index++);
while (func != NULL) { while (func != NULL) {
pci_bus->number = func->bus;
devfn = PCI_DEVFN(func->device, func->function);
// Start at the top of config space so that the control // Start at the top of config space so that the control
// registers are programmed last // registers are programmed last
for (cloop = 0x3C; cloop > 0; cloop -= 4) { for (cloop = 0x3C; cloop > 0; cloop -= 4) {
pci_write_config_dword_nodev(ctrl->pci_ops, func->bus, func->device, func->function, cloop, func->config_space[cloop >> 2]); pci_bus_write_config_dword (pci_bus, devfn, cloop, func->config_space[cloop >> 2]);
} }
pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_HEADER_TYPE, &header_type); pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
// If this is a bridge device, restore subordinate devices // If this is a bridge device, restore subordinate devices
if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge
pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_SECONDARY_BUS, &secondary_bus); pci_bus_read_config_byte (pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus);
sub_bus = (int) secondary_bus; sub_bus = (int) secondary_bus;
...@@ -1172,7 +1186,7 @@ int cpqhp_configure_board(struct controller *ctrl, struct pci_func * func) ...@@ -1172,7 +1186,7 @@ int cpqhp_configure_board(struct controller *ctrl, struct pci_func * func)
// they are the same. If not, the board is different. // they are the same. If not, the board is different.
for (cloop = 16; cloop < 40; cloop += 4) { for (cloop = 16; cloop < 40; cloop += 4) {
pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, cloop, &temp); pci_bus_read_config_dword (pci_bus, devfn, cloop, &temp);
if (temp != func->config_space[cloop >> 2]) { if (temp != func->config_space[cloop >> 2]) {
dbg("Config space compare failure!!! offset = %x\n", cloop); dbg("Config space compare failure!!! offset = %x\n", cloop);
...@@ -1212,6 +1226,8 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func) ...@@ -1212,6 +1226,8 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func)
u32 rc; u32 rc;
struct pci_func *next; struct pci_func *next;
int index = 0; int index = 0;
struct pci_bus *pci_bus = ctrl->pci_bus;
unsigned int devfn;
if (!func->is_a_board) if (!func->is_a_board)
return(ADD_NOT_SUPPORTED); return(ADD_NOT_SUPPORTED);
...@@ -1219,7 +1235,10 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func) ...@@ -1219,7 +1235,10 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func)
func = cpqhp_slot_find(func->bus, func->device, index++); func = cpqhp_slot_find(func->bus, func->device, index++);
while (func != NULL) { while (func != NULL) {
pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_VENDOR_ID, &temp_register); pci_bus->number = func->bus;
devfn = PCI_DEVFN(func->device, func->function);
pci_bus_read_config_dword (pci_bus, devfn, PCI_VENDOR_ID, &temp_register);
// No adapter present // No adapter present
if (temp_register == 0xFFFFFFFF) if (temp_register == 0xFFFFFFFF)
...@@ -1229,14 +1248,14 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func) ...@@ -1229,14 +1248,14 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func)
return(ADAPTER_NOT_SAME); return(ADAPTER_NOT_SAME);
// Check for same revision number and class code // Check for same revision number and class code
pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_CLASS_REVISION, &temp_register); pci_bus_read_config_dword (pci_bus, devfn, PCI_CLASS_REVISION, &temp_register);
// Adapter not the same // Adapter not the same
if (temp_register != func->config_space[0x08 >> 2]) if (temp_register != func->config_space[0x08 >> 2])
return(ADAPTER_NOT_SAME); return(ADAPTER_NOT_SAME);
// Check for Bridge // Check for Bridge
pci_read_config_byte_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_HEADER_TYPE, &header_type); pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type);
if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge
// In order to continue checking, we must program the // In order to continue checking, we must program the
...@@ -1244,7 +1263,7 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func) ...@@ -1244,7 +1263,7 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func)
// for it's subordinate bus(es) // for it's subordinate bus(es)
temp_register = func->config_space[0x18 >> 2]; temp_register = func->config_space[0x18 >> 2];
pci_write_config_dword_nodev(ctrl->pci_ops, func->bus, func->device, func->function, PCI_PRIMARY_BUS, temp_register); pci_bus_write_config_dword (pci_bus, devfn, PCI_PRIMARY_BUS, temp_register);
secondary_bus = (temp_register >> 8) & 0xFF; secondary_bus = (temp_register >> 8) & 0xFF;
...@@ -1263,7 +1282,7 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func) ...@@ -1263,7 +1282,7 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func)
// Check to see if it is a standard config header // Check to see if it is a standard config header
else if ((header_type & 0x7F) == PCI_HEADER_TYPE_NORMAL) { else if ((header_type & 0x7F) == PCI_HEADER_TYPE_NORMAL) {
// Check subsystem vendor and ID // Check subsystem vendor and ID
pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, PCI_SUBSYSTEM_VENDOR_ID, &temp_register); pci_bus_read_config_dword (pci_bus, devfn, PCI_SUBSYSTEM_VENDOR_ID, &temp_register);
if (temp_register != func->config_space[0x2C >> 2]) { if (temp_register != func->config_space[0x2C >> 2]) {
// If it's a SMART-2 and the register isn't filled // If it's a SMART-2 and the register isn't filled
...@@ -1277,10 +1296,8 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func) ...@@ -1277,10 +1296,8 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func)
// Figure out IO and memory base lengths // Figure out IO and memory base lengths
for (cloop = 0x10; cloop <= 0x24; cloop += 4) { for (cloop = 0x10; cloop <= 0x24; cloop += 4) {
temp_register = 0xFFFFFFFF; temp_register = 0xFFFFFFFF;
pci_write_config_dword_nodev(ctrl->pci_ops, func->bus, func->device, func->function, cloop, temp_register); pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register);
pci_bus_read_config_dword (pci_bus, devfn, cloop, &base);
pci_read_config_dword_nodev (ctrl->pci_ops, func->bus, func->device, func->function, cloop, &base);
if (base) { // If this register is implemented if (base) { // If this register is implemented
if (base & 0x01L) { if (base & 0x01L) {
// IO base // IO base
...@@ -1436,8 +1453,8 @@ int cpqhp_find_available_resources (struct controller *ctrl, void *rom_start) ...@@ -1436,8 +1453,8 @@ int cpqhp_find_available_resources (struct controller *ctrl, void *rom_start)
continue; continue;
} }
// find out if this entry is for an occupied slot // find out if this entry is for an occupied slot
pci_read_config_dword_nodev (ctrl->pci_ops, primary_bus, dev_func >> 3, dev_func & 0x07, PCI_VENDOR_ID, &temp_dword); ctrl->pci_bus->number = primary_bus;
pci_bus_read_config_dword (ctrl->pci_bus, dev_func, PCI_VENDOR_ID, &temp_dword);
dbg("temp_D_word = %x\n", temp_dword); dbg("temp_D_word = %x\n", temp_dword);
if (temp_dword != 0xFFFFFFFF) { if (temp_dword != 0xFFFFFFFF) {
...@@ -1586,7 +1603,7 @@ int cpqhp_return_board_resources(struct pci_func * func, struct resource_lists * ...@@ -1586,7 +1603,7 @@ int cpqhp_return_board_resources(struct pci_func * func, struct resource_lists *
int rc = 0; int rc = 0;
struct pci_resource *node; struct pci_resource *node;
struct pci_resource *t_node; struct pci_resource *t_node;
dbg(__FUNCTION__"\n"); dbg("%s\n", __FUNCTION__);
if (!func) if (!func)
return(1); return(1);
......
...@@ -53,8 +53,9 @@ static int read_ctrl (char *buf, char **start, off_t offset, int len, int *eof, ...@@ -53,8 +53,9 @@ static int read_ctrl (char *buf, char **start, off_t offset, int len, int *eof,
*eof = 1; *eof = 1;
out += sprintf(out, "hot plug ctrl Info Page\n"); out += sprintf(out, "hot plug ctrl Info Page\n");
out += sprintf(out, "bus = %d, device = %d, function = %d\n",ctrl->bus, out += sprintf(out, "bus = %d, device = %d, function = %d\n",
ctrl->device, ctrl->function); ctrl->bus, PCI_SLOT(ctrl->pci_dev->devfn),
PCI_FUNC(ctrl->pci_dev->devfn));
out += sprintf(out, "Free resources: memory\n"); out += sprintf(out, "Free resources: memory\n");
index = 11; index = 11;
res = ctrl->mem_head; res = ctrl->mem_head;
...@@ -104,8 +105,9 @@ static int read_dev (char *buf, char **start, off_t offset, int len, int *eof, v ...@@ -104,8 +105,9 @@ static int read_dev (char *buf, char **start, off_t offset, int len, int *eof, v
*eof = 1; *eof = 1;
out += sprintf(out, "hot plug ctrl Info Page\n"); out += sprintf(out, "hot plug ctrl Info Page\n");
out += sprintf(out, "bus = %d, device = %d, function = %d\n",ctrl->bus, out += sprintf(out, "bus = %d, device = %d, function = %d\n",
ctrl->device, ctrl->function); ctrl->bus, PCI_SLOT(ctrl->pci_dev->devfn),
PCI_FUNC(ctrl->pci_dev->devfn));
slot=ctrl->slot; slot=ctrl->slot;
......
...@@ -39,7 +39,8 @@ extern int ibmphp_debug; ...@@ -39,7 +39,8 @@ extern int ibmphp_debug;
#else #else
#define MY_NAME THIS_MODULE->name #define MY_NAME THIS_MODULE->name
#endif #endif
#define debug(fmt, arg...) do { if (ibmphp_debug) printk(KERN_DEBUG "%s: " fmt , MY_NAME , ## arg); } while (0) #define debug(fmt, arg...) do { if (ibmphp_debug == 1) printk(KERN_DEBUG "%s: " fmt , MY_NAME , ## arg); } while (0)
#define debug_pci(fmt, arg...) do { if (ibmphp_debug) printk(KERN_DEBUG "%s: " fmt , MY_NAME , ## arg); } while (0)
#define err(format, arg...) printk(KERN_ERR "%s: " format , MY_NAME , ## arg) #define err(format, arg...) printk(KERN_ERR "%s: " format , MY_NAME , ## arg)
#define info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg) #define info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg)
#define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg) #define warn(format, arg...) printk(KERN_WARNING "%s: " format , MY_NAME , ## arg)
...@@ -121,6 +122,7 @@ struct scal_detail { ...@@ -121,6 +122,7 @@ struct scal_detail {
u8 port1_port_connect; u8 port1_port_connect;
u8 port2_node_connect; u8 port2_node_connect;
u8 port2_port_connect; u8 port2_port_connect;
u8 chassis_num;
// struct list_head scal_detail_list; // struct list_head scal_detail_list;
}; };
...@@ -139,9 +141,27 @@ struct rio_detail { ...@@ -139,9 +141,27 @@ struct rio_detail {
u8 port1_port_connect; u8 port1_port_connect;
u8 first_slot_num; u8 first_slot_num;
u8 status; u8 status;
// struct list_head rio_detail_list; u8 wpindex;
u8 chassis_num;
struct list_head rio_detail_list;
}; };
struct opt_rio {
u8 rio_type;
u8 chassis_num;
u8 first_slot_num;
u8 middle_num;
struct list_head opt_rio_list;
};
struct opt_rio_lo {
u8 rio_type;
u8 chassis_num;
u8 first_slot_num;
u8 middle_num;
u8 pack_count;
struct list_head opt_rio_lo_list;
};
/**************************************************************** /****************************************************************
* HPC DESCRIPTOR NODE * * HPC DESCRIPTOR NODE *
...@@ -153,7 +173,6 @@ struct ebda_hpc_list { ...@@ -153,7 +173,6 @@ struct ebda_hpc_list {
short phys_addr; short phys_addr;
// struct list_head ebda_hpc_list; // struct list_head ebda_hpc_list;
}; };
/***************************************************************** /*****************************************************************
* IN HPC DATA STRUCTURE, THE ASSOCIATED SLOT AND BUS * * IN HPC DATA STRUCTURE, THE ASSOCIATED SLOT AND BUS *
* STRUCTURE * * STRUCTURE *
...@@ -195,6 +214,9 @@ struct wpeg_i2c_ctlr_access { ...@@ -195,6 +214,9 @@ struct wpeg_i2c_ctlr_access {
u8 i2c_addr; u8 i2c_addr;
}; };
#define HPC_DEVICE_ID 0x0246
#define HPC_SUBSYSTEM_ID 0x0247
#define HPC_PCI_OFFSET 0x40
/************************************************************************* /*************************************************************************
* RSTC DESCRIPTOR NODE * * RSTC DESCRIPTOR NODE *
*************************************************************************/ *************************************************************************/
...@@ -215,8 +237,9 @@ struct ebda_pci_rsrc { ...@@ -215,8 +237,9 @@ struct ebda_pci_rsrc {
u8 rsrc_type; u8 rsrc_type;
u8 bus_num; u8 bus_num;
u8 dev_fun; u8 dev_fun;
ulong start_addr; u32 start_addr;
ulong end_addr; u32 end_addr;
u8 marked; /* for NVRAM */
struct list_head ebda_pci_rsrc_list; struct list_head ebda_pci_rsrc_list;
}; };
...@@ -248,7 +271,7 @@ struct bus_info { ...@@ -248,7 +271,7 @@ struct bus_info {
***********************************************************/ ***********************************************************/
extern struct list_head ibmphp_ebda_pci_rsrc_head; extern struct list_head ibmphp_ebda_pci_rsrc_head;
extern struct list_head ibmphp_slot_head; extern struct list_head ibmphp_slot_head;
extern struct list_head ibmphp_res_head;
/*********************************************************** /***********************************************************
* FUNCTION PROTOTYPES * * FUNCTION PROTOTYPES *
***********************************************************/ ***********************************************************/
...@@ -263,6 +286,7 @@ extern void ibmphp_free_ebda_pci_rsrc_queue (void); ...@@ -263,6 +286,7 @@ extern void ibmphp_free_ebda_pci_rsrc_queue (void);
extern struct bus_info *ibmphp_find_same_bus_num (u32); extern struct bus_info *ibmphp_find_same_bus_num (u32);
extern int ibmphp_get_bus_index (u8); extern int ibmphp_get_bus_index (u8);
extern u16 ibmphp_get_total_controllers (void); extern u16 ibmphp_get_total_controllers (void);
extern int ibmphp_register_pci (void);
/* passed parameters */ /* passed parameters */
#define MEM 0 #define MEM 0
...@@ -669,7 +693,7 @@ extern void ibmphp_hpc_stop_poll_thread (void); ...@@ -669,7 +693,7 @@ extern void ibmphp_hpc_stop_poll_thread (void);
#define PCIX66 0x05 #define PCIX66 0x05
#define PCI66 0x04 #define PCI66 0x04
extern struct pci_ops *ibmphp_pci_root_ops; extern struct pci_bus *ibmphp_pci_bus;
/* Variables */ /* Variables */
...@@ -713,6 +737,7 @@ struct slot { ...@@ -713,6 +737,7 @@ struct slot {
struct controller { struct controller {
struct ebda_hpc_slot *slots; struct ebda_hpc_slot *slots;
struct ebda_hpc_bus *buses; struct ebda_hpc_bus *buses;
struct pci_dev *ctrl_dev; /* in case where controller is PCI */
u8 starting_slot_num; /* starting and ending slot #'s this ctrl controls*/ u8 starting_slot_num; /* starting and ending slot #'s this ctrl controls*/
u8 ending_slot_num; u8 ending_slot_num;
u8 revision; u8 revision;
......
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
#define get_ctrl_revision(sl, rev) ibmphp_hpc_readslot (sl, READ_REVLEVEL, rev) #define get_ctrl_revision(sl, rev) ibmphp_hpc_readslot (sl, READ_REVLEVEL, rev)
#define get_hpc_options(sl, opt) ibmphp_hpc_readslot (sl, READ_HPCOPTIONS, opt) #define get_hpc_options(sl, opt) ibmphp_hpc_readslot (sl, READ_HPCOPTIONS, opt)
#define DRIVER_VERSION "0.3" #define DRIVER_VERSION "0.6"
#define DRIVER_DESC "IBM Hot Plug PCI Controller Driver" #define DRIVER_DESC "IBM Hot Plug PCI Controller Driver"
int ibmphp_debug; int ibmphp_debug;
...@@ -56,7 +56,7 @@ MODULE_LICENSE ("GPL"); ...@@ -56,7 +56,7 @@ MODULE_LICENSE ("GPL");
MODULE_DESCRIPTION (DRIVER_DESC); MODULE_DESCRIPTION (DRIVER_DESC);
static int *ops[MAX_OPS + 1]; static int *ops[MAX_OPS + 1];
struct pci_ops *ibmphp_pci_root_ops; struct pci_bus *ibmphp_pci_bus;
static int max_slots; static int max_slots;
static int irqs[16]; /* PIC mode IRQ's we're using so far (in case MPS tables don't provide default info for empty slots */ static int irqs[16]; /* PIC mode IRQ's we're using so far (in case MPS tables don't provide default info for empty slots */
...@@ -88,6 +88,8 @@ static inline int get_cur_bus_info (struct slot **sl) ...@@ -88,6 +88,8 @@ static inline int get_cur_bus_info (struct slot **sl)
slot_cur->bus_on->current_speed = CURRENT_BUS_SPEED (slot_cur->busstatus); slot_cur->bus_on->current_speed = CURRENT_BUS_SPEED (slot_cur->busstatus);
if (READ_BUS_MODE (slot_cur->ctrl)) if (READ_BUS_MODE (slot_cur->ctrl))
slot_cur->bus_on->current_bus_mode = CURRENT_BUS_MODE (slot_cur->busstatus); slot_cur->bus_on->current_bus_mode = CURRENT_BUS_MODE (slot_cur->busstatus);
else
slot_cur->bus_on->current_bus_mode = 0xFF;
debug ("busstatus = %x, bus_speed = %x, bus_mode = %x\n", slot_cur->busstatus, slot_cur->bus_on->current_speed, slot_cur->bus_on->current_bus_mode); debug ("busstatus = %x, bus_speed = %x, bus_mode = %x\n", slot_cur->busstatus, slot_cur->bus_on->current_speed, slot_cur->bus_on->current_bus_mode);
...@@ -108,11 +110,15 @@ static inline int slot_update (struct slot **sl) ...@@ -108,11 +110,15 @@ static inline int slot_update (struct slot **sl)
static int __init get_max_slots (void) static int __init get_max_slots (void)
{ {
struct slot * slot_cur;
struct list_head * tmp; struct list_head * tmp;
int slot_count = 0; u8 slot_count = 0;
list_for_each (tmp, &ibmphp_slot_head) list_for_each (tmp, &ibmphp_slot_head) {
++slot_count; slot_cur = list_entry (tmp, struct slot, ibm_slot_list);
/* sometimes the hot-pluggable slots start with 4 (not always from 1 */
slot_count = max (slot_count, slot_cur->number);
}
return slot_count; return slot_count;
} }
...@@ -330,7 +336,7 @@ static int get_power_status (struct hotplug_slot *hotplug_slot, u8 * value) ...@@ -330,7 +336,7 @@ static int get_power_status (struct hotplug_slot *hotplug_slot, u8 * value)
memcpy ((void *) &myslot, (void *) pslot, sizeof (struct slot)); memcpy ((void *) &myslot, (void *) pslot, sizeof (struct slot));
hpcrc = ibmphp_hpc_readslot (pslot, READ_SLOTSTATUS, &(myslot.status)); hpcrc = ibmphp_hpc_readslot (pslot, READ_SLOTSTATUS, &(myslot.status));
if (!hpcrc) { if (!hpcrc) {
*value = SLOT_POWER (myslot.status); *value = SLOT_PWRGD (myslot.status);
rc = 0; rc = 0;
} }
} }
...@@ -394,15 +400,22 @@ static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, u8 * value) ...@@ -394,15 +400,22 @@ static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, u8 * value)
if (pslot) { if (pslot) {
rc = 0; rc = 0;
mode = pslot->supported_bus_mode; mode = pslot->supported_bus_mode;
*value = pslot->supported_speed; *value = pslot->supported_speed;
*value &= 0x0f; switch (*value) {
case BUS_SPEED_33:
if (mode == BUS_MODE_PCIX) break;
*value |= 0x80; case BUS_SPEED_66:
else if (mode == BUS_MODE_PCI) if (mode == BUS_MODE_PCIX)
*value |= 0x40; *value += 0x01;
else break;
*value |= 0x20; case BUS_SPEED_100:
case BUS_SPEED_133:
*value = pslot->supported_speed + 0x01;
break;
default:
*/ /* Note (will need to change): there would be soon 256, 512 also */
/* rc = -ENODEV;
}
} }
} else } else
rc = -ENODEV; rc = -ENODEV;
...@@ -429,14 +442,25 @@ static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, u8 * value) ...@@ -429,14 +442,25 @@ static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, u8 * value)
if (!rc) { if (!rc) {
mode = pslot->bus_on->current_bus_mode; mode = pslot->bus_on->current_bus_mode;
*value = pslot->bus_on->current_speed; *value = pslot->bus_on->current_speed;
*value &= 0x0f; switch (*value) {
case BUS_SPEED_33:
if (mode == BUS_MODE_PCIX) break;
*value |= 0x80; case BUS_SPEED_66:
else if (mode == BUS_MODE_PCI) if (mode == BUS_MODE_PCIX)
*value |= 0x40; *value += 0x01;
else else if (mode == BUS_MODE_PCI)
*value |= 0x20; ;
else
*value = PCI_SPEED_UNKNOWN;
break;
case BUS_SPEED_100:
case BUS_SPEED_133:
*value += 0x01;
break;
default:
*/ /* Note of change: there would also be 256, 512 soon */
/* rc = -ENODEV;
}
} }
} }
} else } else
...@@ -454,7 +478,7 @@ static int get_max_adapter_speed_1 (struct hotplug_slot *hotplug_slot, u8 * valu ...@@ -454,7 +478,7 @@ static int get_max_adapter_speed_1 (struct hotplug_slot *hotplug_slot, u8 * valu
int hpcrc = 0; int hpcrc = 0;
struct slot myslot; struct slot myslot;
debug ("get_max_adapter_speed - Entry hotplug_slot[%lx] pvalue[%lx]\n", (ulong)hotplug_slot, (ulong) value); debug ("get_max_adapter_speed_1 - Entry hotplug_slot[%lx] pvalue[%lx]\n", (ulong)hotplug_slot, (ulong) value);
if (flag) if (flag)
ibmphp_lock_operations (); ibmphp_lock_operations ();
...@@ -485,17 +509,16 @@ static int get_max_adapter_speed_1 (struct hotplug_slot *hotplug_slot, u8 * valu ...@@ -485,17 +509,16 @@ static int get_max_adapter_speed_1 (struct hotplug_slot *hotplug_slot, u8 * valu
if (flag) if (flag)
ibmphp_unlock_operations (); ibmphp_unlock_operations ();
debug ("get_adapter_present - Exit rc[%d] hpcrc[%x] value[%x]\n", rc, hpcrc, *value); debug ("get_max_adapter_speed_1 - Exit rc[%d] hpcrc[%x] value[%x]\n", rc, hpcrc, *value);
return rc; return rc;
} }
static int get_card_bus_names (struct hotplug_slot *hotplug_slot, char * value) static int get_bus_name (struct hotplug_slot *hotplug_slot, char * value)
{ {
int rc = -ENODEV; int rc = -ENODEV;
struct slot *pslot = NULL; struct slot *pslot = NULL;
struct pci_dev * dev = NULL;
debug ("get_card_bus_names - Entry hotplug_slot[%lx] \n", (ulong)hotplug_slot); debug ("get_bus_name - Entry hotplug_slot[%lx] \n", (ulong)hotplug_slot);
ibmphp_lock_operations (); ibmphp_lock_operations ();
...@@ -503,26 +526,17 @@ static int get_card_bus_names (struct hotplug_slot *hotplug_slot, char * value) ...@@ -503,26 +526,17 @@ static int get_card_bus_names (struct hotplug_slot *hotplug_slot, char * value)
pslot = (struct slot *) hotplug_slot->private; pslot = (struct slot *) hotplug_slot->private;
if (pslot) { if (pslot) {
rc = 0; rc = 0;
if (pslot->func) snprintf (value, 100, "Bus %x", pslot->bus);
dev = pslot->func->dev;
else
dev = pci_find_slot (pslot->bus, (pslot->device << 3) | (0x00 & 0x7));
if (dev)
snprintf (value, 100, "Bus %d : %s", pslot->bus,dev->name);
else
snprintf (value, 100, "Bus %d", pslot->bus);
} }
} else } else
rc = -ENODEV; rc = -ENODEV;
ibmphp_unlock_operations (); ibmphp_unlock_operations ();
debug ("get_card_bus_names - Exit rc[%d] value[%x]\n", rc, *value); debug ("get_bus_name - Exit rc[%d] value[%x]\n", rc, *value);
return rc; return rc;
} }
*/ */
/******************************************************************************* /*******************************************************************************
* This routine will initialize the ops data structure used in the validate * This routine will initialize the ops data structure used in the validate
* function. It will also power off empty slots that are powered on since BIOS * function. It will also power off empty slots that are powered on since BIOS
...@@ -531,12 +545,14 @@ static int get_card_bus_names (struct hotplug_slot *hotplug_slot, char * value) ...@@ -531,12 +545,14 @@ static int get_card_bus_names (struct hotplug_slot *hotplug_slot, char * value)
static int __init init_ops (void) static int __init init_ops (void)
{ {
struct slot *slot_cur; struct slot *slot_cur;
struct list_head *tmp;
int retval; int retval;
int j;
int rc; int rc;
int j;
for (j = 0; j < MAX_OPS; j++) { for (j = 0; j < MAX_OPS; j++) {
ops[j] = (int *) kmalloc ((max_slots + 1) * sizeof (int), GFP_KERNEL); ops[j] = (int *) kmalloc ((max_slots + 1) * sizeof (int), GFP_KERNEL);
memset (ops[j], 0, (max_slots + 1) * sizeof (int));
if (!ops[j]) { if (!ops[j]) {
err ("out of system memory \n"); err ("out of system memory \n");
return -ENOMEM; return -ENOMEM;
...@@ -547,12 +563,13 @@ static int __init init_ops (void) ...@@ -547,12 +563,13 @@ static int __init init_ops (void)
ops[REMOVE][0] = 0; ops[REMOVE][0] = 0;
ops[DETAIL][0] = 0; ops[DETAIL][0] = 0;
for (j = 1; j <= max_slots; j++) { list_for_each (tmp, &ibmphp_slot_head) {
slot_cur = list_entry (tmp, struct slot, ibm_slot_list);
slot_cur = ibmphp_get_slot_from_physical_num (j); if (!slot_cur)
return -ENODEV;
debug ("BEFORE GETTING SLOT STATUS, slot # %x\n", slot_cur->number); debug ("BEFORE GETTING SLOT STATUS, slot # %x\n", slot_cur->number);
if (slot_cur->ctrl->revision == 0xFF) if (slot_cur->ctrl->revision == 0xFF)
if (get_ctrl_revision (slot_cur, &slot_cur->ctrl->revision)) if (get_ctrl_revision (slot_cur, &slot_cur->ctrl->revision))
return -1; return -1;
...@@ -572,21 +589,21 @@ static int __init init_ops (void) ...@@ -572,21 +589,21 @@ static int __init init_ops (void)
debug ("status = %x, ext_status = %x\n", slot_cur->status, slot_cur->ext_status); debug ("status = %x, ext_status = %x\n", slot_cur->status, slot_cur->ext_status);
debug ("SLOT_POWER = %x, SLOT_PRESENT = %x, SLOT_LATCH = %x\n", SLOT_POWER (slot_cur->status), SLOT_PRESENT (slot_cur->status), SLOT_LATCH (slot_cur->status)); debug ("SLOT_POWER = %x, SLOT_PRESENT = %x, SLOT_LATCH = %x\n", SLOT_POWER (slot_cur->status), SLOT_PRESENT (slot_cur->status), SLOT_LATCH (slot_cur->status));
if (!(SLOT_POWER (slot_cur->status)) && (SLOT_PRESENT (slot_cur->status)) && !(SLOT_LATCH (slot_cur->status))) if (!(SLOT_PWRGD (slot_cur->status)) && (SLOT_PRESENT (slot_cur->status)) && !(SLOT_LATCH (slot_cur->status)))
/* No power, adapter, and latch closed */ /* No power, adapter, and latch closed */
ops[ADD][j] = 1; ops[ADD][slot_cur->number] = 1;
else else
ops[ADD][j] = 0; ops[ADD][slot_cur->number] = 0;
ops[DETAIL][j] = 1; ops[DETAIL][slot_cur->number] = 1;
if ((SLOT_POWER (slot_cur->status)) && (SLOT_PRESENT (slot_cur->status)) && !(SLOT_LATCH (slot_cur->status))) if ((SLOT_PWRGD (slot_cur->status)) && (SLOT_PRESENT (slot_cur->status)) && !(SLOT_LATCH (slot_cur->status)))
/*Power,adapter,latch closed */ /*Power,adapter,latch closed */
ops[REMOVE][j] = 1; ops[REMOVE][slot_cur->number] = 1;
else else
ops[REMOVE][j] = 0; ops[REMOVE][slot_cur->number] = 0;
if ((SLOT_POWER (slot_cur->status)) && !(SLOT_PRESENT (slot_cur->status)) && !(SLOT_LATCH (slot_cur->status))) { if ((SLOT_PWRGD (slot_cur->status)) && !(SLOT_PRESENT (slot_cur->status)) && !(SLOT_LATCH (slot_cur->status))) {
debug ("BEFORE POWER OFF COMMAND\n"); debug ("BEFORE POWER OFF COMMAND\n");
rc = power_off (slot_cur); rc = power_off (slot_cur);
if (rc) if (rc)
...@@ -624,7 +641,7 @@ static int validate (struct slot *slot_cur, int opn) ...@@ -624,7 +641,7 @@ static int validate (struct slot *slot_cur, int opn)
if (retval) if (retval)
return retval; return retval;
if (!(SLOT_POWER (slot_cur->status)) && (SLOT_PRESENT (slot_cur->status)) if (!(SLOT_PWRGD (slot_cur->status)) && (SLOT_PRESENT (slot_cur->status))
&& !(SLOT_LATCH (slot_cur->status))) && !(SLOT_LATCH (slot_cur->status)))
ops[ADD][number] = 1; ops[ADD][number] = 1;
else else
...@@ -632,7 +649,7 @@ static int validate (struct slot *slot_cur, int opn) ...@@ -632,7 +649,7 @@ static int validate (struct slot *slot_cur, int opn)
ops[DETAIL][number] = 1; ops[DETAIL][number] = 1;
if ((SLOT_POWER (slot_cur->status)) && (SLOT_PRESENT (slot_cur->status)) if ((SLOT_PWRGD (slot_cur->status)) && (SLOT_PRESENT (slot_cur->status))
&& !(SLOT_LATCH (slot_cur->status))) && !(SLOT_LATCH (slot_cur->status)))
ops[REMOVE][number] = 1; ops[REMOVE][number] = 1;
else else
...@@ -678,7 +695,7 @@ int ibmphp_update_slot_info (struct slot *slot_cur) ...@@ -678,7 +695,7 @@ int ibmphp_update_slot_info (struct slot *slot_cur)
} }
snprintf (buffer, 10, "%d", slot_cur->number); snprintf (buffer, 10, "%d", slot_cur->number);
info->power_status = SLOT_POWER (slot_cur->status); info->power_status = SLOT_PWRGD (slot_cur->status);
info->attention_status = SLOT_ATTN (slot_cur->status, slot_cur->ext_status); info->attention_status = SLOT_ATTN (slot_cur->status, slot_cur->ext_status);
info->latch_status = SLOT_LATCH (slot_cur->status); info->latch_status = SLOT_LATCH (slot_cur->status);
if (!SLOT_PRESENT (slot_cur->status)) { if (!SLOT_PRESENT (slot_cur->status)) {
...@@ -688,8 +705,8 @@ int ibmphp_update_slot_info (struct slot *slot_cur) ...@@ -688,8 +705,8 @@ int ibmphp_update_slot_info (struct slot *slot_cur)
info->adapter_status = 1; info->adapter_status = 1;
// get_max_adapter_speed_1 (slot_cur->hotplug_slot, &info->max_adapter_speed_status, 0); // get_max_adapter_speed_1 (slot_cur->hotplug_slot, &info->max_adapter_speed_status, 0);
} }
/* /* !!!!!!!!!TO DO: THIS NEEDS TO CHANGE!!!!!!!!!!!!! */
bus_speed = slot_cur->bus_on->current_speed; /* bus_speed = slot_cur->bus_on->current_speed;
bus_speed &= 0x0f; bus_speed &= 0x0f;
if (slot_cur->bus_on->current_bus_mode == BUS_MODE_PCIX) if (slot_cur->bus_on->current_bus_mode == BUS_MODE_PCIX)
...@@ -701,7 +718,7 @@ int ibmphp_update_slot_info (struct slot *slot_cur) ...@@ -701,7 +718,7 @@ int ibmphp_update_slot_info (struct slot *slot_cur)
info->cur_bus_speed_status = bus_speed; info->cur_bus_speed_status = bus_speed;
info->max_bus_speed_status = slot_cur->hotplug_slot->info->max_bus_speed_status; info->max_bus_speed_status = slot_cur->hotplug_slot->info->max_bus_speed_status;
// To do: card_bus_names // To do: bus_names
*/ */
rc = pci_hp_change_slot_info (buffer, info); rc = pci_hp_change_slot_info (buffer, info);
kfree (info); kfree (info);
...@@ -752,18 +769,6 @@ static struct pci_bus *find_bus (u8 busno) ...@@ -752,18 +769,6 @@ static struct pci_bus *find_bus (u8 busno)
return NULL; return NULL;
} }
/******************************************************************
* This function is here because we can no longer use pci_root_ops
******************************************************************/
static struct pci_ops *get_root_pci_ops (void)
{
struct pci_bus * bus;
if ((bus = find_bus (0)))
return bus->ops;
return NULL;
}
/************************************************************* /*************************************************************
* This routine frees up memory used by struct slot, including * This routine frees up memory used by struct slot, including
* the pointers to pci_func, bus, hotplug_slot, controller, * the pointers to pci_func, bus, hotplug_slot, controller,
...@@ -775,8 +780,10 @@ static void free_slots (void) ...@@ -775,8 +780,10 @@ static void free_slots (void)
struct list_head * tmp; struct list_head * tmp;
struct list_head * next; struct list_head * next;
list_for_each_safe (tmp, next, &ibmphp_slot_head) { debug ("%s -- enter\n", __FUNCTION__);
list_for_each_safe (tmp, next, &ibmphp_slot_head) {
slot_cur = list_entry (tmp, struct slot, ibm_slot_list); slot_cur = list_entry (tmp, struct slot, ibm_slot_list);
pci_hp_deregister (slot_cur->hotplug_slot); pci_hp_deregister (slot_cur->hotplug_slot);
...@@ -795,7 +802,9 @@ static void free_slots (void) ...@@ -795,7 +802,9 @@ static void free_slots (void)
ibmphp_unconfigure_card (&slot_cur, -1); /* we don't want to actually remove the resources, since free_resources will do just that */ ibmphp_unconfigure_card (&slot_cur, -1); /* we don't want to actually remove the resources, since free_resources will do just that */
kfree (slot_cur); kfree (slot_cur);
slot_cur = NULL;
} }
debug ("%s -- exit\n", __FUNCTION__);
} }
static int ibm_is_pci_dev_in_use (struct pci_dev *dev) static int ibm_is_pci_dev_in_use (struct pci_dev *dev)
...@@ -851,7 +860,7 @@ static int ibm_unconfigure_visit_pci_dev_phase2 (struct pci_dev_wrapped *wrapped ...@@ -851,7 +860,7 @@ static int ibm_unconfigure_visit_pci_dev_phase2 (struct pci_dev_wrapped *wrapped
if (temp_func) if (temp_func)
temp_func->dev = NULL; temp_func->dev = NULL;
else else
err ("No pci_func representation for bus, devfn = %d, %x\n", dev->bus->number, dev->devfn); debug ("No pci_func representation for bus, devfn = %d, %x\n", dev->bus->number, dev->devfn);
return 0; return 0;
} }
...@@ -954,8 +963,8 @@ static int configure_visit_pci_dev (struct pci_dev_wrapped *wrapped_dev, struct ...@@ -954,8 +963,8 @@ static int configure_visit_pci_dev (struct pci_dev_wrapped *wrapped_dev, struct
} }
if (temp_func->dev) { if (temp_func->dev) {
pci_proc_attach_device (temp_func->dev); // pci_proc_attach_device (temp_func->dev);
pci_announce_device_to_drivers (temp_func->dev); // pci_announce_device_to_drivers (temp_func->dev);
} }
return 0; return 0;
...@@ -965,6 +974,51 @@ static struct pci_visit configure_functions = { ...@@ -965,6 +974,51 @@ static struct pci_visit configure_functions = {
.visit_pci_dev =configure_visit_pci_dev, .visit_pci_dev =configure_visit_pci_dev,
}; };
/*
* The following function is to fix kernel bug regarding
* getting bus entries, here we manually add those primary
* bus entries to kernel bus structure whenever apply
*/
static u8 bus_structure_fixup (u8 busno)
{
struct pci_bus *bus;
struct pci_dev *dev;
u16 l;
if (!find_bus (busno) || !(ibmphp_find_same_bus_num (busno)))
return 1;
bus = kmalloc (sizeof (*bus), GFP_KERNEL);
if (!bus) {
err ("%s - out of memory\n", __FUNCTION__);
return 1;
}
dev = kmalloc (sizeof (*dev), GFP_KERNEL);
if (!dev) {
kfree (bus);
err ("%s - out of memory\n", __FUNCTION__);
return 1;
}
bus->number = busno;
bus->ops = ibmphp_pci_bus->ops;
dev->bus = bus;
for (dev->devfn = 0; dev->devfn < 256; dev->devfn += 8) {
if (!pci_read_config_word (dev, PCI_VENDOR_ID, &l) && l != 0x0000 && l != 0xffff) {
debug ("%s - Inside bus_struture_fixup() \n", __FUNCTION__);
pci_scan_bus (busno, ibmphp_pci_bus->ops, NULL);
break;
}
}
kfree (dev);
kfree (bus);
return 0;
}
static int ibm_configure_device (struct pci_func *func) static int ibm_configure_device (struct pci_func *func)
{ {
unsigned char bus; unsigned char bus;
...@@ -972,6 +1026,7 @@ static int ibm_configure_device (struct pci_func *func) ...@@ -972,6 +1026,7 @@ static int ibm_configure_device (struct pci_func *func)
struct pci_bus *child; struct pci_bus *child;
struct pci_dev *temp; struct pci_dev *temp;
int rc = 0; int rc = 0;
int flag = 0; /* this is to make sure we don't double scan the bus, for bridged devices primarily */
struct pci_dev_wrapped wrapped_dev; struct pci_dev_wrapped wrapped_dev;
struct pci_bus_wrapped wrapped_bus; struct pci_bus_wrapped wrapped_bus;
...@@ -980,6 +1035,8 @@ static int ibm_configure_device (struct pci_func *func) ...@@ -980,6 +1035,8 @@ static int ibm_configure_device (struct pci_func *func)
memset (&wrapped_bus, 0, sizeof (struct pci_bus_wrapped)); memset (&wrapped_bus, 0, sizeof (struct pci_bus_wrapped));
memset (&dev0, 0, sizeof (struct pci_dev)); memset (&dev0, 0, sizeof (struct pci_dev));
if (!(bus_structure_fixup (func->busno)))
flag = 1;
if (func->dev == NULL) if (func->dev == NULL)
func->dev = pci_find_slot (func->busno, (func->device << 3) | (func->function & 0x7)); func->dev = pci_find_slot (func->busno, (func->device << 3) | (func->function & 0x7));
...@@ -995,7 +1052,7 @@ static int ibm_configure_device (struct pci_func *func) ...@@ -995,7 +1052,7 @@ static int ibm_configure_device (struct pci_func *func)
return 0; return 0;
} }
} }
if (func->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { if (!(flag) && (func->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)) {
pci_read_config_byte (func->dev, PCI_SECONDARY_BUS, &bus); pci_read_config_byte (func->dev, PCI_SECONDARY_BUS, &bus);
child = (struct pci_bus *) pci_add_new_bus (func->dev->bus, (func->dev), bus); child = (struct pci_bus *) pci_add_new_bus (func->dev->bus, (func->dev), bus);
pci_do_scan_bus (child); pci_do_scan_bus (child);
...@@ -1028,7 +1085,7 @@ static int is_bus_empty (struct slot * slot_cur) ...@@ -1028,7 +1085,7 @@ static int is_bus_empty (struct slot * slot_cur)
rc = slot_update (&tmp_slot); rc = slot_update (&tmp_slot);
if (rc) if (rc)
return 0; return 0;
if (SLOT_PRESENT (tmp_slot->status) && SLOT_POWER (tmp_slot->status)) if (SLOT_PRESENT (tmp_slot->status) && SLOT_PWRGD (tmp_slot->status))
return 0; return 0;
i++; i++;
} }
...@@ -1046,6 +1103,9 @@ static int set_bus (struct slot * slot_cur) ...@@ -1046,6 +1103,9 @@ static int set_bus (struct slot * slot_cur)
int rc; int rc;
u8 speed; u8 speed;
u8 cmd = 0x0; u8 cmd = 0x0;
const struct list_head *tmp;
struct pci_dev * dev;
int retval;
debug ("%s - entry slot # %d \n", __FUNCTION__, slot_cur->number); debug ("%s - entry slot # %d \n", __FUNCTION__, slot_cur->number);
if (SET_BUS_STATUS (slot_cur->ctrl) && is_bus_empty (slot_cur)) { if (SET_BUS_STATUS (slot_cur->ctrl) && is_bus_empty (slot_cur)) {
...@@ -1091,6 +1151,14 @@ static int set_bus (struct slot * slot_cur) ...@@ -1091,6 +1151,14 @@ static int set_bus (struct slot * slot_cur)
cmd = HPC_BUS_100PCIXMODE; cmd = HPC_BUS_100PCIXMODE;
break; break;
case BUS_SPEED_133: case BUS_SPEED_133:
/* This is to take care of the bug in CIOBX chip*/
list_for_each (tmp, &pci_devices) {
dev = (struct pci_dev *) pci_dev_g (tmp);
if (dev) {
if ((dev->vendor == 0x1166) && (dev->device == 0x0101))
ibmphp_hpc_writeslot (slot_cur, HPC_BUS_100PCIXMODE);
}
}
cmd = HPC_BUS_133PCIXMODE; cmd = HPC_BUS_133PCIXMODE;
break; break;
default: default:
...@@ -1103,9 +1171,17 @@ static int set_bus (struct slot * slot_cur) ...@@ -1103,9 +1171,17 @@ static int set_bus (struct slot * slot_cur)
return -ENODEV; return -ENODEV;
} }
debug ("setting bus speed for slot %d, cmd %x\n", slot_cur->number, cmd); debug ("setting bus speed for slot %d, cmd %x\n", slot_cur->number, cmd);
ibmphp_hpc_writeslot (slot_cur, cmd); retval = ibmphp_hpc_writeslot (slot_cur, cmd);
if (retval) {
err ("setting bus speed failed\n");
return retval;
}
if (CTLR_RESULT (slot_cur->ctrl->status)) {
err ("command not completed successfully in set_bus \n");
return -EIO;
}
} }
/* This is for x400, once Brandon fixes the firmware, /* This is for x440, once Brandon fixes the firmware,
will not need this delay */ will not need this delay */
long_delay (1 * HZ); long_delay (1 * HZ);
debug ("%s -Exit \n", __FUNCTION__); debug ("%s -Exit \n", __FUNCTION__);
...@@ -1128,7 +1204,7 @@ static int check_limitations (struct slot *slot_cur) ...@@ -1128,7 +1204,7 @@ static int check_limitations (struct slot *slot_cur)
for (i = slot_cur->bus_on->slot_min; i <= slot_cur->bus_on->slot_max; i++) { for (i = slot_cur->bus_on->slot_min; i <= slot_cur->bus_on->slot_max; i++) {
tmp_slot = ibmphp_get_slot_from_physical_num (i); tmp_slot = ibmphp_get_slot_from_physical_num (i);
if ((SLOT_POWER (tmp_slot->status)) && !(SLOT_CONNECT (tmp_slot->status))) if ((SLOT_PWRGD (tmp_slot->status)) && !(SLOT_CONNECT (tmp_slot->status)))
count++; count++;
} }
get_cur_bus_info (&slot_cur); get_cur_bus_info (&slot_cur);
...@@ -1384,11 +1460,15 @@ int ibmphp_disable_slot (struct hotplug_slot *hotplug_slot) ...@@ -1384,11 +1460,15 @@ int ibmphp_disable_slot (struct hotplug_slot *hotplug_slot)
debug ("DISABLING SLOT... \n"); debug ("DISABLING SLOT... \n");
if (slot_cur == NULL) if (slot_cur == NULL) {
ibmphp_unlock_operations ();
return -ENODEV; return -ENODEV;
}
if (slot_cur->ctrl == NULL) if (slot_cur->ctrl == NULL) {
ibmphp_unlock_operations ();
return -ENODEV; return -ENODEV;
}
flag = slot_cur->flag; /* to see if got here from polling */ flag = slot_cur->flag; /* to see if got here from polling */
...@@ -1463,7 +1543,8 @@ int ibmphp_disable_slot (struct hotplug_slot *hotplug_slot) ...@@ -1463,7 +1543,8 @@ int ibmphp_disable_slot (struct hotplug_slot *hotplug_slot)
return -EFAULT; return -EFAULT;
} }
ibmphp_update_slot_info (slot_cur); if (flag)
ibmphp_update_slot_info (slot_cur);
ibmphp_unlock_operations (); ibmphp_unlock_operations ();
return -EFAULT; return -EFAULT;
} }
...@@ -1503,10 +1584,10 @@ struct hotplug_slot_ops ibmphp_hotplug_slot_ops = { ...@@ -1503,10 +1584,10 @@ struct hotplug_slot_ops ibmphp_hotplug_slot_ops = {
.get_attention_status = get_attention_status, .get_attention_status = get_attention_status,
.get_latch_status = get_latch_status, .get_latch_status = get_latch_status,
.get_adapter_status = get_adapter_present, .get_adapter_status = get_adapter_present,
/* get_max_bus_speed_status: get_max_bus_speed, /* .get_max_bus_speed_status = get_max_bus_speed,
.get_max_adapter_speed_status = get_max_adapter_speed, .get_max_adapter_speed_status = get_max_adapter_speed,
.get_cur_bus_speed_status = get_cur_bus_speed, .get_cur_bus_speed_status = get_cur_bus_speed,
.get_card_bus_names_status = get_card_bus_names, .get_bus_name_status = get_bus_name,
*/ */
}; };
...@@ -1526,6 +1607,7 @@ static void ibmphp_unload (void) ...@@ -1526,6 +1607,7 @@ static void ibmphp_unload (void)
static int __init ibmphp_init (void) static int __init ibmphp_init (void)
{ {
struct pci_bus *bus;
int i = 0; int i = 0;
int rc = 0; int rc = 0;
...@@ -1533,12 +1615,19 @@ static int __init ibmphp_init (void) ...@@ -1533,12 +1615,19 @@ static int __init ibmphp_init (void)
info (DRIVER_DESC " version: " DRIVER_VERSION "\n"); info (DRIVER_DESC " version: " DRIVER_VERSION "\n");
ibmphp_pci_root_ops = get_root_pci_ops (); ibmphp_pci_bus = kmalloc (sizeof (*ibmphp_pci_bus), GFP_KERNEL);
if (ibmphp_pci_root_ops == NULL) { if (!ibmphp_pci_bus) {
err ("cannot read bus operations... will not be able to read the cards. Please check your system\n"); err ("out of memory\n");
return -ENODEV; return -ENOMEM;
} }
bus = find_bus (0);
if (!bus) {
err ("Can't find the root pci bus, can not continue\n");
return -ENODEV;
}
memcpy (ibmphp_pci_bus, bus, sizeof (*ibmphp_pci_bus));
ibmphp_debug = debug; ibmphp_debug = debug;
ibmphp_hpc_initvars (); ibmphp_hpc_initvars ();
...@@ -1559,6 +1648,11 @@ static int __init ibmphp_init (void) ...@@ -1559,6 +1648,11 @@ static int __init ibmphp_init (void)
debug ("AFTER Resource & EBDA INITIALIZATIONS\n"); debug ("AFTER Resource & EBDA INITIALIZATIONS\n");
max_slots = get_max_slots (); max_slots = get_max_slots ();
if ((rc = ibmphp_register_pci ())) {
ibmphp_unload ();
return rc;
}
if (init_ops ()) { if (init_ops ()) {
ibmphp_unload (); ibmphp_unload ();
...@@ -1570,11 +1664,9 @@ static int __init ibmphp_init (void) ...@@ -1570,11 +1664,9 @@ static int __init ibmphp_init (void)
return -ENODEV; return -ENODEV;
} }
/* lock ourselves into memory with a module count of -1 /* if no NVRAM module selected, lock ourselves into memory with a
* so that no one can unload us. */ * module count of -1 so that no one can unload us. */
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
return 0; return 0;
} }
......
...@@ -56,11 +56,17 @@ LIST_HEAD (ibmphp_slot_head); ...@@ -56,11 +56,17 @@ LIST_HEAD (ibmphp_slot_head);
/* Local variables */ /* Local variables */
static struct ebda_hpc_list *hpc_list_ptr; static struct ebda_hpc_list *hpc_list_ptr;
static struct ebda_rsrc_list *rsrc_list_ptr; static struct ebda_rsrc_list *rsrc_list_ptr;
static struct rio_table_hdr *rio_table_ptr; static struct rio_table_hdr *rio_table_ptr = NULL;
static LIST_HEAD (ebda_hpc_head); static LIST_HEAD (ebda_hpc_head);
static LIST_HEAD (bus_info_head); static LIST_HEAD (bus_info_head);
static LIST_HEAD (rio_vg_head);
static LIST_HEAD (rio_lo_head);
static LIST_HEAD (opt_vg_head);
static LIST_HEAD (opt_lo_head);
static void *io_mem; static void *io_mem;
char *chassis_str, *rxe_str, *str;
/* Local functions */ /* Local functions */
static int ebda_rsrc_controller (void); static int ebda_rsrc_controller (void);
static int ebda_rsrc_rsrc (void); static int ebda_rsrc_rsrc (void);
...@@ -125,6 +131,7 @@ static void free_ebda_hpc (struct controller *controller) ...@@ -125,6 +131,7 @@ static void free_ebda_hpc (struct controller *controller)
controller->slots = NULL; controller->slots = NULL;
kfree (controller->buses); kfree (controller->buses);
controller->buses = NULL; controller->buses = NULL;
controller->ctrl_dev = NULL;
kfree (controller); kfree (controller);
} }
...@@ -173,18 +180,77 @@ static void __init print_bus_info (void) ...@@ -173,18 +180,77 @@ static void __init print_bus_info (void)
} }
} }
static void print_ebda_pci_rsrc (void) static void print_lo_info (void)
{
struct rio_detail *ptr;
struct list_head *ptr1;
debug ("print_lo_info ---- \n");
list_for_each (ptr1, &rio_lo_head) {
ptr = list_entry (ptr1, struct rio_detail, rio_detail_list);
debug ("%s - rio_node_id = %x\n", __FUNCTION__, ptr->rio_node_id);
debug ("%s - rio_type = %x\n", __FUNCTION__, ptr->rio_type);
debug ("%s - owner_id = %x\n", __FUNCTION__, ptr->owner_id);
debug ("%s - first_slot_num = %x\n", __FUNCTION__, ptr->first_slot_num);
debug ("%s - wpindex = %x\n", __FUNCTION__, ptr->wpindex);
debug ("%s - chassis_num = %x\n", __FUNCTION__, ptr->chassis_num);
}
}
static void print_vg_info (void)
{
struct rio_detail *ptr;
struct list_head *ptr1;
debug ("%s --- \n", __FUNCTION__);
list_for_each (ptr1, &rio_vg_head) {
ptr = list_entry (ptr1, struct rio_detail, rio_detail_list);
debug ("%s - rio_node_id = %x\n", __FUNCTION__, ptr->rio_node_id);
debug ("%s - rio_type = %x\n", __FUNCTION__, ptr->rio_type);
debug ("%s - owner_id = %x\n", __FUNCTION__, ptr->owner_id);
debug ("%s - first_slot_num = %x\n", __FUNCTION__, ptr->first_slot_num);
debug ("%s - wpindex = %x\n", __FUNCTION__, ptr->wpindex);
debug ("%s - chassis_num = %x\n", __FUNCTION__, ptr->chassis_num);
}
}
static void __init print_ebda_pci_rsrc (void)
{ {
struct ebda_pci_rsrc *ptr; struct ebda_pci_rsrc *ptr;
struct list_head *ptr1; struct list_head *ptr1;
list_for_each (ptr1, &ibmphp_ebda_pci_rsrc_head) { list_for_each (ptr1, &ibmphp_ebda_pci_rsrc_head) {
ptr = list_entry (ptr1, struct ebda_pci_rsrc, ebda_pci_rsrc_list); ptr = list_entry (ptr1, struct ebda_pci_rsrc, ebda_pci_rsrc_list);
debug ("%s - rsrc type: %x bus#: %x dev_func: %x start addr: %lx end addr: %lx\n", debug ("%s - rsrc type: %x bus#: %x dev_func: %x start addr: %x end addr: %x\n",
__FUNCTION__, ptr->rsrc_type ,ptr->bus_num, ptr->dev_fun,ptr->start_addr, ptr->end_addr); __FUNCTION__, ptr->rsrc_type ,ptr->bus_num, ptr->dev_fun,ptr->start_addr, ptr->end_addr);
} }
} }
static void __init print_ibm_slot (void)
{
struct slot *ptr;
struct list_head *ptr1;
list_for_each (ptr1, &ibmphp_slot_head) {
ptr = list_entry (ptr1, struct slot, ibm_slot_list);
debug ("%s - slot_number: %x \n", __FUNCTION__, ptr->number);
}
}
static void __init print_opt_vg (void)
{
struct opt_rio *ptr;
struct list_head *ptr1;
debug ("%s --- \n", __FUNCTION__);
list_for_each (ptr1, &opt_vg_head) {
ptr = list_entry (ptr1, struct opt_rio, opt_rio_list);
debug ("%s - rio_type %x \n", __FUNCTION__, ptr->rio_type);
debug ("%s - chassis_num: %x \n", __FUNCTION__, ptr->chassis_num);
debug ("%s - first_slot_num: %x \n", __FUNCTION__, ptr->first_slot_num);
debug ("%s - middle_num: %x \n", __FUNCTION__, ptr->middle_num);
}
}
static void __init print_ebda_hpc (void) static void __init print_ebda_hpc (void)
{ {
struct controller *hpc_ptr; struct controller *hpc_ptr;
...@@ -221,6 +287,7 @@ static void __init print_ebda_hpc (void) ...@@ -221,6 +287,7 @@ static void __init print_ebda_hpc (void)
break; break;
case 2: case 2:
case 4:
debug ("%s - wpegbbar: %lx\n", __FUNCTION__, hpc_ptr->u.wpeg_ctlr.wpegbbar); debug ("%s - wpegbbar: %lx\n", __FUNCTION__, hpc_ptr->u.wpeg_ctlr.wpegbbar);
debug ("%s - i2c_addr: %x\n", __FUNCTION__, hpc_ptr->u.wpeg_ctlr.i2c_addr); debug ("%s - i2c_addr: %x\n", __FUNCTION__, hpc_ptr->u.wpeg_ctlr.i2c_addr);
debug ("%s - irq: %x\n", __FUNCTION__, hpc_ptr->irq); debug ("%s - irq: %x\n", __FUNCTION__, hpc_ptr->irq);
...@@ -357,31 +424,382 @@ int __init ibmphp_access_ebda (void) ...@@ -357,31 +424,382 @@ int __init ibmphp_access_ebda (void)
rio_complete = 1; rio_complete = 1;
} }
}
if (hs_complete && rio_complete) { if (!hs_complete && !rio_complete) {
rc = ebda_rsrc_controller (); iounmap (io_mem);
if (rc) { return -ENODEV;
iounmap(io_mem); }
return rc;
} if (rio_table_ptr) {
rc = ebda_rsrc_rsrc (); if (rio_complete == 1 && rio_table_ptr->ver_num == 3) {
if (rc) {
iounmap(io_mem);
return rc;
}
rc = ebda_rio_table (); rc = ebda_rio_table ();
if (rc) { if (rc) {
iounmap(io_mem); iounmap (io_mem);
return rc; return rc;
} }
iounmap (io_mem);
return 0;
} }
} }
rc = ebda_rsrc_controller ();
if (rc) {
iounmap (io_mem);
return rc;
}
rc = ebda_rsrc_rsrc ();
if (rc) {
iounmap (io_mem);
return rc;
}
iounmap (io_mem); iounmap (io_mem);
return -ENODEV; return 0;
} }
/*
* map info of scalability details and rio details from physical address
*/
static int __init ebda_rio_table (void)
{
u16 offset;
u8 i;
struct rio_detail *rio_detail_ptr;
offset = rio_table_ptr->offset;
offset += 12 * rio_table_ptr->scal_count;
// we do concern about rio details
for (i = 0; i < rio_table_ptr->riodev_count; i++) {
rio_detail_ptr = kmalloc (sizeof (struct rio_detail), GFP_KERNEL);
if (!rio_detail_ptr)
return -ENOMEM;
memset (rio_detail_ptr, 0, sizeof (struct rio_detail));
rio_detail_ptr->rio_node_id = readb (io_mem + offset);
rio_detail_ptr->bbar = readl (io_mem + offset + 1);
rio_detail_ptr->rio_type = readb (io_mem + offset + 5);
rio_detail_ptr->owner_id = readb (io_mem + offset + 6);
rio_detail_ptr->port0_node_connect = readb (io_mem + offset + 7);
rio_detail_ptr->port0_port_connect = readb (io_mem + offset + 8);
rio_detail_ptr->port1_node_connect = readb (io_mem + offset + 9);
rio_detail_ptr->port1_port_connect = readb (io_mem + offset + 10);
rio_detail_ptr->first_slot_num = readb (io_mem + offset + 11);
rio_detail_ptr->status = readb (io_mem + offset + 12);
rio_detail_ptr->wpindex = readb (io_mem + offset + 13);
rio_detail_ptr->chassis_num = readb (io_mem + offset + 14);
// debug ("rio_node_id: %x\nbbar: %x\nrio_type: %x\nowner_id: %x\nport0_node: %x\nport0_port: %x\nport1_node: %x\nport1_port: %x\nfirst_slot_num: %x\nstatus: %x\n", rio_detail_ptr->rio_node_id, rio_detail_ptr->bbar, rio_detail_ptr->rio_type, rio_detail_ptr->owner_id, rio_detail_ptr->port0_node_connect, rio_detail_ptr->port0_port_connect, rio_detail_ptr->port1_node_connect, rio_detail_ptr->port1_port_connect, rio_detail_ptr->first_slot_num, rio_detail_ptr->status);
//create linked list of chassis
if (rio_detail_ptr->rio_type == 4 || rio_detail_ptr->rio_type == 5)
list_add (&rio_detail_ptr->rio_detail_list, &rio_vg_head);
//create linked list of expansion box
else if (rio_detail_ptr->rio_type == 6 || rio_detail_ptr->rio_type == 7)
list_add (&rio_detail_ptr->rio_detail_list, &rio_lo_head);
else
// not in my concern
kfree (rio_detail_ptr);
offset += 15;
}
print_lo_info ();
print_vg_info ();
return 0;
}
/*
* reorganizing linked list of chassis
*/
static struct opt_rio *search_opt_vg (u8 chassis_num)
{
struct opt_rio *ptr;
struct list_head *ptr1;
list_for_each (ptr1, &opt_vg_head) {
ptr = list_entry (ptr1, struct opt_rio, opt_rio_list);
if (ptr->chassis_num == chassis_num)
return ptr;
}
return NULL;
}
static int __init combine_wpg_for_chassis (void)
{
struct opt_rio *opt_rio_ptr = NULL;
struct rio_detail *rio_detail_ptr = NULL;
struct list_head *list_head_ptr = NULL;
list_for_each (list_head_ptr, &rio_vg_head) {
rio_detail_ptr = list_entry (list_head_ptr, struct rio_detail, rio_detail_list);
opt_rio_ptr = search_opt_vg (rio_detail_ptr->chassis_num);
if (!opt_rio_ptr) {
opt_rio_ptr = (struct opt_rio *) kmalloc (sizeof (struct opt_rio), GFP_KERNEL);
if (!opt_rio_ptr)
return -ENOMEM;
memset (opt_rio_ptr, 0, sizeof (struct opt_rio));
opt_rio_ptr->rio_type = rio_detail_ptr->rio_type;
opt_rio_ptr->chassis_num = rio_detail_ptr->chassis_num;
opt_rio_ptr->first_slot_num = rio_detail_ptr->first_slot_num;
opt_rio_ptr->middle_num = rio_detail_ptr->first_slot_num;
list_add (&opt_rio_ptr->opt_rio_list, &opt_vg_head);
} else {
opt_rio_ptr->first_slot_num = min (opt_rio_ptr->first_slot_num, rio_detail_ptr->first_slot_num);
opt_rio_ptr->middle_num = max (opt_rio_ptr->middle_num, rio_detail_ptr->first_slot_num);
}
}
print_opt_vg ();
return 0;
}
/*
* reorgnizing linked list of expansion box
*/
static struct opt_rio_lo *search_opt_lo (u8 chassis_num)
{
struct opt_rio_lo *ptr;
struct list_head *ptr1;
list_for_each (ptr1, &opt_lo_head) {
ptr = list_entry (ptr1, struct opt_rio_lo, opt_rio_lo_list);
if (ptr->chassis_num == chassis_num)
return ptr;
}
return NULL;
}
static int combine_wpg_for_expansion (void)
{
struct opt_rio_lo *opt_rio_lo_ptr = NULL;
struct rio_detail *rio_detail_ptr = NULL;
struct list_head *list_head_ptr = NULL;
list_for_each (list_head_ptr, &rio_lo_head) {
rio_detail_ptr = list_entry (list_head_ptr, struct rio_detail, rio_detail_list);
opt_rio_lo_ptr = search_opt_lo (rio_detail_ptr->chassis_num);
if (!opt_rio_lo_ptr) {
opt_rio_lo_ptr = (struct opt_rio_lo *) kmalloc (sizeof (struct opt_rio_lo), GFP_KERNEL);
if (!opt_rio_lo_ptr)
return -ENOMEM;
memset (opt_rio_lo_ptr, 0, sizeof (struct opt_rio_lo));
opt_rio_lo_ptr->rio_type = rio_detail_ptr->rio_type;
opt_rio_lo_ptr->chassis_num = rio_detail_ptr->chassis_num;
opt_rio_lo_ptr->first_slot_num = rio_detail_ptr->first_slot_num;
opt_rio_lo_ptr->middle_num = rio_detail_ptr->first_slot_num;
opt_rio_lo_ptr->pack_count = 1;
list_add (&opt_rio_lo_ptr->opt_rio_lo_list, &opt_lo_head);
} else {
opt_rio_lo_ptr->first_slot_num = min (opt_rio_lo_ptr->first_slot_num, rio_detail_ptr->first_slot_num);
opt_rio_lo_ptr->middle_num = max (opt_rio_lo_ptr->middle_num, rio_detail_ptr->first_slot_num);
opt_rio_lo_ptr->pack_count = 2;
}
}
return 0;
}
static char *convert_2digits_to_char (int var)
{
int bit;
char *str1;
str = (char *) kmalloc (3, GFP_KERNEL);
memset (str, 0, 3);
str1 = (char *) kmalloc (2, GFP_KERNEL);
memset (str, 0, 3);
bit = (int)(var / 10);
switch (bit) {
case 0:
//one digit number
*str = (char)(var + 48);
return str;
default:
//2 digits number
*str1 = (char)(bit + 48);
strncpy (str, str1, 1);
memset (str1, 0, 3);
*str1 = (char)((var % 10) + 48);
strcat (str, str1);
return str;
}
return NULL;
}
/* Since we don't know the max slot number per each chassis, hence go
* through the list of all chassis to find out the range
* Arguments: slot_num, 1st slot number of the chassis we think we are on,
* var (0 = chassis, 1 = expansion box)
*/
static int first_slot_num (u8 slot_num, u8 first_slot, u8 var)
{
struct opt_rio *opt_vg_ptr = NULL;
struct opt_rio_lo *opt_lo_ptr = NULL;
struct list_head *ptr = NULL;
int rc = 0;
if (!var) {
list_for_each (ptr, &opt_vg_head) {
opt_vg_ptr = list_entry (ptr, struct opt_rio, opt_rio_list);
if ((first_slot < opt_vg_ptr->first_slot_num) && (slot_num >= opt_vg_ptr->first_slot_num)) {
rc = -ENODEV;
break;
}
}
} else {
list_for_each (ptr, &opt_lo_head) {
opt_lo_ptr = list_entry (ptr, struct opt_rio_lo, opt_rio_lo_list);
if ((first_slot < opt_lo_ptr->first_slot_num) && (slot_num >= opt_lo_ptr->first_slot_num)) {
rc = -ENODEV;
break;
}
}
}
return rc;
}
static struct opt_rio_lo * find_rxe_num (u8 slot_num)
{
struct opt_rio_lo *opt_lo_ptr;
struct list_head *ptr;
list_for_each (ptr, &opt_lo_head) {
opt_lo_ptr = list_entry (ptr, struct opt_rio_lo, opt_rio_lo_list);
//check to see if this slot_num belongs to expansion box
if ((slot_num >= opt_lo_ptr->first_slot_num) && (!first_slot_num (slot_num, opt_lo_ptr->first_slot_num, 1)))
return opt_lo_ptr;
}
return NULL;
}
static struct opt_rio * find_chassis_num (u8 slot_num)
{
struct opt_rio *opt_vg_ptr;
struct list_head *ptr;
list_for_each (ptr, &opt_vg_head) {
opt_vg_ptr = list_entry (ptr, struct opt_rio, opt_rio_list);
//check to see if this slot_num belongs to chassis
if ((slot_num >= opt_vg_ptr->first_slot_num) && (!first_slot_num (slot_num, opt_vg_ptr->first_slot_num, 0)))
return opt_vg_ptr;
}
return NULL;
}
/* This routine will find out how many slots are in the chassis, so that
* the slot numbers for rxe100 would start from 1, and not from 7, or 6 etc
*/
static u8 calculate_first_slot (u8 slot_num)
{
u8 first_slot = 1;
struct list_head * list;
struct slot * slot_cur;
list_for_each (list, &ibmphp_slot_head) {
slot_cur = list_entry (list, struct slot, ibm_slot_list);
if (slot_cur->ctrl) {
if ((slot_cur->ctrl->ctlr_type != 4) && (slot_cur->ctrl->ending_slot_num > first_slot) && (slot_num > slot_cur->ctrl->ending_slot_num))
first_slot = slot_cur->ctrl->ending_slot_num;
}
}
return first_slot + 1;
}
static char *create_file_name (struct slot * slot_cur)
{
struct opt_rio *opt_vg_ptr = NULL;
struct opt_rio_lo *opt_lo_ptr = NULL;
char *ptr_chassis_num, *ptr_rxe_num, *ptr_slot_num;
int which = 0; /* rxe = 1, chassis = 0 */
u8 number = 1; /* either chassis or rxe # */
u8 first_slot = 1;
u8 slot_num;
u8 flag = 0;
if (!slot_cur) {
err ("Structure passed is empty \n");
return NULL;
}
slot_num = slot_cur->number;
chassis_str = (char *) kmalloc (30, GFP_KERNEL);
memset (chassis_str, 0, 30);
rxe_str = (char *) kmalloc (30, GFP_KERNEL);
memset (rxe_str, 0, 30);
ptr_chassis_num = (char *) kmalloc (3, GFP_KERNEL);
memset (ptr_chassis_num, 0, 3);
ptr_rxe_num = (char *) kmalloc (3, GFP_KERNEL);
memset (ptr_rxe_num, 0, 3);
ptr_slot_num = (char *) kmalloc (3, GFP_KERNEL);
memset (ptr_slot_num, 0, 3);
strcpy (chassis_str, "chassis");
strcpy (rxe_str, "rxe");
if (rio_table_ptr) {
if (rio_table_ptr->ver_num == 3) {
opt_vg_ptr = find_chassis_num (slot_num);
opt_lo_ptr = find_rxe_num (slot_num);
}
}
if (opt_vg_ptr) {
if (opt_lo_ptr) {
if ((slot_num - opt_vg_ptr->first_slot_num) > (slot_num - opt_lo_ptr->first_slot_num)) {
number = opt_lo_ptr->chassis_num;
first_slot = opt_lo_ptr->first_slot_num;
which = 1; /* it is RXE */
} else {
first_slot = opt_vg_ptr->first_slot_num;
number = opt_vg_ptr->chassis_num;
which = 0;
}
} else {
first_slot = opt_vg_ptr->first_slot_num;
number = opt_vg_ptr->chassis_num;
which = 0;
}
++flag;
} else if (opt_lo_ptr) {
number = opt_lo_ptr->chassis_num;
first_slot = opt_lo_ptr->first_slot_num;
which = 1;
++flag;
} else if (rio_table_ptr) {
if (rio_table_ptr->ver_num == 3) {
/* if both NULL and we DO have correct RIO table in BIOS */
return NULL;
}
}
if (!flag) {
if (slot_cur->ctrl->ctlr_type == 4) {
first_slot = calculate_first_slot (slot_num);
which = 1;
} else {
which = 0;
}
}
switch (which) {
case 0:
/* Chassis */
*ptr_chassis_num = (char)(number + 48);
strcat (chassis_str, ptr_chassis_num);
kfree (ptr_chassis_num);
strcat (chassis_str, "slot");
ptr_slot_num = convert_2digits_to_char (slot_num - first_slot + 1);
strcat (chassis_str, ptr_slot_num);
kfree (ptr_slot_num);
return chassis_str;
break;
case 1:
/* RXE */
*ptr_rxe_num = (char)(number + 48);
strcat (rxe_str, ptr_rxe_num);
kfree (ptr_rxe_num);
strcat (rxe_str, "slot");
ptr_slot_num = convert_2digits_to_char (slot_num - first_slot + 1);
strcat (rxe_str, ptr_slot_num);
kfree (ptr_slot_num);
return rxe_str;
break;
}
return NULL;
}
static struct pci_driver ibmphp_driver;
/* /*
* map info (ctlr-id, slot count, slot#.. bus count, bus#, ctlr type...) of * map info (ctlr-id, slot count, slot#.. bus count, bus#, ctlr type...) of
...@@ -400,6 +818,9 @@ static int __init ebda_rsrc_controller (void) ...@@ -400,6 +818,9 @@ static int __init ebda_rsrc_controller (void)
struct ebda_hpc_slot *slot_ptr; struct ebda_hpc_slot *slot_ptr;
struct bus_info *bus_info_ptr1, *bus_info_ptr2; struct bus_info *bus_info_ptr1, *bus_info_ptr2;
int rc; int rc;
int retval;
struct slot *slot_cur;
struct list_head *list;
addr = hpc_list_ptr->phys_addr; addr = hpc_list_ptr->phys_addr;
for (ctlr = 0; ctlr < hpc_list_ptr->num_ctlrs; ctlr++) { for (ctlr = 0; ctlr < hpc_list_ptr->num_ctlrs; ctlr++) {
...@@ -510,23 +931,22 @@ static int __init ebda_rsrc_controller (void) ...@@ -510,23 +931,22 @@ static int __init ebda_rsrc_controller (void)
hpc_ptr->u.pci_ctlr.bus = readb (io_mem + addr); hpc_ptr->u.pci_ctlr.bus = readb (io_mem + addr);
hpc_ptr->u.pci_ctlr.dev_fun = readb (io_mem + addr + 1); hpc_ptr->u.pci_ctlr.dev_fun = readb (io_mem + addr + 1);
hpc_ptr->irq = readb (io_mem + addr + 2); hpc_ptr->irq = readb (io_mem + addr + 2);
addr += 3; addr += 3;
debug ("ctrl bus = %x, ctlr devfun = %x, irq = %x\n", hpc_ptr->u.pci_ctlr.bus, hpc_ptr->u.pci_ctlr.dev_fun, hpc_ptr->irq);
break; break;
case 0: case 0:
hpc_ptr->u.isa_ctlr.io_start = readw (io_mem + addr); hpc_ptr->u.isa_ctlr.io_start = readw (io_mem + addr);
hpc_ptr->u.isa_ctlr.io_end = readw (io_mem + addr + 2); hpc_ptr->u.isa_ctlr.io_end = readw (io_mem + addr + 2);
retval = check_region (hpc_ptr->u.isa_ctlr.io_start, (hpc_ptr->u.isa_ctlr.io_end - hpc_ptr->u.isa_ctlr.io_start + 1));
if (retval)
return -ENODEV;
request_region (hpc_ptr->u.isa_ctlr.io_start, (hpc_ptr->u.isa_ctlr.io_end - hpc_ptr->u.isa_ctlr.io_start + 1), "ibmphp");
hpc_ptr->irq = readb (io_mem + addr + 4); hpc_ptr->irq = readb (io_mem + addr + 4);
addr += 5; addr += 5;
break; break;
case 2: case 2:
hpc_ptr->u.wpeg_ctlr.wpegbbar = readl (io_mem + addr);
hpc_ptr->u.wpeg_ctlr.i2c_addr = readb (io_mem + addr + 4);
hpc_ptr->irq = readb (io_mem + addr + 5);
addr += 6;
break;
case 4: case 4:
hpc_ptr->u.wpeg_ctlr.wpegbbar = readl (io_mem + addr); hpc_ptr->u.wpeg_ctlr.wpegbbar = readl (io_mem + addr);
hpc_ptr->u.wpeg_ctlr.i2c_addr = readb (io_mem + addr + 4); hpc_ptr->u.wpeg_ctlr.i2c_addr = readb (io_mem + addr + 4);
...@@ -537,12 +957,10 @@ static int __init ebda_rsrc_controller (void) ...@@ -537,12 +957,10 @@ static int __init ebda_rsrc_controller (void)
iounmap (io_mem); iounmap (io_mem);
return -ENODEV; return -ENODEV;
} }
/* following 3 line: Now our driver only supports I2c ctlrType */
if ((hpc_ptr->ctlr_type != 2) && (hpc_ptr->ctlr_type != 4)) {
err ("Please run this driver on ibm xseries440\n ");
return -ENODEV;
}
//reorganize chassis' linked list
combine_wpg_for_chassis ();
combine_wpg_for_expansion ();
hpc_ptr->revision = 0xff; hpc_ptr->revision = 0xff;
hpc_ptr->options = 0xff; hpc_ptr->options = 0xff;
hpc_ptr->starting_slot_num = hpc_ptr->slots[0].slot_num; hpc_ptr->starting_slot_num = hpc_ptr->slots[0].slot_num;
...@@ -566,7 +984,7 @@ static int __init ebda_rsrc_controller (void) ...@@ -566,7 +984,7 @@ static int __init ebda_rsrc_controller (void)
} }
memset (hp_slot_ptr->info, 0, sizeof (struct hotplug_slot_info)); memset (hp_slot_ptr->info, 0, sizeof (struct hotplug_slot_info));
hp_slot_ptr->name = (char *) kmalloc (10, GFP_KERNEL); hp_slot_ptr->name = (char *) kmalloc (30, GFP_KERNEL);
if (!hp_slot_ptr->name) { if (!hp_slot_ptr->name) {
iounmap (io_mem); iounmap (io_mem);
kfree (hp_slot_ptr->info); kfree (hp_slot_ptr->info);
...@@ -583,9 +1001,7 @@ static int __init ebda_rsrc_controller (void) ...@@ -583,9 +1001,7 @@ static int __init ebda_rsrc_controller (void)
return -ENOMEM; return -ENOMEM;
} }
((struct slot *)hp_slot_ptr->private)->flag = TRUE; ((struct slot *)hp_slot_ptr->private)->flag = TRUE;
snprintf (hp_slot_ptr->name, 10, "%d", hpc_ptr->slots[index].slot_num);
((struct slot *) hp_slot_ptr->private)->capabilities = hpc_ptr->slots[index].slot_cap; ((struct slot *) hp_slot_ptr->private)->capabilities = hpc_ptr->slots[index].slot_cap;
if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_133_MAX) == EBDA_SLOT_133_MAX) if ((hpc_ptr->slots[index].slot_cap & EBDA_SLOT_133_MAX) == EBDA_SLOT_133_MAX)
...@@ -617,7 +1033,6 @@ static int __init ebda_rsrc_controller (void) ...@@ -617,7 +1033,6 @@ static int __init ebda_rsrc_controller (void)
((struct slot *) hp_slot_ptr->private)->number = hpc_ptr->slots[index].slot_num; ((struct slot *) hp_slot_ptr->private)->number = hpc_ptr->slots[index].slot_num;
((struct slot *) hp_slot_ptr->private)->hotplug_slot = hp_slot_ptr; ((struct slot *) hp_slot_ptr->private)->hotplug_slot = hp_slot_ptr;
rc = ibmphp_hpc_fillhpslotinfo (hp_slot_ptr); rc = ibmphp_hpc_fillhpslotinfo (hp_slot_ptr);
if (rc) { if (rc) {
iounmap (io_mem); iounmap (io_mem);
...@@ -631,8 +1046,6 @@ static int __init ebda_rsrc_controller (void) ...@@ -631,8 +1046,6 @@ static int __init ebda_rsrc_controller (void)
} }
hp_slot_ptr->ops = &ibmphp_hotplug_slot_ops; hp_slot_ptr->ops = &ibmphp_hotplug_slot_ops;
pci_hp_register (hp_slot_ptr);
// end of registering ibm slot with hotplug core // end of registering ibm slot with hotplug core
list_add (& ((struct slot *)(hp_slot_ptr->private))->ibm_slot_list, &ibmphp_slot_head); list_add (& ((struct slot *)(hp_slot_ptr->private))->ibm_slot_list, &ibmphp_slot_head);
...@@ -642,7 +1055,20 @@ static int __init ebda_rsrc_controller (void) ...@@ -642,7 +1055,20 @@ static int __init ebda_rsrc_controller (void)
list_add (&hpc_ptr->ebda_hpc_list, &ebda_hpc_head ); list_add (&hpc_ptr->ebda_hpc_list, &ebda_hpc_head );
} /* each hpc */ } /* each hpc */
list_for_each (list, &ibmphp_slot_head) {
slot_cur = list_entry (list, struct slot, ibm_slot_list);
snprintf (slot_cur->hotplug_slot->name, 30, "%s", create_file_name (slot_cur));
if (chassis_str)
kfree (chassis_str);
if (rxe_str)
kfree (rxe_str);
pci_hp_register (slot_cur->hotplug_slot);
}
print_ebda_hpc (); print_ebda_hpc ();
print_ibm_slot ();
return 0; return 0;
} }
...@@ -682,7 +1108,7 @@ static int __init ebda_rsrc_rsrc (void) ...@@ -682,7 +1108,7 @@ static int __init ebda_rsrc_rsrc (void)
addr += 6; addr += 6;
debug ("rsrc from io type ----\n"); debug ("rsrc from io type ----\n");
debug ("rsrc type: %x bus#: %x dev_func: %x start addr: %lx end addr: %lx\n", debug ("rsrc type: %x bus#: %x dev_func: %x start addr: %x end addr: %x\n",
rsrc_ptr->rsrc_type, rsrc_ptr->bus_num, rsrc_ptr->dev_fun, rsrc_ptr->start_addr, rsrc_ptr->end_addr); rsrc_ptr->rsrc_type, rsrc_ptr->bus_num, rsrc_ptr->dev_fun, rsrc_ptr->start_addr, rsrc_ptr->end_addr);
list_add (&rsrc_ptr->ebda_pci_rsrc_list, &ibmphp_ebda_pci_rsrc_head); list_add (&rsrc_ptr->ebda_pci_rsrc_list, &ibmphp_ebda_pci_rsrc_head);
...@@ -703,7 +1129,7 @@ static int __init ebda_rsrc_rsrc (void) ...@@ -703,7 +1129,7 @@ static int __init ebda_rsrc_rsrc (void)
addr += 10; addr += 10;
debug ("rsrc from mem or pfm ---\n"); debug ("rsrc from mem or pfm ---\n");
debug ("rsrc type: %x bus#: %x dev_func: %x start addr: %lx end addr: %lx\n", debug ("rsrc type: %x bus#: %x dev_func: %x start addr: %x end addr: %x\n",
rsrc_ptr->rsrc_type, rsrc_ptr->bus_num, rsrc_ptr->dev_fun, rsrc_ptr->start_addr, rsrc_ptr->end_addr); rsrc_ptr->rsrc_type, rsrc_ptr->bus_num, rsrc_ptr->dev_fun, rsrc_ptr->start_addr, rsrc_ptr->end_addr);
list_add (&rsrc_ptr->ebda_pci_rsrc_list, &ibmphp_ebda_pci_rsrc_head); list_add (&rsrc_ptr->ebda_pci_rsrc_list, &ibmphp_ebda_pci_rsrc_head);
...@@ -715,56 +1141,6 @@ static int __init ebda_rsrc_rsrc (void) ...@@ -715,56 +1141,6 @@ static int __init ebda_rsrc_rsrc (void)
return 0; return 0;
} }
/*
* map info of scalability details and rio details from physical address
*/
static int __init ebda_rio_table(void)
{
u16 offset;
u8 i;
struct scal_detail *scal_detail_ptr;
struct rio_detail *rio_detail_ptr;
offset = rio_table_ptr->offset;
for (i = 0; i < rio_table_ptr->scal_count; i++) {
scal_detail_ptr = kmalloc (sizeof (struct scal_detail), GFP_KERNEL );
if (!scal_detail_ptr )
return -ENOMEM;
memset (scal_detail_ptr, 0, sizeof (struct scal_detail) );
scal_detail_ptr->node_id = readb (io_mem + offset);
scal_detail_ptr->cbar = readl (io_mem+ offset + 1);
scal_detail_ptr->port0_node_connect = readb (io_mem + 5);
scal_detail_ptr->port0_port_connect = readb (io_mem + 6);
scal_detail_ptr->port1_node_connect = readb (io_mem + 7);
scal_detail_ptr->port1_port_connect = readb (io_mem + 8);
scal_detail_ptr->port2_node_connect = readb (io_mem + 9);
scal_detail_ptr->port2_port_connect = readb (io_mem + 10);
debug ("node_id: %x\ncbar: %x\nport0_node: %x\nport0_port: %x\nport1_node: %x\nport1_port: %x\nport2_node: %x\nport2_port: %x\n", scal_detail_ptr->node_id, scal_detail_ptr->cbar, scal_detail_ptr->port0_node_connect, scal_detail_ptr->port0_port_connect, scal_detail_ptr->port1_node_connect, scal_detail_ptr->port1_port_connect, scal_detail_ptr->port2_node_connect, scal_detail_ptr->port2_port_connect);
// list_add (&scal_detail_ptr->scal_detail_list, &scal_detail_head);
offset += 11;
}
for (i=0; i < rio_table_ptr->riodev_count; i++) {
rio_detail_ptr = kmalloc (sizeof (struct rio_detail), GFP_KERNEL );
if (!rio_detail_ptr )
return -ENOMEM;
memset (rio_detail_ptr, 0, sizeof (struct rio_detail) );
rio_detail_ptr->rio_node_id = readb (io_mem + offset );
rio_detail_ptr->bbar = readl (io_mem + offset + 1);
rio_detail_ptr->rio_type = readb (io_mem + offset + 5);
rio_detail_ptr->owner_id = readb (io_mem + offset + 6);
rio_detail_ptr->port0_node_connect = readb (io_mem + offset + 7);
rio_detail_ptr->port0_port_connect = readb (io_mem + offset + 8);
rio_detail_ptr->port1_node_connect = readb (io_mem + offset + 9);
rio_detail_ptr->port1_port_connect = readb (io_mem + offset + 10);
rio_detail_ptr->first_slot_num = readb (io_mem + offset + 11);
rio_detail_ptr->status = readb (io_mem + offset + 12);
debug ("rio_node_id: %x\nbbar: %x\nrio_type: %x\nowner_id: %x\nport0_node: %x\nport0_port: %x\nport1_node: %x\nport1_port: %x\nfirst_slot_num: %x\nstatus: %x\n", rio_detail_ptr->rio_node_id, rio_detail_ptr->bbar, rio_detail_ptr->rio_type, rio_detail_ptr->owner_id, rio_detail_ptr->port0_node_connect, rio_detail_ptr->port0_port_connect, rio_detail_ptr->port1_node_connect, rio_detail_ptr->port1_port_connect, rio_detail_ptr->first_slot_num, rio_detail_ptr->status);
offset += 13;
}
return 0;
}
u16 ibmphp_get_total_controllers (void) u16 ibmphp_get_total_controllers (void)
{ {
return hpc_list_ptr->num_ctlrs; return hpc_list_ptr->num_ctlrs;
...@@ -830,32 +1206,21 @@ void ibmphp_free_bus_info_queue (void) ...@@ -830,32 +1206,21 @@ void ibmphp_free_bus_info_queue (void)
} }
} }
/*
* Calculate the total hot pluggable slots controlled by total hpcs
*/
/*
int ibmphp_get_total_hp_slots (void)
{
struct ebda_hpc *ptr;
int slot_num = 0;
ptr = ebda_hpc_head;
while (ptr != NULL) {
slot_num += ptr->slot_count;
ptr = ptr->next;
}
return slot_num;
}
*/
void ibmphp_free_ebda_hpc_queue (void) void ibmphp_free_ebda_hpc_queue (void)
{ {
struct controller *controller; struct controller *controller = NULL;
struct list_head *list; struct list_head *list;
struct list_head *next; struct list_head *next;
int pci_flag = 0;
list_for_each_safe (list, next, &ebda_hpc_head) { list_for_each_safe (list, next, &ebda_hpc_head) {
controller = list_entry (list, struct controller, ebda_hpc_list); controller = list_entry (list, struct controller, ebda_hpc_list);
if (controller->ctlr_type == 0)
release_region (controller->u.isa_ctlr.io_start, (controller->u.isa_ctlr.io_end - controller->u.isa_ctlr.io_start + 1));
else if ((controller->ctlr_type == 1) && (!pci_flag)) {
++pci_flag;
pci_unregister_driver (&ibmphp_driver);
}
free_ebda_hpc (controller); free_ebda_hpc (controller);
} }
} }
...@@ -873,3 +1238,58 @@ void ibmphp_free_ebda_pci_rsrc_queue (void) ...@@ -873,3 +1238,58 @@ void ibmphp_free_ebda_pci_rsrc_queue (void)
} }
} }
static struct pci_device_id id_table[] __devinitdata = {
{
vendor: PCI_VENDOR_ID_IBM,
device: HPC_DEVICE_ID,
subvendor: PCI_VENDOR_ID_IBM,
subdevice: HPC_SUBSYSTEM_ID,
class: ((PCI_CLASS_SYSTEM_PCI_HOTPLUG << 8) | 0x00),
}, {}
};
MODULE_DEVICE_TABLE(pci, id_table);
static int ibmphp_probe (struct pci_dev *, const struct pci_device_id *);
static struct pci_driver ibmphp_driver = {
name: "ibmphp",
id_table: id_table,
probe: ibmphp_probe,
};
int ibmphp_register_pci (void)
{
struct controller *ctrl;
struct list_head *tmp;
int rc = 0;
list_for_each (tmp, &ebda_hpc_head) {
ctrl = list_entry (tmp, struct controller, ebda_hpc_list);
if (ctrl->ctlr_type == 1) {
rc = pci_module_init (&ibmphp_driver);
break;
}
}
return rc;
}
static int ibmphp_probe (struct pci_dev * dev, const struct pci_device_id *ids)
{
struct controller *ctrl;
struct list_head *tmp;
debug ("inside ibmphp_probe \n");
list_for_each (tmp, &ebda_hpc_head) {
ctrl = list_entry (tmp, struct controller, ebda_hpc_list);
if (ctrl->ctlr_type == 1) {
if ((dev->devfn == ctrl->u.pci_ctlr.dev_fun) && (dev->bus->number == ctrl->u.pci_ctlr.bus)) {
ctrl->ctrl_dev = dev;
debug ("found device!!! \n");
debug ("dev->device = %x, dev->subsystem_device = %x\n", dev->device, dev->subsystem_device);
return 0;
}
}
}
return -ENODEV;
}
...@@ -107,8 +107,8 @@ static struct semaphore sem_exit; // make sure polling thread goes away ...@@ -107,8 +107,8 @@ static struct semaphore sem_exit; // make sure polling thread goes away
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
// local function prototypes // local function prototypes
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
static u8 ctrl_read (struct controller *, void *, u8); static u8 i2c_ctrl_read (struct controller *, void *, u8);
static u8 ctrl_write (struct controller *, void *, u8, u8); static u8 i2c_ctrl_write (struct controller *, void *, u8, u8);
static u8 hpc_writecmdtoindex (u8, u8); static u8 hpc_writecmdtoindex (u8, u8);
static u8 hpc_readcmdtoindex (u8, u8); static u8 hpc_readcmdtoindex (u8, u8);
static void get_hpc_access (void); static void get_hpc_access (void);
...@@ -142,12 +142,12 @@ void __init ibmphp_hpc_initvars (void) ...@@ -142,12 +142,12 @@ void __init ibmphp_hpc_initvars (void)
} }
/*---------------------------------------------------------------------- /*----------------------------------------------------------------------
* Name: ctrl_read * Name: i2c_ctrl_read
* *
* Action: read from HPC over I2C * Action: read from HPC over I2C
* *
*---------------------------------------------------------------------*/ *---------------------------------------------------------------------*/
static u8 ctrl_read (struct controller *ctlr_ptr, void *WPGBbar, u8 index) static u8 i2c_ctrl_read (struct controller *ctlr_ptr, void *WPGBbar, u8 index)
{ {
u8 status; u8 status;
int i; int i;
...@@ -249,13 +249,13 @@ static u8 ctrl_read (struct controller *ctlr_ptr, void *WPGBbar, u8 index) ...@@ -249,13 +249,13 @@ static u8 ctrl_read (struct controller *ctlr_ptr, void *WPGBbar, u8 index)
} }
/*---------------------------------------------------------------------- /*----------------------------------------------------------------------
* Name: ctrl_write * Name: i2c_ctrl_write
* *
* Action: write to HPC over I2C * Action: write to HPC over I2C
* *
* Return 0 or error codes * Return 0 or error codes
*---------------------------------------------------------------------*/ *---------------------------------------------------------------------*/
static u8 ctrl_write (struct controller *ctlr_ptr, void *WPGBbar, u8 index, u8 cmd) static u8 i2c_ctrl_write (struct controller *ctlr_ptr, void *WPGBbar, u8 index, u8 cmd)
{ {
u8 rc; u8 rc;
void *wpg_addr; // base addr + offset void *wpg_addr; // base addr + offset
...@@ -351,6 +351,93 @@ static u8 ctrl_write (struct controller *ctlr_ptr, void *WPGBbar, u8 index, u8 c ...@@ -351,6 +351,93 @@ static u8 ctrl_write (struct controller *ctlr_ptr, void *WPGBbar, u8 index, u8 c
return (rc); return (rc);
} }
//------------------------------------------------------------
// Read from ISA type HPC
//------------------------------------------------------------
static u8 isa_ctrl_read (struct controller *ctlr_ptr, u8 offset)
{
u16 start_address;
u16 end_address;
u8 data;
start_address = ctlr_ptr->u.isa_ctlr.io_start;
end_address = ctlr_ptr->u.isa_ctlr.io_end;
data = inb (start_address + offset);
return data;
}
//--------------------------------------------------------------
// Write to ISA type HPC
//--------------------------------------------------------------
static void isa_ctrl_write (struct controller *ctlr_ptr, u8 offset, u8 data)
{
u16 start_address;
u16 port_address;
start_address = ctlr_ptr->u.isa_ctlr.io_start;
port_address = start_address + (u16) offset;
outb (data, port_address);
}
static u8 pci_ctrl_read (struct controller *ctrl, u8 offset)
{
u8 data = 0x00;
debug ("inside pci_ctrl_read\n");
if (ctrl->ctrl_dev)
pci_read_config_byte (ctrl->ctrl_dev, HPC_PCI_OFFSET + offset, &data);
return data;
}
static u8 pci_ctrl_write (struct controller *ctrl, u8 offset, u8 data)
{
u8 rc = -ENODEV;
debug ("inside pci_ctrl_write\n");
if (ctrl->ctrl_dev) {
pci_write_config_byte (ctrl->ctrl_dev, HPC_PCI_OFFSET + offset, data);
rc = 0;
}
return rc;
}
static u8 ctrl_read (struct controller *ctlr, void *base, u8 offset)
{
u8 rc;
switch (ctlr->ctlr_type) {
case 0:
rc = isa_ctrl_read (ctlr, offset);
break;
case 1:
rc = pci_ctrl_read (ctlr, offset);
break;
case 2:
case 4:
rc = i2c_ctrl_read (ctlr, base, offset);
break;
default:
return -ENODEV;
}
return rc;
}
static u8 ctrl_write (struct controller *ctlr, void *base, u8 offset, u8 data)
{
u8 rc = 0;
switch (ctlr->ctlr_type) {
case 0:
isa_ctrl_write(ctlr, offset, data);
break;
case 1:
rc = pci_ctrl_write (ctlr, offset, data);
break;
case 2:
case 4:
rc = i2c_ctrl_write(ctlr, base, offset, data);
break;
default:
return -ENODEV;
}
return rc;
}
/*---------------------------------------------------------------------- /*----------------------------------------------------------------------
* Name: hpc_writecmdtoindex() * Name: hpc_writecmdtoindex()
* *
...@@ -449,7 +536,7 @@ static u8 hpc_readcmdtoindex (u8 cmd, u8 index) ...@@ -449,7 +536,7 @@ static u8 hpc_readcmdtoindex (u8 cmd, u8 index)
*---------------------------------------------------------------------*/ *---------------------------------------------------------------------*/
int ibmphp_hpc_readslot (struct slot * pslot, u8 cmd, u8 * pstatus) int ibmphp_hpc_readslot (struct slot * pslot, u8 cmd, u8 * pstatus)
{ {
void *wpg_bbar; void *wpg_bbar = NULL;
struct controller *ctlr_ptr; struct controller *ctlr_ptr;
struct list_head *pslotlist; struct list_head *pslotlist;
u8 index, status; u8 index, status;
...@@ -491,7 +578,8 @@ int ibmphp_hpc_readslot (struct slot * pslot, u8 cmd, u8 * pstatus) ...@@ -491,7 +578,8 @@ int ibmphp_hpc_readslot (struct slot * pslot, u8 cmd, u8 * pstatus)
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// map physical address to logical address // map physical address to logical address
//-------------------------------------------------------------------- //--------------------------------------------------------------------
wpg_bbar = ioremap (ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE); if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))
wpg_bbar = ioremap (ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE);
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// check controller status before reading // check controller status before reading
...@@ -569,7 +657,11 @@ int ibmphp_hpc_readslot (struct slot * pslot, u8 cmd, u8 * pstatus) ...@@ -569,7 +657,11 @@ int ibmphp_hpc_readslot (struct slot * pslot, u8 cmd, u8 * pstatus)
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// cleanup // cleanup
//-------------------------------------------------------------------- //--------------------------------------------------------------------
iounmap (wpg_bbar); // remove physical to logical address mapping
// remove physical to logical address mapping
if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))
iounmap (wpg_bbar);
free_hpc_access (); free_hpc_access ();
debug_polling ("%s - Exit rc[%d]\n", __FUNCTION__, rc); debug_polling ("%s - Exit rc[%d]\n", __FUNCTION__, rc);
...@@ -583,7 +675,7 @@ int ibmphp_hpc_readslot (struct slot * pslot, u8 cmd, u8 * pstatus) ...@@ -583,7 +675,7 @@ int ibmphp_hpc_readslot (struct slot * pslot, u8 cmd, u8 * pstatus)
*---------------------------------------------------------------------*/ *---------------------------------------------------------------------*/
int ibmphp_hpc_writeslot (struct slot * pslot, u8 cmd) int ibmphp_hpc_writeslot (struct slot * pslot, u8 cmd)
{ {
void *wpg_bbar; void *wpg_bbar = NULL;
struct controller *ctlr_ptr; struct controller *ctlr_ptr;
u8 index, status; u8 index, status;
int busindex; int busindex;
...@@ -626,12 +718,13 @@ int ibmphp_hpc_writeslot (struct slot * pslot, u8 cmd) ...@@ -626,12 +718,13 @@ int ibmphp_hpc_writeslot (struct slot * pslot, u8 cmd)
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// map physical address to logical address // map physical address to logical address
//-------------------------------------------------------------------- //--------------------------------------------------------------------
wpg_bbar = ioremap (ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE); if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4)) {
wpg_bbar = ioremap (ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE);
debug ("%s - ctlr id[%x] physical[%lx] logical[%lx] i2c[%x]\n", __FUNCTION__, debug ("%s - ctlr id[%x] physical[%lx] logical[%lx] i2c[%x]\n", __FUNCTION__,
ctlr_ptr->ctlr_id, (ulong) (ctlr_ptr->u.wpeg_ctlr.wpegbbar), (ulong) wpg_bbar, ctlr_ptr->ctlr_id, (ulong) (ctlr_ptr->u.wpeg_ctlr.wpegbbar), (ulong) wpg_bbar,
ctlr_ptr->u.wpeg_ctlr.i2c_addr); ctlr_ptr->u.wpeg_ctlr.i2c_addr);
}
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// check controller status before writing // check controller status before writing
//-------------------------------------------------------------------- //--------------------------------------------------------------------
...@@ -668,7 +761,10 @@ int ibmphp_hpc_writeslot (struct slot * pslot, u8 cmd) ...@@ -668,7 +761,10 @@ int ibmphp_hpc_writeslot (struct slot * pslot, u8 cmd)
ctlr_ptr->status = status; ctlr_ptr->status = status;
} }
// cleanup // cleanup
iounmap (wpg_bbar); // remove physical to logical address mapping
// remove physical to logical address mapping
if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))
iounmap (wpg_bbar);
free_hpc_access (); free_hpc_access ();
debug_polling ("%s - Exit rc[%d]\n", __FUNCTION__, rc); debug_polling ("%s - Exit rc[%d]\n", __FUNCTION__, rc);
...@@ -701,6 +797,7 @@ void free_hpc_access (void) ...@@ -701,6 +797,7 @@ void free_hpc_access (void)
void ibmphp_lock_operations (void) void ibmphp_lock_operations (void)
{ {
down (&semOperations); down (&semOperations);
to_debug = TRUE;
} }
/*---------------------------------------------------------------------- /*----------------------------------------------------------------------
...@@ -710,6 +807,7 @@ void ibmphp_unlock_operations (void) ...@@ -710,6 +807,7 @@ void ibmphp_unlock_operations (void)
{ {
debug ("%s - Entry\n", __FUNCTION__); debug ("%s - Entry\n", __FUNCTION__);
up (&semOperations); up (&semOperations);
to_debug = FALSE;
debug ("%s - Exit\n", __FUNCTION__); debug ("%s - Exit\n", __FUNCTION__);
} }
...@@ -734,82 +832,86 @@ static void poll_hpc (void) ...@@ -734,82 +832,86 @@ static void poll_hpc (void)
debug ("%s - Entry\n", __FUNCTION__); debug ("%s - Entry\n", __FUNCTION__);
while (!ibmphp_shutdown) { while (!ibmphp_shutdown) {
if (ibmphp_shutdown)
break;
/* try to get the lock to do some kind of harware access */ /* try to get the lock to do some kind of harware access */
down (&semOperations); down (&semOperations);
switch (poll_state) { switch (poll_state) {
case POLL_LATCH_REGISTER: case POLL_LATCH_REGISTER:
oldlatchlow = curlatchlow; oldlatchlow = curlatchlow;
ctrl_count = 0x00; ctrl_count = 0x00;
list_for_each (pslotlist, &ibmphp_slot_head) { list_for_each (pslotlist, &ibmphp_slot_head) {
if (ctrl_count >= ibmphp_get_total_controllers()) if (ctrl_count >= ibmphp_get_total_controllers())
break; break;
pslot = list_entry (pslotlist, struct slot, ibm_slot_list); pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
if (pslot->ctrl->ctlr_relative_id == ctrl_count) { if (pslot->ctrl->ctlr_relative_id == ctrl_count) {
ctrl_count++; ctrl_count++;
if (READ_SLOT_LATCH (pslot->ctrl)) { if (READ_SLOT_LATCH (pslot->ctrl)) {
rc = ibmphp_hpc_readslot (pslot, rc = ibmphp_hpc_readslot (pslot,
READ_SLOTLATCHLOWREG, READ_SLOTLATCHLOWREG,
&curlatchlow); &curlatchlow);
if (oldlatchlow != curlatchlow) if (oldlatchlow != curlatchlow)
process_changeinlatch (oldlatchlow, process_changeinlatch (oldlatchlow,
curlatchlow, curlatchlow,
pslot->ctrl); pslot->ctrl);
}
} }
} }
poll_state = POLL_SLOTS; }
break; ++poll_count;
poll_state = POLL_SLEEP;
case POLL_SLOTS: break;
list_for_each (pslotlist, &ibmphp_slot_head) { case POLL_SLOTS:
pslot = list_entry (pslotlist, struct slot, ibm_slot_list); list_for_each (pslotlist, &ibmphp_slot_head) {
// make a copy of the old status pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
memcpy ((void *) &myslot, (void *) pslot, // make a copy of the old status
sizeof (struct slot)); memcpy ((void *) &myslot, (void *) pslot,
rc = ibmphp_hpc_readslot (pslot, READ_ALLSTAT, NULL); sizeof (struct slot));
if ((myslot.status != pslot->status) rc = ibmphp_hpc_readslot (pslot, READ_ALLSTAT, NULL);
|| (myslot.ext_status != pslot->ext_status)) if ((myslot.status != pslot->status)
process_changeinstatus (pslot, &myslot); || (myslot.ext_status != pslot->ext_status))
process_changeinstatus (pslot, &myslot);
}
ctrl_count = 0x00;
list_for_each (pslotlist, &ibmphp_slot_head) {
if (ctrl_count >= ibmphp_get_total_controllers())
break;
pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
if (pslot->ctrl->ctlr_relative_id == ctrl_count) {
ctrl_count++;
if (READ_SLOT_LATCH (pslot->ctrl))
rc = ibmphp_hpc_readslot (pslot,
READ_SLOTLATCHLOWREG,
&curlatchlow);
} }
}
++poll_count;
poll_state = POLL_SLEEP;
break;
case POLL_SLEEP:
/* don't sleep with a lock on the hardware */
up (&semOperations);
long_delay (POLL_INTERVAL_SEC * HZ);
ctrl_count = 0x00; if (ibmphp_shutdown)
list_for_each (pslotlist, &ibmphp_slot_head) {
if (ctrl_count >= ibmphp_get_total_controllers())
break;
pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
if (pslot->ctrl->ctlr_relative_id == ctrl_count) {
ctrl_count++;
if (READ_SLOT_LATCH (pslot->ctrl))
rc = ibmphp_hpc_readslot (pslot,
READ_SLOTLATCHLOWREG,
&curlatchlow);
}
}
++poll_count;
if (poll_count >= POLL_LATCH_CNT) {
poll_count = 0;
poll_state = POLL_SLEEP;
}
break; break;
case POLL_SLEEP: down (&semOperations);
/* don't sleep with a lock on the hardware */
up (&semOperations); if (poll_count >= POLL_LATCH_CNT) {
long_delay (POLL_INTERVAL_SEC * HZ); poll_count = 0;
down (&semOperations); poll_state = POLL_SLOTS;
} else
poll_state = POLL_LATCH_REGISTER; poll_state = POLL_LATCH_REGISTER;
break; break;
} }
/* give up the harware semaphore */ /* give up the harware semaphore */
up (&semOperations); up (&semOperations);
/* sleep for a short time just for good measure */ /* sleep for a short time just for good measure */
set_current_state (TASK_INTERRUPTIBLE); set_current_state (TASK_INTERRUPTIBLE);
schedule_timeout (HZ/10); schedule_timeout (HZ/10);
} }
up (&sem_exit); up (&sem_exit);
debug ("%s - Exit\n", __FUNCTION__); debug ("%s - Exit\n", __FUNCTION__);
} }
...@@ -1070,15 +1172,23 @@ void __exit ibmphp_hpc_stop_poll_thread (void) ...@@ -1070,15 +1172,23 @@ void __exit ibmphp_hpc_stop_poll_thread (void)
debug ("%s - Entry\n", __FUNCTION__); debug ("%s - Entry\n", __FUNCTION__);
ibmphp_shutdown = TRUE; ibmphp_shutdown = TRUE;
debug ("before locking operations \n");
ibmphp_lock_operations (); ibmphp_lock_operations ();
debug ("after locking operations \n");
// wait for poll thread to exit // wait for poll thread to exit
debug ("before sem_exit down \n");
down (&sem_exit); down (&sem_exit);
debug ("after sem_exit down \n");
// cleanup // cleanup
debug ("before free_hpc_access \n");
free_hpc_access (); free_hpc_access ();
debug ("after free_hpc_access \n");
ibmphp_unlock_operations (); ibmphp_unlock_operations ();
debug ("after unlock operations \n");
up (&sem_exit); up (&sem_exit);
debug ("after sem exit up\n");
debug ("%s - Exit\n", __FUNCTION__); debug ("%s - Exit\n", __FUNCTION__);
} }
......
...@@ -104,11 +104,15 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno) ...@@ -104,11 +104,15 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno)
/* For every function on the card */ /* For every function on the card */
for (function = 0x00; function < 0x08; function++) { for (function = 0x00; function < 0x08; function++) {
unsigned int devfn = PCI_DEVFN(device, function);
ibmphp_pci_bus->number = cur_func->busno;
cur_func->function = function; cur_func->function = function;
debug ("inside the loop, cur_func->busno = %x, cur_func->device = %x, cur_func->funcion = %x\n", cur_func->busno, device, function); debug ("inside the loop, cur_func->busno = %x, cur_func->device = %x, cur_func->funcion = %x\n",
cur_func->busno, cur_func->device, cur_func->function);
pci_read_config_word_nodev (ibmphp_pci_root_ops, cur_func->busno, device, function, PCI_VENDOR_ID, &vendor_id); pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_VENDOR_ID, &vendor_id);
debug ("vendor_id is %x\n", vendor_id); debug ("vendor_id is %x\n", vendor_id);
if (vendor_id != PCI_VENDOR_ID_NOTVALID) { if (vendor_id != PCI_VENDOR_ID_NOTVALID) {
...@@ -122,8 +126,8 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno) ...@@ -122,8 +126,8 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno)
* |_=> 0 = single function device, 1 = multi-function device * |_=> 0 = single function device, 1 = multi-function device
*/ */
pci_read_config_byte_nodev (ibmphp_pci_root_ops, cur_func->busno, device, function, PCI_HEADER_TYPE, &hdr_type); pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_HEADER_TYPE, &hdr_type);
pci_read_config_dword_nodev (ibmphp_pci_root_ops, cur_func->busno, device, function, PCI_CLASS_REVISION, &class); pci_bus_read_config_dword (ibmphp_pci_bus, devfn, PCI_CLASS_REVISION, &class);
class_code = class >> 24; class_code = class >> 24;
debug ("hrd_type = %x, class = %x, class_code %x \n", hdr_type, class, class_code); debug ("hrd_type = %x, class = %x, class_code %x \n", hdr_type, class, class_code);
...@@ -195,7 +199,7 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno) ...@@ -195,7 +199,7 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno)
goto error; goto error;
} }
pci_read_config_byte_nodev (ibmphp_pci_root_ops, cur_func->busno, device, function, PCI_SECONDARY_BUS, &sec_number); pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number);
flag = FALSE; flag = FALSE;
for (i = 0; i < 32; i++) { for (i = 0; i < 32; i++) {
if (func->devices[i]) { if (func->devices[i]) {
...@@ -267,8 +271,9 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno) ...@@ -267,8 +271,9 @@ int ibmphp_configure_card (struct pci_func *func, u8 slotno)
cleanup_count = 2; cleanup_count = 2;
goto error; goto error;
} }
debug ("cur_func->busno = %x, device = %x, function = %x\n", cur_func->busno, device, function); debug ("cur_func->busno = %x, device = %x, function = %x\n",
pci_read_config_byte_nodev (ibmphp_pci_root_ops, cur_func->busno, device, function, PCI_SECONDARY_BUS, &sec_number); cur_func->busno, device, function);
pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number);
debug ("after configuring bridge..., sec_number = %x\n", sec_number); debug ("after configuring bridge..., sec_number = %x\n", sec_number);
flag = FALSE; flag = FALSE;
for (i = 0; i < 32; i++) { for (i = 0; i < 32; i++) {
...@@ -361,13 +366,12 @@ static int configure_device (struct pci_func *func) ...@@ -361,13 +366,12 @@ static int configure_device (struct pci_func *func)
struct resource_node *mem[6]; struct resource_node *mem[6];
struct resource_node *mem_tmp; struct resource_node *mem_tmp;
struct resource_node *pfmem[6]; struct resource_node *pfmem[6];
u8 device; unsigned int devfn;
u8 function;
debug ("%s - inside\n", __FUNCTION__); debug ("%s - inside\n", __FUNCTION__);
device = func->device; devfn = PCI_DEVFN(func->device, func->function);
function = func->function; ibmphp_pci_bus->number = func->busno;
for (count = 0; address[count]; count++) { /* for 6 BARs */ for (count = 0; address[count]; count++) { /* for 6 BARs */
...@@ -384,8 +388,8 @@ static int configure_device (struct pci_func *func) ...@@ -384,8 +388,8 @@ static int configure_device (struct pci_func *func)
pcibios_write_config_dword(cur_func->busno, cur_func->device, pcibios_write_config_dword(cur_func->busno, cur_func->device,
PCI_BASE_ADDRESS_0 + 4 * count, 0xFFFFFFFF); PCI_BASE_ADDRESS_0 + 4 * count, 0xFFFFFFFF);
*/ */
pci_write_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], 0xFFFFFFFF); pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
pci_read_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], &bar[count]); pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);
if (!bar[count]) /* This BAR is not implemented */ if (!bar[count]) /* This BAR is not implemented */
continue; continue;
...@@ -421,11 +425,11 @@ static int configure_device (struct pci_func *func) ...@@ -421,11 +425,11 @@ static int configure_device (struct pci_func *func)
kfree (io[count]); kfree (io[count]);
return -EIO; return -EIO;
} }
pci_write_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], func->io[count]->start); pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->io[count]->start);
/* _______________This is for debugging purposes only_____________________ */ /* _______________This is for debugging purposes only_____________________ */
debug ("b4 writing, the IO address is %x\n", func->io[count]->start); debug ("b4 writing, the IO address is %x\n", func->io[count]->start);
pci_read_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], &bar[count]); pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);
debug ("after writing.... the start address is %x\n", bar[count]); debug ("after writing.... the start address is %x\n", bar[count]);
/* _________________________________________________________________________*/ /* _________________________________________________________________________*/
...@@ -484,11 +488,11 @@ static int configure_device (struct pci_func *func) ...@@ -484,11 +488,11 @@ static int configure_device (struct pci_func *func)
} }
} }
pci_write_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], func->pfmem[count]->start); pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->pfmem[count]->start);
/*_______________This if for debugging purposes only______________________________*/ /*_______________This is for debugging purposes only______________________________*/
debug ("b4 writing, start addres is %x\n", func->pfmem[count]->start); debug ("b4 writing, start addres is %x\n", func->pfmem[count]->start);
pci_read_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], &bar[count]); pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);
debug ("after writing, start address is %x\n", bar[count]); debug ("after writing, start address is %x\n", bar[count]);
/*_________________________________________________________________________________*/ /*_________________________________________________________________________________*/
...@@ -496,7 +500,7 @@ static int configure_device (struct pci_func *func) ...@@ -496,7 +500,7 @@ static int configure_device (struct pci_func *func)
debug ("inside the mem 64 case, count %d\n", count); debug ("inside the mem 64 case, count %d\n", count);
count += 1; count += 1;
/* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */ /* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */
pci_write_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], 0x00000000); pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0x00000000);
} }
} else { } else {
/* regular memory */ /* regular memory */
...@@ -526,10 +530,10 @@ static int configure_device (struct pci_func *func) ...@@ -526,10 +530,10 @@ static int configure_device (struct pci_func *func)
kfree (mem[count]); kfree (mem[count]);
return -EIO; return -EIO;
} }
pci_write_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], func->mem[count]->start); pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->mem[count]->start);
/* _______________________This is for debugging purposes only _______________________*/ /* _______________________This is for debugging purposes only _______________________*/
debug ("b4 writing, start address is %x\n", func->mem[count]->start); debug ("b4 writing, start address is %x\n", func->mem[count]->start);
pci_read_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], &bar[count]); pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);
debug ("after writing, the address is %x\n", bar[count]); debug ("after writing, the address is %x\n", bar[count]);
/* __________________________________________________________________________________*/ /* __________________________________________________________________________________*/
...@@ -538,22 +542,22 @@ static int configure_device (struct pci_func *func) ...@@ -538,22 +542,22 @@ static int configure_device (struct pci_func *func)
debug ("inside mem 64 case, reg. mem, count %d\n", count); debug ("inside mem 64 case, reg. mem, count %d\n", count);
count += 1; count += 1;
/* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */ /* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */
pci_write_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], 0x00000000); pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0x00000000);
} }
} }
} /* end of mem */ } /* end of mem */
} /* end of for */ } /* end of for */
func->bus = 0; /* To indicate that this is not a PPB */ func->bus = 0; /* To indicate that this is not a PPB */
pci_read_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_INTERRUPT_PIN, &irq); pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_INTERRUPT_PIN, &irq);
if ((irq > 0x00) && (irq < 0x05)) if ((irq > 0x00) && (irq < 0x05))
pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_INTERRUPT_LINE, func->irq[irq - 1]); pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_INTERRUPT_LINE, func->irq[irq - 1]);
pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_CACHE_LINE_SIZE, CACHE); pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_CACHE_LINE_SIZE, CACHE);
pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_LATENCY_TIMER, LATENCY); pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_LATENCY_TIMER, LATENCY);
pci_write_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_ROM_ADDRESS, 0x00L); pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_ROM_ADDRESS, 0x00L);
pci_write_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_COMMAND, DEVICEENABLE); pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_COMMAND, DEVICEENABLE);
return 0; return 0;
} }
...@@ -593,24 +597,23 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno) ...@@ -593,24 +597,23 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
0 0
}; };
struct pci_func *func = *func_passed; struct pci_func *func = *func_passed;
u8 function; unsigned int devfn;
u8 device;
u8 irq; u8 irq;
int retval; int retval;
debug ("%s - enter\n", __FUNCTION__); debug ("%s - enter\n", __FUNCTION__);
function = func->function; devfn = PCI_DEVFN(func->function, func->device);
device = func->device; ibmphp_pci_bus->number = func->busno;
/* Configuring necessary info for the bridge so that we could see the devices /* Configuring necessary info for the bridge so that we could see the devices
* behind it * behind it
*/ */
pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_PRIMARY_BUS, func->busno); pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_PRIMARY_BUS, func->busno);
/* _____________________For debugging purposes only __________________________ /* _____________________For debugging purposes only __________________________
pci_read_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_PRIMARY_BUS, &pri_number); pci_bus_config_byte (ibmphp_pci_bus, devfn, PCI_PRIMARY_BUS, &pri_number);
debug ("primary # written into the bridge is %x\n", pri_number); debug ("primary # written into the bridge is %x\n", pri_number);
___________________________________________________________________________*/ ___________________________________________________________________________*/
...@@ -624,23 +627,23 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno) ...@@ -624,23 +627,23 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
debug ("after find_sec_number, the number we got is %x\n", sec_number); debug ("after find_sec_number, the number we got is %x\n", sec_number);
debug ("AFTER FIND_SEC_NUMBER, func->busno IS %x\n", func->busno); debug ("AFTER FIND_SEC_NUMBER, func->busno IS %x\n", func->busno);
pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_SECONDARY_BUS, sec_number); pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, sec_number);
/* __________________For debugging purposes only __________________________________ /* __________________For debugging purposes only __________________________________
pci_read_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_SECONDARY_BUS, &sec_number); pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number);
debug ("sec_number after write/read is %x\n", sec_number); debug ("sec_number after write/read is %x\n", sec_number);
________________________________________________________________________________*/ ________________________________________________________________________________*/
pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_SUBORDINATE_BUS, sec_number); pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_SUBORDINATE_BUS, sec_number);
/* __________________For debugging purposes only ____________________________________ /* __________________For debugging purposes only ____________________________________
pci_read_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_SUBORDINATE_BUS, &sec_number); pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SUBORDINATE_BUS, &sec_number);
debug ("subordinate number after write/read is %x\n", sec_number); debug ("subordinate number after write/read is %x\n", sec_number);
__________________________________________________________________________________*/ __________________________________________________________________________________*/
pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_CACHE_LINE_SIZE, CACHE); pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_CACHE_LINE_SIZE, CACHE);
pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_LATENCY_TIMER, LATENCY); pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_LATENCY_TIMER, LATENCY);
pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_SEC_LATENCY_TIMER, LATENCY); pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_SEC_LATENCY_TIMER, LATENCY);
debug ("func->busno is %x\n", func->busno); debug ("func->busno is %x\n", func->busno);
debug ("sec_number after writing is %x\n", sec_number); debug ("sec_number after writing is %x\n", sec_number);
...@@ -653,8 +656,8 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno) ...@@ -653,8 +656,8 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
/* First we need to allocate mem/io for the bridge itself in case it needs it */ /* First we need to allocate mem/io for the bridge itself in case it needs it */
for (count = 0; address[count]; count++) { /* for 2 BARs */ for (count = 0; address[count]; count++) { /* for 2 BARs */
pci_write_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], 0xFFFFFFFF); pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
pci_read_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], &bar[count]); pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);
if (!bar[count]) { if (!bar[count]) {
/* This BAR is not implemented */ /* This BAR is not implemented */
...@@ -694,7 +697,7 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno) ...@@ -694,7 +697,7 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
return -EIO; return -EIO;
} }
pci_write_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], func->io[count]->start); pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->io[count]->start);
} else { } else {
/* This is Memory */ /* This is Memory */
...@@ -747,13 +750,13 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno) ...@@ -747,13 +750,13 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
} }
} }
pci_write_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], func->pfmem[count]->start); pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->pfmem[count]->start);
if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) { if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) {
/* takes up another dword */ /* takes up another dword */
count += 1; count += 1;
/* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */ /* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */
pci_write_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], 0x00000000); pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0x00000000);
} }
} else { } else {
...@@ -784,13 +787,13 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno) ...@@ -784,13 +787,13 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
return -EIO; return -EIO;
} }
pci_write_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], func->mem[count]->start); pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], func->mem[count]->start);
if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) { if (bar[count] & PCI_BASE_ADDRESS_MEM_TYPE_64) {
/* takes up another dword */ /* takes up another dword */
count += 1; count += 1;
/* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */ /* on the 2nd dword, write all 0s, since we can't handle them n.e.ways */
pci_write_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, address[count], 0x00000000); pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0x00000000);
} }
} }
...@@ -802,6 +805,7 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno) ...@@ -802,6 +805,7 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
if (amount_needed == NULL) if (amount_needed == NULL)
return -ENOMEM; return -ENOMEM;
ibmphp_pci_bus->number = func->busno;
debug ("after coming back from scan_behind_bridge\n"); debug ("after coming back from scan_behind_bridge\n");
debug ("amount_needed->not_correct = %x\n", amount_needed->not_correct); debug ("amount_needed->not_correct = %x\n", amount_needed->not_correct);
debug ("amount_needed->io = %x\n", amount_needed->io); debug ("amount_needed->io = %x\n", amount_needed->io);
...@@ -920,16 +924,30 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno) ...@@ -920,16 +924,30 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
debug ("flag_io = %x, flag_mem = %x, flag_pfmem = %x\n", flag_io, flag_mem, flag_pfmem); debug ("flag_io = %x, flag_mem = %x, flag_pfmem = %x\n", flag_io, flag_mem, flag_pfmem);
if (flag_io && flag_mem && flag_pfmem) { if (flag_io && flag_mem && flag_pfmem) {
bus = kmalloc (sizeof (struct bus_node), GFP_KERNEL); /* If on bootup, there was a bridged card in this slot,
* then card was removed and ibmphp got unloaded and loaded
* back again, there's no way for us to remove the bus
* struct, so no need to kmalloc, can use existing node
*/
bus = ibmphp_find_res_bus (sec_number);
if (!bus) { if (!bus) {
err ("out of system memory \n"); bus = kmalloc (sizeof (struct bus_node), GFP_KERNEL);
retval = -ENOMEM; if (!bus) {
err ("out of system memory \n");
retval = -ENOMEM;
goto error;
}
memset (bus, 0, sizeof (struct bus_node));
bus->busno = sec_number;
debug ("b4 adding new bus\n");
rc = add_new_bus (bus, io, mem, pfmem, func->busno);
} else if (!(bus->rangeIO) && !(bus->rangeMem) && !(bus->rangePFMem))
rc = add_new_bus (bus, io, mem, pfmem, 0xFF);
else {
err ("expected bus structure not empty? \n");
retval = -EIO;
goto error; goto error;
} }
memset (bus, 0, sizeof (struct bus_node));
bus->busno = sec_number;
debug ("b4 adding new bus\n");
rc = add_new_bus (bus, io, mem, pfmem, func->busno);
if (rc) { if (rc) {
if (rc == -ENOMEM) { if (rc == -ENOMEM) {
ibmphp_remove_bus (bus, func->busno); ibmphp_remove_bus (bus, func->busno);
...@@ -938,8 +956,8 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno) ...@@ -938,8 +956,8 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
retval = rc; retval = rc;
goto error; goto error;
} }
pci_read_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_IO_BASE, &io_base); pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_IO_BASE, &io_base);
pci_read_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_PREF_MEMORY_BASE, &pfmem_base); pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, &pfmem_base);
if ((io_base & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32) { if ((io_base & PCI_IO_RANGE_TYPE_MASK) == PCI_IO_RANGE_TYPE_32) {
debug ("io 32\n"); debug ("io 32\n");
...@@ -951,73 +969,73 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno) ...@@ -951,73 +969,73 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
} }
if (bus->noIORanges) { if (bus->noIORanges) {
pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_IO_BASE, 0x00 | bus->rangeIO->start >> 8); pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_IO_BASE, 0x00 | bus->rangeIO->start >> 8);
pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_IO_LIMIT, 0x00 | bus->rangeIO->end >> 8); pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_IO_LIMIT, 0x00 | bus->rangeIO->end >> 8);
/* _______________This is for debugging purposes only ____________________ /* _______________This is for debugging purposes only ____________________
pci_read_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_IO_BASE, &temp); pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_IO_BASE, &temp);
debug ("io_base = %x\n", (temp & PCI_IO_RANGE_TYPE_MASK) << 8); debug ("io_base = %x\n", (temp & PCI_IO_RANGE_TYPE_MASK) << 8);
pci_read_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_IO_LIMIT, &temp); pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_IO_LIMIT, &temp);
debug ("io_limit = %x\n", (temp & PCI_IO_RANGE_TYPE_MASK) << 8); debug ("io_limit = %x\n", (temp & PCI_IO_RANGE_TYPE_MASK) << 8);
________________________________________________________________________*/ ________________________________________________________________________*/
if (need_io_upper) { /* since can't support n.e.ways */ if (need_io_upper) { /* since can't support n.e.ways */
pci_write_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_IO_BASE_UPPER16, 0x0000); pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_IO_BASE_UPPER16, 0x0000);
pci_write_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_IO_LIMIT_UPPER16, 0x0000); pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_IO_LIMIT_UPPER16, 0x0000);
} }
} else { } else {
pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_IO_BASE, 0x00); pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_IO_BASE, 0x00);
pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_IO_LIMIT, 0x00); pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_IO_LIMIT, 0x00);
} }
if (bus->noMemRanges) { if (bus->noMemRanges) {
pci_write_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_MEMORY_BASE, 0x0000 | bus->rangeMem->start >> 16); pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_BASE, 0x0000 | bus->rangeMem->start >> 16);
pci_write_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_MEMORY_LIMIT, 0x0000 | bus->rangeMem->end >> 16); pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_LIMIT, 0x0000 | bus->rangeMem->end >> 16);
/* ____________________This is for debugging purposes only ________________________ /* ____________________This is for debugging purposes only ________________________
pci_read_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_MEMORY_BASE, &temp); pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_BASE, &temp);
debug ("mem_base = %x\n", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16); debug ("mem_base = %x\n", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16);
pci_read_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_MEMORY_LIMIT, &temp); pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_LIMIT, &temp);
debug ("mem_limit = %x\n", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16); debug ("mem_limit = %x\n", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16);
__________________________________________________________________________________*/ __________________________________________________________________________________*/
} else { } else {
pci_write_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_MEMORY_BASE, 0xffff); pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_BASE, 0xffff);
pci_write_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_MEMORY_LIMIT, 0x0000); pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_LIMIT, 0x0000);
} }
if (bus->noPFMemRanges) { if (bus->noPFMemRanges) {
pci_write_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_PREF_MEMORY_BASE, 0x0000 | bus->rangePFMem->start >> 16); pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, 0x0000 | bus->rangePFMem->start >> 16);
pci_write_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_PREF_MEMORY_LIMIT, 0x0000 | bus->rangePFMem->end >> 16); pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, 0x0000 | bus->rangePFMem->end >> 16);
/* __________________________This is for debugging purposes only _______________________ /* __________________________This is for debugging purposes only _______________________
pci_read_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_PREF_MEMORY_BASE, &temp); pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, &temp);
debug ("pfmem_base = %x", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16); debug ("pfmem_base = %x", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16);
pci_read_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_PREF_MEMORY_LIMIT, &temp); pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, &temp);
debug ("pfmem_limit = %x\n", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16); debug ("pfmem_limit = %x\n", (temp & PCI_MEMORY_RANGE_TYPE_MASK) << 16);
______________________________________________________________________________________*/ ______________________________________________________________________________________*/
if (need_pfmem_upper) { /* since can't support n.e.ways */ if (need_pfmem_upper) { /* since can't support n.e.ways */
pci_write_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_PREF_BASE_UPPER32, 0x00000000); pci_bus_write_config_dword (ibmphp_pci_bus, devfn, PCI_PREF_BASE_UPPER32, 0x00000000);
pci_write_config_dword_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_PREF_LIMIT_UPPER32, 0x00000000); pci_bus_write_config_dword (ibmphp_pci_bus, devfn, PCI_PREF_LIMIT_UPPER32, 0x00000000);
} }
} else { } else {
pci_write_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_PREF_MEMORY_BASE, 0xffff); pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, 0xffff);
pci_write_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_PREF_MEMORY_LIMIT, 0x0000); pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, 0x0000);
} }
debug ("b4 writing control information\n"); debug ("b4 writing control information\n");
pci_read_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_INTERRUPT_PIN, &irq); pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_INTERRUPT_PIN, &irq);
if ((irq > 0x00) && (irq < 0x05)) if ((irq > 0x00) && (irq < 0x05))
pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_INTERRUPT_LINE, func->irq[irq - 1]); pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_INTERRUPT_LINE, func->irq[irq - 1]);
/* /*
pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_BRIDGE_CONTROL, ctrl); pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_BRIDGE_CONTROL, ctrl);
pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_BRIDGE_CONTROL, PCI_BRIDGE_CTL_PARITY); pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_BRIDGE_CONTROL, PCI_BRIDGE_CTL_PARITY);
pci_write_config_byte_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_BRIDGE_CONTROL, PCI_BRIDGE_CTL_SERR); pci_bus_write_config_byte (ibmphp_pci_bus, devfn, PCI_BRIDGE_CONTROL, PCI_BRIDGE_CTL_SERR);
*/ */
pci_write_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_COMMAND, DEVICEENABLE); pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_COMMAND, DEVICEENABLE);
pci_write_config_word_nodev (ibmphp_pci_root_ops, func->busno, device, function, PCI_BRIDGE_CONTROL, 0x07); pci_bus_write_config_word (ibmphp_pci_bus, devfn, PCI_BRIDGE_CONTROL, 0x07);
for (i = 0; i < 32; i++) { for (i = 0; i < 32; i++) {
if (amount_needed->devices[i]) { if (amount_needed->devices[i]) {
debug ("device where devices[i] is 1 = %x\n", i); debug ("device where devices[i] is 1 = %x\n", i);
...@@ -1073,6 +1091,7 @@ static struct res_needed *scan_behind_bridge (struct pci_func * func, u8 busno) ...@@ -1073,6 +1091,7 @@ static struct res_needed *scan_behind_bridge (struct pci_func * func, u8 busno)
u16 vendor_id; u16 vendor_id;
u8 hdr_type; u8 hdr_type;
u8 device, function; u8 device, function;
unsigned int devfn;
int howmany = 0; /*this is to see if there are any devices behind the bridge */ int howmany = 0; /*this is to see if there are any devices behind the bridge */
u32 bar[6], class; u32 bar[6], class;
...@@ -1092,20 +1111,23 @@ static struct res_needed *scan_behind_bridge (struct pci_func * func, u8 busno) ...@@ -1092,20 +1111,23 @@ static struct res_needed *scan_behind_bridge (struct pci_func * func, u8 busno)
return NULL; return NULL;
memset (amount, 0, sizeof (struct res_needed)); memset (amount, 0, sizeof (struct res_needed));
ibmphp_pci_bus->number = busno;
debug ("the bus_no behind the bridge is %x\n", busno); debug ("the bus_no behind the bridge is %x\n", busno);
debug ("scanning devices behind the bridge...\n"); debug ("scanning devices behind the bridge...\n");
for (device = 0; device < 32; device++) { for (device = 0; device < 32; device++) {
amount->devices[device] = 0; amount->devices[device] = 0;
for (function = 0; function < 8; function++) { for (function = 0; function < 8; function++) {
devfn = PCI_DEVFN(device, function);
pci_read_config_word_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_VENDOR_ID, &vendor_id); pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_VENDOR_ID, &vendor_id);
if (vendor_id != PCI_VENDOR_ID_NOTVALID) { if (vendor_id != PCI_VENDOR_ID_NOTVALID) {
/* found correct device!!! */ /* found correct device!!! */
howmany++; howmany++;
pci_read_config_byte_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_HEADER_TYPE, &hdr_type); pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_HEADER_TYPE, &hdr_type);
pci_read_config_dword_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_CLASS_REVISION, &class); pci_bus_read_config_dword (ibmphp_pci_bus, devfn, PCI_CLASS_REVISION, &class);
debug ("hdr_type behind the bridge is %x\n", hdr_type); debug ("hdr_type behind the bridge is %x\n", hdr_type);
if (hdr_type & PCI_HEADER_TYPE_BRIDGE) { if (hdr_type & PCI_HEADER_TYPE_BRIDGE) {
...@@ -1132,14 +1154,14 @@ static struct res_needed *scan_behind_bridge (struct pci_func * func, u8 busno) ...@@ -1132,14 +1154,14 @@ static struct res_needed *scan_behind_bridge (struct pci_func * func, u8 busno)
for (count = 0; address[count]; count++) { for (count = 0; address[count]; count++) {
/* for 6 BARs */ /* for 6 BARs */
/* /*
pci_read_config_byte_nodev(ibmphp_pci_root_ops, busno, device, function, address[count], &tmp); pci_bus_read_config_byte (ibmphp_pci_bus, devfn, address[count], &tmp);
if (tmp & 0x01) // IO if (tmp & 0x01) // IO
pci_write_config_dword_nodev(ibmphp_pci_root_ops, busno, device, function, address[count], 0xFFFFFFFD); pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFD);
else // MEMORY else // MEMORY
pci_write_config_dword_nodev(ibmphp_pci_root_ops, busno, device, function, address[count], 0xFFFFFFFF); pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
*/ */
pci_write_config_dword_nodev (ibmphp_pci_root_ops, busno, device, function, address[count], 0xFFFFFFFF); pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
pci_read_config_dword_nodev (ibmphp_pci_root_ops, busno, device, function, address[count], &bar[count]); pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &bar[count]);
debug ("what is bar[count]? %x, count = %d\n", bar[count], count); debug ("what is bar[count]? %x, count = %d\n", bar[count], count);
...@@ -1223,6 +1245,7 @@ static int unconfigure_boot_device (u8 busno, u8 device, u8 function) ...@@ -1223,6 +1245,7 @@ static int unconfigure_boot_device (u8 busno, u8 device, u8 function)
u32 temp_end; u32 temp_end;
u32 size; u32 size;
u32 tmp_address; u32 tmp_address;
unsigned int devfn;
debug ("%s - enter\n", __FUNCTION__); debug ("%s - enter\n", __FUNCTION__);
...@@ -1232,14 +1255,16 @@ static int unconfigure_boot_device (u8 busno, u8 device, u8 function) ...@@ -1232,14 +1255,16 @@ static int unconfigure_boot_device (u8 busno, u8 device, u8 function)
return -EINVAL; return -EINVAL;
} }
devfn = PCI_DEVFN(device, function);
ibmphp_pci_bus->number = busno;
for (count = 0; address[count]; count++) { /* for 6 BARs */ for (count = 0; address[count]; count++) { /* for 6 BARs */
pci_read_config_dword_nodev (ibmphp_pci_root_ops, busno, device, function, address[count], &start_address); pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &start_address);
/* We can do this here, b/c by that time the device driver of the card has been stopped */ /* We can do this here, b/c by that time the device driver of the card has been stopped */
pci_write_config_dword_nodev (ibmphp_pci_root_ops, busno, device, function, address[count], 0xFFFFFFFF); pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], 0xFFFFFFFF);
pci_read_config_dword_nodev (ibmphp_pci_root_ops, busno, device, function, address[count], &size); pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &size);
pci_write_config_dword_nodev (ibmphp_pci_root_ops, busno, device, function, address[count], start_address); pci_bus_write_config_dword (ibmphp_pci_bus, devfn, address[count], start_address);
debug ("start_address is %x\n", start_address); debug ("start_address is %x\n", start_address);
debug ("busno, device, function %x %x %x\n", busno, device, function); debug ("busno, device, function %x %x %x\n", busno, device, function);
...@@ -1336,13 +1361,16 @@ static int unconfigure_boot_bridge (u8 busno, u8 device, u8 function) ...@@ -1336,13 +1361,16 @@ static int unconfigure_boot_bridge (u8 busno, u8 device, u8 function)
PCI_BASE_ADDRESS_1, PCI_BASE_ADDRESS_1,
0 0
}; };
unsigned int devfn;
devfn = PCI_DEVFN(device, function);
ibmphp_pci_bus->number = busno;
bus_no = (int) busno; bus_no = (int) busno;
debug ("busno is %x\n", busno); debug ("busno is %x\n", busno);
pci_read_config_byte_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_PRIMARY_BUS, &pri_number); pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_PRIMARY_BUS, &pri_number);
debug ("%s - busno = %x, primary_number = %x\n", __FUNCTION__, busno, pri_number); debug ("%s - busno = %x, primary_number = %x\n", __FUNCTION__, busno, pri_number);
pci_read_config_byte_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_SECONDARY_BUS, &sec_number); pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number);
debug ("sec_number is %x\n", sec_number); debug ("sec_number is %x\n", sec_number);
sec_no = (int) sec_number; sec_no = (int) sec_number;
pri_no = (int) pri_number; pri_no = (int) pri_number;
...@@ -1351,10 +1379,10 @@ static int unconfigure_boot_bridge (u8 busno, u8 device, u8 function) ...@@ -1351,10 +1379,10 @@ static int unconfigure_boot_bridge (u8 busno, u8 device, u8 function)
return -EINVAL; return -EINVAL;
} }
pci_read_config_byte_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_SECONDARY_BUS, &sec_number); pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_number);
sec_no = (int) sec_no; sec_no = (int) sec_no;
pci_read_config_byte_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_SUBORDINATE_BUS, &sub_number); pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SUBORDINATE_BUS, &sub_number);
sub_no = (int) sub_number; sub_no = (int) sub_number;
debug ("sub_no is %d, sec_no is %d\n", sub_no, sec_no); debug ("sub_no is %d, sec_no is %d\n", sub_no, sec_no);
if (sec_no != sub_number) { if (sec_no != sub_number) {
...@@ -1374,7 +1402,7 @@ static int unconfigure_boot_bridge (u8 busno, u8 device, u8 function) ...@@ -1374,7 +1402,7 @@ static int unconfigure_boot_bridge (u8 busno, u8 device, u8 function)
for (count = 0; address[count]; count++) { for (count = 0; address[count]; count++) {
/* for 2 BARs */ /* for 2 BARs */
pci_read_config_dword_nodev (ibmphp_pci_root_ops, busno, device, function, address[count], &start_address); pci_bus_read_config_dword (ibmphp_pci_bus, devfn, address[count], &start_address);
if (!start_address) { if (!start_address) {
/* This BAR is not implemented */ /* This BAR is not implemented */
...@@ -1447,6 +1475,7 @@ static int unconfigure_boot_card (struct slot *slot_cur) ...@@ -1447,6 +1475,7 @@ static int unconfigure_boot_card (struct slot *slot_cur)
u8 busno; u8 busno;
u8 function; u8 function;
int rc; int rc;
unsigned int devfn;
u8 valid_device = 0x00; /* To see if we are ever able to find valid device and read it */ u8 valid_device = 0x00; /* To see if we are ever able to find valid device and read it */
debug ("%s - enter\n", __FUNCTION__); debug ("%s - enter\n", __FUNCTION__);
...@@ -1457,8 +1486,10 @@ static int unconfigure_boot_card (struct slot *slot_cur) ...@@ -1457,8 +1486,10 @@ static int unconfigure_boot_card (struct slot *slot_cur)
debug ("b4 for loop, device is %x\n", device); debug ("b4 for loop, device is %x\n", device);
/* For every function on the card */ /* For every function on the card */
for (function = 0x0; function < 0x08; function++) { for (function = 0x0; function < 0x08; function++) {
devfn = PCI_DEVFN(device, function);
ibmphp_pci_bus->number = busno;
pci_read_config_word_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_VENDOR_ID, &vendor_id); pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_VENDOR_ID, &vendor_id);
if (vendor_id != PCI_VENDOR_ID_NOTVALID) { if (vendor_id != PCI_VENDOR_ID_NOTVALID) {
/* found correct device!!! */ /* found correct device!!! */
...@@ -1471,8 +1502,8 @@ static int unconfigure_boot_card (struct slot *slot_cur) ...@@ -1471,8 +1502,8 @@ static int unconfigure_boot_card (struct slot *slot_cur)
* |_=> 0 = single function device, 1 = multi-function device * |_=> 0 = single function device, 1 = multi-function device
*/ */
pci_read_config_byte_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_HEADER_TYPE, &hdr_type); pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_HEADER_TYPE, &hdr_type);
pci_read_config_dword_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_CLASS_REVISION, &class); pci_bus_read_config_dword (ibmphp_pci_bus, devfn, PCI_CLASS_REVISION, &class);
debug ("hdr_type %x, class %x\n", hdr_type, class); debug ("hdr_type %x, class %x\n", hdr_type, class);
class >>= 8; /* to take revision out, class = class.subclass.prog i/f */ class >>= 8; /* to take revision out, class = class.subclass.prog i/f */
...@@ -1579,7 +1610,6 @@ int ibmphp_unconfigure_card (struct slot **slot_cur, int the_end) ...@@ -1579,7 +1610,6 @@ int ibmphp_unconfigure_card (struct slot **slot_cur, int the_end)
} }
if (sl->func) { if (sl->func) {
debug ("do we come in here? \n");
cur_func = sl->func; cur_func = sl->func;
while (cur_func) { while (cur_func) {
/* TO DO: WILL MOST LIKELY NEED TO GET RID OF THE BUS STRUCTURE FROM RESOURCES AS WELL */ /* TO DO: WILL MOST LIKELY NEED TO GET RID OF THE BUS STRUCTURE FROM RESOURCES AS WELL */
...@@ -1619,6 +1649,7 @@ int ibmphp_unconfigure_card (struct slot **slot_cur, int the_end) ...@@ -1619,6 +1649,7 @@ int ibmphp_unconfigure_card (struct slot **slot_cur, int the_end)
sl->func = NULL; sl->func = NULL;
*slot_cur = sl; *slot_cur = sl;
debug ("%s - exit\n", __FUNCTION__);
return 0; return 0;
} }
...@@ -1638,14 +1669,15 @@ static int add_new_bus (struct bus_node *bus, struct resource_node *io, struct r ...@@ -1638,14 +1669,15 @@ static int add_new_bus (struct bus_node *bus, struct resource_node *io, struct r
struct bus_node *cur_bus = NULL; struct bus_node *cur_bus = NULL;
/* Trying to find the parent bus number */ /* Trying to find the parent bus number */
cur_bus = ibmphp_find_res_bus (parent_busno); if (parent_busno != 0xFF) {
if (!cur_bus) { cur_bus = ibmphp_find_res_bus (parent_busno);
err ("strange, cannot find bus which is supposed to be at the system... something is terribly wrong...\n"); if (!cur_bus) {
return -ENODEV; err ("strange, cannot find bus which is supposed to be at the system... something is terribly wrong...\n");
return -ENODEV;
}
list_add (&bus->bus_list, &cur_bus->bus_list);
} }
list_add (&bus->bus_list, &cur_bus->bus_list);
if (io) { if (io) {
io_range = kmalloc (sizeof (struct range_node), GFP_KERNEL); io_range = kmalloc (sizeof (struct range_node), GFP_KERNEL);
if (!io_range) { if (!io_range) {
...@@ -1698,6 +1730,7 @@ static u8 find_sec_number (u8 primary_busno, u8 slotno) ...@@ -1698,6 +1730,7 @@ static u8 find_sec_number (u8 primary_busno, u8 slotno)
int min, max; int min, max;
u8 busno; u8 busno;
struct bus_info *bus; struct bus_info *bus;
struct bus_node *bus_cur;
bus = ibmphp_find_same_bus_num (primary_busno); bus = ibmphp_find_same_bus_num (primary_busno);
if (!bus) { if (!bus) {
...@@ -1712,7 +1745,12 @@ static u8 find_sec_number (u8 primary_busno, u8 slotno) ...@@ -1712,7 +1745,12 @@ static u8 find_sec_number (u8 primary_busno, u8 slotno)
} }
busno = (u8) (slotno - (u8) min); busno = (u8) (slotno - (u8) min);
busno += primary_busno + 0x01; busno += primary_busno + 0x01;
if (!ibmphp_find_res_bus (busno)) bus_cur = ibmphp_find_res_bus (busno);
/* either there is no such bus number, or there are no ranges, which
* can only happen if we removed the bridged device in previous load
* of the driver, and now only have the skeleton bus struct
*/
if ((!bus_cur) || (!(bus_cur->rangeIO) && !(bus_cur->rangeMem) && !(bus_cur->rangePFMem)))
return busno; return busno;
return 0xff; return 0xff;
} }
......
...@@ -45,11 +45,17 @@ static void fix_resources (struct bus_node *); ...@@ -45,11 +45,17 @@ static void fix_resources (struct bus_node *);
static inline struct bus_node *find_bus_wprev (u8, struct bus_node **, u8); static inline struct bus_node *find_bus_wprev (u8, struct bus_node **, u8);
static LIST_HEAD(gbuses); static LIST_HEAD(gbuses);
LIST_HEAD(ibmphp_res_head);
static struct bus_node * __init alloc_error_bus (struct ebda_pci_rsrc * curr) static struct bus_node * __init alloc_error_bus (struct ebda_pci_rsrc * curr, u8 busno, int flag)
{ {
struct bus_node * newbus; struct bus_node * newbus;
if (!(curr) && !(flag)) {
err ("NULL pointer passed \n");
return NULL;
}
newbus = kmalloc (sizeof (struct bus_node), GFP_KERNEL); newbus = kmalloc (sizeof (struct bus_node), GFP_KERNEL);
if (!newbus) { if (!newbus) {
err ("out of system memory \n"); err ("out of system memory \n");
...@@ -57,14 +63,24 @@ static struct bus_node * __init alloc_error_bus (struct ebda_pci_rsrc * curr) ...@@ -57,14 +63,24 @@ static struct bus_node * __init alloc_error_bus (struct ebda_pci_rsrc * curr)
} }
memset (newbus, 0, sizeof (struct bus_node)); memset (newbus, 0, sizeof (struct bus_node));
newbus->busno = curr->bus_num; if (flag)
newbus->busno = busno;
else
newbus->busno = curr->bus_num;
list_add_tail (&newbus->bus_list, &gbuses); list_add_tail (&newbus->bus_list, &gbuses);
return newbus; return newbus;
} }
static struct resource_node * __init alloc_resources (struct ebda_pci_rsrc * curr) static struct resource_node * __init alloc_resources (struct ebda_pci_rsrc * curr)
{ {
struct resource_node *rs = kmalloc (sizeof (struct resource_node), GFP_KERNEL); struct resource_node *rs;
if (!curr) {
err ("NULL passed to allocate \n");
return NULL;
}
rs = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
if (!rs) { if (!rs) {
err ("out of system memory \n"); err ("out of system memory \n");
return NULL; return NULL;
...@@ -299,7 +315,7 @@ int __init ibmphp_rsrc_init (void) ...@@ -299,7 +315,7 @@ int __init ibmphp_rsrc_init (void)
* actually appears... * actually appears...
*/ */
if (ibmphp_add_resource (new_mem) < 0) { if (ibmphp_add_resource (new_mem) < 0) {
newbus = alloc_error_bus (curr); newbus = alloc_error_bus (curr, 0, 0);
if (!newbus) if (!newbus)
return -ENOMEM; return -ENOMEM;
newbus->firstMem = new_mem; newbus->firstMem = new_mem;
...@@ -316,7 +332,7 @@ int __init ibmphp_rsrc_init (void) ...@@ -316,7 +332,7 @@ int __init ibmphp_rsrc_init (void)
new_pfmem->type = PFMEM; new_pfmem->type = PFMEM;
new_pfmem->fromMem = FALSE; new_pfmem->fromMem = FALSE;
if (ibmphp_add_resource (new_pfmem) < 0) { if (ibmphp_add_resource (new_pfmem) < 0) {
newbus = alloc_error_bus (curr); newbus = alloc_error_bus (curr, 0, 0);
if (!newbus) if (!newbus)
return -ENOMEM; return -ENOMEM;
newbus->firstPFMem = new_pfmem; newbus->firstPFMem = new_pfmem;
...@@ -340,7 +356,7 @@ int __init ibmphp_rsrc_init (void) ...@@ -340,7 +356,7 @@ int __init ibmphp_rsrc_init (void)
* range actually appears... * range actually appears...
*/ */
if (ibmphp_add_resource (new_io) < 0) { if (ibmphp_add_resource (new_io) < 0) {
newbus = alloc_error_bus (curr); newbus = alloc_error_bus (curr, 0, 0);
if (!newbus) if (!newbus)
return -ENOMEM; return -ENOMEM;
newbus->firstIO = new_io; newbus->firstIO = new_io;
...@@ -352,8 +368,6 @@ int __init ibmphp_rsrc_init (void) ...@@ -352,8 +368,6 @@ int __init ibmphp_rsrc_init (void)
} }
} }
debug ("after the while loop in rsrc_init \n");
list_for_each (tmp, &gbuses) { list_for_each (tmp, &gbuses) {
bus_cur = list_entry (tmp, struct bus_node, bus_list); bus_cur = list_entry (tmp, struct bus_node, bus_list);
/* This is to get info about PPB resources, since EBDA doesn't put this info into the primary bus info */ /* This is to get info about PPB resources, since EBDA doesn't put this info into the primary bus info */
...@@ -361,11 +375,9 @@ int __init ibmphp_rsrc_init (void) ...@@ -361,11 +375,9 @@ int __init ibmphp_rsrc_init (void)
if (rc) if (rc)
return rc; return rc;
} }
debug ("b4 once_over in rsrc_init \n");
rc = once_over (); /* This is to align ranges (so no -1) */ rc = once_over (); /* This is to align ranges (so no -1) */
if (rc) if (rc)
return rc; return rc;
debug ("after once_over in rsrc_init \n");
return 0; return 0;
} }
...@@ -580,7 +592,7 @@ static void fix_resources (struct bus_node *bus_cur) ...@@ -580,7 +592,7 @@ static void fix_resources (struct bus_node *bus_cur)
* based on their resource type and sorted by their starting addresses. It assigns * based on their resource type and sorted by their starting addresses. It assigns
* the ptrs to next and nextRange if needed. * the ptrs to next and nextRange if needed.
* *
* Input: 3 diff. resources (nulled out if not needed) * Input: resource ptr
* Output: ptrs assigned (to the node) * Output: ptrs assigned (to the node)
* 0 or -1 * 0 or -1
*******************************************************************************/ *******************************************************************************/
...@@ -593,12 +605,17 @@ int ibmphp_add_resource (struct resource_node *res) ...@@ -593,12 +605,17 @@ int ibmphp_add_resource (struct resource_node *res)
struct resource_node *res_start = NULL; struct resource_node *res_start = NULL;
debug ("%s - enter\n", __FUNCTION__); debug ("%s - enter\n", __FUNCTION__);
if (!res) {
err ("NULL passed to add \n");
return -ENODEV;
}
bus_cur = find_bus_wprev (res->busno, NULL, 0); bus_cur = find_bus_wprev (res->busno, NULL, 0);
if (!bus_cur) { if (!bus_cur) {
/* didn't find a bus, smth's wrong!!! */ /* didn't find a bus, smth's wrong!!! */
err ("no bus in the system, either pci_dev's wrong or allocation failed\n"); debug ("no bus in the system, either pci_dev's wrong or allocation failed\n");
return -ENODEV; return -ENODEV;
} }
...@@ -769,6 +786,11 @@ int ibmphp_remove_resource (struct resource_node *res) ...@@ -769,6 +786,11 @@ int ibmphp_remove_resource (struct resource_node *res)
struct resource_node *mem_cur; struct resource_node *mem_cur;
char * type = ""; char * type = "";
if (!res) {
err ("resource to remove is NULL \n");
return -ENODEV;
}
bus_cur = find_bus_wprev (res->busno, NULL, 0); bus_cur = find_bus_wprev (res->busno, NULL, 0);
if (!bus_cur) { if (!bus_cur) {
...@@ -797,7 +819,6 @@ int ibmphp_remove_resource (struct resource_node *res) ...@@ -797,7 +819,6 @@ int ibmphp_remove_resource (struct resource_node *res)
res_prev = NULL; res_prev = NULL;
while (res_cur) { while (res_cur) {
/* ???????????DO WE _NEED_ TO BE CHECKING FOR END AS WELL?????????? */
if ((res_cur->start == res->start) && (res_cur->end == res->end)) if ((res_cur->start == res->start) && (res_cur->end == res->end))
break; break;
res_prev = res_cur; res_prev = res_cur;
...@@ -981,7 +1002,7 @@ int ibmphp_check_resource (struct resource_node *res, u8 bridge) ...@@ -981,7 +1002,7 @@ int ibmphp_check_resource (struct resource_node *res, u8 bridge)
if (!bus_cur) { if (!bus_cur) {
/* didn't find a bus, smth's wrong!!! */ /* didn't find a bus, smth's wrong!!! */
err ("no bus in the system, either pci_dev's wrong or allocation failed \n"); debug ("no bus in the system, either pci_dev's wrong or allocation failed \n");
return -EINVAL; return -EINVAL;
} }
...@@ -1340,7 +1361,7 @@ int ibmphp_remove_bus (struct bus_node *bus, u8 parent_busno) ...@@ -1340,7 +1361,7 @@ int ibmphp_remove_bus (struct bus_node *bus, u8 parent_busno)
prev_bus = find_bus_wprev (parent_busno, NULL, 0); prev_bus = find_bus_wprev (parent_busno, NULL, 0);
if (!prev_bus) { if (!prev_bus) {
err ("something terribly wrong. Cannot find parent bus to the one to remove\n"); debug ("something terribly wrong. Cannot find parent bus to the one to remove\n");
return -ENODEV; return -ENODEV;
} }
...@@ -1467,13 +1488,18 @@ static int remove_ranges (struct bus_node *bus_cur, struct bus_node *bus_prev) ...@@ -1467,13 +1488,18 @@ static int remove_ranges (struct bus_node *bus_cur, struct bus_node *bus_prev)
/* /*
* find the resource node in the bus * find the resource node in the bus
* Input: Resource needed, start address of the resource, type or resource * Input: Resource needed, start address of the resource, type of resource
*/ */
int ibmphp_find_resource (struct bus_node *bus, u32 start_address, struct resource_node **res, int flag) int ibmphp_find_resource (struct bus_node *bus, u32 start_address, struct resource_node **res, int flag)
{ {
struct resource_node *res_cur = NULL; struct resource_node *res_cur = NULL;
char * type = ""; char * type = "";
if (!bus) {
err ("The bus passed in NULL to find resource \n");
return -ENODEV;
}
switch (flag) { switch (flag) {
case IO: case IO:
res_cur = bus->firstIO; res_cur = bus->firstIO;
...@@ -1514,11 +1540,11 @@ int ibmphp_find_resource (struct bus_node *bus, u32 start_address, struct resour ...@@ -1514,11 +1540,11 @@ int ibmphp_find_resource (struct bus_node *bus, u32 start_address, struct resour
res_cur = res_cur->next; res_cur = res_cur->next;
} }
if (!res_cur) { if (!res_cur) {
err ("SOS...cannot find %s resource in the bus. \n", type); debug ("SOS...cannot find %s resource in the bus. \n", type);
return -EINVAL; return -EINVAL;
} }
} else { } else {
err ("SOS... cannot find %s resource in the bus. \n", type); debug ("SOS... cannot find %s resource in the bus. \n", type);
return -EINVAL; return -EINVAL;
} }
} }
...@@ -1756,6 +1782,8 @@ void ibmphp_print_test (void) ...@@ -1756,6 +1782,8 @@ void ibmphp_print_test (void)
struct range_node *range; struct range_node *range;
struct resource_node *res; struct resource_node *res;
struct list_head *tmp; struct list_head *tmp;
debug_pci ("*****************START**********************\n");
if ((!list_empty(&gbuses)) && flags) { if ((!list_empty(&gbuses)) && flags) {
err ("The GBUSES is not NULL?!?!?!?!?\n"); err ("The GBUSES is not NULL?!?!?!?!?\n");
...@@ -1764,50 +1792,50 @@ void ibmphp_print_test (void) ...@@ -1764,50 +1792,50 @@ void ibmphp_print_test (void)
list_for_each (tmp, &gbuses) { list_for_each (tmp, &gbuses) {
bus_cur = list_entry (tmp, struct bus_node, bus_list); bus_cur = list_entry (tmp, struct bus_node, bus_list);
debug ("This is bus # %d. There are \n", bus_cur->busno); debug_pci ("This is bus # %d. There are \n", bus_cur->busno);
debug ("IORanges = %d\t", bus_cur->noIORanges); debug_pci ("IORanges = %d\t", bus_cur->noIORanges);
debug ("MemRanges = %d\t", bus_cur->noMemRanges); debug_pci ("MemRanges = %d\t", bus_cur->noMemRanges);
debug ("PFMemRanges = %d\n", bus_cur->noPFMemRanges); debug_pci ("PFMemRanges = %d\n", bus_cur->noPFMemRanges);
debug ("The IO Ranges are as follows:\n"); debug_pci ("The IO Ranges are as follows:\n");
if (bus_cur->rangeIO) { if (bus_cur->rangeIO) {
range = bus_cur->rangeIO; range = bus_cur->rangeIO;
for (i = 0; i < bus_cur->noIORanges; i++) { for (i = 0; i < bus_cur->noIORanges; i++) {
debug ("rangeno is %d\n", range->rangeno); debug_pci ("rangeno is %d\n", range->rangeno);
debug ("[%x - %x]\n", range->start, range->end); debug_pci ("[%x - %x]\n", range->start, range->end);
range = range->next; range = range->next;
} }
} }
debug ("The Mem Ranges are as follows:\n"); debug_pci ("The Mem Ranges are as follows:\n");
if (bus_cur->rangeMem) { if (bus_cur->rangeMem) {
range = bus_cur->rangeMem; range = bus_cur->rangeMem;
for (i = 0; i < bus_cur->noMemRanges; i++) { for (i = 0; i < bus_cur->noMemRanges; i++) {
debug ("rangeno is %d\n", range->rangeno); debug_pci ("rangeno is %d\n", range->rangeno);
debug ("[%x - %x]\n", range->start, range->end); debug_pci ("[%x - %x]\n", range->start, range->end);
range = range->next; range = range->next;
} }
} }
debug ("The PFMem Ranges are as follows:\n"); debug_pci ("The PFMem Ranges are as follows:\n");
if (bus_cur->rangePFMem) { if (bus_cur->rangePFMem) {
range = bus_cur->rangePFMem; range = bus_cur->rangePFMem;
for (i = 0; i < bus_cur->noPFMemRanges; i++) { for (i = 0; i < bus_cur->noPFMemRanges; i++) {
debug ("rangeno is %d\n", range->rangeno); debug_pci ("rangeno is %d\n", range->rangeno);
debug ("[%x - %x]\n", range->start, range->end); debug_pci ("[%x - %x]\n", range->start, range->end);
range = range->next; range = range->next;
} }
} }
debug ("The resources on this bus are as follows\n"); debug_pci ("The resources on this bus are as follows\n");
debug ("IO...\n"); debug_pci ("IO...\n");
if (bus_cur->firstIO) { if (bus_cur->firstIO) {
res = bus_cur->firstIO; res = bus_cur->firstIO;
while (res) { while (res) {
debug ("The range # is %d\n", res->rangeno); debug_pci ("The range # is %d\n", res->rangeno);
debug ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc); debug_pci ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
debug ("[%x - %x], len=%x\n", res->start, res->end, res->len); debug_pci ("[%x - %x], len=%x\n", res->start, res->end, res->len);
if (res->next) if (res->next)
res = res->next; res = res->next;
else if (res->nextRange) else if (res->nextRange)
...@@ -1816,13 +1844,13 @@ void ibmphp_print_test (void) ...@@ -1816,13 +1844,13 @@ void ibmphp_print_test (void)
break; break;
} }
} }
debug ("Mem...\n"); debug_pci ("Mem...\n");
if (bus_cur->firstMem) { if (bus_cur->firstMem) {
res = bus_cur->firstMem; res = bus_cur->firstMem;
while (res) { while (res) {
debug ("The range # is %d\n", res->rangeno); debug_pci ("The range # is %d\n", res->rangeno);
debug ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc); debug_pci ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
debug ("[%x - %x], len=%x\n", res->start, res->end, res->len); debug_pci ("[%x - %x], len=%x\n", res->start, res->end, res->len);
if (res->next) if (res->next)
res = res->next; res = res->next;
else if (res->nextRange) else if (res->nextRange)
...@@ -1831,13 +1859,13 @@ void ibmphp_print_test (void) ...@@ -1831,13 +1859,13 @@ void ibmphp_print_test (void)
break; break;
} }
} }
debug ("PFMem...\n"); debug_pci ("PFMem...\n");
if (bus_cur->firstPFMem) { if (bus_cur->firstPFMem) {
res = bus_cur->firstPFMem; res = bus_cur->firstPFMem;
while (res) { while (res) {
debug ("The range # is %d\n", res->rangeno); debug_pci ("The range # is %d\n", res->rangeno);
debug ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc); debug_pci ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
debug ("[%x - %x], len=%x\n", res->start, res->end, res->len); debug_pci ("[%x - %x], len=%x\n", res->start, res->end, res->len);
if (res->next) if (res->next)
res = res->next; res = res->next;
else if (res->nextRange) else if (res->nextRange)
...@@ -1847,23 +1875,53 @@ void ibmphp_print_test (void) ...@@ -1847,23 +1875,53 @@ void ibmphp_print_test (void)
} }
} }
debug ("PFMemFromMem...\n"); debug_pci ("PFMemFromMem...\n");
if (bus_cur->firstPFMemFromMem) { if (bus_cur->firstPFMemFromMem) {
res = bus_cur->firstPFMemFromMem; res = bus_cur->firstPFMemFromMem;
while (res) { while (res) {
debug ("The range # is %d\n", res->rangeno); debug_pci ("The range # is %d\n", res->rangeno);
debug ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc); debug_pci ("The bus, devfnc is %d, %x\n", res->busno, res->devfunc);
debug ("[%x - %x], len=%x\n", res->start, res->end, res->len); debug_pci ("[%x - %x], len=%x\n", res->start, res->end, res->len);
res = res->next; res = res->next;
} }
} }
} }
debug_pci ("***********************END***********************\n");
}
int static range_exists_already (struct range_node * range, struct bus_node * bus_cur, u8 type)
{
struct range_node * range_cur = NULL;
switch (type) {
case IO:
range_cur = bus_cur->rangeIO;
break;
case MEM:
range_cur = bus_cur->rangeMem;
break;
case PFMEM:
range_cur = bus_cur->rangePFMem;
break;
default:
err ("wrong type passed to find out if range already exists \n");
return -ENODEV;
}
while (range_cur) {
if ((range_cur->start == range->start) && (range_cur->end == range->end))
return 1;
range_cur = range_cur->next;
}
return 0;
} }
/* This routine will read the windows for any PPB we have and update the /* This routine will read the windows for any PPB we have and update the
* range info for the secondary bus, and will also input this info into * range info for the secondary bus, and will also input this info into
* primary bus, since BIOS doesn't. This is for PPB that are in the system * primary bus, since BIOS doesn't. This is for PPB that are in the system
* on bootup * on bootup. For bridged cards that were added during previous load of the
* driver, only the ranges and the bus structure are added, the devices are
* added from NVRAM
* Input: primary busno * Input: primary busno
* Returns: none * Returns: none
* Note: this function doesn't take into account IO restrictions etc, * Note: this function doesn't take into account IO restrictions etc,
...@@ -1874,7 +1932,7 @@ void ibmphp_print_test (void) ...@@ -1874,7 +1932,7 @@ void ibmphp_print_test (void)
*/ */
static int __init update_bridge_ranges (struct bus_node **bus) static int __init update_bridge_ranges (struct bus_node **bus)
{ {
u8 sec_busno, device, function, busno, hdr_type, start_io_address, end_io_address; u8 sec_busno, device, function, hdr_type, start_io_address, end_io_address;
u16 vendor_id, upper_io_start, upper_io_end, start_mem_address, end_mem_address; u16 vendor_id, upper_io_start, upper_io_end, start_mem_address, end_mem_address;
u32 start_address, end_address, upper_start, upper_end; u32 start_address, end_address, upper_start, upper_end;
struct bus_node *bus_sec; struct bus_node *bus_sec;
...@@ -1883,19 +1941,24 @@ static int __init update_bridge_ranges (struct bus_node **bus) ...@@ -1883,19 +1941,24 @@ static int __init update_bridge_ranges (struct bus_node **bus)
struct resource_node *mem; struct resource_node *mem;
struct resource_node *pfmem; struct resource_node *pfmem;
struct range_node *range; struct range_node *range;
unsigned int devfn;
bus_cur = *bus; bus_cur = *bus;
busno = bus_cur->busno; if (!bus_cur)
return -ENODEV;
ibmphp_pci_bus->number = bus_cur->busno;
debug ("inside %s \n", __FUNCTION__); debug ("inside %s \n", __FUNCTION__);
debug ("bus_cur->busno = %x\n", bus_cur->busno); debug ("bus_cur->busno = %x\n", bus_cur->busno);
for (device = 0; device < 32; device++) { for (device = 0; device < 32; device++) {
for (function = 0x00; function < 0x08; function++) { for (function = 0x00; function < 0x08; function++) {
pci_read_config_word_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_VENDOR_ID, &vendor_id); devfn = PCI_DEVFN(device, function);
pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_VENDOR_ID, &vendor_id);
if (vendor_id != PCI_VENDOR_ID_NOTVALID) { if (vendor_id != PCI_VENDOR_ID_NOTVALID) {
/* found correct device!!! */ /* found correct device!!! */
pci_read_config_byte_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_HEADER_TYPE, &hdr_type); pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_HEADER_TYPE, &hdr_type);
switch (hdr_type) { switch (hdr_type) {
case PCI_HEADER_TYPE_NORMAL: case PCI_HEADER_TYPE_NORMAL:
...@@ -1914,21 +1977,25 @@ static int __init update_bridge_ranges (struct bus_node **bus) ...@@ -1914,21 +1977,25 @@ static int __init update_bridge_ranges (struct bus_node **bus)
temp++; temp++;
} }
*/ */
pci_read_config_byte_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_SECONDARY_BUS, &sec_busno); pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_SECONDARY_BUS, &sec_busno);
bus_sec = find_bus_wprev (sec_busno, NULL, 0); bus_sec = find_bus_wprev (sec_busno, NULL, 0);
pci_read_config_byte_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_IO_BASE, &start_io_address); /* this bus structure doesn't exist yet, PPB was configured during previous loading of ibmphp */
pci_read_config_byte_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_IO_LIMIT, &end_io_address); if (!bus_sec) {
pci_read_config_word_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_IO_BASE_UPPER16, &upper_io_start); bus_sec = alloc_error_bus (NULL, sec_busno, 1);
pci_read_config_word_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_IO_LIMIT_UPPER16, &upper_io_end); /* the rest will be populated during NVRAM call */
return 0;
}
pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_IO_BASE, &start_io_address);
pci_bus_read_config_byte (ibmphp_pci_bus, devfn, PCI_IO_LIMIT, &end_io_address);
pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_IO_BASE_UPPER16, &upper_io_start);
pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_IO_LIMIT_UPPER16, &upper_io_end);
start_address = (start_io_address & PCI_IO_RANGE_MASK) << 8; start_address = (start_io_address & PCI_IO_RANGE_MASK) << 8;
start_address |= (upper_io_start << 16); start_address |= (upper_io_start << 16);
end_address = (end_io_address & PCI_IO_RANGE_MASK) << 8; end_address = (end_io_address & PCI_IO_RANGE_MASK) << 8;
end_address |= (upper_io_end << 16); end_address |= (upper_io_end << 16);
if ((start_address) && (start_address <= end_address)) { if ((start_address) && (start_address <= end_address)) {
range = kmalloc (sizeof (struct range_node), GFP_KERNEL); range = kmalloc (sizeof (struct range_node), GFP_KERNEL);
if (!range) { if (!range) {
err ("out of system memory \n"); err ("out of system memory \n");
return -ENOMEM; return -ENOMEM;
...@@ -1937,36 +2004,42 @@ static int __init update_bridge_ranges (struct bus_node **bus) ...@@ -1937,36 +2004,42 @@ static int __init update_bridge_ranges (struct bus_node **bus)
range->start = start_address; range->start = start_address;
range->end = end_address + 0xfff; range->end = end_address + 0xfff;
if (bus_sec->noIORanges > 0) if (bus_sec->noIORanges > 0) {
add_range (IO, range, bus_sec); if (!range_exists_already (range, bus_sec, IO)) {
else { add_range (IO, range, bus_sec);
++bus_sec->noIORanges;
} else {
kfree (range);
range = NULL;
}
} else {
/* 1st IO Range on the bus */ /* 1st IO Range on the bus */
range->rangeno = 1; range->rangeno = 1;
bus_sec->rangeIO = range; bus_sec->rangeIO = range;
++bus_sec->noIORanges;
} }
++bus_sec->noIORanges;
fix_resources (bus_sec); fix_resources (bus_sec);
io = kmalloc (sizeof (struct resource_node), GFP_KERNEL); if (ibmphp_find_resource (bus_cur, start_address, &io, IO)) {
if (!io) { io = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
kfree (range); if (!io) {
err ("out of system memory \n"); kfree (range);
return -ENOMEM; err ("out of system memory \n");
return -ENOMEM;
}
memset (io, 0, sizeof (struct resource_node));
io->type = IO;
io->busno = bus_cur->busno;
io->devfunc = ((device << 3) | (function & 0x7));
io->start = start_address;
io->end = end_address + 0xfff;
io->len = io->end - io->start + 1;
ibmphp_add_resource (io);
} }
memset (io, 0, sizeof (struct resource_node)); }
io->type = IO;
io->busno = bus_cur->busno;
io->devfunc = ((device << 3) | (function & 0x7));
io->start = start_address;
io->end = end_address + 0xfff;
io->len = io->end - io->start + 1;
ibmphp_add_resource (io);
}
pci_read_config_word_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_MEMORY_BASE, &start_mem_address); pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_BASE, &start_mem_address);
pci_read_config_word_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_MEMORY_LIMIT, &end_mem_address); pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_MEMORY_LIMIT, &end_mem_address);
start_address = 0x00000000 | (start_mem_address & PCI_MEMORY_RANGE_MASK) << 16; start_address = 0x00000000 | (start_mem_address & PCI_MEMORY_RANGE_MASK) << 16;
end_address = 0x00000000 | (end_mem_address & PCI_MEMORY_RANGE_MASK) << 16; end_address = 0x00000000 | (end_mem_address & PCI_MEMORY_RANGE_MASK) << 16;
...@@ -1982,36 +2055,44 @@ static int __init update_bridge_ranges (struct bus_node **bus) ...@@ -1982,36 +2055,44 @@ static int __init update_bridge_ranges (struct bus_node **bus)
range->start = start_address; range->start = start_address;
range->end = end_address + 0xfffff; range->end = end_address + 0xfffff;
if (bus_sec->noMemRanges > 0) if (bus_sec->noMemRanges > 0) {
add_range (MEM, range, bus_sec); if (!range_exists_already (range, bus_sec, MEM)) {
else { add_range (MEM, range, bus_sec);
++bus_sec->noMemRanges;
} else {
kfree (range);
range = NULL;
}
} else {
/* 1st Mem Range on the bus */ /* 1st Mem Range on the bus */
range->rangeno = 1; range->rangeno = 1;
bus_sec->rangeMem = range; bus_sec->rangeMem = range;
++bus_sec->noMemRanges;
} }
++bus_sec->noMemRanges;
fix_resources (bus_sec); fix_resources (bus_sec);
mem = kmalloc (sizeof (struct resource_node), GFP_KERNEL); if (ibmphp_find_resource (bus_cur, start_address, &mem, MEM)) {
if (!mem) { mem = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
kfree (range); if (!mem) {
err ("out of system memory \n"); kfree (range);
return -ENOMEM; err ("out of system memory \n");
return -ENOMEM;
}
memset (mem, 0, sizeof (struct resource_node));
mem->type = MEM;
mem->busno = bus_cur->busno;
mem->devfunc = ((device << 3) | (function & 0x7));
mem->start = start_address;
mem->end = end_address + 0xfffff;
mem->len = mem->end - mem->start + 1;
ibmphp_add_resource (mem);
} }
memset (mem, 0, sizeof (struct resource_node));
mem->type = MEM;
mem->busno = bus_cur->busno;
mem->devfunc = ((device << 3) | (function & 0x7));
mem->start = start_address;
mem->end = end_address + 0xfffff;
mem->len = mem->end - mem->start + 1;
ibmphp_add_resource (mem);
} }
pci_read_config_word_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_PREF_MEMORY_BASE, &start_mem_address); pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_BASE, &start_mem_address);
pci_read_config_word_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_PREF_MEMORY_LIMIT, &end_mem_address); pci_bus_read_config_word (ibmphp_pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, &end_mem_address);
pci_read_config_dword_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_PREF_BASE_UPPER32, &upper_start); pci_bus_read_config_dword (ibmphp_pci_bus, devfn, PCI_PREF_BASE_UPPER32, &upper_start);
pci_read_config_dword_nodev (ibmphp_pci_root_ops, busno, device, function, PCI_PREF_LIMIT_UPPER32, &upper_end); pci_bus_read_config_dword (ibmphp_pci_bus, devfn, PCI_PREF_LIMIT_UPPER32, &upper_end);
start_address = 0x00000000 | (start_mem_address & PCI_MEMORY_RANGE_MASK) << 16; start_address = 0x00000000 | (start_mem_address & PCI_MEMORY_RANGE_MASK) << 16;
end_address = 0x00000000 | (end_mem_address & PCI_MEMORY_RANGE_MASK) << 16; end_address = 0x00000000 | (end_mem_address & PCI_MEMORY_RANGE_MASK) << 16;
#if BITS_PER_LONG == 64 #if BITS_PER_LONG == 64
...@@ -2030,32 +2111,40 @@ static int __init update_bridge_ranges (struct bus_node **bus) ...@@ -2030,32 +2111,40 @@ static int __init update_bridge_ranges (struct bus_node **bus)
range->start = start_address; range->start = start_address;
range->end = end_address + 0xfffff; range->end = end_address + 0xfffff;
if (bus_sec->noPFMemRanges > 0) if (bus_sec->noPFMemRanges > 0) {
add_range (PFMEM, range, bus_sec); if (!range_exists_already (range, bus_sec, PFMEM)) {
else { add_range (PFMEM, range, bus_sec);
++bus_sec->noPFMemRanges;
} else {
kfree (range);
range = NULL;
}
} else {
/* 1st PFMem Range on the bus */ /* 1st PFMem Range on the bus */
range->rangeno = 1; range->rangeno = 1;
bus_sec->rangePFMem = range; bus_sec->rangePFMem = range;
++bus_sec->noPFMemRanges;
} }
++bus_sec->noPFMemRanges;
fix_resources (bus_sec); fix_resources (bus_sec);
if (ibmphp_find_resource (bus_cur, start_address, &pfmem, PFMEM)) {
pfmem = kmalloc (sizeof (struct resource_node), GFP_KERNEL); pfmem = kmalloc (sizeof (struct resource_node), GFP_KERNEL);
if (!pfmem) { if (!pfmem) {
kfree (range); kfree (range);
err ("out of system memory \n"); err ("out of system memory \n");
return -ENOMEM; return -ENOMEM;
}
memset (pfmem, 0, sizeof (struct resource_node));
pfmem->type = PFMEM;
pfmem->busno = bus_cur->busno;
pfmem->devfunc = ((device << 3) | (function & 0x7));
pfmem->start = start_address;
pfmem->end = end_address + 0xfffff;
pfmem->len = pfmem->end - pfmem->start + 1;
pfmem->fromMem = FALSE;
ibmphp_add_resource (pfmem);
} }
memset (pfmem, 0, sizeof (struct resource_node));
pfmem->type = PFMEM;
pfmem->busno = bus_cur->busno;
pfmem->devfunc = ((device << 3) | (function & 0x7));
pfmem->start = start_address;
pfmem->end = end_address + 0xfffff;
pfmem->len = pfmem->end - pfmem->start + 1;
pfmem->fromMem = FALSE;
ibmphp_add_resource (pfmem);
} }
break; break;
} /* end of switch */ } /* end of switch */
......
...@@ -141,20 +141,5 @@ extern int pci_visit_dev (struct pci_visit *fn, ...@@ -141,20 +141,5 @@ extern int pci_visit_dev (struct pci_visit *fn,
struct pci_dev_wrapped *wrapped_dev, struct pci_dev_wrapped *wrapped_dev,
struct pci_bus_wrapped *wrapped_parent); struct pci_bus_wrapped *wrapped_parent);
extern int pci_read_config_byte_nodev (struct pci_ops *ops, u8 bus, u8 device,
u8 function, int where, u8 *val);
extern int pci_read_config_word_nodev (struct pci_ops *ops, u8 bus, u8 device,
u8 function, int where, u16 *val);
extern int pci_read_config_dword_nodev (struct pci_ops *ops, u8 bus, u8 device,
u8 function, int where, u32 *val);
extern int pci_write_config_byte_nodev (struct pci_ops *ops, u8 bus, u8 device,
u8 function, int where, u8 val);
extern int pci_write_config_word_nodev (struct pci_ops *ops, u8 bus, u8 device,
u8 function, int where, u16 val);
extern int pci_write_config_dword_nodev (struct pci_ops *ops, u8 bus, u8 device,
u8 function, int where, u32 val);
#endif #endif
...@@ -6,10 +6,8 @@ export-objs := access.o hotplug.o pci-driver.o pci.o pool.o \ ...@@ -6,10 +6,8 @@ export-objs := access.o hotplug.o pci-driver.o pci.o pool.o \
probe.o proc.o search.o compat.o probe.o proc.o search.o compat.o
obj-y += access.o probe.o pci.o pool.o quirks.o \ obj-y += access.o probe.o pci.o pool.o quirks.o \
compat.o names.o pci-driver.o search.o compat.o names.o pci-driver.o search.o hotplug.o
obj-$(CONFIG_PM) += power.o obj-$(CONFIG_PM) += power.o
obj-$(CONFIG_HOTPLUG) += hotplug.o
obj-$(CONFIG_PROC_FS) += proc.o obj-$(CONFIG_PROC_FS) += proc.o
ifndef CONFIG_SPARC64 ifndef CONFIG_SPARC64
......
...@@ -7,8 +7,8 @@ ...@@ -7,8 +7,8 @@
#define TRUE (!FALSE) #define TRUE (!FALSE)
#endif #endif
static void #ifdef CONFIG_HOTPLUG
run_sbin_hotplug(struct pci_dev *pdev, int insert) static void run_sbin_hotplug(struct pci_dev *pdev, int insert)
{ {
int i; int i;
char *argv[3], *envp[8]; char *argv[3], *envp[8];
...@@ -45,13 +45,18 @@ run_sbin_hotplug(struct pci_dev *pdev, int insert) ...@@ -45,13 +45,18 @@ run_sbin_hotplug(struct pci_dev *pdev, int insert)
call_usermodehelper (argv [0], argv, envp); call_usermodehelper (argv [0], argv, envp);
} }
#else
static void run_sbin_hotplug(struct pci_dev *pdev, int insert) { }
#endif
/** /**
* pci_insert_device - insert a hotplug device * pci_insert_device - insert a pci device
* @dev: the device to insert * @dev: the device to insert
* @bus: where to insert it * @bus: where to insert it
* *
* Add a new device to the device lists and notify userspace (/sbin/hotplug). * Link the device to both the global PCI device chain and the
* per-bus list of devices, add the /proc entry, and notify
* userspace (/sbin/hotplug).
*/ */
void void
pci_insert_device(struct pci_dev *dev, struct pci_bus *bus) pci_insert_device(struct pci_dev *dev, struct pci_bus *bus)
...@@ -78,11 +83,11 @@ pci_free_resources(struct pci_dev *dev) ...@@ -78,11 +83,11 @@ pci_free_resources(struct pci_dev *dev)
} }
/** /**
* pci_remove_device - remove a hotplug device * pci_remove_device - remove a pci device
* @dev: the device to remove * @dev: the device to remove
* *
* Delete the device structure from the device lists and * Delete the device structure from the device lists,
* notify userspace (/sbin/hotplug). * remove the /proc entry, and notify userspace (/sbin/hotplug).
*/ */
void void
pci_remove_device(struct pci_dev *dev) pci_remove_device(struct pci_dev *dev)
...@@ -94,10 +99,11 @@ pci_remove_device(struct pci_dev *dev) ...@@ -94,10 +99,11 @@ pci_remove_device(struct pci_dev *dev)
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
pci_proc_detach_device(dev); pci_proc_detach_device(dev);
#endif #endif
/* notify userspace of hotplug device removal */ /* notify userspace of hotplug device removal */
run_sbin_hotplug(dev, FALSE); run_sbin_hotplug(dev, FALSE);
} }
#ifdef CONFIG_HOTPLUG
EXPORT_SYMBOL(pci_insert_device); EXPORT_SYMBOL(pci_insert_device);
EXPORT_SYMBOL(pci_remove_device); EXPORT_SYMBOL(pci_remove_device);
#endif
...@@ -479,10 +479,10 @@ struct pci_dev * __devinit pci_scan_slot(struct pci_dev *temp) ...@@ -479,10 +479,10 @@ struct pci_dev * __devinit pci_scan_slot(struct pci_dev *temp)
/* /*
* Link the device to both the global PCI device chain and * Link the device to both the global PCI device chain and
* the per-bus list of devices. * the per-bus list of devices and call /sbin/hotplug if we
* should.
*/ */
list_add_tail(&dev->global_list, &pci_devices); pci_insert_device (dev, bus);
list_add_tail(&dev->bus_list, &bus->devices);
/* Fix up broken headers */ /* Fix up broken headers */
pci_fixup_device(PCI_FIXUP_HEADER, dev); pci_fixup_device(PCI_FIXUP_HEADER, dev);
...@@ -594,4 +594,5 @@ EXPORT_SYMBOL(pci_setup_device); ...@@ -594,4 +594,5 @@ EXPORT_SYMBOL(pci_setup_device);
EXPORT_SYMBOL(pci_add_new_bus); EXPORT_SYMBOL(pci_add_new_bus);
EXPORT_SYMBOL(pci_do_scan_bus); EXPORT_SYMBOL(pci_do_scan_bus);
EXPORT_SYMBOL(pci_scan_slot); EXPORT_SYMBOL(pci_scan_slot);
EXPORT_SYMBOL(pci_scan_bus);
#endif #endif
...@@ -18,6 +18,8 @@ ...@@ -18,6 +18,8 @@
#define PCI_CFG_SPACE_SIZE 256 #define PCI_CFG_SPACE_SIZE 256
static int proc_initialized; /* = 0 */
static loff_t static loff_t
proc_bus_pci_lseek(struct file *file, loff_t off, int whence) proc_bus_pci_lseek(struct file *file, loff_t off, int whence)
{ {
...@@ -410,6 +412,9 @@ int pci_proc_attach_device(struct pci_dev *dev) ...@@ -410,6 +412,9 @@ int pci_proc_attach_device(struct pci_dev *dev)
struct proc_dir_entry *de, *e; struct proc_dir_entry *de, *e;
char name[16]; char name[16];
if (!proc_initialized)
return -EACCES;
if (!(de = bus->procdir)) { if (!(de = bus->procdir)) {
sprintf(name, "%02x", bus->number); sprintf(name, "%02x", bus->number);
de = bus->procdir = proc_mkdir(name, proc_bus_pci_dir); de = bus->procdir = proc_mkdir(name, proc_bus_pci_dir);
...@@ -446,6 +451,9 @@ int pci_proc_attach_bus(struct pci_bus* bus) ...@@ -446,6 +451,9 @@ int pci_proc_attach_bus(struct pci_bus* bus)
{ {
struct proc_dir_entry *de = bus->procdir; struct proc_dir_entry *de = bus->procdir;
if (!proc_initialized)
return -EACCES;
if (!de) { if (!de) {
char name[16]; char name[16];
sprintf(name, "%02x", bus->number); sprintf(name, "%02x", bus->number);
...@@ -595,6 +603,7 @@ static int __init pci_proc_init(void) ...@@ -595,6 +603,7 @@ static int __init pci_proc_init(void)
entry = create_proc_entry("devices", 0, proc_bus_pci_dir); entry = create_proc_entry("devices", 0, proc_bus_pci_dir);
if (entry) if (entry)
entry->proc_fops = &proc_bus_pci_dev_operations; entry->proc_fops = &proc_bus_pci_dev_operations;
proc_initialized = 1;
pci_for_each_dev(dev) { pci_for_each_dev(dev) {
pci_proc_attach_device(dev); pci_proc_attach_device(dev);
} }
......
...@@ -634,7 +634,6 @@ void pci_insert_device(struct pci_dev *, struct pci_bus *); ...@@ -634,7 +634,6 @@ void pci_insert_device(struct pci_dev *, struct pci_bus *);
void pci_remove_device(struct pci_dev *); void pci_remove_device(struct pci_dev *);
struct pci_driver *pci_dev_driver(const struct pci_dev *); struct pci_driver *pci_dev_driver(const struct pci_dev *);
const struct pci_device_id *pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev); const struct pci_device_id *pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev);
void pci_announce_device_to_drivers(struct pci_dev *);
unsigned int pci_do_scan_bus(struct pci_bus *bus); unsigned int pci_do_scan_bus(struct pci_bus *bus);
struct pci_bus * pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, int busnr); struct pci_bus * pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, int busnr);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment