static int enable_slot()

in hotplug/ibmphp_core.c [893:1054]


static int enable_slot(struct hotplug_slot *hs)
{
	int rc, i, rcpr;
	struct slot *slot_cur;
	u8 function;
	struct pci_func *tmp_func;

	ibmphp_lock_operations();

	debug("ENABLING SLOT........\n");
	slot_cur = to_slot(hs);

	rc = validate(slot_cur, ENABLE);
	if (rc) {
		err("validate function failed\n");
		goto error_nopower;
	}

	attn_LED_blink(slot_cur);

	rc = set_bus(slot_cur);
	if (rc) {
		err("was not able to set the bus\n");
		goto error_nopower;
	}

	/*-----------------debugging------------------------------*/
	get_cur_bus_info(&slot_cur);
	debug("the current bus speed right after set_bus = %x\n",
					slot_cur->bus_on->current_speed);
	/*----------------------------------------------------------*/

	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("Try hot-adding into another bus\n");
		rc = -EINVAL;
		goto error_nopower;
	}

	rc = power_on(slot_cur);

	if (rc) {
		err("something wrong when powering up... please see below for details\n");
		/* need to turn off before on, otherwise, blinking overwrites */
		attn_off(slot_cur);
		attn_on(slot_cur);
		if (slot_update(&slot_cur)) {
			attn_off(slot_cur);
			attn_on(slot_cur);
			rc = -ENODEV;
			goto exit;
		}
		/* Check to see the error of why it failed */
		if ((SLOT_POWER(slot_cur->status)) &&
					!(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");
			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");
			print_card_capability(slot_cur);
		}
		ibmphp_update_slot_info(slot_cur);
		goto exit;
	}
	debug("after power_on\n");
	/*-----------------------debugging---------------------------*/
	get_cur_bus_info(&slot_cur);
	debug("the current bus speed right after power_on = %x\n",
					slot_cur->bus_on->current_speed);
	/*----------------------------------------------------------*/

	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");
		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))) {
		err("power on failed...\n");
		goto error_power;
	}

	slot_cur->func = kzalloc(sizeof(struct pci_func), GFP_KERNEL);
	if (!slot_cur->func) {
		/* do update_slot_info here? */
		rc = -ENOMEM;
		goto error_power;
	}
	slot_cur->func->busno = slot_cur->bus;
	slot_cur->func->device = slot_cur->device;
	for (i = 0; i < 4; i++)
		slot_cur->func->irq[i] = slot_cur->irq[i];

	debug("b4 configure_card, slot_cur->bus = %x, slot_cur->device = %x\n",
					slot_cur->bus, slot_cur->device);

	if (ibmphp_configure_card(slot_cur->func, slot_cur->number)) {
		err("configure_card was unsuccessful...\n");
		/* true because don't need to actually deallocate resources,
		 * just remove references */
		ibmphp_unconfigure_card(&slot_cur, 1);
		debug("after unconfigure_card\n");
		slot_cur->func = NULL;
		rc = -ENOMEM;
		goto error_power;
	}

	function = 0x00;
	do {
		tmp_func = ibm_slot_find(slot_cur->bus, slot_cur->func->device,
							function++);
		if (tmp_func && !(tmp_func->dev))
			ibm_configure_device(tmp_func);
	} while (tmp_func);

	attn_off(slot_cur);
	if (slot_update(&slot_cur)) {
		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;
}