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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [uclinux/] [uClinux-2.0.x/] [arch/] [armnommu/] [drivers/] [scsi/] [hosts.c] - Blame information for rev 199

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

Line No. Rev Author Line
1 199 simons
/*
2
 *  hosts.c Copyright (C) 1992 Drew Eckhardt
3
 *          Copyright (C) 1993, 1994, 1995 Eric Youngdale
4
 *
5
 *  mid to lowlevel SCSI driver interface
6
 *      Initial versions: Drew Eckhardt
7
 *      Subsequent revisions: Eric Youngdale
8
 *
9
 *  <drew@colorado.edu>
10
 */
11
 
12
 
13
/*
14
 *  This file contains the medium level SCSI
15
 *  host interface initialization, as well as the scsi_hosts array of SCSI
16
 *  hosts currently present in the system.
17
 */
18
 
19
/*
20
 * Don't import our own symbols, as this would severely mess up our
21
 * symbol tables.
22
 */
23
#define _SCSI_SYMS_VER_
24
#define __NO_VERSION__
25
#include <linux/module.h>
26
 
27
#include <linux/config.h>
28
#include <linux/blk.h>
29
#include <linux/kernel.h>
30
#include <linux/string.h>
31
#include <linux/mm.h>
32
#include <linux/proc_fs.h>
33
 
34
#include "scsi.h"
35
 
36
#ifndef NULL
37
#define NULL 0L
38
#endif
39
 
40
#define HOSTS_C
41
 
42
#include "hosts.h"
43
 
44
#ifdef CONFIG_SCSI_ACORNSCSI_3
45
#include "acornscsi.h"
46
#endif
47
 
48
#ifdef CONFIG_SCSI_CUMANA_1
49
#include "cumana_1.h"
50
#endif
51
 
52
#ifdef CONFIG_SCSI_OAK1
53
#include "oak.h"
54
#endif
55
 
56
#ifdef CONFIG_SCSI_ECOSCSI
57
#include "ecoscsi.h"
58
#endif
59
 
60
#ifdef CONFIG_SCSI_POWERTECSCSI
61
#include "powertec.h"
62
#endif
63
 
64
#ifdef CONFIG_SCSI_EESOXSCSI
65
#include "eesox.h"
66
#endif
67
 
68
#ifdef CONFIG_BLK_DEV_IDESCSI
69
#include "ide-scsi.h"
70
#endif
71
 
72
#ifdef CONFIG_SCSI_DEBUG
73
#include "scsi_debug.h"
74
#endif
75
 
76
/*
77
static const char RCSid[] = "$Header: /home/marcus/revision_ctrl_test/oc_cvs/cvs/or1k/uclinux/uClinux-2.0.x/arch/armnommu/drivers/scsi/hosts.c,v 1.1.1.1 2001-09-10 07:43:54 simons Exp $";
78
*/
79
 
80
/*
81
 *  The scsi host entries should be in the order you wish the
82
 *  cards to be detected.  A driver may appear more than once IFF
83
 *  it can deal with being detected (and therefore initialized)
84
 *  with more than one simultaneous host number, can handle being
85
 *  reentrant, etc.
86
 *
87
 *  They may appear in any order, as each SCSI host is told which host
88
 *  number it is during detection.
89
 */
90
 
91
/* This is a placeholder for controllers that are not configured into
92
 * the system - we do this to ensure that the controller numbering is
93
 * always consistent, no matter how the kernel is configured. */
94
 
95
#define NO_CONTROLLER {NULL, NULL, NULL, NULL, NULL, NULL, NULL, \
96
                           NULL, NULL, 0, 0, 0, 0, 0, 0}
97
 
98
/*
99
 *  When figure is run, we don't want to link to any object code.  Since
100
 *  the macro for each host will contain function pointers, we cannot
101
 *  use it and instead must use a "blank" that does no such
102
 *  idiocy.
103
 */
104
 
105
Scsi_Host_Template * scsi_hosts = NULL;
106
 
