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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [scsi/] [NCR53c406a.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
 *  NCR53c406.c
3
 *  Low-level SCSI driver for NCR53c406a chip.
4
 *  Copyright (C) 1994, 1995, 1996 Normunds Saumanis (normunds@fi.ibm.com)
5
 *
6
 *  LILO command line usage: ncr53c406a=<PORTBASE>[,<IRQ>[,<FASTPIO>]]
7
 *  Specify IRQ = 0 for non-interrupt driven mode.
8
 *  FASTPIO = 1 for fast pio mode, 0 for slow mode.
9
 *
10
 *  This program is free software; you can redistribute it and/or modify it
11
 *  under the terms of the GNU General Public License as published by the
12
 *  Free Software Foundation; either version 2, or (at your option) any
13
 *  later version.
14
 *
15
 *  This program is distributed in the hope that it will be useful, but
16
 *  WITHOUT ANY WARRANTY; without even the implied warranty of
17
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18
 *  General Public License for more details.
19
 *
20
 */
21
 
22
#define NCR53C406A_DEBUG 0
23
#define VERBOSE_NCR53C406A_DEBUG 0
24
 
25
/* Set this to 1 for PIO mode (recommended) or to 0 for DMA mode */
26
#define USE_PIO 1
27
 
28
#define USE_BIOS 0
29
/* #define BIOS_ADDR 0xD8000 */ /* define this if autoprobe fails */
30
/* #define PORT_BASE 0x330 */   /* define this if autoprobe fails */
31
/* #define IRQ_LEV   0  */      /* define this if autoprobe fails */
32
#define DMA_CHAN  5             /* this is ignored if DMA is disabled */
33
 
34
/* Set this to 0 if you encounter kernel lockups while transferring
35
 * data in PIO mode */
36
#define USE_FAST_PIO 1
37
 
38
/* ============= End of user configurable parameters ============= */
39
 
40
#include <linux/module.h>
41
 
42
#include <linux/errno.h>
43
#include <linux/ioport.h>
44
#include <linux/sched.h>
45
#include <linux/interrupt.h>
46
#include <linux/proc_fs.h>
47
#include <linux/stat.h>
48
#include <asm/io.h>
49
#include <asm/dma.h>
50
#include <asm/bitops.h>
51
#include <asm/irq.h>
52
 
53
#include <linux/blk.h>
54
#include "scsi.h"
55
#include "hosts.h"
56
#include "sd.h"
57
 
58
#include "NCR53c406a.h"
59
 
60
/* ============================================================= */
61
 
62
#define WATCHDOG 5000000
63
 
64
#define SYNC_MODE 0             /* Synchronous transfer mode */
65
 
66
#if DEBUG
67
#undef NCR53C406A_DEBUG
68
#define NCR53C406A_DEBUG 1
69
#endif
70
 
71
#if USE_PIO
72
#define USE_DMA 0
73
#else
74
#define USE_DMA 1
75
#endif
76
 
77
/* Default configuration */
78
#define C1_IMG   0x07           /* ID=7 */
79
#define C2_IMG   0x48           /* FE SCSI2 */
80
#if USE_DMA
81
#define C3_IMG   0x21           /* CDB TE */
82
#else
83
#define C3_IMG   0x20           /* CDB */
84
#endif
85
#define C4_IMG   0x04           /* ANE */
86
#define C5_IMG   0xb6           /* AA PI SIE POL */
87
 
88
#define REG0 (outb(C4_IMG, CONFIG4))
89
#define REG1 (outb(C5_IMG, CONFIG5))
90
 
91
#if NCR53C406A_DEBUG
92
#define DEB(x) x
93
#else
94
#define DEB(x)
95
#endif
96
 
97
#if VERBOSE_NCR53C406A_DEBUG
98
#define VDEB(x) x
99
#else
100
#define VDEB(x)
101
#endif
102
 
103
#define LOAD_DMA_COUNT(count) \
104
  outb(count & 0xff, TC_LSB); \
105
  outb((count >> 8) & 0xff, TC_MSB); \
106
  outb((count >> 16) & 0xff, TC_HIGH);
107
 
108
/* Chip commands */
109
#define DMA_OP               0x80
110
 
111
#define SCSI_NOP             0x00
112
#define FLUSH_FIFO           0x01
113
#define CHIP_RESET           0x02
114
#define SCSI_RESET           0x03
115
#define RESELECT             0x40
116
#define SELECT_NO_ATN        0x41
117
#define SELECT_ATN           0x42
118
#define SELECT_ATN_STOP      0x43
119
#define ENABLE_SEL           0x44
120
#define DISABLE_SEL          0x45
121
#define SELECT_ATN3          0x46
122
#define RESELECT3            0x47
123
#define TRANSFER_INFO        0x10
124
#define INIT_CMD_COMPLETE    0x11
125
#define MSG_ACCEPT           0x12
126
#define TRANSFER_PAD         0x18
127
#define SET_ATN              0x1a
128
#define RESET_ATN            0x1b
129
#define SEND_MSG             0x20
130
#define SEND_STATUS          0x21
131
#define SEND_DATA            0x22
132
#define DISCONN_SEQ          0x23
133
#define TERMINATE_SEQ        0x24
134
#define TARG_CMD_COMPLETE    0x25
135
#define DISCONN              0x27
136
#define RECV_MSG             0x28
137
#define RECV_CMD             0x29
138
#define RECV_DATA            0x2a
139
#define RECV_CMD_SEQ         0x2b
140
#define TARGET_ABORT_DMA     0x04
141
 
142
/*----------------------------------------------------------------*/
143
/* the following will set the monitor border color (useful to find
144
   where something crashed or gets stuck at */
145
/* 1 = blue
146
   2 = green
147
   3 = cyan
148
   4 = red
149
   5 = magenta
150
   6 = yellow
151
   7 = white
152
*/
153
 
154
#if NCR53C406A_DEBUG
155
#define rtrc(i) {inb(0x3da);outb(0x31,0x3c0);outb((i),0x3c0);}
156
#else
157
#define rtrc(i) {}
158
#endif
159
/*----------------------------------------------------------------*/
160
 
161
enum Phase {
162
    idle,
163
    data_out,
164
    data_in,
165
    command_ph,
166
    status_ph,
167
    message_out,
168
    message_in
169
};
170
 
171
/* Static function prototypes */
172
static  void NCR53c406a_intr(int, void *, struct pt_regs *);
173
static  void internal_done(Scsi_Cmnd *);
174
static  void wait_intr(void);
175
static  void chip_init(void);
176
static  void calc_port_addr(void);
177
#ifndef IRQ_LEV
178
static  int  irq_probe(void);
179
#endif
180
 
181
/* ================================================================= */
182
 
183
#if USE_BIOS
184
static void *bios_base = (void *)0;
185
#endif
186
 
187
#if PORT_BASE
188
static int   port_base = PORT_BASE;
189
#else
190
static int   port_base = 0;
191
#endif
192
 
193
#if IRQ_LEV
194
static int   irq_level = IRQ_LEV;
195
#else
196
static int   irq_level = -1; /* 0 is 'no irq', so use -1 for 'uninitialized'*/
197
#endif
198
 
199
#if USE_DMA
200
static int   dma_chan = 0;
201
#endif
202
 
203
#if USE_PIO
204
static int   fast_pio = USE_FAST_PIO;
205
#endif
206
 
207
static Scsi_Cmnd         *current_SC       = NULL;
208
static volatile int internal_done_flag = 0;
209
static volatile int internal_done_errcode = 0;
210
static char info_msg[256];
211
 
212
struct proc_dir_entry proc_scsi_NCR53c406a = {
213
    PROC_SCSI_NCR53C406A, 7, "NCR53c406a",
214
    S_IFDIR | S_IRUGO | S_IXUGO, 2
215
};
216
/* ================================================================= */
217
 
218
/* possible BIOS locations */
219
#if USE_BIOS
220
static void *addresses[] = {
221
    (void *)0xd8000,
222
    (void *)0xc8000
223
};
224
#define ADDRESS_COUNT (sizeof( addresses ) / sizeof( unsigned ))
225
#endif USE_BIOS
226
 
227
/* possible i/o port addresses */
228
static unsigned short ports[] = { 0x230, 0x330 };
229
#define PORT_COUNT (sizeof( ports ) / sizeof( unsigned short ))
230
 
231
/* possible interrupt channels */
232
static unsigned short intrs[] = { 10, 11, 12, 15 };
233
#define INTR_COUNT (sizeof( intrs ) / sizeof( unsigned short ))
234
 
235
/* signatures for NCR 53c406a based controllers */
236
#if USE_BIOS
237
struct signature {
238
    char *signature;
239
    int  sig_offset;
240
    int  sig_length;
241
} signatures[] = {
242
    /*          1         2         3         4         5         6 */
243
    /* 123456789012345678901234567890123456789012345678901234567890 */
244
    { "Copyright (C) Acculogic, Inc.\r\n2.8M Diskette Extension Bios ver 4.04.03 03/01/1993", 61, 82 },
245
};
246
#define SIGNATURE_COUNT (sizeof( signatures ) / sizeof( struct signature ))
247
#endif USE_BIOS
248
 
249
/* ============================================================ */
250
 
251
/* Control Register Set 0 */
252
static int TC_LSB;              /* transfer counter lsb         */
253
static int TC_MSB;              /* transfer counter msb */
254
static int SCSI_FIFO;           /* scsi fifo register   */
255
static int CMD_REG;             /* command register             */
256
static int STAT_REG;            /* status register              */
257
static int DEST_ID;             /* selection/reselection bus id */
258
static int INT_REG;             /* interrupt status register    */
259
static int SRTIMOUT;            /* select/reselect timeout reg  */
260
static int SEQ_REG;             /* sequence step register       */
261
static int SYNCPRD;             /* synchronous transfer period  */
262
static int FIFO_FLAGS;          /* indicates # of bytes in fifo */
263
static int SYNCOFF;             /* synchronous offset register  */
264
static int CONFIG1;             /* configuration register       */
265
static int CLKCONV;             /* clock conversion reg */
266
/*static int TESTREG;*/         /* test mode register           */
267
static int CONFIG2;             /* Configuration 2 Register     */
268
static int CONFIG3;             /* Configuration 3 Register     */
269
static int CONFIG4;             /* Configuration 4 Register     */
270
static int TC_HIGH;             /* Transfer Counter High */
271
/*static int FIFO_BOTTOM;*/     /* Reserve FIFO byte register   */
272
 
273
/* Control Register Set 1 */
274
/*static int JUMPER_SENSE;*/    /* Jumper sense port reg (r/w) */
275
/*static int SRAM_PTR;*/        /* SRAM address pointer reg (r/w) */
276
/*static int SRAM_DATA;*/       /* SRAM data register (r/w) */
277
static int PIO_FIFO;            /* PIO FIFO registers (r/w) */
278
/*static int PIO_FIFO1;*/       /*  */
279
/*static int PIO_FIFO2;*/       /*  */
280
/*static int PIO_FIFO3;*/       /*  */
281
static int PIO_STATUS;          /* PIO status (r/w) */
282
/*static int ATA_CMD;*/         /* ATA command/status reg (r/w) */
283
/*static int ATA_ERR;*/         /* ATA features/error register (r/w)*/
284
static int PIO_FLAG;            /* PIO flag interrupt enable (r/w) */
285
static int CONFIG5;             /* Configuration 5 register (r/w) */
286
/*static int SIGNATURE;*/       /* Signature Register (r) */
287
/*static int CONFIG6;*/         /* Configuration 6 register (r) */
288
 
289
/* ============================================================== */
290
 
291
#if USE_DMA
292
static __inline__ int
293
NCR53c406a_dma_setup (unsigned char *ptr,
294
                      unsigned int count,
295
                      unsigned char mode) {
296
    unsigned limit;
297
    unsigned long flags = 0;
298
 
299
    VDEB(printk("dma: before count=%d   ", count));
300
    if (dma_chan <=3) {
301
        if (count > 65536)
302
            count = 65536;
303
        limit = 65536 - (((unsigned) ptr) & 0xFFFF);
304
    } else {
305
        if (count > (65536<<1))
306
            count = (65536<<1);
307
        limit = (65536<<1) - (((unsigned) ptr) & 0x1FFFF);
308
    }
309
 
310
    if (count > limit) count = limit;
311
 
312
    VDEB(printk("after count=%d\n", count));
313
    if ((count & 1) || (((unsigned) ptr) & 1))
314
        panic ("NCR53c406a: attempted unaligned DMA transfer\n");
315
 
316
    save_flags(flags);
317
    cli();
318
    disable_dma(dma_chan);
319
    clear_dma_ff(dma_chan);
320
    set_dma_addr(dma_chan, (long) ptr);
321
    set_dma_count(dma_chan, count);
322
    set_dma_mode(dma_chan, mode);
323
    enable_dma(dma_chan);
324
    restore_flags(flags);
325
 
326
    return count;
327
}
328
 
329
static __inline__ int
330
NCR53c406a_dma_write(unsigned char *src, unsigned int count) {
331
    return NCR53c406a_dma_setup (src, count, DMA_MODE_WRITE);
332
}
333
 
334
static __inline__ int
335
NCR53c406a_dma_read(unsigned char *src, unsigned int count) {
336
    return NCR53c406a_dma_setup (src, count, DMA_MODE_READ);
337
}
338
 
339
static __inline__ int
340
NCR53c406a_dma_residual (void) {
341
    register int tmp;
342
    unsigned long flags = 0;
343
    save_flags(flags);
344
    cli();
345
    clear_dma_ff(dma_chan);
346
    tmp = get_dma_residue(dma_chan);
347
    restore_flags(flags);
348
 
349
    return tmp;
350
}
351
#endif USE_DMA
352
 
353
#if USE_PIO
354
static __inline__ int NCR53c406a_pio_read(unsigned char *request,
355
                                          unsigned int reqlen)
356
{
357
    int i;
358
    int len;    /* current scsi fifo size */
359
    unsigned long flags = 0;
360
 
361
    REG1;
362
    while (reqlen) {
363
        i = inb(PIO_STATUS);
364
        /*    VDEB(printk("pio_status=%x\n", i)); */
365
        if (i & 0x80)
366
            return 0;
367
 
368
        switch( i & 0x1e ) {
369
        default:
370
        case 0x10:
371
            len=0; break;
372
        case 0x0:
373
            len=1; break;
374
        case 0x8:
375
            len=42; break;
376
        case 0xc:
377
            len=84; break;
378
        case 0xe:
379
            len=128; break;
380
        }
381
 
382
        if ((i & 0x40) && len == 0) { /* fifo empty and interrupt occurred */
383
            return 0;
384
        }
385
 
386
        if (len) {
387
            if( len > reqlen )
388
                len = reqlen;
389
 
390
            save_flags(flags);
391
            cli();
392
            if( fast_pio && len > 3 ) {
393
                insl(PIO_FIFO,request,len>>2);
394
                request += len & 0xfc;
395
                reqlen -= len & 0xfc;
396
            }
397
            else {
398
                while(len--) {
399
                    *request++ = inb(PIO_FIFO);
400
                    reqlen--;
401
                }
402
            }
403
            restore_flags(flags);
404
        }
405
    }
406
    return 0;
407
}
408
 
409
static __inline__ int NCR53c406a_pio_write(unsigned char *request,
410
                                           unsigned int reqlen)
411
{
412
    int i = 0;
413
    int len;    /* current scsi fifo size */
414
    unsigned long flags = 0;
415
 
416
    REG1;
417
    while (reqlen && !(i&0x40)) {
418
        i = inb(PIO_STATUS);
419
        /*    VDEB(printk("pio_status=%x\n", i)); */
420
        if (i & 0x80)           /* error */
421
            return 0;
422
 
423
        switch( i & 0x1e ) {
424
        case 0x10:
425
            len=128; break;
426
        case 0x0:
427
            len=84; break;
428
        case 0x8:
429
            len=42; break;
430
        case 0xc:
431
            len=1; break;
432
        default:
433
        case 0xe:
434
            len=0; break;
435
        }
436
 
437
        if (len) {
438
            if( len > reqlen )
439
                len = reqlen;
440
 
441
            save_flags(flags);
442
            cli();
443
            if( fast_pio && len > 3 ) {
444
                outsl(PIO_FIFO,request,len>>2);
445
                request += len & 0xfc;
446
                reqlen -= len & 0xfc;
447
            }
448
            else {
449
                while(len--) {
450
                    outb(*request++, PIO_FIFO);
451
                    reqlen--;
452
                }
453
            }
454
            restore_flags(flags);
455
        }
456
    }
457
    return 0;
458
}
459
#endif USE_PIO
460
 
461
int
462
NCR53c406a_detect(Scsi_Host_Template * tpnt){
463
    struct Scsi_Host *shpnt;
464
#ifndef PORT_BASE
465
    int i;
466
#endif
467
 
468
#if USE_BIOS
469
    int ii, jj;
470
    bios_base = 0;
471
    /* look for a valid signature */
472
    for( ii=0; ii < ADDRESS_COUNT && !bios_base; ii++)
473
        for( jj=0; (jj < SIGNATURE_COUNT) && !bios_base; jj++)
474
            if(!memcmp((void *) addresses[ii]+signatures[jj].sig_offset,
475
                       (void *) signatures[jj].signature,
476
                       (int) signatures[jj].sig_length))
477
                bios_base=addresses[ii];
478
 
479
    if(!bios_base){
480
        printk("NCR53c406a: BIOS signature not found\n");
481
        return 0;
482
    }
483
 
484
    DEB(printk("NCR53c406a BIOS found at %X\n", (unsigned int) bios_base););
485
#endif USE_BIOS
486
 
487
#ifdef PORT_BASE
488
    if (check_region(port_base, 0x10)) /* ports already snatched */
489
        port_base = 0;
490
 
491
#else  /* autodetect */
492
    if (port_base) {            /* LILO override */
493
        if (check_region(port_base, 0x10))
494
            port_base = 0;
495
    }
496
    else {
497
        for(i=0;  i<PORT_COUNT && !port_base; i++){
498
            if(check_region(ports[i], 0x10)){
499
                DEB(printk("NCR53c406a: port %x in use\n", ports[i]));
500
            }
501
            else {
502
                VDEB(printk("NCR53c406a: port %x available\n", ports[i]));
503
                outb(C5_IMG, ports[i] + 0x0d); /* reg set 1 */
504
                if(   (inb(ports[i] + 0x0e) ^ inb(ports[i] + 0x0e)) == 7
505
                   && (inb(ports[i] + 0x0e) ^ inb(ports[i] + 0x0e)) == 7
506
                   && (inb(ports[i] + 0x0e) & 0xf8) == 0x58 ) {
507
                    VDEB(printk("NCR53c406a: Sig register valid\n"));
508
                    VDEB(printk("port_base=%x\n", port_base));
509
                    port_base = ports[i];
510
                }
511
            }
512
        }
513
    }
514
#endif PORT_BASE
515
 
516
    if(!port_base){             /* no ports found */
517
        printk("NCR53c406a: no available ports found\n");
518
        return 0;
519
    }
520
 
521
    DEB(printk("NCR53c406a detected\n"));
522
 
523
    calc_port_addr();
524
    chip_init();
525
 
526
#ifndef IRQ_LEV
527
    if (irq_level < 0) {         /* LILO override if >= 0*/
528
        irq_level=irq_probe();
529
        if (irq_level < 0) {             /* Trouble */
530
            printk("NCR53c406a: IRQ problem, irq_level=%d, giving up\n", irq_level);
531
            return 0;
532
        }
533
    }
534
#endif
535
 
536
    DEB(printk("NCR53c406a: using port_base %x\n", port_base));
537
    request_region(port_base, 0x10, "NCR53c406a");
538
 
539
    if(irq_level > 0) {
540
        if(request_irq(irq_level, NCR53c406a_intr, 0, "NCR53c406a", NULL)){
541
            printk("NCR53c406a: unable to allocate IRQ %d\n", irq_level);
542
            return 0;
543
        }
544
        tpnt->can_queue = 1;
545
        DEB(printk("NCR53c406a: allocated IRQ %d\n", irq_level));
546
    }
547
    else if (irq_level == 0) {
548
        tpnt->can_queue = 0;
549
        DEB(printk("NCR53c406a: No interrupts detected\n"));
550
#if USE_DMA
551
        printk("NCR53c406a: No interrupts found and DMA mode defined. Giving up.\n");
552
        return 0;
553
#endif USE_DMA
554
    }
555
    else {
556
        DEB(printk("NCR53c406a: Shouldn't get here!\n"));
557
        return 0;
558
    }
559
 
560
#if USE_DMA
561
    dma_chan = DMA_CHAN;
562
    if(request_dma(dma_chan, "NCR53c406a") != 0){
563
        printk("NCR53c406a: unable to allocate DMA channel %d\n", dma_chan);
564
        return 0;
565
    }
566
 
567
    DEB(printk("Allocated DMA channel %d\n", dma_chan));
568
#endif USE_DMA 
569
 
570
    tpnt->present = 1;
571
    tpnt->proc_dir = &proc_scsi_NCR53c406a;
572
 
573
    shpnt = scsi_register(tpnt, 0);
574
    shpnt->irq = irq_level;
575
    shpnt->io_port = port_base;
576
    shpnt->n_io_port = 0x10;
577
#if USE_DMA
578
    shpnt->dma = dma_chan;
579
#endif
580
 
581
#if USE_DMA
582
    sprintf(info_msg, "NCR53c406a at 0x%x, IRQ %d, DMA channel %d.",
583
            port_base, irq_level, dma_chan);
584
#else
585
    sprintf(info_msg, "NCR53c406a at 0x%x, IRQ %d, %s PIO mode.",
586
            port_base, irq_level, fast_pio ? "fast" : "slow");
587
#endif
588
 
589
    return (tpnt->present);
590
}
591
 
592
/* called from init/main.c */
593
void NCR53c406a_setup(char *str, int *ints)
594
{
595
    static size_t setup_idx = 0;
596
    size_t i;
597
 
598
    DEB(printk("NCR53c406a: Setup called\n"););
599
 
600
    if (setup_idx >= PORT_COUNT - 1) {
601
        printk("NCR53c406a: Setup called too many times.  Bad LILO params?\n");
602
        return;
603
    }
604
    if (ints[0] < 1 || ints[0] > 3) {
605
        printk("NCR53c406a: Malformed command line\n");
606
        printk("NCR53c406a: Usage: ncr53c406a=<PORTBASE>[,<IRQ>[,<FASTPIO>]]\n");
607
        return;
608
    }
609
    for (i = 0; i < PORT_COUNT && !port_base; i++)
610
        if (ports[i] == ints[1]) {
611
            port_base = ints[1];
612
            DEB(printk("NCR53c406a: Specified port_base 0x%X\n", port_base);)
613
        }
614
    if (!port_base) {
615
        printk("NCR53c406a: Invalid PORTBASE 0x%X specified\n", ints[1]);
616
        return;
617
    }
618
 
619
    if (ints[0] > 1) {
620
        if (ints[2] == 0) {
621
            irq_level = 0;
622
            DEB(printk("NCR53c406a: Specified irq %d\n", irq_level);)
623
        }
624
        else
625
            for (i = 0; i < INTR_COUNT && irq_level < 0; i++)
626
                if (intrs[i] == ints[2]) {
627
                    irq_level = ints[2];
628
                    DEB(printk("NCR53c406a: Specified irq %d\n", port_base);)
629
                }
630
        if (irq_level < 0)
631
            printk("NCR53c406a: Invalid IRQ %d specified\n", ints[2]);
632
    }
633
 
634
    if (ints[0] > 2)
635
        fast_pio = ints[3];
636
 
637
    DEB(printk("NCR53c406a: port_base=0x%X, irq=%d, fast_pio=%d\n",
638
               port_base, irq_level, fast_pio);)
639
}
640
 
641
const char*
642
NCR53c406a_info(struct Scsi_Host *SChost){
643
    DEB(printk("NCR53c406a_info called\n"));
644
    return (info_msg);
645
}
646
 
647
static void internal_done(Scsi_Cmnd *SCpnt) {
648
    internal_done_errcode = SCpnt->result;
649
    ++internal_done_flag;
650
}
651
 
652
 
653
static void wait_intr() {
654
    int i = jiffies + WATCHDOG;
655
 
656
    while(i>jiffies && !(inb(STAT_REG)&0xe0)) /* wait for a pseudo-interrupt */
657
        barrier();
658
 
659
    if (i <= jiffies) {         /* Timed out */
660
        rtrc(0);
661
        current_SC->result = DID_TIME_OUT << 16;
662
        current_SC->SCp.phase = idle;
663
        current_SC->scsi_done(current_SC);
664
        return;
665
    }
666
 
667
    NCR53c406a_intr(0, NULL, NULL);
668
}
669
 
670
int NCR53c406a_command(Scsi_Cmnd *SCpnt){
671
    DEB(printk("NCR53c406a_command called\n"));
672
    NCR53c406a_queue(SCpnt, internal_done);
673
    if(irq_level)
674
        while (!internal_done_flag);
675
    else                        /* interrupts not supported */
676
        while (!internal_done_flag)
677
            wait_intr();
678
 
679
    internal_done_flag = 0;
680
    return internal_done_errcode;
681
}
682
 
683
 
684
int
685
NCR53c406a_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)){
686
    int i;
687
    unsigned long flags = 0;
688
 
689
    VDEB(printk("NCR53c406a_queue called\n"));
690
    DEB(printk("cmd=%02x, cmd_len=%02x, target=%02x, lun=%02x, bufflen=%d\n",
691
               SCpnt->cmnd[0],
692
               SCpnt->cmd_len,
693
               SCpnt->target,
694
               SCpnt->lun,
695
               SCpnt->request_bufflen));
696
 
697
#if 0
698
    VDEB(for(i=0; i<SCpnt->cmd_len; i++)
699
         printk("cmd[%d]=%02x  ", i, SCpnt->cmnd[i]));
700
    VDEB(printk("\n"));
701
#endif
702
 
703
    current_SC = SCpnt;
704
    current_SC->scsi_done = done;
705
    current_SC->SCp.phase = command_ph;
706
    current_SC->SCp.Status = 0;
707
    current_SC->SCp.Message = 0;
708
 
709
    save_flags(flags);
710
    cli();
711
    REG0;
712
    outb(SCpnt->target, DEST_ID); /* set destination */
713
    outb(FLUSH_FIFO, CMD_REG);  /* reset the fifos */
714
 
715
    for(i=0; i<SCpnt->cmd_len; i++){
716
        outb(SCpnt->cmnd[i], SCSI_FIFO);
717
    }
718
    outb(SELECT_NO_ATN, CMD_REG);
719
    restore_flags(flags);
720
 
721
    rtrc(1);
722
    return 0;
723
}
724
 
