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

📄 shpchp_ctrl.c

📁 audio driver for hotplug pci on linux 2.6.27
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (shpchp_unconfigure_device(p_slot))		return(1);	hp_slot = p_slot->device - ctrl->slot_device_offset;	p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);	dbg("In %s, hp_slot = %d\n", __func__, hp_slot);	/* Change status to shutdown */	if (p_slot->is_a_board)		p_slot->status = 0x01;	/* turn off slot, turn on Amber LED, turn off Green LED */	rc = p_slot->hpc_ops->slot_disable(p_slot);	if (rc) {		err("%s: Issue of Slot Disable command failed\n", __func__);		return rc;	}	rc = p_slot->hpc_ops->set_attention_status(p_slot, 0);	if (rc) {		err("%s: Issue of Set Attention command failed\n", __func__);		return rc;	}	p_slot->pwr_save = 0;	p_slot->is_a_board = 0;	return 0;}struct pushbutton_work_info {	struct slot *p_slot;	struct work_struct work;};/** * shpchp_pushbutton_thread - handle pushbutton events * @work: &struct work_struct to be handled * * Scheduled procedure to handle blocking stuff for the pushbuttons. * Handles all pending events and exits. */static void shpchp_pushbutton_thread(struct work_struct *work){	struct pushbutton_work_info *info =		container_of(work, struct pushbutton_work_info, work);	struct slot *p_slot = info->p_slot;	mutex_lock(&p_slot->lock);	switch (p_slot->state) {	case POWEROFF_STATE:		mutex_unlock(&p_slot->lock);		shpchp_disable_slot(p_slot);		mutex_lock(&p_slot->lock);		p_slot->state = STATIC_STATE;		break;	case POWERON_STATE:		mutex_unlock(&p_slot->lock);		if (shpchp_enable_slot(p_slot))			p_slot->hpc_ops->green_led_off(p_slot);		mutex_lock(&p_slot->lock);		p_slot->state = STATIC_STATE;		break;	default:		break;	}	mutex_unlock(&p_slot->lock);	kfree(info);}void shpchp_queue_pushbutton_work(struct work_struct *work){	struct slot *p_slot = container_of(work, struct slot, work.work);	struct pushbutton_work_info *info;	info = kmalloc(sizeof(*info), GFP_KERNEL);	if (!info) {		err("%s: Cannot allocate memory\n", __func__);		return;	}	info->p_slot = p_slot;	INIT_WORK(&info->work, shpchp_pushbutton_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(shpchp_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){	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", slot_name(p_slot));		} else {			p_slot->state = BLINKINGON_STATE;			info("PCI slot #%s - powering on due to button "			     "press.\n", slot_name(p_slot));		}		/* blink green LED and turn off amber */		p_slot->hpc_ops->green_led_blink(p_slot);		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", slot_name(p_slot));		dbg("%s: button cancel\n", __func__);		cancel_delayed_work(&p_slot->work);		if (p_slot->state == BLINKINGOFF_STATE)			p_slot->hpc_ops->green_led_on(p_slot);		else			p_slot->hpc_ops->green_led_off(p_slot);		p_slot->hpc_ops->set_attention_status(p_slot, 0);		info("PCI slot #%s - action canceled due to button press\n",		     slot_name(p_slot));		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", slot_name(p_slot));		update_slot_info(p_slot);		break;	default:		warn("Not a valid state\n");		break;	}}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;	mutex_lock(&p_slot->lock);	switch (info->event_type) {	case INT_BUTTON_PRESS:		handle_button_press_event(p_slot);		break;	case INT_POWER_FAULT:		dbg("%s: power fault\n", __func__);		p_slot->hpc_ops->set_attention_status(p_slot, 1);		p_slot->hpc_ops->green_led_off(p_slot);		break;	default:		update_slot_info(p_slot);		break;	}	mutex_unlock(&p_slot->lock);	kfree(info);}static int shpchp_enable_slot (struct slot *p_slot){	u8 getstatus = 0;	int rc, retval = -ENODEV;	/* 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("No adapter on slot(%s)\n", slot_name(p_slot));		goto out;	}	rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);	if (rc || getstatus) {		info("Latch open on slot(%s)\n", slot_name(p_slot));		goto out;	}	rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);	if (rc || getstatus) {		info("Already enabled on slot(%s)\n", slot_name(p_slot));		goto out;	}	p_slot->is_a_board = 1;	/* We have to save the presence info for these slots */	p_slot->hpc_ops->get_adapter_status(p_slot, &(p_slot->presence_save));	p_slot->hpc_ops->get_power_status(p_slot, &(p_slot->pwr_save));	dbg("%s: p_slot->pwr_save %x\n", __func__, p_slot->pwr_save);	p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);	if(((p_slot->ctrl->pci_dev->vendor == PCI_VENDOR_ID_AMD) ||	    (p_slot->ctrl->pci_dev->device == PCI_DEVICE_ID_AMD_POGO_7458))	     && p_slot->ctrl->num_slots == 1) {		/* handle amd pogo errata; this must be done before enable  */		amd_pogo_errata_save_misc_reg(p_slot);		retval = board_added(p_slot);		/* handle amd pogo errata; this must be done after enable  */		amd_pogo_errata_restore_misc_reg(p_slot);	} else		retval = board_added(p_slot);	if (retval) {		p_slot->hpc_ops->get_adapter_status(p_slot,				&(p_slot->presence_save));		p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);	}	update_slot_info(p_slot); out:	mutex_unlock(&p_slot->ctrl->crit_sect);	return retval;}static int shpchp_disable_slot (struct slot *p_slot){	u8 getstatus = 0;	int rc, retval = -ENODEV;	if (!p_slot->ctrl)		return -ENODEV;	/* Check to see if (latch closed, card present, power on) */	mutex_lock(&p_slot->ctrl->crit_sect);	rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus);	if (rc || !getstatus) {		info("No adapter on slot(%s)\n", slot_name(p_slot));		goto out;	}	rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);	if (rc || getstatus) {		info("Latch open on slot(%s)\n", slot_name(p_slot));		goto out;	}	rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);	if (rc || !getstatus) {		info("Already disabled slot(%s)\n", slot_name(p_slot));		goto out;	}	retval = remove_board(p_slot);	update_slot_info(p_slot); out:	mutex_unlock(&p_slot->ctrl->crit_sect);	return retval;}int shpchp_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 = shpchp_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",		     slot_name(p_slot));		break;	case BLINKINGOFF_STATE:	case POWEROFF_STATE:		info("Already enabled on slot %s\n", slot_name(p_slot));		break;	default:		err("Not a valid state on slot %s\n", slot_name(p_slot));		break;	}	mutex_unlock(&p_slot->lock);	return retval;}int shpchp_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 = shpchp_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",		     slot_name(p_slot));		break;	case BLINKINGON_STATE:	case POWERON_STATE:		info("Already disabled on slot %s\n", slot_name(p_slot));		break;	default:		err("Not a valid state on slot %s\n", slot_name(p_slot));		break;	}	mutex_unlock(&p_slot->lock);	return retval;}

⌨️ 快捷键说明

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