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

Commit c1637532 authored by Martin Schwidefsky's avatar Martin Schwidefsky
Browse files

[S390] more workqueue fixes.

parent e45ccc05
Loading
Loading
Loading
Loading
+2 −1
Original line number Original line Diff line number Diff line
@@ -179,6 +179,7 @@ struct tape_char_data {
/* Block Frontend Data */
/* Block Frontend Data */
struct tape_blk_data
struct tape_blk_data
{
{
	struct tape_device *	device;
	/* Block device request queue. */
	/* Block device request queue. */
	request_queue_t *	request_queue;
	request_queue_t *	request_queue;
	spinlock_t		request_queue_lock;
	spinlock_t		request_queue_lock;
@@ -240,7 +241,7 @@ struct tape_device {
#endif
#endif


	/* Function to start or stop the next request later. */
	/* Function to start or stop the next request later. */
	struct work_struct		tape_dnr;
	struct delayed_work		tape_dnr;
};
};


/* Externals from tape_core.c */
/* Externals from tape_core.c */
+11 −12
Original line number Original line Diff line number Diff line
@@ -95,6 +95,12 @@ tape_34xx_medium_sense(struct tape_device *device)
	return rc;
	return rc;
}
}


struct tape_34xx_work {
	struct tape_device	*device;
	enum tape_op		 op;
	struct work_struct	 work;
};

/*
/*
 * These functions are currently used only to schedule a medium_sense for
 * These functions are currently used only to schedule a medium_sense for
 * later execution. This is because we get an interrupt whenever a medium
 * later execution. This is because we get an interrupt whenever a medium
@@ -103,13 +109,10 @@ tape_34xx_medium_sense(struct tape_device *device)
 * interrupt handler.
 * interrupt handler.
 */
 */
