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

Subversion Repositories or1k

[/] [or1k/] [tags/] [before_ORP/] [uclinux/] [uClinux-2.0.x/] [drivers/] [scsi/] [g_NCR5380.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 199 simons
/*
2
 * Generic Generic NCR5380 driver
3
 *
4
 * Copyright 1993, Drew Eckhardt
5
 *      Visionary Computing
6
 *      (Unix and Linux consulting and custom programming)
7
 *      drew@colorado.edu
8
 *      +1 (303) 440-4894
9
 *
10
 * NCR53C400 extensions (c) 1994,1995,1996, Kevin Lentin
11
 *    K.Lentin@cs.monash.edu.au
12
 *
13
 * ALPHA RELEASE 1.
14
 *
15
 * For more information, please consult
16
 *
17
 * NCR 5380 Family
18
 * SCSI Protocol Controller
19
 * Databook
20
 *
21
 * NCR Microelectronics
22
 * 1635 Aeroplaza Drive
23
 * Colorado Springs, CO 80916
24
 * 1+ (719) 578-3400
25
 * 1+ (800) 334-5454
26
 */
27
 
28
/*
29
 * TODO : flesh out DMA support, find some one actually using this (I have
30
 *      a memory mapped Trantor board that works fine)
31
 */
32
 
33
/*
34
 * Options :
35
 *
36
 * PARITY - enable parity checking.  Not supported.
37
 *
38
 * SCSI2 - enable support for SCSI-II tagged queueing.  Untested.
39
 *
40
 * USLEEP - enable support for devices that don't disconnect.  Untested.
41
 *
42
 * The card is detected and initialized in one of several ways :
43
 * 1.  With command line overrides - NCR5380=port,irq may be
44
 *     used on the LILO command line to override the defaults.
45
 *
46
 * 2.  With the GENERIC_NCR5380_OVERRIDE compile time define.  This is
47
 *     specified as an array of address, irq, dma, board tuples.  Ie, for
48
 *     one board at 0x350, IRQ5, no dma, I could say
49
 *     -DGENERIC_NCR5380_OVERRIDE={{0xcc000, 5, DMA_NONE, BOARD_NCR5380}}
50
 *
51
 * -1 should be specified for no or DMA interrupt, -2 to autoprobe for an
52
 *      IRQ line if overridden on the command line.
53
 *
54
 * 3.  When included as a module, with arguments passed on the command line:
55
 *         ncr_irq=xx   the interrupt
56
 *         ncr_addr=xx  the port or base address (for port or memory
57
 *                      mapped, resp.)
58
 *         ncr_dma=xx   the DMA
59
 *         ncr_5380=1   to set up for a NCR5380 board
60
 *         ncr_53c400=1 to set up for a NCR53C400 board
61
 *     e.g.
62
 *     modprobe g_NCR5380 ncr_irq=5 ncr_addr=0x350 ncr_5380=1
63
 *       for a port mapped NCR5380 board or
64
 *     modprobe g_NCR5380 ncr_irq=255 ncr_addr=0xc8000 ncr_53c400=1
65
 *       for a memory mapped NCR53C400 board with interrupts disabled.
66
 *
67
 * 255 should be specified for no or DMA interrupt, 254 to autoprobe for an
68
 *      IRQ line if overridden on the command line.
69
 *
70
 */
71
 
72
/*
73
 * $Log: not supported by cvs2svn $
74
 * Revision 1.1.1.1  2001/07/02 17:58:27  simons
75
 * Initial revision
76
 *
77
 */
78
 
79
#define AUTOPROBE_IRQ
80
#define AUTOSENSE
81
 
82
#include <linux/config.h>
83
 
84
#ifdef CONFIG_SCSI_GENERIC_NCR53C400
85
#define NCR53C400_PSEUDO_DMA 1
86
#define PSEUDO_DMA
87
#define NCR53C400
88
#define NCR5380_STATS
89
#undef NCR5380_STAT_LIMIT
90
#endif
91
#if defined(CONFIG_SCSI_G_NCR5380_PORT) && defined(CONFIG_SCSI_G_NCR5380_MEM)
92
#error You can not configure the Generic NCR 5380 SCSI Driver for memory mapped I/O and port mapped I/O at the same time (yet)
93
#endif
94
#if !defined(CONFIG_SCSI_G_NCR5380_PORT) && !defined(CONFIG_SCSI_G_NCR5380_MEM)
95
#error You must configure the Generic NCR 5380 SCSI Driver for one of memory mapped I/O and port mapped I/O.
96
#endif
97
 
98
#include <asm/system.h>
99
#include <asm/io.h>
100
#include <linux/signal.h>
101
#include <linux/sched.h>
102
#include <linux/blk.h>
103
#include "scsi.h"
104
#include "hosts.h"
105
#include "g_NCR5380.h"
106
#include "NCR5380.h"
107
#include "constants.h"
108
#include "sd.h"
109
#include<linux/stat.h>
110
 
111
struct proc_dir_entry proc_scsi_g_ncr5380 = {
112
    PROC_SCSI_GENERIC_NCR5380, 9, "g_NCR5380",
113
    S_IFDIR | S_IRUGO | S_IXUGO, 2
114
};
115
 
116
#define NCR_NOT_SET 0
117
static int ncr_irq=NCR_NOT_SET;
118
static int ncr_dma=NCR_NOT_SET;
119
static int ncr_addr=NCR_NOT_SET;
120
static int ncr_5380=NCR_NOT_SET;
121
static int ncr_53c400=NCR_NOT_SET;
122
 
123
static struct override {
124
        NCR5380_implementation_fields;
125
    int irq;
126
    int dma;
127
    int board;  /* Use NCR53c400, Ricoh, etc. extensions ? */
128
} overrides
129
#ifdef GENERIC_NCR5380_OVERRIDE 
130
    [] = GENERIC_NCR5380_OVERRIDE
131
#else
132
    [1] = {{0,},};
133
#endif
134
 
135
#define NO_OVERRIDES (sizeof(overrides) / sizeof(struct override))
136
 
137
/*
138
 * Function : static internal_setup(int board, char *str, int *ints)
139
 *
140
 * Purpose : LILO command line initialization of the overrides array,
141
 *
142
 * Inputs : board - either BOARD_NCR5380 for a normal NCR5380 board,
143
 *      or BOARD_NCR53C400 for a NCR53C400 board. str - unused, ints -
144
 *      array of integer parameters with ints[0] equal to the number of ints.
145
 *
146
 */
147
 
148
static void internal_setup(int board, char *str, int *ints) {
149
    static int commandline_current = 0;
150
    switch (board) {
151
    case BOARD_NCR5380:
152
        if (ints[0] != 2 && ints[0] != 3) {
153
            printk("generic_NCR5380_setup : usage ncr5380=" STRVAL(NCR5380_map_name) ",irq,dma\n");
154
            return;
155
        }
156
    case BOARD_NCR53C400:
157
        if (ints[0] != 2) {
158
            printk("generic_NCR53C400_setup : usage ncr53c400=" STRVAL(NCR5380_map_name) ",irq\n");
159
            return;
160
        }
161
    }
162
 
163
    if (commandline_current < NO_OVERRIDES) {
164
        overrides[commandline_current].NCR5380_map_name = (NCR5380_map_type)ints[1];
165
        overrides[commandline_current].irq = ints[2];
166
        if (ints[0] == 3)
167
            overrides[commandline_current].dma = ints[3];
168
        else
169
            overrides[commandline_current].dma = DMA_NONE;
170
        overrides[commandline_current].board = board;
171
            ++commandline_current;
172
    }
173
}
174
 
175
/*
176
 * Function : generic_NCR5380_setup (char *str, int *ints)
177
 *
178
 * Purpose : LILO command line initialization of the overrides array,
179
 *
180
 * Inputs : str - unused, ints - array of integer parameters with ints[0]
181
 *      equal to the number of ints.
182
 */
183
 
184
void generic_NCR5380_setup (char *str, int *ints) {
185
    internal_setup (BOARD_NCR5380, str, ints);
186
}
187
 
188
/*
189
 * Function : generic_NCR53C400_setup (char *str, int *ints)
190
 *
191
 * Purpose : LILO command line initialization of the overrides array,
192
 *
193
 * Inputs : str - unused, ints - array of integer parameters with ints[0]
194
 *      equal to the number of ints.
195
 */
196
 
197
void generic_NCR53C400_setup (char *str, int *ints) {
198
    internal_setup (BOARD_NCR53C400, str, ints);
199
}
200
 
201
/*
202
 * Function : int generic_NCR5380_detect(Scsi_Host_Template * tpnt)
203
 *
204
 * Purpose : initializes generic NCR5380 driver based on the
205
 *      command line / compile time port and irq definitions.
206
 *
207
 * Inputs : tpnt - template for this SCSI adapter.
208
 *
209
 * Returns : 1 if a host adapter was found, 0 if not.
210
 *
211
 */
212
 
213
int generic_NCR5380_detect(Scsi_Host_Template * tpnt) {
214
    static int current_override = 0;
215
    int count;
216
    int flags = 0;
217
    struct Scsi_Host *instance;
218
 
219
    if (ncr_irq != NCR_NOT_SET)
220
        overrides[0].irq=ncr_irq;
221
    if (ncr_dma != NCR_NOT_SET)
222
        overrides[0].dma=ncr_dma;
223
    if (ncr_addr != NCR_NOT_SET)
224
        overrides[0].NCR5380_map_name=(NCR5380_map_type)ncr_addr;
225
    if (ncr_5380 != NCR_NOT_SET)
226
        overrides[0].board=BOARD_NCR5380;
227
    else if (ncr_53c400 != NCR_NOT_SET)
228
        overrides[0].board=BOARD_NCR53C400;
229
 
230
    tpnt->proc_dir = &proc_scsi_g_ncr5380;
231
 
232
    for (count = 0; current_override < NO_OVERRIDES; ++current_override) {
233
        if (!(overrides[current_override].NCR5380_map_name))
234
            continue;
235
 
236
        switch (overrides[current_override].board) {
237
        case BOARD_NCR5380:
238
            flags = FLAG_NO_PSEUDO_DMA;
239
            break;
240
        case BOARD_NCR53C400:
241
            flags = FLAG_NCR53C400;
242
            break;
243
        }
244
 
245
        instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata));
246
        instance->NCR5380_instance_name = overrides[current_override].NCR5380_map_name;
247
 
248
        NCR5380_init(instance, flags);
249
 
250
        if (overrides[current_override].irq != IRQ_AUTO)
251
            instance->irq = overrides[current_override].irq;
252
        else
253
            instance->irq = NCR5380_probe_irq(instance, 0xffff);
254
 
255
        if (instance->irq != IRQ_NONE)
256
            if (request_irq(instance->irq, generic_NCR5380_intr, SA_INTERRUPT, "NCR5380", NULL)) {
257
                printk("scsi%d : IRQ%d not free, interrupts disabled\n",
258
                    instance->host_no, instance->irq);
259
                instance->irq = IRQ_NONE;
260
            }
261
 
262
        if (instance->irq == IRQ_NONE) {
263
            printk("scsi%d : interrupts not enabled. for better interactive performance,\n", instance->host_no);
264
            printk("scsi%d : please jumper the board for a free IRQ.\n", instance->host_no);
265
        }
266
 
267
        printk("scsi%d : at " STRVAL(NCR5380_map_name) " 0x%x", instance->host_no, (unsigned int)instance->NCR5380_instance_name);
268
        if (instance->irq == IRQ_NONE)
269
            printk (" interrupts disabled");
270
        else
271
            printk (" irq %d", instance->irq);
272
        printk(" options CAN_QUEUE=%d  CMD_PER_LUN=%d release=%d",
273
            CAN_QUEUE, CMD_PER_LUN, GENERIC_NCR5380_PUBLIC_RELEASE);
274
        NCR5380_print_options(instance);
275
        printk("\n");
276
 
277
        ++current_override;
278
        ++count;
279
    }
