Commit af6e9e07 authored by Irene Zubarev's avatar Irene Zubarev Committed by Greg Kroah-Hartman

[PATCH] IBM PCI Hotplug driver update

- fix polling logic
- add ability to write [chassis/rxe]#slot# instead of just slot#
parent d9a26363
...@@ -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
...@@ -739,6 +763,7 @@ extern int ibmphp_disable_slot (struct hotplug_slot *); /* This function is call ...@@ -739,6 +763,7 @@ extern int ibmphp_disable_slot (struct hotplug_slot *); /* This function is call
extern int ibmphp_update_slot_info (struct slot *); /* This function is called from HPC, so we need it to not be be static */ extern int ibmphp_update_slot_info (struct slot *); /* This function is called from HPC, so we need it to not be be static */
extern int ibmphp_configure_card (struct pci_func *, u8); extern int ibmphp_configure_card (struct pci_func *, u8);
extern int ibmphp_unconfigure_card (struct slot **, int); extern int ibmphp_unconfigure_card (struct slot **, int);
extern void ibmphp_increase_count (void);
extern struct hotplug_slot_ops ibmphp_hotplug_slot_ops; extern struct hotplug_slot_ops ibmphp_hotplug_slot_ops;
static inline void long_delay (int delay) static inline void long_delay (int delay)
......
This diff is collapsed.
This diff is collapsed.
...@@ -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,33 @@ static u8 ctrl_write (struct controller *ctlr_ptr, void *WPGBbar, u8 index, u8 c ...@@ -351,6 +351,33 @@ static u8 ctrl_write (struct controller *ctlr_ptr, void *WPGBbar, u8 index, u8 c
return (rc); return (rc);
} }
static u8 ctrl_read (struct controller *ctlr, void *base, u8 offset)
{
u8 rc;
switch (ctlr->ctlr_type) {
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 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 +476,7 @@ static u8 hpc_readcmdtoindex (u8 cmd, u8 index) ...@@ -449,7 +476,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,6 +518,7 @@ int ibmphp_hpc_readslot (struct slot * pslot, u8 cmd, u8 * pstatus) ...@@ -491,6 +518,7 @@ int ibmphp_hpc_readslot (struct slot * pslot, u8 cmd, u8 * pstatus)
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// map physical address to logical address // map physical address to logical address
//-------------------------------------------------------------------- //--------------------------------------------------------------------
if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4))
wpg_bbar = ioremap (ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE); wpg_bbar = ioremap (ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE);
//-------------------------------------------------------------------- //--------------------------------------------------------------------
...@@ -569,7 +597,11 @@ int ibmphp_hpc_readslot (struct slot * pslot, u8 cmd, u8 * pstatus) ...@@ -569,7 +597,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 +615,7 @@ int ibmphp_hpc_readslot (struct slot * pslot, u8 cmd, u8 * pstatus) ...@@ -583,7 +615,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 +658,13 @@ int ibmphp_hpc_writeslot (struct slot * pslot, u8 cmd) ...@@ -626,12 +658,13 @@ int ibmphp_hpc_writeslot (struct slot * pslot, u8 cmd)
//-------------------------------------------------------------------- //--------------------------------------------------------------------
// map physical address to logical address // map physical address to logical address
//-------------------------------------------------------------------- //--------------------------------------------------------------------
if ((ctlr_ptr->ctlr_type == 2) || (ctlr_ptr->ctlr_type == 4)) {
wpg_bbar = ioremap (ctlr_ptr->u.wpeg_ctlr.wpegbbar, WPG_I2C_IOREMAP_SIZE); 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 +701,10 @@ int ibmphp_hpc_writeslot (struct slot * pslot, u8 cmd) ...@@ -668,7 +701,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 +737,7 @@ void free_hpc_access (void) ...@@ -701,6 +737,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 +747,7 @@ void ibmphp_unlock_operations (void) ...@@ -710,6 +747,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,6 +772,9 @@ static void poll_hpc (void) ...@@ -734,6 +772,9 @@ 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);
...@@ -758,9 +799,9 @@ static void poll_hpc (void) ...@@ -758,9 +799,9 @@ static void poll_hpc (void)
} }
} }
} }
poll_state = POLL_SLOTS; ++poll_count;
poll_state = POLL_SLEEP;
break; break;
case POLL_SLOTS: case POLL_SLOTS:
list_for_each (pslotlist, &ibmphp_slot_head) { list_for_each (pslotlist, &ibmphp_slot_head) {
pslot = list_entry (pslotlist, struct slot, ibm_slot_list); pslot = list_entry (pslotlist, struct slot, ibm_slot_list);
...@@ -772,7 +813,6 @@ static void poll_hpc (void) ...@@ -772,7 +813,6 @@ static void poll_hpc (void)
|| (myslot.ext_status != pslot->ext_status)) || (myslot.ext_status != pslot->ext_status))
process_changeinstatus (pslot, &myslot); process_changeinstatus (pslot, &myslot);
} }
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())
...@@ -787,29 +827,31 @@ static void poll_hpc (void) ...@@ -787,29 +827,31 @@ static void poll_hpc (void)
} }
} }
++poll_count; ++poll_count;
if (poll_count >= POLL_LATCH_CNT) {
poll_count = 0;
poll_state = POLL_SLEEP; poll_state = POLL_SLEEP;
}
break; break;
case POLL_SLEEP: case POLL_SLEEP:
/* don't sleep with a lock on the hardware */ /* don't sleep with a lock on the hardware */
up (&semOperations); up (&semOperations);
long_delay (POLL_INTERVAL_SEC * HZ); long_delay (POLL_INTERVAL_SEC * HZ);
if (ibmphp_shutdown)
break;
down (&semOperations); down (&semOperations);
if (poll_count >= POLL_LATCH_CNT) {
poll_count = 0;
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 +1112,23 @@ void __exit ibmphp_hpc_stop_poll_thread (void) ...@@ -1070,15 +1112,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__);
} }
......
...@@ -920,6 +920,13 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno) ...@@ -920,6 +920,13 @@ 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) {
/* 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) {
bus = kmalloc (sizeof (struct bus_node), GFP_KERNEL); bus = kmalloc (sizeof (struct bus_node), GFP_KERNEL);
if (!bus) { if (!bus) {
err ("out of system memory \n"); err ("out of system memory \n");
...@@ -930,6 +937,13 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno) ...@@ -930,6 +937,13 @@ static int configure_bridge (struct pci_func **func_passed, u8 slotno)
bus->busno = sec_number; bus->busno = sec_number;
debug ("b4 adding new bus\n"); debug ("b4 adding new bus\n");
rc = add_new_bus (bus, io, mem, pfmem, func->busno); 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;
}
if (rc) { if (rc) {
if (rc == -ENOMEM) { if (rc == -ENOMEM) {
ibmphp_remove_bus (bus, func->busno); ibmphp_remove_bus (bus, func->busno);
...@@ -1579,7 +1593,6 @@ int ibmphp_unconfigure_card (struct slot **slot_cur, int the_end) ...@@ -1579,7 +1593,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 +1632,7 @@ int ibmphp_unconfigure_card (struct slot **slot_cur, int the_end) ...@@ -1619,6 +1632,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,6 +1652,7 @@ static int add_new_bus (struct bus_node *bus, struct resource_node *io, struct r ...@@ -1638,6 +1652,7 @@ 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 */
if (parent_busno != 0xFF) {
cur_bus = ibmphp_find_res_bus (parent_busno); cur_bus = ibmphp_find_res_bus (parent_busno);
if (!cur_bus) { if (!cur_bus) {
err ("strange, cannot find bus which is supposed to be at the system... something is terribly wrong...\n"); err ("strange, cannot find bus which is supposed to be at the system... something is terribly wrong...\n");
...@@ -1645,7 +1660,7 @@ static int add_new_bus (struct bus_node *bus, struct resource_node *io, struct r ...@@ -1645,7 +1660,7 @@ static int add_new_bus (struct bus_node *bus, struct resource_node *io, struct r
} }
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 +1713,7 @@ static u8 find_sec_number (u8 primary_busno, u8 slotno) ...@@ -1698,6 +1713,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 +1728,12 @@ static u8 find_sec_number (u8 primary_busno, u8 slotno) ...@@ -1712,7 +1728,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;
} }
......
This diff is collapsed.
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