static void
static void
tape_34xx_work_handler(void *data)
tape_34xx_work_handler(struct work_struct *work)
{
{
	struct {
	struct tape_34xx_work *p =
		struct tape_device	*device;
		container_of(work, struct tape_34xx_work, work);
		enum tape_op		 op;
		struct work_struct	 work;
	} *p = data;


	switch(p->op) {
	switch(p->op) {
		case TO_MSEN:
		case TO_MSEN:
@@ -126,17 +129,13 @@ tape_34xx_work_handler(void *data)
static int
static int
tape_34xx_schedule_work(struct tape_device *device, enum tape_op op)
tape_34xx_schedule_work(struct tape_device *device, enum tape_op op)
{
{
	struct {
	struct tape_34xx_work *p;
		struct tape_device	*device;
		enum tape_op		 op;
		struct work_struct	 work;
	} *p;


	if ((p = kmalloc(sizeof(*p), GFP_ATOMIC)) == NULL)
	if ((p = kmalloc(sizeof(*p), GFP_ATOMIC)) == NULL)
		return -ENOMEM;
		return -ENOMEM;


	memset(p, 0, sizeof(*p));
	memset(p, 0, sizeof(*p));
	INIT_WORK(&p->work, tape_34xx_work_handler, p);
	INIT_WORK(&p->work, tape_34xx_work_handler);


	p->device = tape_get_device_reference(device);
	p->device = tape_get_device_reference(device);
	p->op     = op;
	p->op     = op;
+4 −3
Original line number Original line Diff line number Diff line
@@ -236,9 +236,10 @@ struct work_handler_data {
};
};


static void
static void
tape_3590_work_handler(void *data)
tape_3590_work_handler(struct work_struct *work)
{
{
	struct work_handler_data *p = data;
	struct work_handler_data *p =
		container_of(work, struct work_handler_data, work);


	switch (p->op) {
	switch (p->op) {
	case TO_MSEN:
	case TO_MSEN:
@@ -263,7 +264,7 @@ tape_3590_schedule_work(struct tape_device *device, enum tape_op op)
	if ((p = kzalloc(sizeof(*p), GFP_ATOMIC)) == NULL)
	if ((p = kzalloc(sizeof(*p), GFP_ATOMIC)) == NULL)
		return -ENOMEM;
		return -ENOMEM;


	INIT_WORK(&p->work, tape_3590_work_handler, p);
	INIT_WORK(&p->work, tape_3590_work_handler);


	p->device = tape_get_device_reference(device);
	p->device = tape_get_device_reference(device);
	p->op = op;
	p->op = op;
+9 −5
Original line number Original line Diff line number Diff line
@@ -15,6 +15,7 @@
#include <linux/blkdev.h>
#include <linux/blkdev.h>
#include <linux/interrupt.h>
#include <linux/interrupt.h>
#include <linux/buffer_head.h>
#include <linux/buffer_head.h>
#include <linux/kernel.h>


#include <asm/debug.h>
#include <asm/debug.h>


@@ -143,7 +144,8 @@ tapeblock_start_request(struct tape_device *device, struct request *req)
 * queue.
 * queue.
 */
 */
static void
static void
tapeblock_requeue(void *data) {
tapeblock_requeue(struct work_struct *work) {
	struct tape_blk_data *	blkdat;
	struct tape_device *	device;
	struct tape_device *	device;
	request_queue_t *	queue;
	request_queue_t *	queue;
	int			nr_queued;
	int			nr_queued;
@@ -151,7 +153,8 @@ tapeblock_requeue(void *data) {
	struct list_head *	l;
	struct list_head *	l;
	int			rc;
	int			rc;


	device = (struct tape_device *) data;
	blkdat = container_of(work, struct tape_blk_data, requeue_task);
	device = blkdat->device;
	if (!device)
	if (!device)
		return;
		return;


@@ -212,6 +215,7 @@ tapeblock_setup_device(struct tape_device * device)
	int			rc;
	int			rc;


	blkdat = &device->blk_data;
	blkdat = &device->blk_data;
	blkdat->device = device;
	spin_lock_init(&blkdat->request_queue_lock);
	spin_lock_init(&blkdat->request_queue_lock);
	atomic_set(&blkdat->requeue_scheduled, 0);
	atomic_set(&blkdat->requeue_scheduled, 0);


@@ -255,8 +259,8 @@ tapeblock_setup_device(struct tape_device * device)


	add_disk(disk);
	add_disk(disk);


	INIT_WORK(&blkdat->requeue_task, tapeblock_requeue,
	tape_get_device_reference(device);
		tape_get_device_reference(device));
	INIT_WORK(&blkdat->requeue_task, tapeblock_requeue);


	return 0;
	return 0;


@@ -271,7 +275,7 @@ void
tapeblock_cleanup_device(struct tape_device *device)
tapeblock_cleanup_device(struct tape_device *device)
{
{
	flush_scheduled_work();
	flush_scheduled_work();
	device->blk_data.requeue_task.data = tape_put_device(device);
	tape_put_device(device);


	if (!device->blk_data.disk) {
	if (!device->blk_data.disk) {
		PRINT_ERR("(%s): No gendisk to clean up!\n",
		PRINT_ERR("(%s): No gendisk to clean up!\n",
+7 −7
Original line number Original line Diff line number Diff line
@@ -28,7 +28,7 @@
#define PRINTK_HEADER "TAPE_CORE: "
#define PRINTK_HEADER "TAPE_CORE: "


static void __tape_do_irq (struct ccw_device *, unsigned long, struct irb *);
static void __tape_do_irq (struct ccw_device *, unsigned long, struct irb *);
static void tape_delayed_next_request(void * data);
static void tape_delayed_next_request(struct work_struct *);


/*
/*
 * One list to contain all tape devices of all disciplines, so
 * One list to contain all tape devices of all disciplines, so
@@ -272,7 +272,7 @@ __tape_cancel_io(struct tape_device *device, struct tape_request *request)
				return 0;
				return 0;
			case -EBUSY:
			case -EBUSY:
				request->status	= TAPE_REQUEST_CANCEL;
				request->status	= TAPE_REQUEST_CANCEL;
				schedule_work(&device->tape_dnr);
				schedule_delayed_work(&device->tape_dnr, 0);
				return 0;
				return 0;
			case -ENODEV:
			case -ENODEV:
				DBF_EXCEPTION(2, "device gone, retry\n");
				DBF_EXCEPTION(2, "device gone, retry\n");
@@ -470,7 +470,7 @@ tape_alloc_device(void)
	*device->modeset_byte = 0;
	*device->modeset_byte = 0;
	device->first_minor = -1;
	device->first_minor = -1;
	atomic_set(&device->ref_count, 1);
	atomic_set(&device->ref_count, 1);
	INIT_WORK(&device->tape_dnr, tape_delayed_next_request, device);
	INIT_DELAYED_WORK(&device->tape_dnr, tape_delayed_next_request);


	return device;
	return device;
}
}
@@ -724,7 +724,7 @@ __tape_start_io(struct tape_device *device, struct tape_request *request)
	} else if (rc == -EBUSY) {
	} else if (rc == -EBUSY) {
		/* The common I/O subsystem is currently busy. Retry later. */
		/* The common I/O subsystem is currently busy. Retry later. */
		request->status = TAPE_REQUEST_QUEUED;
		request->status = TAPE_REQUEST_QUEUED;
		schedule_work(&device->tape_dnr);
		schedule_delayed_work(&device->tape_dnr, 0);
		rc = 0;
		rc = 0;
	} else {
	} else {
		/* Start failed. Remove request and indicate failure. */
		/* Start failed. Remove request and indicate failure. */
@@ -790,11 +790,11 @@ __tape_start_next_request(struct tape_device *device)
}
}


static void
static void
tape_delayed_next_request(void *data)
tape_delayed_next_request(struct work_struct *work)
{
{
	struct tape_device *	device;
	struct tape_device *device =
		container_of(work, struct tape_device, tape_dnr.work);


	device = (struct tape_device *) data;
	DBF_LH(6, "tape_delayed_next_request(%p)\n", device);
	DBF_LH(6, "tape_delayed_next_request(%p)\n", device);
	spin_lock_irq(get_ccwdev_lock(device->cdev));
	spin_lock_irq(get_ccwdev_lock(device->cdev));
	__tape_start_next_request(device);
	__tape_start_next_request(device);
Loading