280
    return count;
281
}
282
 
283
const char * generic_NCR5380_info (struct Scsi_Host* host) {
284
    static const char string[]="Generic NCR5380/53C400 Driver";
285
    return string;
286
}
287
 
288
int generic_NCR5380_release_resources(struct Scsi_Host * instance)
289
{
290
    NCR5380_local_declare();
291
 
292
    NCR5380_setup(instance);
293
 
294
    if (instance->irq != IRQ_NONE)
295
        free_irq(instance->irq, NULL);
296
 
297
        return 0;
298
}
299
 
300
#ifdef BIOSPARAM
301
/*
302
 * Function : int generic_NCR5380_biosparam(Disk * disk, kdev_t dev, int *ip)
303
 *
304
 * Purpose : Generates a BIOS / DOS compatible H-C-S mapping for
305
 *      the specified device / size.
306
 *
307
 * Inputs : size = size of device in sectors (512 bytes), dev = block device
308
 *      major / minor, ip[] = {heads, sectors, cylinders}
309
 *
310
 * Returns : always 0 (success), initializes ip
311
 *
312
 */
313
 
314
/*
315
 * XXX Most SCSI boards use this mapping, I could be incorrect.  Some one
316
 * using hard disks on a trantor should verify that this mapping corresponds
317
 * to that used by the BIOS / ASPI driver by running the linux fdisk program
318
 * and matching the H_C_S coordinates to what DOS uses.
319
 */
