patch-1.3.78 linux/drivers/block/ll_rw_blk.c
Next file: linux/drivers/block/loop.c
Previous file: linux/drivers/block/ide.c
Back to the patch index
Back to the overall index
- Lines: 124
- Date:
Sun Mar 24 20:07:00 1996
- Orig file:
v1.3.77/linux/drivers/block/ll_rw_blk.c
- Orig date:
Tue Mar 5 10:10:52 1996
diff -u --recursive --new-file v1.3.77/linux/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c
@@ -76,40 +76,30 @@
int * hardsect_size[MAX_BLKDEV] = { NULL, NULL, };
/*
- * "plug" the device if there are no outstanding requests: this will
- * force the transfer to start only after we have put all the requests
- * on the list.
+ * remove the plug and let it rip..
*/
-static inline void plug_device(struct blk_dev_struct * dev, struct request * plug)
+static void unplug_device(void * data)
{
+ struct blk_dev_struct * dev = (struct blk_dev_struct *) data;
unsigned long flags;
- plug->rq_status = RQ_INACTIVE;
- plug->cmd = -1;
- plug->next = NULL;
save_flags(flags);
cli();
- if (!dev->current_request)
- dev->current_request = plug;
+ if (dev->current_request)
+ (dev->request_fn)();
restore_flags(flags);
}
/*
- * remove the plug and let it rip..
+ * "plug" the device if there are no outstanding requests: this will
+ * force the transfer to start only after we have put all the requests
+ * on the list.
*/
-static inline void unplug_device(struct blk_dev_struct * dev)
+static inline void plug_device(struct blk_dev_struct * dev)
{
- struct request * req;
- unsigned long flags;
-
- save_flags(flags);
- cli();
- req = dev->current_request;
- if (req && req->rq_status == RQ_INACTIVE && req->cmd == -1) {
- dev->current_request = req->next;
- (dev->request_fn)();
+ if (!dev->current_request && !IS_PLUGGED(dev)) {
+ queue_task_irq_off(&dev->plug_tq, &tq_scheduler);
}
- restore_flags(flags);
}
/*
@@ -154,7 +144,6 @@
add_wait_queue(&wait_for_request, &wait);
for (;;) {
- unplug_device(MAJOR(dev)+blk_dev);
current->state = TASK_UNINTERRUPTIBLE;
cli();
req = get_request(n, dev);
@@ -261,7 +250,8 @@
if (!(tmp = dev->current_request)) {
dev->current_request = req;
up (&request_lock);
- (dev->request_fn)();
+ if (!IS_PLUGGED(dev))
+ (dev->request_fn)();
sti();
return;
}
@@ -276,7 +266,7 @@
up (&request_lock);
/* for SCSI devices, call request_fn unconditionally */
- if (scsi_major(MAJOR(req->rq_dev)) && MAJOR(req->rq_dev)!=MD_MAJOR)
+ if (!IS_PLUGGED(dev) && scsi_major(MAJOR(req->rq_dev)) && MAJOR(req->rq_dev)!=MD_MAJOR)
(dev->request_fn)();
sti();
@@ -340,8 +330,8 @@
}
/* look for a free request. */
- cli();
down (&request_lock);
+ cli();
/* The scsi disk and cdrom drivers completely remove the request
* from the queue when they start processing an entry. For this reason
@@ -479,7 +469,6 @@
void ll_rw_block(int rw, int nr, struct buffer_head * bh[])
{
unsigned int major;
- struct request plug;
int correct_size;
struct blk_dev_struct * dev;
int i;
@@ -531,8 +520,7 @@
from starting until we have shoved all of the blocks into the
queue, and then we let it rip. */
- if (nr > 1)
- plug_device(dev, &plug);
+ plug_device(dev);
for (i = 0; i < nr; i++) {
if (bh[i]) {
set_bit(BH_Req, &bh[i]->b_state);
@@ -543,7 +531,6 @@
make_request(major, rw, bh[i]);
}
}
- unplug_device(dev);
return;
sorry:
@@ -622,6 +609,8 @@
for (dev = blk_dev + MAX_BLKDEV; dev-- != blk_dev;) {
dev->request_fn = NULL;
dev->current_request = NULL;
+ dev->plug_tq.routine = &unplug_device;
+ dev->plug_tq.data = dev;
}
req = all_requests + NR_REQUEST;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this