⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pciehp_ctrl.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	default:		break;	}	mutex_unlock(&p_slot->lock);	kfree(info);}void pciehp_queue_pushbutton_work(struct work_struct *work){	struct slot *p_slot = container_of(work, struct slot, work.work);	struct power_work_info *info;	info = kmalloc(sizeof(*info), GFP_KERNEL);	if (!info) {		err("%s: Cannot allocate memory\n", __FUNCTION__);		return;	}	info->p_slot = p_slot;	INIT_WORK(&info->work, pciehp_power_thread);	mutex_lock(&p_slot->lock);	switch (p_slot->state) {	case BLINKINGOFF_STATE:		p_slot->state = POWEROFF_STATE;		break;	case BLINKINGON_STATE:		p_slot->state = POWERON_STATE;		break;	default:		goto out;	}	queue_work(pciehp_wq, &info->work); out:	mutex_unlock(&p_slot->lock);}static int update_slot_info(struct slot *slot){	struct hotplug_slot_info *info;	int result;	info = kmalloc(sizeof(*info), GFP_KERNEL);	if (!info)		return -ENOMEM;	slot->hpc_ops->get_power_status(slot, &(info->power_status));	slot->hpc_ops->get_attention_status(slot, &(info->attention_status));	slot->hpc_ops->get_latch_status(slot, &(info->latch_status));	slot->hpc_ops->get_adapter_status(slot, &(info->adapter_status));	result = pci_hp_change_slot_info(slot->hotplug_slot, info);	kfree (info);	return result;}/* * Note: This function must be called with slot->lock held */static void handle_button_press_event(struct slot *p_slot){	struct controller *ctrl = p_slot->ctrl;	u8 getstatus;	switch (p_slot->state) {	case STATIC_STATE:		p_slot->hpc_ops->get_power_status(p_slot, &getstatus);		if (getstatus) {			p_slot->state = BLINKINGOFF_STATE;			info("PCI slot #%s - powering off due to button "			     "press.\n", p_slot->name);		} else {			p_slot->state = BLINKINGON_STATE;			info("PCI slot #%s - powering on due to button "			     "press.\n", p_slot->name);		}		/* blink green LED and turn off amber */		if (PWR_LED(ctrl->ctrlcap))			p_slot->hpc_ops->green_led_blink(p_slot);		if (ATTN_LED(ctrl->ctrlcap))			p_slot->hpc_ops->set_attention_status(p_slot, 0);		schedule_delayed_work(&p_slot->work, 5*HZ);		break;	case BLINKINGOFF_STATE:	case BLINKINGON_STATE:		/*		 * Cancel if we are still blinking; this means that we		 * press the attention again before the 5 sec. limit		 * expires to cancel hot-add or hot-remove		 */		info("Button cancel on Slot(%s)\n", p_slot->name);		dbg("%s: button cancel\n", __FUNCTION__);		cancel_delayed_work(&p_slot->work);		if (p_slot->state == BLINKINGOFF_STATE) {			if (PWR_LED(ctrl->ctrlcap))				p_slot->hpc_ops->green_led_on(p_slot);		} else {			if (PWR_LED(ctrl->ctrlcap))				p_slot->hpc_ops->green_led_off(p_slot);		}		if (ATTN_LED(ctrl->ctrlcap))			p_slot->hpc_ops->set_attention_status(p_slot, 0);		info("PCI slot #%s - action canceled due to button press\n",		     p_slot->name);		p_slot->state = STATIC_STATE;		break;	case POWEROFF_STATE:	case POWERON_STATE:		/*		 * Ignore if the slot is on power-on or power-off state;		 * this means that the previous attention button action		 * to hot-add or hot-remove is undergoing		 */		info("Button ignore on Slot(%s)\n", p_slot->name);		update_slot_info(p_slot);		break;	default:		warn("Not a valid state\n");		break;	}}/* * Note: This function must be called with slot->lock held */static void handle_surprise_event(struct slot *p_slot){	u8 getstatus;	struct power_work_info *info;	info = kmalloc(sizeof(*info), GFP_KERNEL);	if (!info) {		err("%s: Cannot allocate memory\n", __FUNCTION__);		return;	}	info->p_slot = p_slot;	INIT_WORK(&info->work, pciehp_power_thread);	p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);	if (!getstatus)		p_slot->state = POWEROFF_STATE;	else		p_slot->state = POWERON_STATE;	queue_work(pciehp_wq, &info->work);}static void interrupt_event_handler(struct work_struct *work){	struct event_info *info = container_of(work, struct event_info, work);	struct slot *p_slot = info->p_slot;	struct controller *ctrl = p_slot->ctrl;	mutex_lock(&p_slot->lock);	switch (info->event_type) {	case INT_BUTTON_PRESS:		handle_button_press_event(p_slot);		break;	case INT_POWER_FAULT:		if (!POWER_CTRL(ctrl->ctrlcap))			break;		if (ATTN_LED(ctrl->ctrlcap))			p_slot->hpc_ops->set_attention_status(p_slot, 1);		if (PWR_LED(ctrl->ctrlcap))			p_slot->hpc_ops->green_led_off(p_slot);		break;	case INT_PRESENCE_ON:	case INT_PRESENCE_OFF:		if (!HP_SUPR_RM(ctrl->ctrlcap))			break;		dbg("Surprise Removal\n");		update_slot_info(p_slot);		handle_surprise_event(p_slot);		break;	default:		update_slot_info(p_slot);		break;	}	mutex_unlock(&p_slot->lock);	kfree(info);}int pciehp_enable_slot(struct slot *p_slot){	u8 getstatus = 0;	int rc;	/* Check to see if (latch closed, card present, power off) */	mutex_lock(&p_slot->ctrl->crit_sect);	rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);	if (rc || !getstatus) {		info("%s: no adapter on slot(%s)\n", __FUNCTION__,		     p_slot->name);		mutex_unlock(&p_slot->ctrl->crit_sect);		return -ENODEV;	}	if (MRL_SENS(p_slot->ctrl->ctrlcap)) {		rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);		if (rc || getstatus) {			info("%s: latch open on slot(%s)\n", __FUNCTION__,			     p_slot->name);			mutex_unlock(&p_slot->ctrl->crit_sect);			return -ENODEV;		}	}	if (POWER_CTRL(p_slot->ctrl->ctrlcap)) {		rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);		if (rc || getstatus) {			info("%s: already enabled on slot(%s)\n", __FUNCTION__,			     p_slot->name);			mutex_unlock(&p_slot->ctrl->crit_sect);			return -EINVAL;		}	}	p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);	rc = board_added(p_slot);	if (rc) {		p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);	}	update_slot_info(p_slot);	mutex_unlock(&p_slot->ctrl->crit_sect);	return rc;}int pciehp_disable_slot(struct slot *p_slot){	u8 getstatus = 0;	int ret = 0;	if (!p_slot->ctrl)		return 1;	/* Check to see if (latch closed, card present, power on) */	mutex_lock(&p_slot->ctrl->crit_sect);	if (!HP_SUPR_RM(p_slot->ctrl->ctrlcap)) {		ret = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);		if (ret || !getstatus) {			info("%s: no adapter on slot(%s)\n", __FUNCTION__,			     p_slot->name);			mutex_unlock(&p_slot->ctrl->crit_sect);			return -ENODEV;		}	}	if (MRL_SENS(p_slot->ctrl->ctrlcap)) {		ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);		if (ret || getstatus) {			info("%s: latch open on slot(%s)\n", __FUNCTION__,			     p_slot->name);			mutex_unlock(&p_slot->ctrl->crit_sect);			return -ENODEV;		}	}	if (POWER_CTRL(p_slot->ctrl->ctrlcap)) {		ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);		if (ret || !getstatus) {			info("%s: already disabled slot(%s)\n", __FUNCTION__,			     p_slot->name);			mutex_unlock(&p_slot->ctrl->crit_sect);			return -EINVAL;		}		/*		 * After turning power off, we must wait for at least		 * 1 second before taking any action that relies on		 * power having been removed from the slot/adapter.		 */		msleep(1000);	}	ret = remove_board(p_slot);	update_slot_info(p_slot);	mutex_unlock(&p_slot->ctrl->crit_sect);	return ret;}int pciehp_sysfs_enable_slot(struct slot *p_slot){	int retval = -ENODEV;	mutex_lock(&p_slot->lock);	switch (p_slot->state) {	case BLINKINGON_STATE:		cancel_delayed_work(&p_slot->work);	case STATIC_STATE:		p_slot->state = POWERON_STATE;		mutex_unlock(&p_slot->lock);		retval = pciehp_enable_slot(p_slot);		mutex_lock(&p_slot->lock);		p_slot->state = STATIC_STATE;		break;	case POWERON_STATE:		info("Slot %s is already in powering on state\n",		     p_slot->name);		break;	case BLINKINGOFF_STATE:	case POWEROFF_STATE:		info("Already enabled on slot %s\n", p_slot->name);		break;	default:		err("Not a valid state on slot %s\n", p_slot->name);		break;	}	mutex_unlock(&p_slot->lock);	return retval;}int pciehp_sysfs_disable_slot(struct slot *p_slot){	int retval = -ENODEV;	mutex_lock(&p_slot->lock);	switch (p_slot->state) {	case BLINKINGOFF_STATE:		cancel_delayed_work(&p_slot->work);	case STATIC_STATE:		p_slot->state = POWEROFF_STATE;		mutex_unlock(&p_slot->lock);		retval = pciehp_disable_slot(p_slot);		mutex_lock(&p_slot->lock);		p_slot->state = STATIC_STATE;		break;	case POWEROFF_STATE:		info("Slot %s is already in powering off state\n",		     p_slot->name);		break;	case BLINKINGON_STATE:	case POWERON_STATE:		info("Already disabled on slot %s\n", p_slot->name);		break;	default:		err("Not a valid state on slot %s\n", p_slot->name);		break;	}	mutex_unlock(&p_slot->lock);	return retval;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -