--- arch/parisc/kernel/inventory.orig Fri Feb 2 12:46:00 2001 +++ arch/parisc/kernel/inventory.c Fri Feb 2 12:37:36 2001 @@ -171,59 +171,88 @@ } #endif /* __LP64__ */ +#ifdef __LP64__ +#define FPA 0xFFFFFFFFFFF80000 /* Fixed Physical Address - Location of the Central Bus */ +#else /* !__LP64__ */ +#define FPA 0xFFF80000 /* Fixed Physical Address - Location of the Central Bus */ +#endif /* __LP64__ */ + +/* The fixed portion is contained in hpa[14..19] for 32 bit and hpa[46..51] for 64 bit. +** The maximum number of native devices is 2^6 (64) and the offset between devices is +** 2^12 (0x1000). +** - Ryan +*/ +#define MAX_NATIVE_DEVICES 64 +#define NATIVE_DEVICE_OFFSET 0x1000 - -static int do_newer_workstation_inventory(void) +static int do_native_bus_walk(unsigned long hpa) { - long status, mod_index, addr_index; - struct hp_device *hp_device; - int num; + int num = 0; + struct hp_device *hp_device; + unsigned long hpa_end = hpa + (MAX_NATIVE_DEVICES * NATIVE_DEVICE_OFFSET); + + for(; hpa < hpa_end; hpa += NATIVE_DEVICE_OFFSET) { + hp_device = alloc_pa_dev(hpa); + if (!hp_device) + continue; + + register_pa_dev(hp_device); + ++num; + } + return num; +} - /* So the idea here is to simply try one SYSTEM_MAP call. If - that one works, great, otherwise do it another way */ - status = pdc_system_map_find_mods(&module_result, &module_path, 0); - if (status != PDC_RET_OK) - return 0; - - /* This is for newer non-PDC-PAT boxes */ - printk("a newer box...\n"); - num = 0; - for (mod_index = 0, status = PDC_RET_OK; - status != PDC_RET_NE_PROC && status != PDC_RET_NE_MOD; - mod_index++) - { - status = pdc_system_map_find_mods(&module_result, - &module_path, mod_index); +static int do_newer_workstation_inventory(void) +{ + long status, mod_index, addr_index; + struct hp_device *hp_device; + int num; + + /* So the idea here is to simply try one SYSTEM_MAP call. If + that one works, great, otherwise do it another way */ + + status = pdc_system_map_find_mods(&module_result, &module_path, 0); if (status != PDC_RET_OK) - continue; - - hp_device = alloc_pa_dev((unsigned long) module_result.mod_addr); - if (!hp_device) - continue; - - (void) register_pa_dev(hp_device); - num++; - - /* if available, get the additional addresses for a module */ - if (!module_result.add_addrs) - continue; + return 0; - for (addr_index = 1; addr_index <= module_result.add_addrs; addr_index++) { - status = pdc_system_map_find_addrs( - &addr_result, mod_index, addr_index); - - if (status == PDC_RET_OK) - add_pa_dev_addr(hp_device, (unsigned long)addr_result.mod_addr); - else { - printk("Bad PDC_FIND_ADDRESS status return (%ld) for index %ld\n", - status, addr_index); - status = PDC_RET_OK; /* reset status for outer loop */ - } - } - } /* end of main loop */ - - return (num > 0); + /* This is for newer non-PDC-PAT boxes */ + printk("a newer box...\n"); + num = 0; + for (mod_index = 0, status = PDC_RET_OK; + status != PDC_RET_NE_PROC && status != PDC_RET_NE_MOD; + mod_index++) { + status = pdc_system_map_find_mods(&module_result, + &module_path, mod_index); + if (status != PDC_RET_OK) + continue; + + hp_device = alloc_pa_dev((unsigned long) module_result.mod_addr); + if (!hp_device) + continue; + + (void) register_pa_dev(hp_device); + num++; + + /* if available, get the additional addresses for a module */ + if (!module_result.add_addrs) + continue; + + for (addr_index = 1; addr_index <= module_result.add_addrs; addr_index++) { + status = pdc_system_map_find_addrs(&addr_result, mod_index, addr_index); + if (status == PDC_RET_OK) { + add_pa_dev_addr(hp_device, (unsigned long)addr_result.mod_addr); + } else { + printk("Bad PDC_FIND_ADDRESS status return (%ld) for index %ld\n", + status, addr_index); + status = PDC_RET_OK; /* reset status for outer loop */ + } + } + } /* end of main loop */ + + /* Walk the system bus */ + num += do_native_bus_walk(FPA); + return (num > 0); } --- arch/parisc/kernel/drivers.orig Fri Feb 2 12:46:10 2001 +++ arch/parisc/kernel/drivers.c Fri Feb 2 12:01:28 2001 @@ -103,15 +103,20 @@ struct hp_device *alloc_pa_dev(unsigned long hpa) { - + int i, status; struct hp_device * d; - int status; d = &pa_devices[num_devices]; status = pdc_iodc_read(&pdc_result, (void *)hpa, 0, &iodc_data, 32); if (status != PDC_RET_OK) { /* There is no device here, so we'll skip it */ return NULL; + } + + /* Check to make sure this device has not already been added -Ryan */ + for(i = 0; i < num_devices; ++i) { + if((unsigned long)pa_devices[i].hpa == hpa) + return NULL; } d->hw_type = iodc_data[3]&0x1f;