1 /*
2  *  scsi_queue.c Copyright (C) 1997 Eric Youngdale
3  *
4  *  generic mid-level SCSI queueing.
5  *
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.
11  */
12 
13 #define __NO_VERSION__
14 #include <linux/module.h>
15 
16 #include <linux/sched.h>
17 #include <linux/timer.h>
18 #include <linux/string.h>
19 #include <linux/slab.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>
27 
28 #define __KERNEL_SYSCALLS__
29 
30 #include <linux/unistd.h>
31 
32 #include <asm/system.h>
33 #include <asm/irq.h>
34 #include <asm/dma.h>
35 
36 #include "scsi.h"
37 #include "hosts.h"
38 #include "constants.h"
39 
40 /*
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.
55  */
56 
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 $";
58 
59 
60 /*
61  * Function:    scsi_mlqueue_insert()
62  *
63  * Purpose:     Insert a command in the midlevel queue.
64  *
65  * Arguments:   cmd    - command that we are adding to queue.
66  *              reason - why we are inserting command to queue.
67  *
68  * Lock status: Assumed that lock is not held upon entry.
69  *
70  * Returns:     Nothing.
71  *
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.
78  */
scsi_mlqueue_insert(Scsi_Cmnd * cmd,int reason)79 int scsi_mlqueue_insert(Scsi_Cmnd * cmd, int reason)
80 {
81 	struct Scsi_Host *host;
82 	unsigned long flags;
83 
84 	SCSI_LOG_MLQUEUE(1, printk("Inserting command %p into mlqueue\n", cmd));
85 
86 	/*
87 	 * We are inserting the command into the ml queue.  First, we
88 	 * cancel the timer, so it doesn't time out.
89 	 */
90 	scsi_delete_timer(cmd);
91 
92 	host = cmd->host;
93 
94 	/*
95 	 * Next, set the appropriate busy bit for the device/host.
96 	 */
97 	if (reason == SCSI_MLQUEUE_HOST_BUSY) {
98 		/*
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.
105 		 */
106 		if (host->host_busy == 0) {
107 			if (scsi_retry_command(cmd) == 0) {
108 				return 0;
109 			}
110 		}
111 		host->host_blocked = TRUE;
112 	} else {
113 		/*
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.
120 		 */
121 		if (cmd->device->device_busy == 0) {
122 			if (scsi_retry_command(cmd) == 0) {
123 				return 0;
124 			}
125 		}
126 		cmd->device->device_blocked = TRUE;
127 	}
128 
129 	/*
130 	 * Register the fact that we own the thing for now.
131 	 */
132 	cmd->state = SCSI_STATE_MLQUEUE;
133 	cmd->owner = SCSI_OWNER_MIDLEVEL;
134 	cmd->bh_next = NULL;
135 
136 	/*
137 	 * Decrement the counters, since these commands are no longer
138 	 * active on the host/device.
139 	 */
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);
144 
145 	/*
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.
148 	 */
149 	scsi_insert_special_cmd(cmd, 1);
150 	return 0;
151 }
152