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

Subversion Repositories or1k

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

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

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

powered by: WebSVN 2.1.0

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