Messages in this thread | | | Date | Mon, 8 Feb 1999 10:20:39 -0600 (CST) | From | Ravi Wijayaratne <> | Subject | plug_device and unplu_device question |
| |
Hi,
This question is about the plug_device and unplug_device routines in lnux/drivers/block/ll_rw_blk.c
1. I cannot find the place where linux fills up the dev->plug structure apart from the initilizing routine. But in unplug_device routine dev->plug.next is used. Also in plug device dev->current_request =&dev->plug is done. Where is the contents from dev->plug coming from ?
2. The plug_device is called when there is a request to the device but dev->current_request is currently empty.(in make request). However my understanding is that the request is actually attached to the request queue of the device in add_request routine which is called after the task is scheduled. What happens is the dev->req_fn() is called before add_request can schdule the requests ? Or is this possible ?
3. If some one can explain how the plug_device and the unplug_device works with the ide disk drives that will be the answer I am looking for.
Some help on these questions is very much appreciated.
Thanx Ravi
*************************************************************************** plug_device and unplug_device fit in as follows
***************************************************************************** The initialising is done here
blk_dev_init() { ..... for (dev = blk_dev + MAX_BLKDEV; dev-- != blk_dev;) { dev->request_fn = NULL; dev->current_request = NULL; dev->plug.rq_status = RQ_INACTIVE; dev->plug.cmd = -1; dev->plug.next = NULL; dev->plug_tq.routine = &unplug_device; dev->plug_tq.data = dev; }
....... }
The calling is done in
static void make_request(int major,int rw, struct buffer_head * bh) { ......
req = blk_dev[major].current_request;
if (!req) { /* MD and loop can't handle plugging without deadlocking */ if (major != MD_MAJOR && major != LOOP_MAJOR) plug_device(blk_dev + major); } else switch (major) { ............. }
and the two routines are as follows
static inline void plug_device(struct blk_dev_struct * dev) { dev->current_request = &dev->plug; queue_task_irq_off(&dev->plug_tq, &tq_disk); }
void unplug_device(void * data) { struct blk_dev_struct * dev = (struct blk_dev_struct *) data; unsigned long flags; save_flags(flags); cli(); if (dev->current_request == &dev->plug) { struct request * next = dev->plug.next; dev->current_request = next; if (next) { dev->plug.next = NULL; (dev->request_fn)(); } } restore_flags(flags); }
**********************************************************************
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |