diff options
Diffstat (limited to 'drivers/pci/hotplug/ibmphp_core.c')
| -rw-r--r-- | drivers/pci/hotplug/ibmphp_core.c | 180 | 
1 files changed, 93 insertions, 87 deletions
diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c index d934dd4fa87..f7b8684a773 100644 --- a/drivers/pci/hotplug/ibmphp_core.c +++ b/drivers/pci/hotplug/ibmphp_core.c @@ -49,7 +49,7 @@  int ibmphp_debug; -static int debug; +static bool debug;  module_param(debug, bool, S_IRUGO | S_IWUSR);  MODULE_PARM_DESC (debug, "Debugging mode enabled or not");  MODULE_LICENSE ("GPL"); @@ -58,7 +58,7 @@ MODULE_DESCRIPTION (DRIVER_DESC);  struct pci_bus *ibmphp_pci_bus;  static int max_slots; -static int irqs[16];    /* PIC mode IRQ's we're using so far (in case MPS +static int irqs[16];    /* PIC mode IRQs we're using so far (in case MPS  			 * tables don't provide default info for empty slots */  static int init_flag; @@ -71,20 +71,20 @@ static inline int get_max_adapter_speed (struct hotplug_slot *hs, u8 *value)  	return get_max_adapter_speed_1 (hs, value, 1);  }  */ -static inline int get_cur_bus_info(struct slot **sl)  +static inline int get_cur_bus_info(struct slot **sl)  {  	int rc = 1; -	struct slot * slot_cur = *sl; +	struct slot *slot_cur = *sl;  	debug("options = %x\n", slot_cur->ctrl->options); -	debug("revision = %x\n", slot_cur->ctrl->revision);	 +	debug("revision = %x\n", slot_cur->ctrl->revision); -	if (READ_BUS_STATUS(slot_cur->ctrl))  +	if (READ_BUS_STATUS(slot_cur->ctrl))  		rc = ibmphp_hpc_readslot(slot_cur, READ_BUSSTATUS, NULL); -	 -	if (rc)  + +	if (rc)  		return rc; -	   +  	slot_cur->bus_on->current_speed = CURRENT_BUS_SPEED(slot_cur->busstatus);  	if (READ_BUS_MODE(slot_cur->ctrl))  		slot_cur->bus_on->current_bus_mode = @@ -96,7 +96,7 @@ static inline int get_cur_bus_info(struct slot **sl)  			slot_cur->busstatus,  			slot_cur->bus_on->current_speed,  			slot_cur->bus_on->current_bus_mode); -	 +  	*sl = slot_cur;  	return 0;  } @@ -104,8 +104,8 @@ static inline int get_cur_bus_info(struct slot **sl)  static inline int slot_update(struct slot **sl)  {  	int rc; - 	rc = ibmphp_hpc_readslot(*sl, READ_ALLSTAT, NULL); -	if (rc)  +	rc = ibmphp_hpc_readslot(*sl, READ_ALLSTAT, NULL); +	if (rc)  		return rc;  	if (!init_flag)  		rc = get_cur_bus_info(sl); @@ -114,8 +114,8 @@ static inline int slot_update(struct slot **sl)  static int __init get_max_slots (void)  { -	struct slot * slot_cur; -	struct list_head * tmp; +	struct slot *slot_cur; +	struct list_head *tmp;  	u8 slot_count = 0;  	list_for_each(tmp, &ibmphp_slot_head) { @@ -172,7 +172,7 @@ int ibmphp_init_devno(struct slot **cur_slot)  			debug("(*cur_slot)->irq[3] = %x\n",  					(*cur_slot)->irq[3]); -			debug("rtable->exlusive_irqs = %x\n", +			debug("rtable->exclusive_irqs = %x\n",  					rtable->exclusive_irqs);  			debug("rtable->slots[loop].irq[0].bitmap = %x\n",  					rtable->slots[loop].irq[0].bitmap); @@ -271,7 +271,7 @@ static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 value)  			else  				rc = -ENODEV;  		} -	} else	 +	} else  		rc = -ENODEV;  	ibmphp_unlock_operations(); @@ -280,7 +280,7 @@ static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 value)  	return rc;  } -static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 * value) +static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value)  {  	int rc = -ENODEV;  	struct slot *pslot; @@ -288,7 +288,7 @@ static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 * value)  	debug("get_attention_status - Entry hotplug_slot[%lx] pvalue[%lx]\n",  					(ulong) hotplug_slot, (ulong) value); -         +  	ibmphp_lock_operations();  	if (hotplug_slot) {  		pslot = hotplug_slot->private; @@ -311,7 +311,7 @@ static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 * value)  	return rc;  } -static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 * value) +static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 *value)  {  	int rc = -ENODEV;  	struct slot *pslot; @@ -338,7 +338,7 @@ static int get_latch_status(struct hotplug_slot *hotplug_slot, u8 * value)  } -static int get_power_status(struct hotplug_slot *hotplug_slot, u8 * value) +static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value)  {  	int rc = -ENODEV;  	struct slot *pslot; @@ -364,7 +364,7 @@ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 * value)  	return rc;  } -static int get_adapter_present(struct hotplug_slot *hotplug_slot, u8 * value) +static int get_adapter_present(struct hotplug_slot *hotplug_slot, u8 *value)  {  	int rc = -ENODEV;  	struct slot *pslot; @@ -406,14 +406,14 @@ static int get_max_bus_speed(struct slot *slot)  	ibmphp_lock_operations();  	mode = slot->supported_bus_mode; -	speed = slot->supported_speed;  +	speed = slot->supported_speed;  	ibmphp_unlock_operations();  	switch (speed) {  	case BUS_SPEED_33:  		break;  	case BUS_SPEED_66: -		if (mode == BUS_MODE_PCIX)  +		if (mode == BUS_MODE_PCIX)  			speed += 0x01;  		break;  	case BUS_SPEED_100: @@ -433,7 +433,7 @@ static int get_max_bus_speed(struct slot *slot)  }  /* -static int get_max_adapter_speed_1(struct hotplug_slot *hotplug_slot, u8 * value, u8 flag) +static int get_max_adapter_speed_1(struct hotplug_slot *hotplug_slot, u8 *value, u8 flag)  {  	int rc = -ENODEV;  	struct slot *pslot; @@ -471,7 +471,7 @@ static int get_max_adapter_speed_1(struct hotplug_slot *hotplug_slot, u8 * value  	return rc;  } -static int get_bus_name(struct hotplug_slot *hotplug_slot, char * value) +static int get_bus_name(struct hotplug_slot *hotplug_slot, char *value)  {  	int rc = -ENODEV;  	struct slot *pslot = NULL; @@ -515,13 +515,13 @@ static int __init init_ops(void)  		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))  				return -1; -		if (slot_cur->bus_on->current_speed == 0xFF)  -			if (get_cur_bus_info(&slot_cur))  +		if (slot_cur->bus_on->current_speed == 0xFF) +			if (get_cur_bus_info(&slot_cur))  				return -1;  		get_max_bus_speed(slot_cur); @@ -539,8 +539,8 @@ static int __init init_ops(void)  		debug("SLOT_PRESENT = %x\n", SLOT_PRESENT(slot_cur->status));  		debug("SLOT_LATCH = %x\n", SLOT_LATCH(slot_cur->status)); -		if ((SLOT_PWRGD(slot_cur->status)) &&  -		    !(SLOT_PRESENT(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");  				rc = power_off(slot_cur); @@ -581,13 +581,13 @@ static int validate(struct slot *slot_cur, int opn)  	switch (opn) {  		case ENABLE: -			if (!(SLOT_PWRGD(slot_cur->status)) &&  -			     (SLOT_PRESENT(slot_cur->status)) &&  +			if (!(SLOT_PWRGD(slot_cur->status)) && +			     (SLOT_PRESENT(slot_cur->status)) &&  			     !(SLOT_LATCH(slot_cur->status)))  				return 0;  			break;  		case DISABLE: -			if ((SLOT_PWRGD(slot_cur->status)) &&  +			if ((SLOT_PWRGD(slot_cur->status)) &&  			    (SLOT_PRESENT(slot_cur->status)) &&  			    !(SLOT_LATCH(slot_cur->status)))  				return 0; @@ -617,7 +617,7 @@ int ibmphp_update_slot_info(struct slot *slot_cur)  		err("out of system memory\n");  		return -ENOMEM;  	} -         +  	info->power_status = SLOT_PWRGD(slot_cur->status);  	info->attention_status = SLOT_ATTN(slot_cur->status,  						slot_cur->ext_status); @@ -638,7 +638,7 @@ int ibmphp_update_slot_info(struct slot *slot_cur)  		case BUS_SPEED_33:  			break;  		case BUS_SPEED_66: -			if (mode == BUS_MODE_PCIX)  +			if (mode == BUS_MODE_PCIX)  				bus_speed += 0x01;  			else if (mode == BUS_MODE_PCI)  				; @@ -654,8 +654,8 @@ int ibmphp_update_slot_info(struct slot *slot_cur)  	}  	bus->cur_bus_speed = bus_speed; -	// To do: bus_names  -	 +	// To do: bus_names +  	rc = pci_hp_change_slot_info(slot_cur->hotplug_slot, info);  	kfree(info);  	return rc; @@ -671,7 +671,7 @@ static struct pci_func *ibm_slot_find(u8 busno, u8 device, u8 function)  {  	struct pci_func *func_cur;  	struct slot *slot_cur; -	struct list_head * tmp; +	struct list_head *tmp;  	list_for_each(tmp, &ibmphp_slot_head) {  		slot_cur = list_entry(tmp, struct slot, ibm_slot_list);  		if (slot_cur->func) { @@ -696,8 +696,8 @@ static struct pci_func *ibm_slot_find(u8 busno, u8 device, u8 function)  static void free_slots(void)  {  	struct slot *slot_cur; -	struct list_head * tmp; -	struct list_head * next; +	struct list_head *tmp; +	struct list_head *next;  	debug("%s -- enter\n", __func__); @@ -718,19 +718,24 @@ static void ibm_unconfigure_device(struct pci_func *func)  					func->device, func->function);  	debug("func->device << 3 | 0x0  = %x\n", func->device << 3 | 0x0); +	pci_lock_rescan_remove(); +  	for (j = 0; j < 0x08; j++) {  		temp = pci_get_bus_and_slot(func->busno, (func->device << 3) | j);  		if (temp) { -			pci_remove_bus_device(temp); +			pci_stop_and_remove_bus_device(temp);  			pci_dev_put(temp);  		}  	} +  	pci_dev_put(func->dev); + +	pci_unlock_rescan_remove();  }  /* - * The following function is to fix kernel bug regarding  - * getting bus entries, here we manually add those primary  + * 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) @@ -760,7 +765,7 @@ static u8 bus_structure_fixup(u8 busno)  	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", +			debug("%s - Inside bus_structure_fixup()\n",  							__func__);  			pci_scan_bus(busno, ibmphp_pci_bus->ops, NULL);  			break; @@ -775,12 +780,13 @@ static u8 bus_structure_fixup(u8 busno)  static int ibm_configure_device(struct pci_func *func)  { -	unsigned char bus;  	struct pci_bus *child;  	int num;  	int flag = 0;	/* this is to make sure we don't double scan the bus,  					for bridged devices primarily */ +	pci_lock_rescan_remove(); +  	if (!(bus_structure_fixup(func->busno)))  		flag = 1;  	if (func->dev == NULL) @@ -790,7 +796,7 @@ static int ibm_configure_device(struct pci_func *func)  	if (func->dev == NULL) {  		struct pci_bus *bus = pci_find_bus(0, func->busno);  		if (!bus) -			return 0; +			goto out;  		num = pci_scan_slot(bus,  				PCI_DEVFN(func->device, func->function)); @@ -801,25 +807,28 @@ static int ibm_configure_device(struct pci_func *func)  				PCI_DEVFN(func->device, func->function));  		if (func->dev == NULL) {  			err("ERROR... : pci_dev still NULL\n"); -			return 0; +			goto out;  		}  	}  	if (!(flag) && (func->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE)) { -		pci_read_config_byte(func->dev, PCI_SECONDARY_BUS, &bus); -		child = pci_add_new_bus(func->dev->bus, func->dev, bus); -		pci_do_scan_bus(child); +		pci_hp_add_bridge(func->dev); +		child = func->dev->subordinate; +		if (child) +			pci_bus_add_devices(child);  	} + out: +	pci_unlock_rescan_remove();  	return 0;  }  /******************************************************* - * Returns whether the bus is empty or not  + * Returns whether the bus is empty or not   *******************************************************/ -static int is_bus_empty(struct slot * slot_cur) +static int is_bus_empty(struct slot *slot_cur)  {  	int rc; -	struct slot * tmp_slot; +	struct slot *tmp_slot;  	u8 i = slot_cur->bus_on->slot_min;  	while (i <= slot_cur->bus_on->slot_max) { @@ -842,12 +851,12 @@ static int is_bus_empty(struct slot * slot_cur)  }  /*********************************************************** - * If the HPC permits and the bus currently empty, tries to set the  + * If the HPC permits and the bus currently empty, tries to set the   * bus speed and mode at the maximum card and bus capability   * Parameters: slot   * Returns: bus is set (0) or error code   ***********************************************************/ -static int set_bus(struct slot * slot_cur) +static int set_bus(struct slot *slot_cur)  {  	int rc;  	u8 speed; @@ -856,7 +865,7 @@ static int set_bus(struct slot * slot_cur)  	static struct pci_device_id ciobx[] = {  		{ PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, 0x0101) },  	        { }, -	};	 +	};  	debug("%s - entry slot # %d\n", __func__, slot_cur->number);  	if (SET_BUS_STATUS(slot_cur->ctrl) && is_bus_empty(slot_cur)) { @@ -877,7 +886,7 @@ static int set_bus(struct slot * slot_cur)  				else if (!SLOT_BUS_MODE(slot_cur->ext_status))  					/* if max slot/bus capability is 66 pci  					and there's no bus mode mismatch, then -					the adapter supports 66 pci */  +					the adapter supports 66 pci */  					cmd = HPC_BUS_66CONVMODE;  				else  					cmd = HPC_BUS_33CONVMODE; @@ -930,7 +939,7 @@ static int set_bus(struct slot * slot_cur)  			return -EIO;  		}  	} -	/* This is for x440, once Brandon fixes the firmware,  +	/* This is for x440, once Brandon fixes the firmware,  	will not need this delay */  	msleep(1000);  	debug("%s -Exit\n", __func__); @@ -938,16 +947,16 @@ static int set_bus(struct slot * slot_cur)  }  /* This routine checks the bus limitations that the slot is on from the BIOS. - * This is used in deciding whether or not to power up the slot.   + * This is used in deciding whether or not to power up the slot.   * (electrical/spec limitations. For example, >1 133 MHz or >2 66 PCI cards on - * same bus)  + * same bus)   * Parameters: slot   * Returns: 0 = no limitations, -EINVAL = exceeded limitations on the bus   */  static int check_limitations(struct slot *slot_cur)  {  	u8 i; -	struct slot * tmp_slot; +	struct slot *tmp_slot;  	u8 count = 0;  	u8 limitation = 0; @@ -986,7 +995,7 @@ static int check_limitations(struct slot *slot_cur)  static inline void print_card_capability(struct slot *slot_cur)  {  	info("capability of the card is "); -	if ((slot_cur->ext_status & CARD_INFO) == PCIX133)  +	if ((slot_cur->ext_status & CARD_INFO) == PCIX133)  		info("   133 MHz PCI-X\n");  	else if ((slot_cur->ext_status & CARD_INFO) == PCIX66)  		info("    66 MHz PCI-X\n"); @@ -1020,7 +1029,7 @@ static int enable_slot(struct hotplug_slot *hs)  	}  	attn_LED_blink(slot_cur); -	 +  	rc = set_bus(slot_cur);  	if (rc) {  		err("was not able to set the bus\n"); @@ -1036,8 +1045,7 @@ static int enable_slot(struct hotplug_slot *hs)  	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"); +		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; @@ -1061,12 +1069,10 @@ static int enable_slot(struct hotplug_slot *hs)  					!(SLOT_PWRGD(slot_cur->status)))  			err("power fault occurred trying to power up\n");  		else if (SLOT_BUS_SPEED(slot_cur->status)) { -			err("bus speed mismatch occurred.  please check " -				"current bus speed and card capability\n"); +			err("bus speed mismatch occurred.  please check current bus speed and card capability\n");  			print_card_capability(slot_cur);  		} else if (SLOT_BUS_MODE(slot_cur->ext_status)) { -			err("bus mode mismatch occurred.  please check " -				"current bus mode and card capability\n"); +			err("bus mode mismatch occurred.  please check current bus mode and card capability\n");  			print_card_capability(slot_cur);  		}  		ibmphp_update_slot_info(slot_cur); @@ -1082,18 +1088,17 @@ static int enable_slot(struct hotplug_slot *hs)  	rc = slot_update(&slot_cur);  	if (rc)  		goto error_power; -	 +  	rc = -EINVAL;  	if (SLOT_POWER(slot_cur->status) && !(SLOT_PWRGD(slot_cur->status))) {  		err("power fault occurred trying to power up...\n");  		goto error_power;  	}  	if (SLOT_POWER(slot_cur->status) && (SLOT_BUS_SPEED(slot_cur->status))) { -		err("bus speed mismatch occurred.  please check current bus " -					"speed and card capability\n"); +		err("bus speed mismatch occurred.  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 */  	if (!(SLOT_POWER(slot_cur->status))) { @@ -1144,7 +1149,7 @@ static int enable_slot(struct hotplug_slot *hs)  	ibmphp_print_test();  	rc = ibmphp_update_slot_info(slot_cur);  exit: -	ibmphp_unlock_operations();  +	ibmphp_unlock_operations();  	return rc;  error_nopower: @@ -1180,7 +1185,7 @@ static 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(); @@ -1192,12 +1197,12 @@ int ibmphp_do_disable_slot(struct slot *slot_cur)  	int rc;  	u8 flag; -	debug("DISABLING SLOT...\n");  -		 +	debug("DISABLING SLOT...\n"); +  	if ((slot_cur == NULL) || (slot_cur->ctrl == NULL)) {  		return -ENODEV;  	} -	 +  	flag = slot_cur->flag;  	slot_cur->flag = 1; @@ -1210,7 +1215,7 @@ int ibmphp_do_disable_slot(struct slot *slot_cur)  	attn_LED_blink(slot_cur);  	if (slot_cur->func == NULL) { -		/* We need this for fncs's that were there on bootup */ +		/* We need this for functions that were there on bootup */  		slot_cur->func = kzalloc(sizeof(struct pci_func), GFP_KERNEL);  		if (!slot_cur->func) {  			err("out of system memory\n"); @@ -1222,12 +1227,13 @@ int ibmphp_do_disable_slot(struct slot *slot_cur)  	}  	ibm_unconfigure_device(slot_cur->func); -         -	/* If we got here from latch suddenly opening on operating card or  -	a power fault, there's no power to the card, so cannot -	read from it to determine what resources it occupied.  This operation -	is forbidden anyhow.  The best we can do is remove it from kernel -	lists at least */ + +	/* +	 * If we got here from latch suddenly opening on operating card or +	 * a power fault, there's no power to the card, so cannot +	 * read from it to determine what resources it occupied.  This operation +	 * is forbidden anyhow.  The best we can do is remove it from kernel +	 * lists at least */  	if (!flag) {  		attn_off(slot_cur); @@ -1264,7 +1270,7 @@ error:  		rc = -EFAULT;  		goto exit;  	} -	if (flag)		 +	if (flag)  		ibmphp_update_slot_info(slot_cur);  	goto exit;  } @@ -1339,7 +1345,7 @@ static int __init ibmphp_init(void)  	debug("AFTER Resource & EBDA INITIALIZATIONS\n");  	max_slots = get_max_slots(); -	 +  	if ((rc = ibmphp_register_pci()))  		goto error;  | 
