~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/drivers/scsi/scsi_queue.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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/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>
 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  */
 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 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.