725
int
726
NCR53c406a_abort(Scsi_Cmnd *SCpnt){
727
    DEB(printk("NCR53c406a_abort called\n"));
728
    return SCSI_ABORT_SNOOZE;   /* Don't know how to abort */
729
}
730
 
731
int
732
NCR53c406a_reset(Scsi_Cmnd *SCpnt, unsigned int flags){
733
    DEB(printk("NCR53c406a_reset called\n"));
734
    outb(C4_IMG, CONFIG4);      /* Select reg set 0 */
735
    outb(CHIP_RESET, CMD_REG);
736
    outb(SCSI_NOP, CMD_REG);    /* required after reset */
737
    outb(SCSI_RESET, CMD_REG);
738
    chip_init();
739
 
740
    rtrc(2);
741
    if (irq_level)
742
        return SCSI_RESET_PENDING; /* should get an interrupt */
743
    else
744
        return SCSI_RESET_WAKEUP; /* won't get any interrupts */
745
}
746
 
747
int
748
NCR53c406a_biosparm(Scsi_Disk *disk, kdev_t dev, int* info_array){
749
    int size;
750
 
751
    DEB(printk("NCR53c406a_biosparm called\n"));
752
 
753
    size = disk->capacity;
754
    info_array[0] = 64;         /* heads */
755
    info_array[1] = 32;         /* sectors */
756
    info_array[2] = size>>11;   /* cylinders */
757
    if (info_array[2] > 1024) { /* big disk */
758
      info_array[0] = 255;
759
      info_array[1] = 63;
760
      info_array[2] = size / (255*63);
761
    }
762
    return 0;
763
  }
