Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3b210e76 authored by Martin Schwidefsky's avatar Martin Schwidefsky Committed by Martin Schwidefsky
Browse files

[S390] tape: add medium state notifications



Add uevent notifications for tape cartridge load and tape
cartridge unload events.

Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 25591b07
Loading
Loading
Loading
Loading
+59 −9
Original line number Diff line number Diff line
@@ -209,29 +209,79 @@ tape_state_set(struct tape_device *device, enum tape_state newstate)
	wake_up(&device->state_change_wq);
}

struct tape_med_state_work_data {
	struct tape_device *device;
	enum tape_medium_state state;
	struct work_struct  work;
};

static void
tape_med_state_work_handler(struct work_struct *work)
{
	static char env_state_loaded[] = "MEDIUM_STATE=LOADED";
	static char env_state_unloaded[] = "MEDIUM_STATE=UNLOADED";
	struct tape_med_state_work_data *p =
		container_of(work, struct tape_med_state_work_data, work);
	struct tape_device *device = p->device;
	char *envp[] = { NULL, NULL };

	switch (p->state) {
	case MS_UNLOADED:
		pr_info("%s: The tape cartridge has been successfully "
			"unloaded\n", dev_name(&device->cdev->dev));
		envp[0] = env_state_unloaded;
		kobject_uevent_env(&device->cdev->dev.kobj, KOBJ_CHANGE, envp);
		break;
	case MS_LOADED:
		pr_info("%s: A tape cartridge has been mounted\n",
			dev_name(&device->cdev->dev));
		envp[0] = env_state_loaded;
		kobject_uevent_env(&device->cdev->dev.kobj, KOBJ_CHANGE, envp);
		break;
	default:
		break;
	}
	tape_put_device(device);
	kfree(p);
}

static void
tape_med_state_work(struct tape_device *device, enum tape_medium_state state)
{
	struct tape_med_state_work_data *p;

	p = kzalloc(sizeof(*p), GFP_ATOMIC);
	if (p) {
		INIT_WORK(&p->work, tape_med_state_work_handler);
		p->device = tape_get_device(device);
		p->state = state;
		schedule_work(&p->work);
	}
}

void
tape_med_state_set(struct tape_device *device, enum tape_medium_state newstate)
{
	if (device->medium_state == newstate)
	enum tape_medium_state oldstate;

	oldstate = device->medium_state;
	if (oldstate == newstate)
		return;
	device->medium_state = newstate;
	switch(newstate){
	case MS_UNLOADED:
		device->tape_generic_status |= GMT_DR_OPEN(~0);
		if (device->medium_state == MS_LOADED)
			pr_info("%s: The tape cartridge has been successfully "
				"unloaded\n", dev_name(&device->cdev->dev));
		if (oldstate == MS_LOADED)
			tape_med_state_work(device, MS_UNLOADED);
		break;
	case MS_LOADED:
		device->tape_generic_status &= ~GMT_DR_OPEN(~0);
		if (device->medium_state == MS_UNLOADED)
			pr_info("%s: A tape cartridge has been mounted\n",
				dev_name(&device->cdev->dev));
		if (oldstate == MS_UNLOADED)
			tape_med_state_work(device, MS_LOADED);
		break;
	default:
		// print nothing
		break;
	}
	device->medium_state = newstate;
	wake_up(&device->state_change_wq);
}