Commit 0ad0eff9 authored by Finn Thain's avatar Finn Thain Committed by Martin K. Petersen
Browse files

ncr5380: Introduce unbound workqueue



Allocate a work queue that will permit busy waiting and sleeping. This
means NCR5380_init() can potentially fail, so add this error path.

Signed-off-by: default avatarFinn Thain <fthain@telegraphics.com.au>
Reviewed-by: default avatarHannes Reinecke <hare@suse.com>
Tested-by: default avatarOndrej Zary <linux@rainbow-software.org>
Tested-by: default avatarMichael Schmitz <schmitzmic@gmail.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent e52bbd5c
Loading
Loading
Loading
Loading
+11 −4
Original line number Diff line number Diff line
@@ -514,7 +514,7 @@ static int should_disconnect(unsigned char cmd)
static void NCR5380_set_timer(struct NCR5380_hostdata *hostdata, unsigned long timeout)
{
	hostdata->time_expires = jiffies + timeout;
	schedule_delayed_work(&hostdata->coroutine, timeout);
	queue_delayed_work(hostdata->work_q, &hostdata->coroutine, timeout);
}


@@ -791,6 +791,11 @@ static int NCR5380_init(struct Scsi_Host *instance, int flags)
	hostdata->disconnected_queue = NULL;
	
	INIT_DELAYED_WORK(&hostdata->coroutine, NCR5380_main);
	hostdata->work_q = alloc_workqueue("ncr5380_%d",
	                        WQ_UNBOUND | WQ_MEM_RECLAIM,
	                        1, instance->host_no);
	if (!hostdata->work_q)
		return -ENOMEM;

	/* The CHECK code seems to break the 53C400. Will check it later maybe */
	if (flags & FLAG_NCR53C400)
@@ -872,6 +877,7 @@ static void NCR5380_exit(struct Scsi_Host *instance)
	struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata;

	cancel_delayed_work_sync(&hostdata->coroutine);
	destroy_workqueue(hostdata->work_q);
}

/**
@@ -932,7 +938,7 @@ static int NCR5380_queue_command_lck(struct scsi_cmnd *cmd, void (*done) (struct

	/* Run the coroutine if it isn't already running. */
	/* Kick off command processing */
	schedule_delayed_work(&hostdata->coroutine, 0);
	queue_delayed_work(hostdata->work_q, &hostdata->coroutine, 0);
	return 0;
}

@@ -1128,7 +1134,8 @@ static irqreturn_t NCR5380_intr(int dummy, void *dev_id)
		}	/* if BASR_IRQ */
		spin_unlock_irqrestore(instance->host_lock, flags);
		if(!done)
			schedule_delayed_work(&hostdata->coroutine, 0);
			queue_delayed_work(hostdata->work_q,
			                   &hostdata->coroutine, 0);
	} while (!done);
	return IRQ_HANDLED;
}
+1 −0
Original line number Diff line number Diff line
@@ -284,6 +284,7 @@ struct NCR5380_hostdata {
	unsigned spin_max_r;
	unsigned spin_max_w;
#endif
	struct workqueue_struct *work_q;
};

#ifdef __KERNEL__
+6 −2
Original line number Diff line number Diff line
@@ -238,7 +238,9 @@ static int cumanascsi1_probe(struct expansion_card *ec,

	host->irq = ec->irq;

	NCR5380_init(host, 0);
	ret = NCR5380_init(host, 0);
	if (ret)
		goto out_unmap;

	NCR5380_maybe_reset_bus(host);

@@ -250,7 +252,7 @@ static int cumanascsi1_probe(struct expansion_card *ec,
	if (ret) {
		printk("scsi%d: IRQ%d not free: %d\n",
		    host->host_no, host->irq, ret);
		goto out_unmap;
		goto out_exit;
	}

	ret = scsi_add_host(host, &ec->dev);
@@ -262,6 +264,8 @@ static int cumanascsi1_probe(struct expansion_card *ec,

 out_free_irq:
	free_irq(host->irq, host);
 out_exit:
	NCR5380_exit(host);
 out_unmap:
	iounmap(priv(host)->base);
	iounmap(priv(host)->dma);
+6 −2
Original line number Diff line number Diff line
@@ -143,17 +143,21 @@ static int oakscsi_probe(struct expansion_card *ec, const struct ecard_id *id)
	host->irq = NO_IRQ;
	host->n_io_port = 255;

	NCR5380_init(host, 0);
	ret = NCR5380_init(host, 0);
	if (ret)
		goto out_unmap;

	NCR5380_maybe_reset_bus(host);

	ret = scsi_add_host(host, &ec->dev);
	if (ret)
		goto out_unmap;
		goto out_exit;

	scsi_scan_host(host);
	goto out;

 out_exit:
	NCR5380_exit(host);
 out_unmap:
	iounmap(priv(host)->base);
 unreg:
+7 −1
Original line number Diff line number Diff line
@@ -643,7 +643,7 @@ static inline void queue_main(struct NCR5380_hostdata *hostdata)
		   queue it on the 'immediate' task queue, to be processed
		   immediately after the current interrupt processing has
		   finished. */
		schedule_work(&hostdata->main_task);
		queue_work(hostdata->work_q, &hostdata->main_task);
	}
	/* else: nothing to do: the running NCR5380_main() will pick up
	   any newly queued command. */
@@ -832,6 +832,11 @@ static int __init NCR5380_init(struct Scsi_Host *instance, int flags)
	hostdata->flags = flags;

	INIT_WORK(&hostdata->main_task, NCR5380_main);
	hostdata->work_q = alloc_workqueue("ncr5380_%d",
	                        WQ_UNBOUND | WQ_MEM_RECLAIM,
	                        1, instance->host_no);
	if (!hostdata->work_q)
		return -ENOMEM;

	prepare_info(instance);

@@ -907,6 +912,7 @@ static void NCR5380_exit(struct Scsi_Host *instance)
	struct NCR5380_hostdata *hostdata = shost_priv(instance);

	cancel_work_sync(&hostdata->main_task);
	destroy_workqueue(hostdata->work_q);
}

/**
Loading