764
 
765
     static void
766
NCR53c406a_intr(int unused, void *dev_id, struct pt_regs *regs){
767
    DEB(unsigned char fifo_size;)
768
    DEB(unsigned char seq_reg;)
769
    unsigned char status, int_reg;
770
    unsigned long flags = 0;
771
#if USE_PIO
772
    unsigned char pio_status;
773
    struct scatterlist *sglist;
774
    unsigned int sgcount;
775
#endif
776
 
777
    VDEB(printk("NCR53c406a_intr called\n"));
778
 
779
    save_flags(flags);
780
    cli();
781
#if USE_PIO
782
    REG1;
783
    pio_status = inb(PIO_STATUS);
784
#endif
785
    REG0;
786
    status = inb(STAT_REG);
787
    DEB(seq_reg = inb(SEQ_REG));
788
    int_reg = inb(INT_REG);
789
    DEB(fifo_size = inb(FIFO_FLAGS) & 0x1f);
790
    restore_flags(flags);
791
 
792
#if NCR53C406A_DEBUG
793
    printk("status=%02x, seq_reg=%02x, int_reg=%02x, fifo_size=%02x",
794
           status, seq_reg, int_reg, fifo_size);
795
#if (USE_DMA)
796
    printk("\n");
797
#else
798
    printk(", pio=%02x\n", pio_status);
799
#endif USE_DMA
800
#endif NCR53C406A_DEBUG
801
 
802
    if(int_reg & 0x80){         /* SCSI reset intr */
803
        rtrc(3);
804
        DEB(printk("NCR53c406a: reset intr received\n"));
805
        current_SC->SCp.phase = idle;
806
        current_SC->result = DID_RESET << 16;
807
        current_SC->scsi_done(current_SC);
808
        return;
809
    }
810
 
811
#if USE_PIO
812
    if(pio_status & 0x80) {
813
        printk("NCR53C406A: Warning: PIO error!\n");
814
        current_SC->SCp.phase = idle;
815
        current_SC->result = DID_ERROR << 16;
816
        current_SC->scsi_done(current_SC);
817
        return;
818
    }
819
#endif USE_PIO
820
 
821
    if(status & 0x20) {         /* Parity error */
822
        printk("NCR53c406a: Warning: parity error!\n");
823
        current_SC->SCp.phase = idle;
824
        current_SC->result = DID_PARITY << 16;
825
        current_SC->scsi_done(current_SC);
826
        return;
827
    }
828
 
829
    if(status & 0x40) {         /* Gross error */
830
        printk("NCR53c406a: Warning: gross error!\n");
831
        current_SC->SCp.phase = idle;
832
        current_SC->result = DID_ERROR << 16;
833
        current_SC->scsi_done(current_SC);
834
        return;
835
    }
836
 
837
    if(int_reg & 0x20){         /* Disconnect */
838
        DEB(printk("NCR53c406a: disconnect intr received\n"));
839
        if(current_SC->SCp.phase != message_in){ /* Unexpected disconnect */
840
            current_SC->result = DID_NO_CONNECT << 16;
841
        }
842
        else{  /* Command complete, return status and message */
843
            current_SC->result = (current_SC->SCp.Status & 0xff)
844
                | ((current_SC->SCp.Message & 0xff) << 8) | (DID_OK << 16);
845
        }
846
 
847
        rtrc(0);
848
        current_SC->SCp.phase = idle;
849
        current_SC->scsi_done( current_SC );
850
        return;
851
    }
852
 
853
    switch(status & 0x07){      /* scsi phase */
854
    case 0x00:                  /* DATA-OUT */
855
        if(int_reg & 0x10){     /* Target requesting info transfer */
856
            rtrc(5);
857
            current_SC->SCp.phase = data_out;
858
            VDEB(printk("NCR53c406a: Data-Out phase\n"));
859
            outb(FLUSH_FIFO, CMD_REG);
860
            LOAD_DMA_COUNT(current_SC->request_bufflen); /* Max transfer size */
861
#if USE_DMA                     /* No s/g support for DMA */
862
            NCR53c406a_dma_write(current_SC->request_buffer,
863
                                 current_SC->request_bufflen);
864
#endif USE_DMA
865
            outb(TRANSFER_INFO | DMA_OP, CMD_REG);
866
#if USE_PIO
867
            if (!current_SC->use_sg) /* Don't use scatter-gather */
868
                NCR53c406a_pio_write(current_SC->request_buffer,
869
                                     current_SC->request_bufflen);
870
            else {              /* use scatter-gather */
871
                sgcount = current_SC->use_sg;
872
                sglist = current_SC->request_buffer;
873
                while( sgcount-- ) {
874
                    NCR53c406a_pio_write(sglist->address, sglist->length);
875
                    sglist++;
876
                }
877
            }
878
            REG0;
879
#endif USE_PIO
880
        }
881
        break;
882
 
883
    case 0x01:                  /* DATA-IN */
884
        if(int_reg & 0x10){     /* Target requesting info transfer */
885
            rtrc(6);
886
            current_SC->SCp.phase = data_in;
887
            VDEB(printk("NCR53c406a: Data-In phase\n"));
888
            outb(FLUSH_FIFO, CMD_REG);
889
            LOAD_DMA_COUNT(current_SC->request_bufflen); /* Max transfer size */
890
#if USE_DMA                     /* No s/g support for DMA */
891
            NCR53c406a_dma_read(current_SC->request_buffer,
892
                                current_SC->request_bufflen);
893
#endif USE_DMA
894
            outb(TRANSFER_INFO | DMA_OP, CMD_REG);
895
#if USE_PIO
896
            if (!current_SC->use_sg) /* Don't use scatter-gather */
897
                NCR53c406a_pio_read(current_SC->request_buffer,
898
                                    current_SC->request_bufflen);
899
            else {              /* Use scatter-gather */
900
                sgcount = current_SC->use_sg;
901
                sglist = current_SC->request_buffer;
902
                while( sgcount-- ) {
903
                    NCR53c406a_pio_read(sglist->address, sglist->length);
904
                    sglist++;
905
                }
906
            }
907
            REG0;
908
#endif USE_PIO
909
        }
910
        break;
911
 
912
    case 0x02:                  /* COMMAND */
913
        current_SC->SCp.phase = command_ph;
914
        printk("NCR53c406a: Warning: Unknown interrupt occurred in command phase!\n");
915
        break;
916
 
917
    case 0x03:                  /* STATUS */
918
        rtrc(7);
919
        current_SC->SCp.phase = status_ph;
920
        VDEB(printk("NCR53c406a: Status phase\n"));
921
        outb(FLUSH_FIFO, CMD_REG);
922
        outb(INIT_CMD_COMPLETE, CMD_REG);
923
        break;
924
 
925
    case 0x04:                  /* Reserved */
926
    case 0x05:                  /* Reserved */
927
        printk("NCR53c406a: WARNING: Reserved phase!!!\n");
928
        break;
929
 
930
    case 0x06:                  /* MESSAGE-OUT */
931
        DEB(printk("NCR53c406a: Message-Out phase\n"));
932
        current_SC->SCp.phase = message_out;
933
        outb(SET_ATN, CMD_REG); /* Reject the message */
934
        outb(MSG_ACCEPT, CMD_REG);
935
        break;
936
 
937
    case 0x07:                  /* MESSAGE-IN */
938
        rtrc(4);
939
        VDEB(printk("NCR53c406a: Message-In phase\n"));
940
        current_SC->SCp.phase = message_in;
941
 
942
        current_SC->SCp.Status = inb(SCSI_FIFO);
943
        current_SC->SCp.Message = inb(SCSI_FIFO);
944
 
945
        VDEB(printk("SCSI FIFO size=%d\n", inb(FIFO_FLAGS) & 0x1f));
946
        DEB(printk("Status = %02x  Message = %02x\n",
947
                   current_SC->SCp.Status, current_SC->SCp.Message));
948
 
949
        if(current_SC->SCp.Message == SAVE_POINTERS ||
950
           current_SC->SCp.Message == DISCONNECT) {
951
            outb(SET_ATN, CMD_REG); /* Reject message */
952
            DEB(printk("Discarding SAVE_POINTERS message\n"));
953
        }
954
        outb(MSG_ACCEPT, CMD_REG);
955
        break;
956
    }
957
}
958
 
