Linux 2.4.0-test7pre1
[davej-history.git] / drivers / scsi / scsi_queue.c
blob1620882045243aa1bb47f54f62bbebda4ac72e84
1 /*
2 * scsi_queue.c Copyright (C) 1997 Eric Youngdale
4 * generic mid-level SCSI queueing.
6 * The point of this is that we need to track when hosts are unable to
7 * accept a command because they are busy. In addition, we track devices
8 * that cannot accept a command because of a QUEUE_FULL condition. In both
9 * of these cases, we enter the command in the queue. At some later point,
10 * we attempt to remove commands from the queue and retry them.
13 #define __NO_VERSION__
14 #include <linux/module.h>
16 #include <linux/sched.h>
17 #include <linux/timer.h>
18 #include <linux/string.h>
19 #include <linux/malloc.h>
20 #include <linux/ioport.h>
21 #include <linux/kernel.h>
22 #include <linux/stat.h>
23 #include <linux/blk.h>
24 #include <linux/interrupt.h>
25 #include <linux/delay.h>
26 #include <linux/smp_lock.h>
28 #define __KERNEL_SYSCALLS__
30 #include <linux/unistd.h>
32 #include <asm/system.h>
33 #include <asm/irq.h>
34 #include <asm/dma.h>
36 #include "scsi.h"
37 #include "hosts.h"
38 #include "constants.h"
41 * TODO:
42 * 1) Prevent multiple traversals of list to look for commands to
43 * queue.
44 * 2) Protect against multiple insertions of list at the same time.
45 * DONE:
46 * 1) Set state of scsi command to a new state value for ml queue.
47 * 2) Insert into queue when host rejects command.
48 * 3) Make sure status code is properly passed from low-level queue func
49 * so that internal_cmnd properly returns the right value.
50 * 4) Insert into queue when QUEUE_FULL.
51 * 5) Cull queue in bottom half handler.
52 * 6) Check usage count prior to queue insertion. Requeue if usage
53 * count is 0.
54 * 7) Don't send down any more commands if the host/device is busy.
57 static const char RCSid[] = "$Header: /mnt/ide/home/eric/CVSROOT/linux/drivers/scsi/scsi_queue.c,v 1.1 1997/10/21 11:16:38 eric Exp $";
61 * Function: scsi_mlqueue_insert()
63 * Purpose: Insert a command in the midlevel queue.
65 * Arguments: cmd - command that we are adding to queue.
66 * reason - why we are inserting command to queue.
68 * Lock status: Assumed that lock is not held upon entry.
70 * Returns: Nothing.
72 * Notes: We do this for one of two cases. Either the host is busy
73 * and it cannot accept any more commands for the time being,
74 * or the device returned QUEUE_FULL and can accept no more
75 * commands.
76 * Notes: This could be called either from an interrupt context or a
77 * normal process context.
79 int scsi_mlqueue_insert(Scsi_Cmnd * cmd, int reason)
81 struct Scsi_Host *host;
82 unsigned long flags;
84 SCSI_LOG_MLQUEUE(1, printk("Inserting command %p into mlqueue\n", cmd));
87 * We are inserting the command into the ml queue. First, we
88 * cancel the timer, so it doesn't time out.
90 scsi_delete_timer(cmd);
92 host = cmd->host;
95 * Next, set the appropriate busy bit for the device/host.
97 if (reason == SCSI_MLQUEUE_HOST_BUSY) {
99 * Protect against race conditions. If the host isn't busy,
100 * assume that something actually completed, and that we should
101 * be able to queue a command now. Note that there is an implicit
102 * assumption that every host can always queue at least one command.
103 * If a host is inactive and cannot queue any commands, I don't see
104 * how things could possibly work anyways.
106 if (host->host_busy == 0) {
107 if (scsi_retry_command(cmd) == 0) {
108 return 0;
111 host->host_blocked = TRUE;
112 } else {
114 * Protect against race conditions. If the device isn't busy,
115 * assume that something actually completed, and that we should
116 * be able to queue a command now. Note that there is an implicit
117 * assumption that every host can always queue at least one command.
118 * If a host is inactive and cannot queue any commands, I don't see
119 * how things could possibly work anyways.
121 if (cmd->device->device_blocked == 0) {
122 if (scsi_retry_command(cmd) == 0) {
123 return 0;
126 cmd->device->device_blocked = TRUE;
130 * Register the fact that we own the thing for now.
132 cmd->state = SCSI_STATE_MLQUEUE;
133 cmd->owner = SCSI_OWNER_MIDLEVEL;
134 cmd->bh_next = NULL;
137 * Decrement the counters, since these commands are no longer
138 * active on the host/device.
140 spin_lock_irqsave(&io_request_lock, flags);
141 cmd->host->host_busy--;
142 cmd->device->device_busy--;
143 spin_unlock_irqrestore(&io_request_lock, flags);
146 * Insert this command at the head of the queue for it's device.
147 * It will go before all other commands that are already in the queue.
149 scsi_insert_special_cmd(cmd, 1);
150 return 0;