OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [scsi/] [scsi_queue.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
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: /home/marcus/revision_ctrl_test/oc_cvs/cvs/or1k/linux/linux-2.4/drivers/scsi/scsi_queue.c,v 1.1.1.1 2004-04-15 02:08:35 phoenix 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
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.