959
#ifndef IRQ_LEV
960
static int irq_probe()
961
{
962
    int irqs, irq;
963
    int i;
964
 
965
    inb(INT_REG);               /* clear the interrupt register */
966
    sti();
967
    irqs = probe_irq_on();
968
 
969
    /* Invalid command will cause an interrupt */
970
    REG0;
971
    outb(0xff, CMD_REG);
972
 
973
    /* Wait for the interrupt to occur */
974
    i = jiffies + WATCHDOG;
975
    while(i > jiffies && !(inb(STAT_REG) & 0x80))
976
        barrier();
977
    if (i <= jiffies) {         /* Timed out, must be hardware trouble */
978
        probe_irq_off(irqs);
979
        return -1;
980
    }
981
 
982
    irq = probe_irq_off(irqs);
983
 
984
    /* Kick the chip */
985
    outb(CHIP_RESET, CMD_REG);
986
    outb(SCSI_NOP, CMD_REG);
987
    chip_init();
988
 
989
    return irq;
990
}
991
#endif IRQ_LEV
992
 
993
static void chip_init()
994
{
995
    REG1;
996
#if USE_DMA
997
    outb(0x00, PIO_STATUS);
998
#else  /* USE_PIO */
999
    outb(0x01, PIO_STATUS);
1000
#endif
1001
    outb(0x00, PIO_FLAG);
1002
 
1003
    outb(C4_IMG, CONFIG4);      /* REG0; */
1004
    outb(C3_IMG, CONFIG3);
1005
    outb(C2_IMG, CONFIG2);
1006
    outb(C1_IMG, CONFIG1);
1007
 
1008
    outb(0x05, CLKCONV);        /* clock conversion factor */
1009
    outb(0x9C, SRTIMOUT);       /* Selection timeout */
1010
    outb(0x05, SYNCPRD);        /* Synchronous transfer period */
1011
    outb(SYNC_MODE, SYNCOFF);   /* synchronous mode */
1012
}
1013
 