320
 
321
int generic_NCR5380_biosparam(Disk * disk, kdev_t dev, int *ip)
322
{
323
  int size = disk->capacity;
324
  ip[0] = 64;
325
  ip[1] = 32;
326
  ip[2] = size >> 11;
327
  return 0;
328
}
329
#endif
330
 
331
#if NCR53C400_PSEUDO_DMA
332
static inline int NCR5380_pread (struct Scsi_Host *instance, unsigned char *dst,    int len)
333
{
334
    int blocks = len / 128;
335
    int start = 0;
336
    int i;
337
    int bl;
338
    NCR5380_local_declare();
339
 
340
    NCR5380_setup(instance);
341
 
342
#if (NDEBUG & NDEBUG_C400_PREAD)
343
    printk("53C400r: About to read %d blocks for %d bytes\n", blocks, len);
344
#endif
345
 
346
    NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE | CSR_TRANS_DIR);
347
    NCR5380_write(C400_BLOCK_COUNTER_REG, blocks);
348
    while (1) {
349
 
350
#if (NDEBUG & NDEBUG_C400_PREAD)
351
        printk("53C400r: %d blocks left\n", blocks);
352
#endif
353
 
354
        if ((bl=NCR5380_read(C400_BLOCK_COUNTER_REG)) == 0) {
355
#if (NDEBUG & NDEBUG_C400_PREAD)
356
            if (blocks)
357
                printk("53C400r: blocks still == %d\n", blocks);
358
            else
359
                printk("53C400r: Exiting loop\n");
360
#endif
361
            break;
362
        }
363
 
364
#if 1
365
        if (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ) {
366
            printk("53C400r: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks);
367
            return -1;
368
        }
369
#endif
370
 
371
#if (NDEBUG & NDEBUG_C400_PREAD)
372
        printk("53C400r: Waiting for buffer, bl=%d\n", bl);
373
#endif
374
 
375
        while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
376
            ;
377
#if (NDEBUG & NDEBUG_C400_PREAD)
378
        printk("53C400r: Transferring 128 bytes\n");
379
#endif
380
 
381
#ifdef CONFIG_SCSI_G_NCR5380_PORT
382
        for (i=0; i<128; i++)
383
            dst[start+i] = NCR5380_read(C400_HOST_BUFFER);
384
#else
385
        /* implies CONFIG_SCSI_G_NCR5380_MEM */
386
        memmove(dst+start,NCR53C400_host_buffer+NCR5380_map_name,128);
387
#endif
388
        start+=128;
389
        blocks--;
390
    }
391
 
392
    if (blocks) {
393
#if (NDEBUG & NDEBUG_C400_PREAD)
394
        printk("53C400r: EXTRA: Waiting for buffer\n");
395
#endif
396
        while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
397
            ;
398
 
399
#if (NDEBUG & NDEBUG_C400_PREAD)
400
        printk("53C400r: Transferring EXTRA 128 bytes\n");
401
#endif
402
#ifdef CONFIG_SCSI_G_NCR5380_PORT
403
        for (i=0; i<128; i++)
404
            dst[start+i] = NCR5380_read(C400_HOST_BUFFER);
405
#else
406
        /* implies CONFIG_SCSI_G_NCR5380_MEM */
407
        memmove(dst+start,NCR53C400_host_buffer+NCR5380_map_name,128);
408
#endif
409
        start+=128;
410
        blocks--;
411
    }
412
#if (NDEBUG & NDEBUG_C400_PREAD)
413
    else
414
        printk("53C400r: No EXTRA required\n");
415
#endif
416
 
417
#if (NDEBUG & NDEBUG_C400_PREAD)
418
    printk("53C400r: Final values: blocks=%d   start=%d\n", blocks, start);
419
#endif
420
 
421
    if (!(NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ))
422
        printk("53C400r: no 53C80 gated irq after transfer");
423
#if (NDEBUG & NDEBUG_C400_PREAD)
424
    else
425
        printk("53C400r: Got 53C80 interrupt and tried to clear it\n");
426
#endif
427
 
428
/* DON'T DO THIS - THEY NEVER ARRIVE!
429
    printk("53C400r: Waiting for 53C80 registers\n");
430
    while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_53C80_REG)
431
        ;
432
*/
433
 
434
    if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER))
