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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
#define AUTOSENSE
2
#define PSEUDO_DMA
3
#define DONT_USE_INTR
4
#define UNSAFE                  /* Leave interrupts enabled during pseudo-dma I/O */
5
#define xNDEBUG (NDEBUG_INTR+NDEBUG_RESELECTION+\
6
                 NDEBUG_SELECTION+NDEBUG_ARBITRATION)
7
#define DMA_WORKS_RIGHT
8
 
9
/*
10
 * DTC 3180/3280 driver, by
11
 *      Ray Van Tassle  rayvt@comm.mot.com
12
 *
13
 *      taken from ...
14
 *      Trantor T128/T128F/T228 driver by...
15
 *
16
 *      Drew Eckhardt
17
 *      Visionary Computing
18
 *      (Unix and Linux consulting and custom programming)
19
 *      drew@colorado.edu
20
 *      +1 (303) 440-4894
21
 *
22
 * DISTRIBUTION RELEASE 1.
23
 *
24
 * For more information, please consult
25
 *
26
 * NCR 5380 Family
27
 * SCSI Protocol Controller
28
 * Databook
29
*/
30
 
31
/*
32
 * Options :
33
 * AUTOSENSE - if defined, REQUEST SENSE will be performed automatically
34
 *      for commands that return with a CHECK CONDITION status.
35
 *
36
 * PSEUDO_DMA - enables PSEUDO-DMA hardware, should give a 3-4X performance
37
 * increase compared to polled I/O.
38
 *
39
 * PARITY - enable parity checking.  Not supported.
40
 *
41
 * UNSAFE - leave interrupts enabled during pseudo-DMA transfers.
42
 *              You probably want this.
43
 *
44
 * The card is detected and initialized in one of several ways :
45
 * 1.  Autoprobe (default) - since the board is memory mapped,
46
 *     a BIOS signature is scanned for to locate the registers.
47
 *     An interrupt is triggered to autoprobe for the interrupt
48
 *     line.
49
 *
50
 * 2.  With command line overrides - dtc=address,irq may be
51
 *     used on the LILO command line to override the defaults.
52
 *
53
*/
54
 
55
/*----------------------------------------------------------------*/
56
/* the following will set the monitor border color (useful to find
57
 where something crashed or gets stuck at */
58
/* 1 = blue
59
 2 = green
60
 3 = cyan
61
 4 = red
62
 5 = magenta
63
 6 = yellow
64
 7 = white
65
*/
66
 
67
#if 0
68
#define rtrc(i) {inb(0x3da); outb(0x31, 0x3c0); outb((i), 0x3c0);}
69
#else
70
#define rtrc(i) {}
71
#endif
72
 
73
 
74
#include <asm/system.h>
75
#include <linux/module.h>
76
#include <linux/signal.h>
77
#include <linux/sched.h>
78
#include <linux/blk.h>
79
#include <asm/io.h>
80
#include "scsi.h"
81
#include "hosts.h"
82
#include "dtc.h"
83
#define AUTOPROBE_IRQ
84
#include "NCR5380.h"
85
#include "constants.h"
86
#include "sd.h"
87
#include <linux/stat.h>
88
#include <linux/string.h>
89
#include <linux/init.h>
90
 
91
 
92
#define DTC_PUBLIC_RELEASE 2
93
 
94
/*#define DTCDEBUG 0x1*/
95
#define DTCDEBUG_INIT   0x1
96
#define DTCDEBUG_TRANSFER 0x2
97
 
98
/*
99
 * The DTC3180 & 3280 boards are memory mapped.
100
 *
101
 */
102
 
103
/*
104
 */
105
/* Offset from DTC_5380_OFFSET */
106
#define DTC_CONTROL_REG         0x100   /* rw */
107
#define D_CR_ACCESS             0x80    /* ro set=can access 3280 registers */
108
#define CSR_DIR_READ            0x40    /* rw direction, 1 = read 0 = write */
109
 
