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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [scsi/] [g_NCR5380.c] - Blame information for rev 1777

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

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

powered by: WebSVN 2.1.0

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