435
        printk("53C400r: no end dma signal\n");
436
#if (NDEBUG & NDEBUG_C400_PREAD)
437
    else
438
        printk("53C400r: end dma as expected\n");
439
#endif
440
 
441
    NCR5380_write(MODE_REG, MR_BASE);
442
    NCR5380_read(RESET_PARITY_INTERRUPT_REG);
443
    return 0;
444
}
445
 
446
static inline int NCR5380_pwrite (struct Scsi_Host *instance, unsigned char *src,    int len)
447
{
448
    int blocks = len / 128;
449
    int start = 0;
450
    int i;
451
    int bl;
452
    NCR5380_local_declare();
453
 
454
    NCR5380_setup(instance);
455
 
456
#if (NDEBUG & NDEBUG_C400_PWRITE)
457
    printk("53C400w: About to write %d blocks for %d bytes\n", blocks, len);
458
#endif
459
 
460
    NCR5380_write(C400_CONTROL_STATUS_REG, CSR_BASE);
461
    NCR5380_write(C400_BLOCK_COUNTER_REG, blocks);
462
    while (1) {
463
        if (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ) {
464
            printk("53C400w: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks);
465
            return -1;
466
        }
467
 
468
        if ((bl=NCR5380_read(C400_BLOCK_COUNTER_REG)) == 0) {
469
#if (NDEBUG & NDEBUG_C400_PWRITE)
470
            if (blocks)
471
                printk("53C400w: exiting loop, blocks still == %d\n", blocks);
472
            else
473
                printk("53C400w: exiting loop\n");
474
#endif
475
            break;
476
        }
477
 
478
#if (NDEBUG & NDEBUG_C400_PWRITE)
479
        printk("53C400w: %d blocks left\n", blocks);
480
 
481
        printk("53C400w: waiting for buffer, bl=%d\n", bl);
482
#endif
483
        while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
484
            ;
485
 
486
#if (NDEBUG & NDEBUG_C400_PWRITE)
487
        printk("53C400w: transferring 128 bytes\n");
488
#endif
489
#ifdef CONFIG_SCSI_G_NCR5380_PORT
490
        for (i=0; i<128; i++)
491
            NCR5380_write(C400_HOST_BUFFER, src[start+i]);
492
#else
493
        /* implies CONFIG_SCSI_G_NCR5380_MEM */
494
        memmove(NCR53C400_host_buffer+NCR5380_map_name,src+start,128);
495
#endif
496
        start+=128;
497
        blocks--;
498
    }
499
    if (blocks) {
500
#if (NDEBUG & NDEBUG_C400_PWRITE)
501
        printk("53C400w: EXTRA waiting for buffer\n");
502
#endif
503
        while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_HOST_BUF_NOT_RDY)
504
            ;
505
 
506
#if (NDEBUG & NDEBUG_C400_PWRITE)
507
        printk("53C400w: transferring EXTRA 128 bytes\n");
508
#endif
509
#ifdef CONFIG_SCSI_G_NCR5380_PORT
510
        for (i=0; i<128; i++)
511
            NCR5380_write(C400_HOST_BUFFER, src[start+i]);
512
#else
513
        /* implies CONFIG_SCSI_G_NCR5380_MEM */
514
        memmove(NCR53C400_host_buffer+NCR5380_map_name,src+start,128);
515
#endif
516
        start+=128;
517
        blocks--;
518
    }
519
#if (NDEBUG & NDEBUG_C400_PWRITE)
520
    else
521
        printk("53C400w: No EXTRA required\n");
522
#endif
523
 
524
#if (NDEBUG & NDEBUG_C400_PWRITE)
525
    printk("53C400w: Final values: blocks=%d   start=%d\n", blocks, start);
526
#endif
527
 
528
#if 0
529
    printk("53C400w: waiting for registers to be available\n");
530
    THEY NEVER DO!
531
    while (NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_53C80_REG)
532
        ;
533
    printk("53C400w: Got em\n");
534
#endif
535
 
536
    /* Let's wait for this instead - could be ugly */
537
    /* All documentation says to check for this. Maybe my hardware is too
538
     * fast. Waiting for it seems to work fine! KLL
539
     */
540
    while (!(i = NCR5380_read(C400_CONTROL_STATUS_REG) & CSR_GATED_53C80_IRQ))
541
        ;
542
 
543
    /*
544
     * I know. i is certainly != 0 here but the loop is new. See previous
545
     * comment.
546
     */
547
    if (i) {
548
#if (NDEBUG & NDEBUG_C400_PWRITE)
549
        printk("53C400w: got 53C80 gated irq (last block)\n");
550
#endif
551
        if (!((i=NCR5380_read(BUS_AND_STATUS_REG)) & BASR_END_DMA_TRANSFER))
552
            printk("53C400w: No END OF DMA bit - WHOOPS! BASR=%0x\n",i);
553
#if (NDEBUG & NDEBUG_C400_PWRITE)
554
        else
555
            printk("53C400w: Got END OF DMA\n");
556
#endif
557
    }
558
    else
559
        printk("53C400w: no 53C80 gated irq after transfer (last block)\n");
560
 
561
#if 0
562
    if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER)) {
563
        printk("53C400w: no end dma signal\n");
564
    }