110
#define CSR_RESET              0x80     /* wo  Resets 53c400 */
111
#define CSR_5380_REG           0x80     /* ro  5380 registers can be accessed */
112
#define CSR_TRANS_DIR          0x40     /* rw  Data transfer direction */
113
#define CSR_SCSI_BUFF_INTR     0x20     /* rw  Enable int on transfer ready */
114
#define CSR_5380_INTR          0x10     /* rw  Enable 5380 interrupts */
115
#define CSR_SHARED_INTR        0x08     /* rw  Interrupt sharing */
116
#define CSR_HOST_BUF_NOT_RDY   0x04     /* ro  Host buffer not ready */
117
#define CSR_SCSI_BUF_RDY       0x02     /* ro  SCSI buffer ready */
118
#define CSR_GATED_5380_IRQ     0x01     /* ro  Last block xferred */
119
#define CSR_INT_BASE (CSR_SCSI_BUFF_INTR | CSR_5380_INTR)
120
 
121
 
122
#define DTC_BLK_CNT             0x101   /* rw 
123
                                         * # of 128-byte blocks to transfer */
124
 
125
 
126
#define D_CR_ACCESS             0x80    /* ro set=can access 3280 registers */
127
 
128
#define DTC_SWITCH_REG          0x3982  /* ro - DIP switches */
129
#define DTC_RESUME_XFER         0x3982  /* wo - resume data xfer 
130
                                           * after disconnect/reconnect */
131
 
132
#define DTC_5380_OFFSET         0x3880  /* 8 registers here, see NCR5380.h */
133
 
134
/*!!!! for dtc, it's a 128 byte buffer at 3900 !!! */
135
#define DTC_DATA_BUF            0x3900  /* rw 128 bytes long */
136
 
137
static struct override {
138
        unsigned int address;
139
        int irq;
140
} overrides
141
#ifdef OVERRIDE
142
[] __initdata = OVERRIDE;
143
#else
144
[4] __initdata = {
145
        {0, IRQ_AUTO},
146
        {0, IRQ_AUTO},
147
        {0, IRQ_AUTO},
148
        {0, IRQ_AUTO}
149
};
150
#endif
151
 
152
#define NO_OVERRIDES (sizeof(overrides) / sizeof(struct override))
153
 
154
static struct base {
155
        unsigned long address;
156
        int noauto;
157
} bases[] __initdata = {
158
        {0xcc000, 0},
159
        {0xc8000, 0},
160
        {0xdc000, 0},
161
        {0xd8000, 0}
162
};
163
 
164
#define NO_BASES (sizeof (bases) / sizeof (struct base))
165
 
166
static const struct signature {
167
        const char *string;
168
        int offset;
169
} signatures[] = {
170
        {"DATA TECHNOLOGY CORPORATION BIOS", 0x25},
171
};
172
 
173
#define NO_SIGNATURES (sizeof (signatures) /  sizeof (struct signature))
174
 
175
/**
176
 *      dtc_setup       -       option setup for dtc3x80
177
 *
178
 *      LILO command line initialization of the overrides array,
179
 */
180
 
181
static int __init dtc_setup(char *str)
182
{
183
        static int commandline_current = 0;
184
        int i;
185
        int ints[10];
186
 
187
        get_options(str, sizeof(ints) / sizeof(int), ints);
188
 
189
        if (ints[0] != 2)
190
                printk(KERN_ERR "dtc_setup: usage dtc=address,irq\n");
191
        else if (commandline_current < NO_OVERRIDES) {
192
                overrides[commandline_current].address = ints[1];
193
                overrides[commandline_current].irq = ints[2];
194
                for (i = 0; i < NO_BASES; ++i)
195
                        if (bases[i].address == ints[1]) {
196
                                bases[i].noauto = 1;
197
                                break;
198
                        }
199
                ++commandline_current;
200
        }
201
        return 1;
202
}
203
 
204
__setup("dtc=", dtc_setup);
205
 
206
/**
207
 *      dtc_detect      -       detect DTC 3x80 controllers
208
 *      @tpnt: controller template
209
 *
210
 *      Detects and initializes DTC 3180/3280 controllers
211
 *      that were autoprobed, overridden on the LILO command line,
212
 *      or specified at compile time.
213
 */
214
 