1014
void calc_port_addr()
1015
{
1016
    /* Control Register Set 0 */
1017
    TC_LSB              = (port_base+0x00);
1018
    TC_MSB              = (port_base+0x01);
1019
    SCSI_FIFO           = (port_base+0x02);
1020
    CMD_REG             = (port_base+0x03);
1021
    STAT_REG            = (port_base+0x04);
1022
    DEST_ID             = (port_base+0x04);
1023
    INT_REG             = (port_base+0x05);
1024
    SRTIMOUT            = (port_base+0x05);
1025
    SEQ_REG             = (port_base+0x06);
1026
    SYNCPRD             = (port_base+0x06);
1027
    FIFO_FLAGS          = (port_base+0x07);
1028
    SYNCOFF             = (port_base+0x07);
1029
    CONFIG1             = (port_base+0x08);
1030
    CLKCONV             = (port_base+0x09);
1031
    /* TESTREG          = (port_base+0x0A); */
1032
    CONFIG2             = (port_base+0x0B);
1033
    CONFIG3             = (port_base+0x0C);
1034
    CONFIG4             = (port_base+0x0D);
1035
    TC_HIGH             = (port_base+0x0E);
1036
    /* FIFO_BOTTOM      = (port_base+0x0F); */
1037
 
1038
    /* Control Register Set 1 */
1039
    /* JUMPER_SENSE     = (port_base+0x00);*/
1040
    /* SRAM_PTR         = (port_base+0x01);*/
1041
    /* SRAM_DATA        = (port_base+0x02);*/
1042
    PIO_FIFO            = (port_base+0x04);
1043
    /* PIO_FIFO1        = (port_base+0x05);*/
1044
    /* PIO_FIFO2        = (port_base+0x06);*/
1045
    /* PIO_FIFO3        = (port_base+0x07);*/
1046
    PIO_STATUS          = (port_base+0x08);
1047
    /* ATA_CMD          = (port_base+0x09);*/
1048
    /* ATA_ERR          = (port_base+0x0A);*/
1049
    PIO_FLAG            = (port_base+0x0B);
1050
    CONFIG5             = (port_base+0x0D);
1051
    /* SIGNATURE        = (port_base+0x0E);*/
1052
    /* CONFIG6          = (port_base+0x0F);*/
1053
}
1054
 
1055
#ifdef MODULE
1056
/* Eventually this will go into an include file, but this will be later */
1057
Scsi_Host_Template driver_template = NCR53c406a;
1058
 
1059
#include "scsi_module.c"
1060
#endif
1061
 
1062
/*
1063
 * Overrides for Emacs so that we get a uniform tabbing style.
1064
 * Emacs will notice this stuff at the end of the file and automatically
1065
 * adjust the settings for this buffer only.  This must remain at the end
1066
 * of the file.
1067
 * ---------------------------------------------------------------------------
1068
 * Local variables:
1069
 * c-indent-level: 4
1070
 * c-brace-imaginary-offset: 0
1071
 * c-brace-offset: -4
1072
 * c-argdecl-indent: 4
1073
 * c-label-offset: -4
1074
 * c-continued-statement-offset: 4
1075
 * c-continued-brace-offset: 0
1076
 * indent-tabs-mode: nil
1077
 * tab-width: 8
1078
 * End:
1079
 */

powered by: WebSVN 2.1.0

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