107
static Scsi_Host_Template builtin_scsi_hosts[] =
108
{
109
#ifdef CONFIG_SCSI_ACORNSCSI_3
110
    ACORNSCSI_3,
111
#endif
112
#ifdef CONFIG_SCSI_CUMANA_1
113
    CUMANA_NCR5380,
114
#endif
115
#ifdef CONFIG_SCSI_OAK1
116
    OAK_NCR5380,
117
#endif
118
#ifdef CONFIG_SCSI_ECOSCSI
119
    ECOSCSI_NCR5380,
120
#endif
121
#ifdef CONFIG_BLK_DEV_IDESCSI
122
    IDESCSI,
123
#endif
124
#ifdef CONFIG_SCSI_POWERTECSCSI
125
    POWERTECSCSI,
126
#endif
127
#ifdef CONFIG_SCSI_EESOXSCSI
128
    EESOXSCSI,
129
#endif
130
#ifdef CONFIG_SCSI_DEBUG
131
    SCSI_DEBUG,
132
#endif
133
};
134
 
135
#define MAX_SCSI_HOSTS (sizeof(builtin_scsi_hosts) / sizeof(Scsi_Host_Template))
136
 
137
 
138
/*
139
 *  Our semaphores and timeout counters, where size depends on
140
 *      MAX_SCSI_HOSTS here.
141
 */
142
 
143
struct Scsi_Host * scsi_hostlist = NULL;
144
struct Scsi_Device_Template * scsi_devicelist = NULL;
145
 
146
int max_scsi_hosts = 0;
147
int next_scsi_host = 0;
148
 
149
void
150
scsi_unregister(struct Scsi_Host * sh){
151
    struct Scsi_Host * shpnt;
152
 
153
    if(scsi_hostlist == sh)
154
        scsi_hostlist = sh->next;
155
    else {
156
        shpnt = scsi_hostlist;
157
        while(shpnt->next != sh) shpnt = shpnt->next;
158
        shpnt->next = shpnt->next->next;
159
    }
160
 
161
    /* If we are removing the last host registered, it is safe to reuse
162
     * its host number (this avoids "holes" at boot time) (DB)
163
     */
164
    if (max_scsi_hosts == next_scsi_host)
165
        max_scsi_hosts--;
166
 
167
    next_scsi_host--;
168
    scsi_init_free((char *) sh, sizeof(struct Scsi_Host) + sh->extra_bytes);
169
}
170
 
171
/* We call this when we come across a new host adapter. We only do this
172
 * once we are 100% sure that we want to use this host adapter -  it is a
173
 * pain to reverse this, so we try to avoid it
174
 */
175
 
176
struct Scsi_Host * scsi_register(Scsi_Host_Template * tpnt, int j){
177
    struct Scsi_Host * retval, *shpnt;
178
    retval = (struct Scsi_Host *)scsi_init_malloc(sizeof(struct Scsi_Host) + j,
179
                                                  (tpnt->unchecked_isa_dma && j ? GFP_DMA : 0) | GFP_ATOMIC);
180
    retval->host_busy = 0;
181
    retval->block = NULL;
182
    retval->wish_block = 0;
183
    if(j > 0xffff) panic("Too many extra bytes requested\n");
184
    retval->extra_bytes = j;
185
    retval->loaded_as_module = scsi_loadable_module_flag;
186
    retval->host_no = max_scsi_hosts++; /* never reuse host_no (DB) */
187
    next_scsi_host++;
188
    retval->host_queue = NULL;
189
    retval->host_wait = NULL;
190
    retval->last_reset = 0;
191
    retval->irq = 0;
192
    retval->dma_channel = 0xff;
193
 
194
    /* These three are default values which can be overridden */
195
    retval->max_channel = 0;
196
    retval->max_id = 8;
197
    retval->max_lun = 8;
198
 
199
    retval->unique_id = 0;
200
    retval->io_port = 0;
201
    retval->hostt = tpnt;
202
    retval->next = NULL;
203
#ifdef DEBUG
204
    printk("Register %x %x: %d\n", (int)retval, (int)retval->hostt, j);
205
#endif
206
 
207
    /* The next six are the default values which can be overridden
208
     * if need be */
209
    retval->this_id = tpnt->this_id;
210
    retval->can_queue = tpnt->can_queue;
211
    retval->sg_tablesize = tpnt->sg_tablesize;
212
    retval->cmd_per_lun = tpnt->cmd_per_lun;
213
    retval->unchecked_isa_dma = tpnt->unchecked_isa_dma;
214
    retval->use_clustering = tpnt->use_clustering;
215
 
216
    retval->select_queue_depths = NULL;
217
 
218
    if(!scsi_hostlist)
219
        scsi_hostlist = retval;
220
    else
221
    {
222
        shpnt = scsi_hostlist;
223
        while(shpnt->next) shpnt = shpnt->next;
224
        shpnt->next = retval;
225
    }
226
 
227
    return retval;
228
}
229
 
