PCI Hotplug fixes for 2.4.21-rc1
PATCH 1/1 PCI Hotplug fixes for 2.4.21-rc1
Hi,
Here are three PCI Hotplug fixes for 2.4.21-rc1. Two of them are for the IBM PCI Hotplug driver, fixing a bug that Arjan van de Ven pointed out in the last fix for this driver that was accepted, and another fix for some memory leaks that happen on the error paths. Both of these patches have been in the 2.5 tree for some time.
The other patch fixes the Compaq PCI Hotplug driver to work properly on machines with faster PCI busses (PCI-X).
Please pull from: bk://kernel.bkbits.net/gregkh/linux/marcelo-2.4
The raw patches will follow.
thanks,
greg k-h
drivers/hotplug/cpqphp.h | 194 +++++++++++++++++++++++++++++++++++ drivers/hotplug/cpqphp_core.c | 59 +++++++++- drivers/hotplug/cpqphp_ctrl.c | 147 ++++++++++++++------------- drivers/hotplug/ibmphp_ebda.c | 228 +++++++++++++----------------------------- 4 files changed, 394 insertions(+), 234 deletions(-)
-----
[email protected], 2003-05-02 11:35:50-07:00, [email protected]
[PATCH] IBM PCI Hotplug: fix up a number of memory leaks on the error path
drivers/hotplug/ibmphp_ebda.c | 144 ++++++++++++++++++------------------------ 1 files changed, 65 insertions(+), 79 deletions(-)
------
[email protected], 2003-05-02 11:35:34-07:00, [email protected]
[PATCH] IBM PCI Hotplug: fix up a lot of memory allocations and leaks just to figure out a slot name.
drivers/hotplug/ibmphp_ebda.c | 84 +++--------------------------------------- 1 files changed, 6 insertions(+), 78 deletions(-)
------
[email protected], 2003-05-02 11:35:06-07:00, [email protected]
[PATCH] PCI Hotplug: cpqphp 66/100/133MHz PCI-X support
Push file://home/greg/linux/BK/gregkh-2.4 -> file://home/greg/linux/BK/bleed-2.4
drivers/hotplug/cpqphp.h | 194 +++++++++++++++++++++++++++++++++++++++++- drivers/hotplug/cpqphp_core.c | 59 +++++++++++- drivers/hotplug/cpqphp_ctrl.c | 147 +++++++++++++++++-------------- 3 files changed, 323 insertions(+), 77 deletions(-)
------
PATCH 1/1 PCI Hotplug fixes for 2.4.21-rc1
ChangeSet 1.1142, 2003/05/02 11:35:06-07:00, [email protected]
[PATCH] PCI Hotplug: cpqphp 66/100/133MHz PCI-X support
drivers/hotplug/cpqphp.h | 194 +++++++++++++++++++++++++++++++++++++++++- drivers/hotplug/cpqphp_core.c | 59 +++++++++++- drivers/hotplug/cpqphp_ctrl.c | 147 +++++++++++++++++-------------- 3 files changed, 323 insertions(+), 77 deletions(-)
drivers/hotplug/cpqphp.h +190 -4
@@ -30,7 +30,7 @@#include "pci_hotplug.h" #include <asm/io.h> /* for read? and write? functions */ - +#include <linux/delay.h> /* for delays */ #if !defined(CONFIG_HOTPLUG_PCI_COMPAQ_MODULE )#define MY_NAME "cpqphp.o"
@@ -145,6 +145,10 @@u8 reserved11;/* 0x2b */ u8 slot_SERR;/* 0x2c */ u8 slot_power;/* 0x2d */ +u8 reserved12;/* 0x2e */ +u8 reserved13;/* 0x2f */ +u8 next_curr_freq;/* 0x30 */ +u8 reset_freq_mode;/* 0x31 */ } __attribute__ ((packed));/* offsets to the controller registers based on the above structure layout */
@@ -172,6 +176,8 @@CTRL_RESERVED11 = offsetof(struct ctrl_reg , reserved11),SLOT_SERR = offsetof(struct ctrl_reg , slot_SERR),SLOT_POWER = offsetof(struct ctrl_reg , slot_power), +NEXT_CURR_FREQ = offsetof(struct ctrl_reg , next_curr_freq), + RESET_FREQ_MODE = offsetof(struct ctrl_reg, reset_freq_mode), }; struct hrt {
@@ -345,6 +351,7 @@#define PCI_SUB_HPC_ID2 0xA2F8#define PCI_SUB_HPC_ID3 0xA2F9#define PCI_SUB_HPC_ID_INTC 0xA2FA +#define PCI_SUB_HPC_ID4 0xA2FD#define INT_BUTTON_IGNORE 0#define INT_PRESENCE_ON 1
@@ -460,6 +467,7 @@extern void cpqhp_destroy_resource_list (struct resource_lists * resources);extern int cpqhp_configure_device (struct controller * ctrl,struct pci_func * func);extern int cpqhp_unconfigure_device (struct pci_func * func); +extern struct slot *cpqhp_find_slot (struct controller *ctrl,u8 device);/* Global variables */
@@ -473,8 +481,6 @@ -/* inline functions */ -/* Inline functions to check the sanity of a pointer that is passed to us */ static inline int slot_paranoia_check (struct slot *slot,const char *function)
@@ -588,6 +594,7 @@u32 led_control; led_control =readl (ctrl->hpc_reg +LED_CONTROL ); + led_control &= ~(0x0101L << slot); led_control |= (0x0001L << slot);writel (led_control, ctrl->hpc_reg +LED_CONTROL ); }
@@ -629,14 +636,62 @@ } +/* +* get_controller_speed - find the current frequency/mode of controller. +* +* @ctrl: controller to get frequency/mode for. +* +* Returns controller speed. +* +*/ static inline u8 get_controller_speed (struct controller *ctrl) { +u8 curr_freq;u16 misc; +if (ctrl->pcix_support) { + curr_freq =readb (ctrl->hpc_reg +NEXT_CURR_FREQ ); +if ((curr_freq &0xB0 ) ==0xB0 ) +return PCI_SPEED_133MHz_PCIX; +if ((curr_freq &0xA0 ) ==0xA0 ) +return PCI_SPEED_100MHz_PCIX; +if ((curr_freq &0x90 ) ==0x90 ) +return PCI_SPEED_66MHz_PCIX; +if (curr_freq &0x10 ) +return PCI_SPEED_66MHz; + +return PCI_SPEED_33MHz; + } + misc =readw (ctrl->hpc_reg +MISC );return (misc &0x0800 ) ? PCI_SPEED_66MHz : PCI_SPEED_33MHz; } +/* +* get_adapter_speed - find the max supported frequency/mode of adapter. +* +* @ctrl: hotplug controller. +* @hp_slot: hotplug slot where adapter is installed. +* +* Returns adapter speed. +* +*/ +static inline u8 get_adapter_speed (struct controller *ctrl,u8 hp_slot) +{ +u32 temp_dword =readl (ctrl->hpc_reg +NON_INT_INPUT ); +dbg ("slot: %d, PCIXCAP: %8x\n" , hp_slot, temp_dword); +if (ctrl->pcix_support) { +if (temp_dword & (0x10000 << hp_slot)) +return PCI_SPEED_133MHz_PCIX; +if (temp_dword & (0x100 << hp_slot)) +return PCI_SPEED_66MHz_PCIX; + } + +if (temp_dword & (0x01 << hp_slot)) +return PCI_SPEED_66MHz; + +return PCI_SPEED_33MHz; +}static inline void enable_slot_power (struct controller *ctrl,u8 slot) {
@@ -744,5 +799,136 @@ return retval; } -#endif +/** +* set_controller_speed - set the frequency and/or mode of a specific +* controller segment. +* +* @ctrl: controller to change frequency/mode for. +* @adapter_speed: the speed of the adapter we want to match. +* @hp_slot: the slot number where the adapter is installed. +* +* Returns 0 if we successfully change frequency and/or mode to match the +* adapter speed. +* +*/ +static inline u8 set_controller_speed (struct controller *ctrl,u8 adapter_speed,u8 hp_slot) +{ +struct slot *slot; +u8 reg; +u8 slot_power =readb (ctrl->hpc_reg +SLOT_POWER ); +u16 reg16; +u32 leds =readl (ctrl->hpc_reg +LED_CONTROL ); + +if (ctrl->speed == adapter_speed) +return 0 ; + +/* We don't allow freq/mode changes if we find another adapter running +* in another slot on this controller */ +for (slot = ctrl->slot; slot; slot = slot->next) { +if (slot->device == (hp_slot + ctrl->slot_device_offset)) +continue ; +if (!slot->hotplug_slot && !slot->hotplug_slot->info) +continue ; +if (slot->hotplug_slot->info->adapter_status ==0 ) +continue ; +/* If another adapter is running on the same segment but at a +* lower speed/mode, we allow the new adapter to function at +* this rate if supported */ +if (ctrl->speed < adapter_speed) +return 0 ; + +return 1 ; + } + +/* If the controller doesn't support freq/mode changes and the +* controller is running at a higher mode, we bail */ +if ((ctrl->speed > adapter_speed) && (!ctrl->pcix_speed_capability)) +return 1 ; + +/* But we allow the adapter to run at a lower rate if possible */ +if ((ctrl->speed < adapter_speed) && (!ctrl->pcix_speed_capability)) +return 0 ; + +/* We try to set the max speed supported by both the adapter and +* controller */ +if (ctrl->speed_capability < adapter_speed) { +if (ctrl->speed == ctrl->speed_capability) +return 0 ; + adapter_speed = ctrl->speed_capability; + } + +writel (0x0L , ctrl->hpc_reg +LED_CONTROL ); +writeb (0x00 , ctrl->hpc_reg +SLOT_ENABLE ); + +set_SOGO (ctrl); +wait_for_ctrl_irq (ctrl); + +if (adapter_speed != PCI_SPEED_133MHz_PCIX) + reg =0xF5 ; +else + reg =0xF4 ; +pci_write_config_byte (ctrl->pci_dev,0x41 , reg); + + reg16 =readw (ctrl->hpc_reg +NEXT_CURR_FREQ ); + reg16 &= ~0x000F ; +switch (adapter_speed) { +case (PCI_SPEED_133MHz_PCIX): + reg =0x75 ; + reg16 |=0xB ; +break ; +case (PCI_SPEED_100MHz_PCIX): + reg =0x74 ; + reg16 |=0xA ; +break ; +case (PCI_SPEED_66MHz_PCIX): + reg =0x73 ; + reg16 |=0x9 ; +break ; +case (PCI_SPEED_66MHz): + reg =0x73 ; + reg16 |=0x1 ; +break ; +default :/* 33MHz PCI 2.2 */ + reg =0x71 ; +break ; + + } + reg16 |=0xB <<12 ; +writew (reg16, ctrl->hpc_reg +NEXT_CURR_FREQ ); + +mdelay (5 ); + +/* Reenable interrupts */ +writel (0 , ctrl->hpc_reg +INT_MASK ); + +pci_write_config_byte (ctrl->pci_dev,0x41 , reg); + +/* Restart state machine */ + reg = ~0xF ; +pci_read_config_byte (ctrl->pci_dev,0x43 , ®); +pci_write_config_byte (ctrl->pci_dev,0x43 , reg); + +/* Only if mode change...*/ +if (((ctrl->speed == PCI_SPEED_66MHz) && (adapter_speed == PCI_SPEED_66MHz_PCIX)) || + ((ctrl->speed == PCI_SPEED_66MHz_PCIX) && (adapter_speed == PCI_SPEED_66MHz))) +set_SOGO (ctrl); + +wait_for_ctrl_irq (ctrl); +mdelay (1100 ); + +/* Restore LED/Slot state */ +writel (leds, ctrl->hpc_reg +LED_CONTROL ); +writeb (slot_power, ctrl->hpc_reg +SLOT_ENABLE ); + +set_SOGO (ctrl); +wait_for_ctrl_irq (ctrl); + + ctrl->speed = adapter_speed; + slot =cpqhp_find_slot (ctrl, hp_slot + ctrl->slot_device_offset); +info ("Successfully changed frequency/mode for adapter in slot %d\n" , + slot->number); +return 0 ; +} + +#endif
drivers/hotplug/cpqphp_core.c +52 -7
103 lines not on this page · raw message
drivers/hotplug/cpqphp_ctrl.c +81 -66
236 lines not on this page · raw message
ChangeSet 1.1143, 2003/05/02 11:35:34-07:00, [email protected]
[PATCH] IBM PCI Hotplug: fix up a lot of memory allocations and leaks just to figure out a slot name.
drivers/hotplug/ibmphp_ebda.c | 84 +++--------------------------------------- 1 files changed, 6 insertions(+), 78 deletions(-)
drivers/hotplug/ibmphp_ebda.c +6 -78
@@ -65,8 +65,6 @@static LIST_HEAD (opt_lo_head);static void *io_mem; -char *chassis_str, *rxe_str, *str; -/* Local functions */ static int ebda_rsrc_controller (void );static int ebda_rsrc_rsrc (void );
@@ -591,39 +589,6 @@return 0 ; } -static char *convert_2digits_to_char (int var) -{ -int bit; -char *str1; - - str = (char *)kmalloc (3 ,GFP_KERNEL ); -if (!str) -return NULL ; -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 *)kmalloc (2 ,GFP_KERNEL ); -if (!str1) { -break ; - } -memset (str,0 ,3 ); - *str1 = (char )(bit +48 ); -strncpy (str, str1,1 ); -memset (str1,0 ,3 ); - *str1 = (char )((var %10 ) +48 ); -strcat (str, str1); -kfree (str1); -return str; - } -kfree (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
@@ -708,7 +673,7 @@ {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; +static char str[30 ];int which =0 ;/* rxe = 1, chassis = 0 */ u8 number =1 ;/* either chassis or rxe # */ u8 first_slot =1 ;
@@ -722,19 +687,7 @@ 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" ); +memset (str,0 ,sizeof (str));if (rio_table_ptr) {if (rio_table_ptr->ver_num ==3 ) {
@@ -779,31 +732,10 @@ } } -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 ; +sprintf (str,"%s%dslot%d" , + which ==0 ?"chassis" :"rxe" , + number, slot_num - first_slot +1 ); +return str; }static struct pci_driver ibmphp_driver;
@@ -1079,10 +1011,6 @@ 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); }
ChangeSet 1.1144, 2003/05/02 11:35:50-07:00, [email protected]
[PATCH] IBM PCI Hotplug: fix up a number of memory leaks on the error path
drivers/hotplug/ibmphp_ebda.c | 144 ++++++++++++++++++------------------------ 1 files changed, 65 insertions(+), 79 deletions(-)
drivers/hotplug/ibmphp_ebda.c +65 -79
@@ -70,17 +70,6 @@static int ebda_rsrc_rsrc (void );static int ebda_rio_table (void ); -static struct slot *alloc_ibm_slot (void ) -{ -struct slot *slot; - - slot =kmalloc (sizeof (struct slot ),GFP_KERNEL ); -if (!slot) -return NULL ; -memset (slot,0 ,sizeof (*slot)); -return slot; -} -static struct ebda_hpc_list *__init alloc_ebda_hpc_list (void ) {struct ebda_hpc_list *list;
@@ -757,8 +746,7 @@struct ebda_hpc_slot *slot_ptr;struct bus_info *bus_info_ptr1, *bus_info_ptr2;int rc; -int retval; -struct slot *slot_cur; +struct slot *tmp_slot;struct list_head *list; addr = hpc_list_ptr->phys_addr;
@@ -783,8 +771,8 @@/* init hpc structure */ hpc_ptr =alloc_ebda_hpc (slot_num, bus_num);if (!hpc_ptr ) { -iounmap (io_mem); -return -ENOMEM ; + rc = -ENOMEM ; + goto error_no_hpc; } hpc_ptr->ctlr_id = ctlr_id; hpc_ptr->ctlr_relative_id = ctlr;
@@ -810,8 +798,8 @@if (!bus_info_ptr2) { bus_info_ptr1 = (struct bus_info *)kmalloc (sizeof (struct bus_info ),GFP_KERNEL );if (!bus_info_ptr1) { -iounmap (io_mem); -return -ENOMEM ; + rc = -ENOMEM ; + goto error_no_hp_slot; }memset (bus_info_ptr1,0 ,sizeof (struct bus_info )); bus_info_ptr1->slot_min = slot_ptr->slot_num;
@@ -871,16 +859,20 @@ hpc_ptr->u.pci_ctlr.dev_fun =readb (io_mem + addr +1 ); hpc_ptr->irq =readb (io_mem + addr +2 ); 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); +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 ;case 0 : hpc_ptr->u.isa_ctlr.io_start =readw (io_mem + addr); 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" ); +if (!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" )) { + rc = -ENODEV ; + goto error_no_hp_slot; + } hpc_ptr->irq =readb (io_mem + addr +4 ); addr +=5 ;break ;
@@ -893,8 +885,8 @@ addr +=6 ;break ;default : -iounmap (io_mem); -return -ENODEV ; + rc = -ENODEV ; + goto error_no_hp_slot; }//reorganize chassis' linked list
@@ -910,91 +902,71 @@ hp_slot_ptr = (struct hotplug_slot *)kmalloc (sizeof (struct hotplug_slot ),GFP_KERNEL );if (!hp_slot_ptr) { -iounmap (io_mem); -return -ENOMEM ; + rc = -ENOMEM ; + goto error_no_hp_slot; }memset (hp_slot_ptr,0 ,sizeof (struct hotplug_slot )); hp_slot_ptr->info = (struct hotplug_slot_info *)kmalloc (sizeof (struct hotplug_slot_info ),GFP_KERNEL );if (!hp_slot_ptr->info) { -iounmap (io_mem); -kfree (hp_slot_ptr); -return -ENOMEM ; + rc = -ENOMEM ; + goto error_no_hp_info; }memset (hp_slot_ptr->info,0 ,sizeof (struct hotplug_slot_info )); hp_slot_ptr->name = (char *)kmalloc (30 ,GFP_KERNEL );if (!hp_slot_ptr->name) { -iounmap (io_mem); -kfree (hp_slot_ptr->info); -kfree (hp_slot_ptr); -return -ENOMEM ; + rc = -ENOMEM ; + goto error_no_hp_name; } - hp_slot_ptr->private =alloc_ibm_slot (); -if (!hp_slot_ptr->private) { -iounmap (io_mem); -kfree (hp_slot_ptr->name); -kfree (hp_slot_ptr->info); -kfree (hp_slot_ptr); -return -ENOMEM ; + tmp_slot =kmalloc (sizeof (struct slot ),GFP_KERNEL ); +if (!tmp_slot) { + rc = -ENOMEM ; + goto error_no_slot; } +memset (tmp_slot,0 ,sizeof (*tmp_slot)); - ((struct slot *)hp_slot_ptr->private)->flag = TRUE; + tmp_slot->flag = TRUE; - ((struct slot *) hp_slot_ptr->private)->capabilities = hpc_ptr->slots[index].slot_cap; + tmp_slot->capabilities = hpc_ptr->slots[index].slot_cap;if ((hpc_ptr->slots[index].slot_cap &EBDA_SLOT_133_MAX ) ==EBDA_SLOT_133_MAX ) - ((struct slot *) hp_slot_ptr->private)->supported_speed =3 ; + tmp_slot->supported_speed =3 ;else if ((hpc_ptr->slots[index].slot_cap &EBDA_SLOT_100_MAX ) ==EBDA_SLOT_100_MAX ) - ((struct slot *) hp_slot_ptr->private)->supported_speed =2 ; + tmp_slot->supported_speed =2 ;else if ((hpc_ptr->slots[index].slot_cap &EBDA_SLOT_66_MAX ) ==EBDA_SLOT_66_MAX ) - ((struct slot *) hp_slot_ptr->private)->supported_speed =1 ; + tmp_slot->supported_speed =1 ;if ((hpc_ptr->slots[index].slot_cap &EBDA_SLOT_PCIX_CAP ) ==EBDA_SLOT_PCIX_CAP ) - ((struct slot *) hp_slot_ptr->private)->supported_bus_mode =1 ; + tmp_slot->supported_bus_mode =1 ;else - ((struct slot *) hp_slot_ptr->private)->supported_bus_mode =0 ; + tmp_slot->supported_bus_mode =0 ; - ((struct slot *) hp_slot_ptr->private)->bus = hpc_ptr->slots[index].slot_bus_num; + tmp_slot->bus = hpc_ptr->slots[index].slot_bus_num; bus_info_ptr1 =ibmphp_find_same_bus_num (hpc_ptr->slots[index].slot_bus_num);if (!bus_info_ptr1) { -iounmap (io_mem); -kfree (hp_slot_ptr->name); -kfree (hp_slot_ptr->info); -kfree (hp_slot_ptr->private); -kfree (hp_slot_ptr); -return -ENODEV ; + rc = -ENODEV ; + goto error; } - ((struct slot *) hp_slot_ptr->private)->bus_on = bus_info_ptr1; + tmp_slot->bus_on = bus_info_ptr1; bus_info_ptr1 =NULL ; - ((struct slot *) hp_slot_ptr->private)->ctrl = hpc_ptr; + tmp_slot->ctrl = hpc_ptr; + tmp_slot->ctlr_index = hpc_ptr->slots[index].ctl_index; + tmp_slot->number = hpc_ptr->slots[index].slot_num; + tmp_slot->hotplug_slot = hp_slot_ptr; + + hp_slot_ptr->private = tmp_slot; - ((struct slot *) hp_slot_ptr->private)->ctlr_index = hpc_ptr->slots[index].ctl_index; - ((struct slot *) hp_slot_ptr->private)->number = hpc_ptr->slots[index].slot_num; - - ((struct slot *) hp_slot_ptr->private)->hotplug_slot = hp_slot_ptr; rc =ibmphp_hpc_fillhpslotinfo (hp_slot_ptr); -if (rc) { -iounmap (io_mem); -kfree (hp_slot_ptr->name); -kfree (hp_slot_ptr->info); -kfree (hp_slot_ptr->private); -kfree (hp_slot_ptr); -return rc; - } +if (rc) + goto error; rc =ibmphp_init_devno ((struct slot **) &hp_slot_ptr->private); -if (rc) { -iounmap (io_mem); -kfree (hp_slot_ptr->name); -kfree (hp_slot_ptr->info); -kfree (hp_slot_ptr->private); -kfree (hp_slot_ptr); -return rc; - } +if (rc) + goto error; hp_slot_ptr->ops = &ibmphp_hotplug_slot_ops;// end of registering ibm slot with hotplug core
@@ -1008,15 +980,29 @@ }/* each hpc */ list_for_each (list, &ibmphp_slot_head) { - slot_cur = list_entry (list, struct slot, ibm_slot_list); + tmp_slot = list_entry (list, struct slot, ibm_slot_list); -snprintf (slot_cur->hotplug_slot->name,30 ,"%s" ,create_file_name (slot_cur)); -pci_hp_register (slot_cur->hotplug_slot); +snprintf (tmp_slot->hotplug_slot->name,30 ,"%s" ,create_file_name (tmp_slot)); +pci_hp_register (tmp_slot->hotplug_slot); }print_ebda_hpc ();print_ibm_slot ();return 0 ; + +error: +kfree (hp_slot_ptr->private); +error_no_slot: +kfree (hp_slot_ptr->name); +error_no_hp_name: +kfree (hp_slot_ptr->info); +error_no_hp_info: +kfree (hp_slot_ptr); +error_no_hp_slot: +free_ebda_hpc (hpc_ptr); +error_no_hpc: +iounmap (io_mem); +return rc; }/*