drivers/pci/hotplug/shpchp_ctrl.c

Source file repositories/reference/linux-study-clean/drivers/pci/hotplug/shpchp_ctrl.c

File Facts

System
Linux kernel
Corpus path
drivers/pci/hotplug/shpchp_ctrl.c
Extension
.c
Size
17415 bytes
Lines
705
Domain
Representative Device Path
Bucket
PCIe NVMe Storage Path
Inferred role
Representative Device Path: implementation source
Status
source implementation candidate

Why This File Exists

Part of the selected hardware vertical slice: PCI discovery, driver binding, NVMe queues, block requests, DMA, interrupts, and completion.

Dependency Surface

Detected Declarations

Annotated Snippet

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))
			shpchp_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_obj(*info);
	if (!info) {
		ctrl_err(p_slot->ctrl, "%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:
		kfree(info);
		goto out;
	}
	queue_work(p_slot->wq, &info->work);
 out:
	mutex_unlock(&p_slot->lock);
}

static void update_slot_info(struct slot *slot)
{
	shpchp_get_power_status(slot, &slot->pwr_save);
	shpchp_get_attention_status(slot, &slot->attention_save);
	shpchp_get_latch_status(slot, &slot->latch_save);
	shpchp_get_adapter_status(slot, &slot->presence_save);
}

/*
 * Note: This function must be called with slot->lock held
 */
static void handle_button_press_event(struct slot *p_slot)
{
	u8 getstatus;
	struct controller *ctrl = p_slot->ctrl;

	switch (p_slot->state) {
	case STATIC_STATE:

Annotation

Implementation Notes