ChangeSet 1.1022.1.1, 2003/02/24 16:24:48-08:00, greg@kroah.com [PATCH] IBM PCI Hotplug: Clean up the error handling logic for a number of functions, and fix a locking mess. diff -Nru a/drivers/hotplug/ibmphp.h b/drivers/hotplug/ibmphp.h --- a/drivers/hotplug/ibmphp.h Mon Feb 24 17:16:04 2003 +++ b/drivers/hotplug/ibmphp.h Mon Feb 24 17:16:04 2003 @@ -761,6 +761,7 @@ extern int ibmphp_init_devno (struct slot **); /* This function is called from EBDA, so we need it not be static */ extern int ibmphp_disable_slot (struct hotplug_slot *); /* This function is called from HPC, so we need it to not be static */ +extern int ibmphp_do_disable_slot (struct slot *slot_cur); 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_unconfigure_card (struct slot **, int); diff -Nru a/drivers/hotplug/ibmphp_core.c b/drivers/hotplug/ibmphp_core.c --- a/drivers/hotplug/ibmphp_core.c Mon Feb 24 17:16:04 2003 +++ b/drivers/hotplug/ibmphp_core.c Mon Feb 24 17:16:04 2003 @@ -1274,7 +1274,6 @@ int rc, i, rcpr; struct slot *slot_cur; u8 function; - u8 faulted = 0; struct pci_func *tmp_func; ibmphp_lock_operations (); @@ -1284,16 +1283,7 @@ if ((rc = validate (slot_cur, ENABLE))) { err ("validate function failed \n"); - attn_off (slot_cur); /* need to turn off if was blinking b4 */ - attn_on (slot_cur); - rc = slot_update (&slot_cur); - if (rc) { - ibmphp_unlock_operations(); - return rc; - } - ibmphp_update_slot_info (slot_cur); - ibmphp_unlock_operations (); - return rc; + goto error_nopower; } attn_LED_blink (slot_cur); @@ -1301,10 +1291,7 @@ rc = set_bus (slot_cur); if (rc) { err ("was not able to set the bus \n"); - attn_off (slot_cur); - attn_on (slot_cur); - ibmphp_unlock_operations (); - return -ENODEV; + goto error_nopower; } /*-----------------debugging------------------------------*/ @@ -1314,18 +1301,12 @@ rc = check_limitations (slot_cur); if (rc) { - err ("Adding this card exceeds the limitations of this bus. \n"); - err ("(i.e., >1 133MHz cards running on same bus, or >2 66 PCI cards running on same bus \n. Try hot-adding into another bus \n"); - attn_off (slot_cur); - attn_on (slot_cur); - - if (slot_update (&slot_cur)) { - ibmphp_unlock_operations (); - return -ENODEV; - } - ibmphp_update_slot_info (slot_cur); - ibmphp_unlock_operations (); - return -EINVAL; + err ("Adding this card exceeds the limitations of this bus.\n"); + err ("(i.e., >1 133MHz cards running on same bus, or " + ">2 66 PCI cards running on same bus\n."); + err ("Try hot-adding into another bus \n"); + rc = -EINVAL; + goto error_nopower; } rc = power_on (slot_cur); @@ -1338,8 +1319,8 @@ if (slot_update (&slot_cur)) { attn_off (slot_cur); attn_on (slot_cur); - ibmphp_unlock_operations (); - return -ENODEV; + rc = -ENODEV; + goto exit; } /* Check to see the error of why it failed */ if ((SLOT_POWER (slot_cur->status)) && !(SLOT_PWRGD (slot_cur->status))) @@ -1352,8 +1333,7 @@ print_card_capability (slot_cur); } ibmphp_update_slot_info (slot_cur); - ibmphp_unlock_operations (); - return rc; + goto exit; } debug ("after power_on\n"); /*-----------------------debugging---------------------------*/ @@ -1362,61 +1342,32 @@ /*----------------------------------------------------------*/ rc = slot_update (&slot_cur); - if (rc) { - attn_off (slot_cur); - attn_on (slot_cur); - rcpr = power_off (slot_cur); - if (rcpr) { - ibmphp_unlock_operations (); - return rcpr; - } - ibmphp_unlock_operations (); - return rc; - } + if (rc) + goto error_power; + rc = -EINVAL; if (SLOT_POWER (slot_cur->status) && !(SLOT_PWRGD (slot_cur->status))) { - faulted = 1; err ("power fault occured trying to power up... \n"); - } else if (SLOT_POWER (slot_cur->status) && (SLOT_BUS_SPEED (slot_cur->status))) { - faulted = 1; + goto error_power; + } + if (SLOT_POWER (slot_cur->status) && (SLOT_BUS_SPEED (slot_cur->status))) { err ("bus speed mismatch occured. please check current bus speed and card capability \n"); print_card_capability (slot_cur); + goto error_power; } /* Don't think this case will happen after above checks... but just in case, for paranoia sake */ - else if (!(SLOT_POWER (slot_cur->status))) { + if (!(SLOT_POWER (slot_cur->status))) { err ("power on failed... \n"); - faulted = 1; - } - if (faulted) { - attn_off (slot_cur); /* need to turn off b4 on */ - attn_on (slot_cur); - rcpr = power_off (slot_cur); - if (rcpr) { - ibmphp_unlock_operations (); - return rcpr; - } - - if (slot_update (&slot_cur)) { - ibmphp_unlock_operations (); - return -ENODEV; - } - ibmphp_update_slot_info (slot_cur); - ibmphp_unlock_operations (); - return -EINVAL; + goto error_power; } slot_cur->func = (struct pci_func *) kmalloc (sizeof (struct pci_func), GFP_KERNEL); - if (!slot_cur->func) { /* We cannot do update_slot_info here, since no memory for kmalloc n.e.ways, and update_slot_info allocates some */ + if (!slot_cur->func) { + /* We cannot do update_slot_info here, since no memory for + * kmalloc n.e.ways, and update_slot_info allocates some */ err ("out of system memory \n"); - attn_off (slot_cur); - attn_on (slot_cur); - rcpr = power_off (slot_cur); - if (rcpr) { - ibmphp_unlock_operations (); - return rcpr; - } - ibmphp_unlock_operations (); - return -ENOMEM; + rc = -ENOMEM; + goto error_power; } memset (slot_cur->func, 0, sizeof (struct pci_func)); slot_cur->func->busno = slot_cur->bus; @@ -1431,21 +1382,10 @@ ibmphp_unconfigure_card (&slot_cur, 1); /* true because don't need to actually deallocate resources, just remove references */ debug ("after unconfigure_card\n"); slot_cur->func = NULL; - attn_off (slot_cur); /* need to turn off in case was blinking */ - attn_on (slot_cur); - rcpr = power_off (slot_cur); - if (rcpr) { - ibmphp_unlock_operations (); - return rcpr; - } - if (slot_update (&slot_cur)) { - ibmphp_unlock_operations(); - return -ENODEV; - } - ibmphp_update_slot_info (slot_cur); - ibmphp_unlock_operations (); - return -ENOMEM; + rc = -ENOMEM; + goto error_power; } + function = 0x00; do { tmp_func = ibm_slot_find (slot_cur->bus, slot_cur->func->device, function++); @@ -1455,13 +1395,36 @@ attn_off (slot_cur); if (slot_update (&slot_cur)) { - ibmphp_unlock_operations (); - return -EFAULT; + rc = -EFAULT; + goto exit; } ibmphp_print_test (); rc = ibmphp_update_slot_info (slot_cur); +exit: ibmphp_unlock_operations(); return rc; + +error_nopower: + attn_off (slot_cur); /* need to turn off if was blinking b4 */ + attn_on (slot_cur); +error_cont: + rcpr = slot_update (&slot_cur); + if (rcpr) { + rc = rcpr; + goto exit; + } + ibmphp_update_slot_info (slot_cur); + goto exit; + +error_power: + attn_off (slot_cur); /* need to turn off if was blinking b4 */ + attn_on (slot_cur); + rcpr = power_off (slot_cur); + if (rcpr) { + rc = rcpr; + goto exit; + } + goto error_cont; } /************************************************************** @@ -1472,45 +1435,34 @@ **************************************************************/ int ibmphp_disable_slot (struct hotplug_slot *hotplug_slot) { + struct slot *slot = hotplug_slot->private; + int rc; + + ibmphp_lock_operations(); + rc = ibmphp_do_disable_slot(slot); + ibmphp_unlock_operations(); + return rc; +} + +int ibmphp_do_disable_slot (struct slot *slot_cur) +{ int rc; - struct slot *slot_cur = (struct slot *) hotplug_slot->private; u8 flag; int parm = 0; debug ("DISABLING SLOT... \n"); - if (slot_cur == NULL) { - ibmphp_unlock_operations (); - return -ENODEV; - } - - if (slot_cur->ctrl == NULL) { - ibmphp_unlock_operations (); + if ((slot_cur == NULL) || (slot_cur->ctrl == NULL)) { return -ENODEV; } - flag = slot_cur->flag; /* to see if got here from polling */ - - if (flag) - ibmphp_lock_operations (); - + flag = slot_cur->flag; slot_cur->flag = TRUE; if (flag == TRUE) { rc = validate (slot_cur, DISABLE); /* checking if powered off already & valid slot # */ - if (rc) { - /* Need to turn off if was blinking b4 */ - attn_off (slot_cur); - attn_on (slot_cur); - if (slot_update (&slot_cur)) { - ibmphp_unlock_operations (); - return -EFAULT; - } - - ibmphp_update_slot_info (slot_cur); - ibmphp_unlock_operations (); - return rc; - } + if (rc) + goto error; } attn_LED_blink (slot_cur); @@ -1519,10 +1471,8 @@ slot_cur->func = (struct pci_func *) kmalloc (sizeof (struct pci_func), GFP_KERNEL); if (!slot_cur->func) { err ("out of system memory \n"); - attn_off (slot_cur); - attn_on (slot_cur); - ibmphp_unlock_operations (); - return -ENOMEM; + rc = -ENOMEM; + goto error; } memset (slot_cur->func, 0, sizeof (struct pci_func)); slot_cur->func->busno = slot_cur->bus; @@ -1531,11 +1481,9 @@ if ((rc = ibm_unconfigure_device (slot_cur->func))) { err ("removing from kernel failed... \n"); - err ("Please check to see if it was statically linked or is in use otherwise. (perhaps the driver is not 'hot-removable')\n"); - attn_off (slot_cur); - attn_on (slot_cur); - ibmphp_unlock_operations (); - return rc; + err ("Please check to see if it was statically linked or is " + "in use otherwise. (perhaps the driver is not 'hot-removable')\n"); + goto error; } /* If we got here from latch suddenly opening on operating card or @@ -1554,43 +1502,34 @@ debug ("in disable_slot. after unconfigure_card\n"); if (rc) { err ("could not unconfigure card.\n"); - attn_off (slot_cur); /* need to turn off if was blinking b4 */ - attn_on (slot_cur); - - if (slot_update (&slot_cur)) { - ibmphp_unlock_operations (); - return -EFAULT; - } - - if (flag) - ibmphp_update_slot_info (slot_cur); - ibmphp_unlock_operations (); - return -EFAULT; + goto error; } - rc = ibmphp_hpc_writeslot (hotplug_slot->private, HPC_SLOT_OFF); - if (rc) { - attn_off (slot_cur); - attn_on (slot_cur); - if (slot_update (&slot_cur)) { - ibmphp_unlock_operations (); - return -EFAULT; - } - - ibmphp_update_slot_info (slot_cur); - ibmphp_unlock_operations (); - return rc; - } + rc = ibmphp_hpc_writeslot (slot_cur, HPC_SLOT_OFF); + if (rc) + goto error; attn_off (slot_cur); - if (slot_update (&slot_cur)) { - ibmphp_unlock_operations (); - return -EFAULT; - } + rc = slot_update (&slot_cur); + if (rc) + goto exit; + rc = ibmphp_update_slot_info (slot_cur); ibmphp_print_test (); - ibmphp_unlock_operations(); +exit: return rc; + +error: + /* Need to turn off if was blinking b4 */ + attn_off (slot_cur); + attn_on (slot_cur); + if (slot_update (&slot_cur)) { + rc = -EFAULT; + goto exit; + } + if (flag) + ibmphp_update_slot_info (slot_cur); + goto exit; } struct hotplug_slot_ops ibmphp_hotplug_slot_ops = { @@ -1622,6 +1561,7 @@ debug ("after ebda hpc \n"); ibmphp_free_ebda_pci_rsrc_queue (); debug ("after ebda pci rsrc \n"); + kfree (ibmphp_pci_bus); } static int __init ibmphp_init (void) @@ -1637,13 +1577,15 @@ ibmphp_pci_bus = kmalloc (sizeof (*ibmphp_pci_bus), GFP_KERNEL); if (!ibmphp_pci_bus) { err ("out of memory\n"); - return -ENOMEM; + rc = -ENOMEM; + goto exit; } bus = ibmphp_find_bus (0); if (!bus) { err ("Can't find the root pci bus, can not continue\n"); - return -ENODEV; + rc -ENODEV; + goto error; } memcpy (ibmphp_pci_bus, bus, sizeof (*ibmphp_pci_bus)); @@ -1654,39 +1596,39 @@ for (i = 0; i < 16; i++) irqs[i] = 0; - if ((rc = ibmphp_access_ebda ())) { - ibmphp_unload (); - return rc; - } + if ((rc = ibmphp_access_ebda ())) + goto error; debug ("after ibmphp_access_ebda ()\n"); - if ((rc = ibmphp_rsrc_init ())) { - ibmphp_unload (); - return rc; - } + if ((rc = ibmphp_rsrc_init ())) + goto error; debug ("AFTER Resource & EBDA INITIALIZATIONS\n"); max_slots = get_max_slots (); - if ((rc = ibmphp_register_pci ())) { - ibmphp_unload (); - return rc; - } + if ((rc = ibmphp_register_pci ())) + goto error; if (init_ops ()) { - ibmphp_unload (); - return -ENODEV; + rc = -ENODEV; + goto error; } + ibmphp_print_test (); if ((rc = ibmphp_hpc_start_poll_thread ())) { - ibmphp_unload (); - return -ENODEV; + goto error; } - /* if no NVRAM module selected, lock ourselves into memory with a - * module count of -1 so that no one can unload us. */ + /* lock ourselves into memory with a module + * count of -1 so that no one can unload us. */ MOD_DEC_USE_COUNT; - return 0; + +exit: + return rc; + +error: + ibmphp_unload (); + goto exit; } static void __exit ibmphp_exit (void) diff -Nru a/drivers/hotplug/ibmphp_hpc.c b/drivers/hotplug/ibmphp_hpc.c --- a/drivers/hotplug/ibmphp_hpc.c Mon Feb 24 17:16:04 2003 +++ b/drivers/hotplug/ibmphp_hpc.c Mon Feb 24 17:16:04 2003 @@ -1063,7 +1063,7 @@ if (disable) { debug ("process_changeinstatus - disable slot\n"); pslot->flag = FALSE; - rc = ibmphp_disable_slot (pslot->hotplug_slot); + rc = ibmphp_do_disable_slot (pslot); } if (update || disable) {