215
int __init dtc_detect(Scsi_Host_Template * tpnt)
216
{
217
        static int current_override = 0, current_base = 0;
218
        struct Scsi_Host *instance;
219
        unsigned int base;
220
        int sig, count;
221
 
222
        tpnt->proc_name = "dtc3x80";
223
        tpnt->proc_info = &dtc_proc_info;
224
 
225
        for (count = 0; current_override < NO_OVERRIDES; ++current_override)
226
        {
227
                base = 0;
228
 
229
                if (overrides[current_override].address)
230
                        base = overrides[current_override].address;
231
                else
232
                {
233
                        for (; !base && (current_base < NO_BASES); ++current_base) {
234
                                for (sig = 0; sig < NO_SIGNATURES; ++sig)
235
                                {
236
                                        if (!bases[current_base].noauto && isa_check_signature(bases[current_base].address + signatures[sig].offset, signatures[sig].string, strlen(signatures[sig].string))) {
237
                                                base = bases[current_base].address;
238
                                                break;
239
                                        }
240
                                }
241
                        }
242
                }
243
 
244
                if (!base)
245
                        break;
246
 
247
                instance = scsi_register(tpnt, sizeof(struct NCR5380_hostdata));
248
                if (instance == NULL)
249
                        break;
250
 
251
                instance->base = base;
252
 
253
                NCR5380_init(instance, 0);
254
 
255
                NCR5380_write(DTC_CONTROL_REG, CSR_5380_INTR);  /* Enable int's */
256
                if (overrides[current_override].irq != IRQ_AUTO)
257
                        instance->irq = overrides[current_override].irq;
258
                else
259
                        instance->irq = NCR5380_probe_irq(instance, DTC_IRQS);
260
 
261
#ifndef DONT_USE_INTR
262
                /* With interrupts enabled, it will sometimes hang when doing heavy
263
                 * reads. So better not enable them until I figure it out. */
264
                if (instance->irq != SCSI_IRQ_NONE)
265
                        if (request_irq(instance->irq, do_dtc_intr, SA_INTERRUPT, "dtc"))
266
                        {
267
                                printk(KERN_WARNING "scsi%d : IRQ%d not free, interrupts disabled\n", instance->host_no, instance->irq);
268
                                instance->irq = SCSI_IRQ_NONE;
269
                        }
270
 
271
                if (instance->irq == SCSI_IRQ_NONE) {
272
                        printk(KERN_INFO "scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
273
                        printk(KERN_INFO "scsi%d : please jumper the board for a free IRQ.\n", instance->host_no);
274
                }
275
#else
276
                if (instance->irq != SCSI_IRQ_NONE)
277
                        printk(KERN_INFO "scsi%d : interrupts not used. Might as well not jumper it.\n", instance->host_no);
278
                instance->irq = SCSI_IRQ_NONE;
279
#endif
280
                printk(KERN_INFO "scsi%d : at 0x%05X", instance->host_no, (int) instance->base);
281
                if (instance->irq == SCSI_IRQ_NONE)
282
                        printk(" interrupts disabled");
283
                else
284
                        printk(" irq %d", instance->irq);
285
                printk(" options CAN_QUEUE=%d  CMD_PER_LUN=%d release=%d", CAN_QUEUE, CMD_PER_LUN, DTC_PUBLIC_RELEASE);
286
                NCR5380_print_options(instance);
287
                printk("\n");
288
 
289
                ++current_override;
290
                ++count;
291
        }
292
        return count;
293
}
294
 
295
/**
296
 *      dtc_biosparam           -       compute disk geometry
297
 *      @disk: disk to generate for
298
 *      @dev: major/minor of device
299
 *      @ip: returned geometry
300
 *
301
 *      Generates a BIOS / DOS compatible H-C-S mapping for
302
 *      the specified device / size.
303
 */
304
 
305
int dtc_biosparam(Disk * disk, kdev_t dev, int *ip)
306
{
307
        int size = disk->capacity;
308
 
309
        ip[0] = 64;
310
        ip[1] = 32;
311
        ip[2] = size >> 11;
312
        return 0;
313
}
314
 
315
 
316
static int dtc_maxi = 0;
317
static int dtc_wmaxi = 0;
318
 
319
/**
320
 *      NCR5380_pread           -       fast pseudo DMA read
321
 *      @instance: controller
322
 *      @dst: destination buffer
323
 *      @len: expected/max size
324
 *
325
 *      Fast 5380 pseudo-dma read function, reads len bytes from the controller
326
 *      mmio area into dst.
327
 */
328
 
329
static inline int NCR5380_pread(struct Scsi_Host *instance, unsigned char *dst, int len)
330
{
331
        unsigned char *d = dst;
332
        int i;                  /* For counting time spent in the poll-loop */
333
        NCR5380_local_declare();
334
        NCR5380_setup(instance);
335
 
336
        i = 0;
337
        NCR5380_read(RESET_PARITY_INTERRUPT_REG);
338
        NCR5380_write(MODE_REG, MR_ENABLE_EOP_INTR | MR_DMA_MODE);
339
        if (instance->irq == SCSI_IRQ_NONE)
340
                NCR5380_write(DTC_CONTROL_REG, CSR_DIR_READ);
341
        else
342
                NCR5380_write(DTC_CONTROL_REG, CSR_DIR_READ | CSR_INT_BASE);
343
        NCR5380_write(DTC_BLK_CNT, len >> 7);   /* Block count */
344
        rtrc(1);
345
        while (len > 0) {
346
                rtrc(2);
347
                while (NCR5380_read(DTC_CONTROL_REG) & CSR_HOST_BUF_NOT_RDY)
348
                        ++i;
349
                rtrc(3);
350
                isa_memcpy_fromio(d, base + DTC_DATA_BUF, 128);
351
                d += 128;
352
                len -= 128;
353
                rtrc(7);
354
                /*** with int's on, it sometimes hangs after here.
355
                 * Looks like something makes HBNR go away. */
356
        }
357
        rtrc(4);
358
        while (!(NCR5380_read(DTC_CONTROL_REG) & D_CR_ACCESS))
359
                ++i;
360
        NCR5380_write(MODE_REG, 0);      /* Clear the operating mode */
361
        rtrc(0);
362
        NCR5380_read(RESET_PARITY_INTERRUPT_REG);
363
        if (i > dtc_maxi)
364
                dtc_maxi = i;
365
        return (0);
366
}
367
 
368
/**
369
 *      NCR5380_pwrite          -       fast pseudo DMA write
370
 *      @instance: controller
371
 *      @dst: destination buffer
372
 *      @len: expected/max size
373
 *
374
 *      Fast 5380 pseudo-dma write function, writes len bytes to the
375
 *      controller mmio area from src.
376
 */
377
 
378
static inline int NCR5380_pwrite(struct Scsi_Host *instance, unsigned char *src, int len)
379
{
380
        int i;
381
        NCR5380_local_declare();
382
        NCR5380_setup(instance);
383
 
384
        NCR5380_read(RESET_PARITY_INTERRUPT_REG);
385
        NCR5380_write(MODE_REG, MR_ENABLE_EOP_INTR | MR_DMA_MODE);
386
        /* set direction (write) */
387
        if (instance->irq == SCSI_IRQ_NONE)
388
                NCR5380_write(DTC_CONTROL_REG, 0);
389
        else
390
                NCR5380_write(DTC_CONTROL_REG, CSR_5380_INTR);
391
        NCR5380_write(DTC_BLK_CNT, len >> 7);   /* Block count */
392
        for (i = 0; len > 0; ++i) {
393
                rtrc(5);
394
                /* Poll until the host buffer can accept data. */
395
                while (NCR5380_read(DTC_CONTROL_REG) & CSR_HOST_BUF_NOT_RDY)
396
                        ++i;
397
                rtrc(3);
398
                isa_memcpy_toio(base + DTC_DATA_BUF, src, 128);
399
                src += 128;
400
                len -= 128;
401
        }
402
        rtrc(4);
403
        while (!(NCR5380_read(DTC_CONTROL_REG) & D_CR_ACCESS))
404
                ++i;
405
        rtrc(6);
406
        /* Wait until the last byte has been sent to the disk */
407
        while (!(NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT))
408
                ++i;
409
        rtrc(7);
410
        /* Check for parity error here. fixme. */
411
        NCR5380_write(MODE_REG, 0);      /* Clear the operating mode */
412
        rtrc(0);
413
        if (i > dtc_wmaxi)
414
                dtc_wmaxi = i;
415
        return (0);
416
}
417
 
418
MODULE_LICENSE("GPL");
419
 
420
#include "NCR5380.c"
421
 
422
/* Eventually this will go into an include file, but this will be later */
423
static Scsi_Host_Template driver_template = DTC3x80;
424
#include "scsi_module.c"

powered by: WebSVN 2.1.0

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