565
#endif
566
 
567
#if (NDEBUG & NDEBUG_C400_PWRITE)
568
    printk("53C400w: waiting for last byte...\n");
569
#endif
570
    while (!(NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT))
571
        ;
572
 
573
#if (NDEBUG & NDEBUG_C400_PWRITE)
574
    printk("53C400w:     got last byte.\n");
575
    printk("53C400w: pwrite exiting with status 0, whoopee!\n");
576
#endif
577
    return 0;
578
}
579
#endif /* PSEUDO_DMA */
580
 
581
#include "NCR5380.c"
582
 
583
#define PRINTP(x) len += sprintf(buffer+len, x)
584
#define ANDP ,
585
 
586
static int sprint_opcode(char* buffer, int len, int opcode) {
587
    int start = len;
588
    PRINTP("0x%02x " ANDP opcode);
589
    return len-start;
590
}
591
 
592
static int sprint_command (char* buffer, int len, unsigned char *command) {
593
    int i,s,start=len;
594
    len += sprint_opcode(buffer, len, command[0]);
595
    for ( i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i)
596
        PRINTP("%02x " ANDP command[i]);
597
    PRINTP("\n");
598
    return len-start;
599
}
600
 
601
static int sprint_Scsi_Cmnd (char* buffer, int len, Scsi_Cmnd *cmd) {
602
    int start = len;
603
    PRINTP("host number %d destination target %d, lun %d\n" ANDP
604
       cmd->host->host_no ANDP
605
       cmd->target ANDP
606
       cmd->lun);
607
    PRINTP("        command = ");
608
    len += sprint_command (buffer, len, cmd->cmnd);
609
    return len-start;
610
}
611
 