230
int
231
scsi_register_device(struct Scsi_Device_Template * sdpnt)
232
{
233
    if(sdpnt->next) panic("Device already registered");
234
    sdpnt->next = scsi_devicelist;
235
    scsi_devicelist = sdpnt;
236
    return 0;
237
}
238
 
239
unsigned int scsi_init()
240
{
241
    static int called = 0;
242
    int i, pcount;
243
    Scsi_Host_Template * tpnt;
244
    struct Scsi_Host * shpnt;
245
    const char * name;
246
 
247
    if(called) return 0;
248
 
249
    called = 1;
250
    for (tpnt = &builtin_scsi_hosts[0], i = 0; i < MAX_SCSI_HOSTS; ++i, tpnt++)
251
    {
252
        /*
253
         * Initialize our semaphores.  -1 is interpreted to mean
254
         * "inactive" - where as 0 will indicate a time out condition.
255
         */
256
 
257
        pcount = next_scsi_host;
258
        if ((tpnt->detect) &&
259
            (tpnt->present =
260
             tpnt->detect(tpnt)))
261
        {
262
            /* The only time this should come up is when people use
263
             * some kind of patched driver of some kind or another. */
264
            if(pcount == next_scsi_host) {
265
                if(tpnt->present > 1)
266
                    panic("Failure to register low-level scsi driver");
267
                /* The low-level driver failed to register a driver.  We
268
                 * can do this now. */
269
                scsi_register(tpnt,0);
270
            }
271
            tpnt->next = scsi_hosts;
272
            scsi_hosts = tpnt;
273
 
274
            /* Add the driver to /proc/scsi */
275
#if CONFIG_PROC_FS 
276
            build_proc_dir_entries(tpnt);
277
#endif
278
        }
279
    }
280
 
281
    for(shpnt=scsi_hostlist; shpnt; shpnt = shpnt->next)
282
    {
283
        if(shpnt->hostt->info)
284
            name = shpnt->hostt->info(shpnt);
285
        else
286
            name = shpnt->hostt->name;
287
        printk ("scsi%d : %s\n", /* And print a little message */
288
                shpnt->host_no, name);
289
    }
290
 
291
    printk ("scsi : %d host%s.\n", next_scsi_host,
292
            (next_scsi_host == 1) ? "" : "s");
293
 
294
    scsi_make_blocked_list();
295
 
296
    /* Now attach the high level drivers */
297
#ifdef CONFIG_BLK_DEV_SD
298
    scsi_register_device(&sd_template);
299
#endif
300
#ifdef CONFIG_BLK_DEV_SR
301
    scsi_register_device(&sr_template);
302
#endif
303
#ifdef CONFIG_CHR_DEV_ST
304
    scsi_register_device(&st_template);
305
#endif
306
#ifdef CONFIG_CHR_DEV_SG
307
    scsi_register_device(&sg_template);
308
#endif
309
 
310
#if 0      
311
    max_scsi_hosts = next_scsi_host;
312
#endif
313
    return 0;
314
}
315
 
316
/*
317
 * Overrides for Emacs so that we follow Linus's tabbing style.
318
 * Emacs will notice this stuff at the end of the file and automatically
319
 * adjust the settings for this buffer only.  This must remain at the end
320
 * of the file.
321
 * ---------------------------------------------------------------------------
322
 * Local variables:
323
 * c-indent-level: 4
324
 * c-brace-imaginary-offset: 0
325
 * c-brace-offset: -4
326
 * c-argdecl-indent: 4
327
 * c-label-offset: -4
328
 * c-continued-statement-offset: 4
329
 * c-continued-brace-offset: 0
330
 * indent-tabs-mode: nil
331
 * tab-width: 8
332
 * End:
333
 */

powered by: WebSVN 2.1.0

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