612
int generic_NCR5380_proc_info(char* buffer, char** start, off_t offset, int length, int hostno, int inout)
613
{
614
    int len = 0;
615
    NCR5380_local_declare();
616
    unsigned char status;
617
    int i;
618
    struct Scsi_Host *scsi_ptr;
619
    Scsi_Cmnd *ptr;
620
    Scsi_Device *dev;
621
    struct NCR5380_hostdata *hostdata;
622
 
623
    cli();
624
 
625
    for (scsi_ptr = first_instance; scsi_ptr; scsi_ptr=scsi_ptr->next)
626
        if (scsi_ptr->host_no == hostno)
627
            break;
628
    NCR5380_setup(scsi_ptr);
629
    hostdata = (struct NCR5380_hostdata *)scsi_ptr->hostdata;
630
 
631
    PRINTP("SCSI host number %d : %s\n" ANDP scsi_ptr->host_no ANDP scsi_ptr->hostt->name);
632
    PRINTP("Generic NCR5380 driver version %d\n" ANDP GENERIC_NCR5380_PUBLIC_RELEASE);
633
    PRINTP("NCR5380 core version %d\n" ANDP NCR5380_PUBLIC_RELEASE);
634
#ifdef NCR53C400
635
    PRINTP("NCR53C400 extension version %d\n" ANDP NCR53C400_PUBLIC_RELEASE);
636
    PRINTP("NCR53C400 card%s detected\n" ANDP  (((struct NCR5380_hostdata *)scsi_ptr->hostdata)->flags & FLAG_NCR53C400)?"":" not");
637
# if NCR53C400_PSEUDO_DMA
638
    PRINTP("NCR53C400 pseudo DMA used\n");
639
# endif
640
#else
641
    PRINTP("NO NCR53C400 driver extensions\n");
642
#endif
643
    PRINTP("Using %s mapping at %s 0x%x, " ANDP STRVAL(NCR5380_map_config) ANDP STRVAL(NCR5380_map_name) ANDP scsi_ptr->NCR5380_instance_name);
644
    if (scsi_ptr->irq == IRQ_NONE)
645
        PRINTP("no interrupt\n");
646
    else
647
        PRINTP("on interrupt %d\n" ANDP scsi_ptr->irq);
648
 
649
#ifdef NCR5380_STATS
650
    if (hostdata->connected || hostdata->issue_queue || hostdata->disconnected_queue)
651
        PRINTP("There are commands pending, transfer rates may be crud\n");
652
    if (hostdata->pendingr)
653
        PRINTP("  %d pending reads" ANDP hostdata->pendingr);
654
    if (hostdata->pendingw)
655
        PRINTP("  %d pending writes" ANDP hostdata->pendingw);
656
    if (hostdata->pendingr || hostdata->pendingw)
657
        PRINTP("\n");
658
    for (dev = scsi_devices; dev; dev=dev->next) {
659
        if (dev->host == scsi_ptr) {
660
            unsigned long br = hostdata->bytes_read[dev->id];
661
            unsigned long bw = hostdata->bytes_write[dev->id];
662
            long tr = hostdata->time_read[dev->id] / HZ;
663
            long tw = hostdata->time_write[dev->id] / HZ;
664
 
665
            PRINTP("  T:%d %s " ANDP dev->id ANDP (dev->type < MAX_SCSI_DEVICE_CODE) ? scsi_device_types[(int)dev->type] : "Unknown");
666
            for (i=0; i<8; i++)
667
                if (dev->vendor[i] >= 0x20)
668
                    *(buffer+(len++)) = dev->vendor[i];
669
            *(buffer+(len++)) = ' ';
670
            for (i=0; i<16; i++)
671
                if (dev->model[i] >= 0x20)
672
                    *(buffer+(len++)) = dev->model[i];
673
            *(buffer+(len++)) = ' ';
674
            for (i=0; i<4; i++)
675
                if (dev->rev[i] >= 0x20)
676
                    *(buffer+(len++)) = dev->rev[i];
677
            *(buffer+(len++)) = ' ';
678
 
679
            PRINTP("\n%10ld kb read    in %5ld secs" ANDP br/1024 ANDP tr);
680
            if (tr)
681
                PRINTP(" @ %5ld bps" ANDP br / tr);
682
 
683
            PRINTP("\n%10ld kb written in %5ld secs" ANDP bw/1024 ANDP tw);
684
            if (tw)
685
                PRINTP(" @ %5ld bps" ANDP bw / tw);
686
            PRINTP("\n");
687
        }
688
    }
689
#endif
690
 
691
    status = NCR5380_read(STATUS_REG);
692
    if (!(status & SR_REQ))
693
        PRINTP("REQ not asserted, phase unknown.\n");
694
    else {
695
        for (i = 0; (phases[i].value != PHASE_UNKNOWN) &&
696
                    (phases[i].value != (status & PHASE_MASK)); ++i)
697
            ;
698
        PRINTP("Phase %s\n" ANDP phases[i].name);
699
    }
700
 
701
    if (!hostdata->connected) {
702
        PRINTP("No currently connected command\n");
703
    } else {
704
        len += sprint_Scsi_Cmnd (buffer, len, (Scsi_Cmnd *) hostdata->connected);
705
    }
706
 
707
    PRINTP("issue_queue\n");
708
 
709
    for (ptr = (Scsi_Cmnd *) hostdata->issue_queue; ptr;
710
                ptr = (Scsi_Cmnd *) ptr->host_scribble)
711
        len += sprint_Scsi_Cmnd (buffer, len, ptr);
712
 
713
    PRINTP("disconnected_queue\n");
714
 
715
    for (ptr = (Scsi_Cmnd *) hostdata->disconnected_queue; ptr;
716
                ptr = (Scsi_Cmnd *) ptr->host_scribble)
717
        len += sprint_Scsi_Cmnd (buffer, len, ptr);
718
 
719
    *start = buffer + offset;
720
    len -= offset;
721
    if (len > length)
722
            len = length;
723
    sti();
724
    return len;
725
}
726
 
727
#undef PRINTP
728
#undef ANDP
729
 
730
#ifdef MODULE
731
/* Eventually this will go into an include file, but this will be later */
732
Scsi_Host_Template driver_template = GENERIC_NCR5380;
733
 
734
#include <linux/module.h>
735
#include "scsi_module.c"
736
#endif

powered by: WebSVN 2.1.0

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