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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1626 jcastillo
/*  $Id: aha1740.c,v 1.1 2005-12-20 10:17:45 jcastillo Exp $
2
 *  1993/03/31
3
 *  linux/kernel/aha1740.c
4
 *
5
 *  Based loosely on aha1542.c which is
6
 *  Copyright (C) 1992  Tommy Thorn and
7
 *  Modified by Eric Youngdale
8
 *
9
 *  This file is aha1740.c, written and
10
 *  Copyright (C) 1992,1993  Brad McLean
11
 *
12
 *  Modifications to makecode and queuecommand
13
 *  for proper handling of multiple devices courteously
14
 *  provided by Michael Weller, March, 1993
15
 *
16
 *  Multiple adapter support, extended translation detection,
17
 *  update to current scsi subsystem changes, proc fs support,
18
 *  working (!) module support based on patches from Andreas Arens,
19
 *  by Andreas Degert <ad@papyrus.hamburg.com>, 2/1997
20
 *
21
 * aha1740_makecode may still need even more work
22
 * if it doesn't work for your devices, take a look.
23
 */
24
 
25
#ifdef MODULE
26
#include <linux/module.h>
27
#endif
28
 
29
#include <linux/kernel.h>
30
#include <linux/head.h>
31
#include <linux/types.h>
32
#include <linux/string.h>
33
#include <linux/ioport.h>
34
#include <linux/proc_fs.h>
35
#include <linux/sched.h>
36
#include <asm/dma.h>
37
 
38
#include <asm/system.h>
39
#include <asm/io.h>
40
#include <linux/blk.h>
41
#include "scsi.h"
42
#include "hosts.h"
43
#include "sd.h"
44
 
45
#include "aha1740.h"
46
#include<linux/stat.h>
47
 
48
struct proc_dir_entry proc_scsi_aha1740 = {
49
    PROC_SCSI_AHA1740, 7, "aha1740",
50
    S_IFDIR | S_IRUGO | S_IXUGO, 2
51
};
52
 
53
/* IF YOU ARE HAVING PROBLEMS WITH THIS DRIVER, AND WANT TO WATCH
54
   IT WORK, THEN:
55
#define DEBUG
56
*/
57
#ifdef DEBUG
58
#define DEB(x) x
59
#else
60
#define DEB(x)
61
#endif
62
 
63
/*
64
static const char RCSid[] = "$Header: /home/marcus/revision_ctrl_test/oc_cvs/cvs/or1k/rc203soc/sw/uClinux/drivers/scsi/aha1740.c,v 1.1 2005-12-20 10:17:45 jcastillo Exp $";
65
*/
66
 
67
struct aha1740_hostdata {
68
    unsigned int slot;
69
    unsigned int translation;
70
    unsigned int last_ecb_used;
71
    struct ecb ecb[AHA1740_ECBS];
72
};
73
 
74
#define HOSTDATA(host) ((struct aha1740_hostdata *) &host->hostdata)
75
 
76
/* One for each IRQ level (9-15) */
77
static struct Scsi_Host * aha_host[8] = {NULL, };
78
 
79
int aha1740_proc_info(char *buffer, char **start, off_t offset,
80
                      int length, int hostno, int inout)
81
{
82
    int len;
83
    struct Scsi_Host * shpnt;
84
    struct aha1740_hostdata *host;
85
 
86
    if (inout)
87
        return(-ENOSYS);
88
 
89
    for (len = 0; len < 8; len++) {
90
        shpnt = aha_host[len];
91
        if (shpnt && shpnt->host_no == hostno)
92
            break;
93
    }
94
    host = HOSTDATA(shpnt);
95
 
96
    len = sprintf(buffer, "aha174x at IO:%x, IRQ %d, SLOT %d.\n"
97
                  "Extended translation %sabled.\n",
98
                  shpnt->io_port, shpnt->irq, host->slot,
99
                  host->translation ? "en" : "dis");
100
 
101
    if (offset > len) {
102
        *start = buffer;
103
        return 0;
104
    }
105
 
106
    *start = buffer + offset;
107
    len -= offset;
108
    if (len > length)
109
        len = length;
110
    return len;
111
}
112
 
113
 
114
int aha1740_makecode(unchar *sense, unchar *status)
115
{
116
    struct statusword
117
    {
118
        ushort  don:1,  /* Command Done - No Error */
119
                du:1,   /* Data underrun */
120
        :1,     qf:1,   /* Queue full */
121
                sc:1,   /* Specification Check */
122
                dor:1,  /* Data overrun */
123
                ch:1,   /* Chaining Halted */
124
                intr:1, /* Interrupt issued */
125
                asa:1,  /* Additional Status Available */
126
                sns:1,  /* Sense information Stored */
127
        :1,     ini:1,  /* Initialization Required */
128
                me:1,   /* Major error or exception */
129
        :1,     eca:1,  /* Extended Contingent alliance */
130
        :1;
131
    } status_word;
132
    int retval = DID_OK;
133
 
134
    status_word = * (struct statusword *) status;
135
#ifdef DEBUG
136
    printk("makecode from %x,%x,%x,%x %x,%x,%x,%x",
137
           status[0], status[1], status[2], status[3],
138
           sense[0], sense[1], sense[2], sense[3]);
139
#endif
140
    if (!status_word.don) /* Anything abnormal was detected */
141
    {
142
        if ( (status[1]&0x18) || status_word.sc ) /*Additional info available*/
143
        {
144
            /* Use the supplied info for further diagnostics */
145
            switch ( status[2] )
146
            {
147
            case 0x12:
148
                if ( status_word.dor )
149
                    retval=DID_ERROR;   /* It's an Overrun */
150
                /* If not overrun, assume underrun and ignore it! */
151
            case 0x00: /* No info, assume no error, should not occur */
152
                break;
153
            case 0x11:
154
            case 0x21:
155
                retval=DID_TIME_OUT;
156
                break;
157
            case 0x0a:
158
                retval=DID_BAD_TARGET;
159
                break;
160
            case 0x04:
161
            case 0x05:
162
                retval=DID_ABORT;
163
                /* Either by this driver or the AHA1740 itself */
164
                break;
165
            default:
166
                retval=DID_ERROR; /* No further diagnostics possible */
167
            }
168
        }
169
        else
170
        { /* Michael suggests, and Brad concurs: */
171
            if ( status_word.qf )
172
            {
173
                retval = DID_TIME_OUT; /* forces a redo */
174
                /* I think this specific one should not happen -Brad */
175
                printk("aha1740.c: WARNING: AHA1740 queue overflow!\n");
176
            }
177
            else if ( status[0]&0x60 )
178
            {
179
                retval = DID_ERROR; /* Didn't find a better error */
180
            }
181
            /* In any other case return DID_OK so for example
182
               CONDITION_CHECKS make it through to the appropriate
183
               device driver */
184
        }
185
    }
186
    /* Under all circumstances supply the target status -Michael */
187
    return status[3] | retval << 16;
188
}
189
 
190
int aha1740_test_port(unsigned int base)
191
{
192
    char name[4], tmp;
193
 
194
    /* Okay, look for the EISA ID's */
195
    name[0]= 'A' -1 + ((tmp = inb(HID0(base))) >> 2); /* First character */
196
    name[1]= 'A' -1 + ((tmp & 3) << 3);
197
    name[1]+= ((tmp = inb(HID1(base))) >> 5)&0x7;       /* Second Character */
198
    name[2]= 'A' -1 + (tmp & 0x1f);             /* Third Character */
199
    name[3]=0;
200
    tmp = inb(HID2(base));
201
    if ( strcmp ( name, HID_MFG ) || inb(HID2(base)) != HID_PRD )
202
        return 0;   /* Not an Adaptec 174x */
203
 
204
/*  if ( inb(HID3(base)) != HID_REV )
205
        printk("aha174x: Warning; board revision of %d; expected %d\n",
206
            inb(HID3(base)),HID_REV); */
207
 
208
    if ( inb(EBCNTRL(base)) != EBCNTRL_VALUE )
209
    {
210
        printk("aha174x: Board detected, but EBCNTRL = %x, so disabled it.\n",
211
            inb(EBCNTRL(base)));
212
        return 0;
213
    }
214
 
215
    if ( inb(PORTADR(base)) & PORTADDR_ENH )
216
        return 1;   /* Okay, we're all set */
217
 
218
    printk("aha174x: Board detected, but not in enhanced mode, so disabled it.\n");
219
    return 0;
220
}
221
 
222
/* A "high" level interrupt handler */
223
void aha1740_intr_handle(int irq, void *dev_id, struct pt_regs * regs)
224
{
225
    void (*my_done)(Scsi_Cmnd *);
226
    int errstatus, adapstat;
227
    int number_serviced;
228
    struct ecb *ecbptr;
229
    Scsi_Cmnd *SCtmp;
230
    unsigned int base;
231
 
232
    if (!aha_host[irq - 9])
233
        panic("aha1740.c: Irq from unknown host!\n");
234
    base = aha_host[irq - 9]->io_port;
235
    number_serviced = 0;
236
 
237
    while(inb(G2STAT(base)) & G2STAT_INTPEND)
238
    {
239
        DEB(printk("aha1740_intr top of loop.\n"));
240
        adapstat = inb(G2INTST(base));
241
        ecbptr = (struct ecb *) bus_to_virt(inl(MBOXIN0(base)));
242
        outb(G2CNTRL_IRST,G2CNTRL(base)); /* interrupt reset */
243
 
244
        switch ( adapstat & G2INTST_MASK )
245
        {
246
        case    G2INTST_CCBRETRY:
247
        case    G2INTST_CCBERROR:
248
        case    G2INTST_CCBGOOD:
249
            /* Host Ready -> Mailbox in complete */
250
            outb(G2CNTRL_HRDY,G2CNTRL(base));
251
            if (!ecbptr)
252
            {
253
                printk("Aha1740 null ecbptr in interrupt (%x,%x,%x,%d)\n",
254
                       inb(G2STAT(base)),adapstat,
255
                       inb(G2INTST(base)), number_serviced++);
256
                continue;
257
            }
258
            SCtmp = ecbptr->SCpnt;
259
            if (!SCtmp)
260
            {
261
                printk("Aha1740 null SCtmp in interrupt (%x,%x,%x,%d)\n",
262
                       inb(G2STAT(base)),adapstat,
263
                       inb(G2INTST(base)), number_serviced++);
264
                continue;
265
            }
266
            if (SCtmp->host_scribble)
267
                scsi_free(SCtmp->host_scribble, 512);
268
            /* Fetch the sense data, and tuck it away, in the required slot.
269
               The Adaptec automatically fetches it, and there is no
270
               guarantee that we will still have it in the cdb when we come
271
               back */
272
            if ( (adapstat & G2INTST_MASK) == G2INTST_CCBERROR )
273
            {
274
                memcpy(SCtmp->sense_buffer, ecbptr->sense,
275
                       sizeof(SCtmp->sense_buffer));
276
                errstatus = aha1740_makecode(ecbptr->sense,ecbptr->status);
277
            }
278
            else
279
                errstatus = 0;
280
            DEB(if (errstatus) printk("aha1740_intr_handle: returning %6x\n",
281
                                      errstatus));
282
            SCtmp->result = errstatus;
283
            my_done = ecbptr->done;
284
            memset(ecbptr,0,sizeof(struct ecb));
285
            if ( my_done )
286
                my_done(SCtmp);
287
            break;
288
        case    G2INTST_HARDFAIL:
289
            printk(KERN_ALERT "aha1740 hardware failure!\n");
290
            panic("aha1740.c"); /* Goodbye */
291
        case    G2INTST_ASNEVENT:
292
            printk("aha1740 asynchronous event: %02x %02x %02x %02x %02x\n",
293
                   adapstat, inb(MBOXIN0(base)), inb(MBOXIN1(base)),
294
                   inb(MBOXIN2(base)), inb(MBOXIN3(base))); /* Say What? */
295
            /* Host Ready -> Mailbox in complete */
296
            outb(G2CNTRL_HRDY,G2CNTRL(base));
297
            break;
298
        case    G2INTST_CMDGOOD:
299
            /* set immediate command success flag here: */
300
            break;
301
        case    G2INTST_CMDERROR:
302
            /* Set immediate command failure flag here: */
303
            break;
304
        }
305
        number_serviced++;
306
    }
307
}
308
 
309
int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
310
{
311
    unchar direction;
312
    unchar *cmd = (unchar *) SCpnt->cmnd;
313
    unchar target = SCpnt->target;
314
    struct aha1740_hostdata *host = HOSTDATA(SCpnt->host);
315
    unsigned long flags;
316
    void *buff = SCpnt->request_buffer;
317
    int bufflen = SCpnt->request_bufflen;
318
    int ecbno;
319
    DEB(int i);
320
 
321
    if(*cmd == REQUEST_SENSE)
322
    {
323
        if (bufflen != sizeof(SCpnt->sense_buffer))
324
        {
325
            printk("Wrong buffer length supplied for request sense (%d)\n",
326
                   bufflen);
327
        }
328
        SCpnt->result = 0;
329
        done(SCpnt);
330
        return 0;
331
    }
332
 
333
#ifdef DEBUG
334
    if (*cmd == READ_10 || *cmd == WRITE_10)
335
        i = xscsi2int(cmd+2);
336
    else if (*cmd == READ_6 || *cmd == WRITE_6)
337
        i = scsi2int(cmd+2);
338
    else
339
        i = -1;
340
    printk("aha1740_queuecommand: dev %d cmd %02x pos %d len %d ",
341
           target, *cmd, i, bufflen);
342
    printk("scsi cmd:");
343
    for (i = 0; i < SCpnt->cmd_len; i++) printk("%02x ", cmd[i]);
344
    printk("\n");
345
#endif
346
 
347
    /* locate an available ecb */
348
    save_flags(flags);
349
    cli();
350
    ecbno = host->last_ecb_used + 1;            /* An optimization */
351
    if (ecbno >= AHA1740_ECBS)
352
        ecbno = 0;
353
    do {
354
        if (!host->ecb[ecbno].cmdw)
355
            break;
356
        ecbno++;
357
        if (ecbno >= AHA1740_ECBS)
358
            ecbno = 0;
359
    } while (ecbno != host->last_ecb_used);
360
 
361
    if (host->ecb[ecbno].cmdw)
362
        panic("Unable to find empty ecb for aha1740.\n");
363
 
364
    host->ecb[ecbno].cmdw = AHA1740CMD_INIT;    /* SCSI Initiator Command
365
                                                   doubles as reserved flag */
366
 
367
    host->last_ecb_used = ecbno;
368
    restore_flags(flags);
369
 
370
#ifdef DEBUG
371
    printk("Sending command (%d %x)...", ecbno, done);
372
#endif
373
 
374
    host->ecb[ecbno].cdblen = SCpnt->cmd_len;   /* SCSI Command Descriptor Block Length */
375
 
376
    direction = 0;
377
    if (*cmd == READ_10 || *cmd == READ_6)
378
        direction = 1;
379
    else if (*cmd == WRITE_10 || *cmd == WRITE_6)
380
        direction = 0;
381
 
382
    memcpy(host->ecb[ecbno].cdb, cmd, SCpnt->cmd_len);
383
 
384
    if (SCpnt->use_sg)
385
    {
386
        struct scatterlist * sgpnt;
387
        struct aha1740_chain * cptr;
388
        int i;
389
        DEB(unsigned char * ptr);
390
 
391
        host->ecb[ecbno].sg = 1;  /* SCSI Initiator Command  w/scatter-gather*/
392
        SCpnt->host_scribble = (unsigned char *) scsi_malloc(512);
393
        sgpnt = (struct scatterlist *) SCpnt->request_buffer;
394
        cptr = (struct aha1740_chain *) SCpnt->host_scribble;
395
        if (cptr == NULL) panic("aha1740.c: unable to allocate DMA memory\n");
396
        for(i=0; i<SCpnt->use_sg; i++)
397
        {
398
            cptr[i].datalen = sgpnt[i].length;
399
            cptr[i].dataptr = virt_to_bus(sgpnt[i].address);
400
        }
401
        host->ecb[ecbno].datalen = SCpnt->use_sg * sizeof(struct aha1740_chain);
402
        host->ecb[ecbno].dataptr = virt_to_bus(cptr);
403
#ifdef DEBUG
404
        printk("cptr %x: ",cptr);
405
        ptr = (unsigned char *) cptr;
406
        for(i=0;i<24;i++) printk("%02x ", ptr[i]);
407
#endif
408
    }
409
    else
410
    {
411
        SCpnt->host_scribble = NULL;
412
        host->ecb[ecbno].datalen = bufflen;
413
        host->ecb[ecbno].dataptr = virt_to_bus(buff);
414
    }
415
    host->ecb[ecbno].lun = SCpnt->lun;
416
    host->ecb[ecbno].ses = 1;   /* Suppress underrun errors */
417
    host->ecb[ecbno].dir = direction;
418
    host->ecb[ecbno].ars = 1;  /* Yes, get the sense on an error */
419
    host->ecb[ecbno].senselen = 12;
420
    host->ecb[ecbno].senseptr = virt_to_bus(host->ecb[ecbno].sense);
421
    host->ecb[ecbno].statusptr = virt_to_bus(host->ecb[ecbno].status);
422
    host->ecb[ecbno].done = done;
423
    host->ecb[ecbno].SCpnt = SCpnt;
424
#ifdef DEBUG
425
    {
426
        int i;
427
        printk("aha1740_command: sending.. ");
428
        for (i = 0; i < sizeof(host->ecb[ecbno]) - 10; i++)
429
            printk("%02x ", ((unchar *)&host->ecb[ecbno])[i]);
430
    }
431
    printk("\n");
432
#endif
433
    if (done)
434
    { /*  The Adaptec Spec says the card is so fast that the loops will
435
          only be executed once in the code below. Even if this was true
436
          with the fastest processors when the spec was written, it doesn't
437
          seem to be true with todays fast processors. We print a warning
438
          if the code is executed more often than LOOPCNT_WARN. If this
439
          happens, it should be investigated. If the count reaches
440
          LOOPCNT_MAX, we assume something is broken; since there is no
441
          way to return an error (the return value is ignored by the
442
          mid-level scsi layer) we have to panic (and maybe that's the
443
          best thing we can do then anyhow). */
444
 
445
#define LOOPCNT_WARN 10         /* excessive mbxout wait -> syslog-msg */
446
#define LOOPCNT_MAX 1000000     /* mbxout deadlock -> panic() after ~ 2 sec. */
447
        int loopcnt;
448
        unsigned int base = SCpnt->host->io_port;
449
        DEB(printk("aha1740[%d] critical section\n",ecbno));
450
        save_flags(flags);
451
        cli();
452
        for (loopcnt = 0; ; loopcnt++) {
453
            if (inb(G2STAT(base)) & G2STAT_MBXOUT) break;
454
            if (loopcnt == LOOPCNT_WARN) {
455
                printk("aha1740[%d]_mbxout wait!\n",ecbno);
456
                cli(); /* printk may have done a sti()! */
457
            }
458
            if (loopcnt == LOOPCNT_MAX)
459
                panic("aha1740.c: mbxout busy!\n");
460
        }
461
        outl(virt_to_bus(host->ecb + ecbno), MBOXOUT0(base));
462
        for (loopcnt = 0; ; loopcnt++) {
463
            if (! (inb(G2STAT(base)) & G2STAT_BUSY)) break;
464
            if (loopcnt == LOOPCNT_WARN) {
465
                printk("aha1740[%d]_attn wait!\n",ecbno);
466
                cli();
467
            }
468
            if (loopcnt == LOOPCNT_MAX)
469
                panic("aha1740.c: attn wait failed!\n");
470
        }
471
        outb(ATTN_START | (target & 7), ATTN(base)); /* Start it up */
472
        restore_flags(flags);
473
        DEB(printk("aha1740[%d] request queued.\n",ecbno));
474
    }
475
    else
476
        printk(KERN_ALERT "aha1740_queuecommand: done can't be NULL\n");
477
    return 0;
478
}
479
 
480
static void internal_done(Scsi_Cmnd * SCpnt)
481
{
482
    SCpnt->SCp.Status++;
483
}
484
 
485
int aha1740_command(Scsi_Cmnd * SCpnt)
486
{
487
    aha1740_queuecommand(SCpnt, internal_done);
488
    SCpnt->SCp.Status = 0;
489
    while (!SCpnt->SCp.Status)
490
        barrier();
491
    return SCpnt->result;
492
}
493
 
494
/* Query the board for its irq_level.  Nothing else matters
495
   in enhanced mode on an EISA bus. */
496
 
497
void aha1740_getconfig(unsigned int base, unsigned int *irq_level,
498
                       unsigned int *translation)
499
{
500
    static int intab[] = { 9, 10, 11, 12, 0, 14, 15, 0 };
501
 
502
    *irq_level = intab[inb(INTDEF(base)) & 0x7];
503
    *translation = inb(RESV1(base)) & 0x1;
504
    outb(inb(INTDEF(base)) | 0x10, INTDEF(base));
505
}
506
 
507
int aha1740_detect(Scsi_Host_Template * tpnt)
508
{
509
    int count = 0, slot;
510
 
511
    DEB(printk("aha1740_detect: \n"));
512
 
513
    for ( slot=MINEISA; slot <= MAXEISA; slot++ )
514
    {
515
        int slotbase;
516
        unsigned int irq_level, translation;
517
        struct Scsi_Host *shpnt;
518
        struct aha1740_hostdata *host;
519
        slotbase = SLOTBASE(slot);
520
        /*
521
         * The ioports for eisa boards are generally beyond that used in the
522
         * check/allocate region code, but this may change at some point,
523
         * so we go through the motions.
524
         */
525
        if (check_region(slotbase, SLOTSIZE))  /* See if in use */
526
            continue;
527
        if (!aha1740_test_port(slotbase))
528
            continue;
529
        aha1740_getconfig(slotbase,&irq_level,&translation);
530
        if ((inb(G2STAT(slotbase)) &
531
             (G2STAT_MBXOUT|G2STAT_BUSY)) != G2STAT_MBXOUT)
532
        {       /* If the card isn't ready, hard reset it */
533
            outb(G2CNTRL_HRST, G2CNTRL(slotbase));
534
            outb(0, G2CNTRL(slotbase));
535
        }
536
        printk("Configuring aha174x at IO:%x, IRQ %d\n", slotbase, irq_level);
537
        printk("aha174x: Extended translation %sabled.\n",
538
               translation ? "en" : "dis");
539
        DEB(printk("aha1740_detect: enable interrupt channel %d\n",irq_level));
540
        if (request_irq(irq_level,aha1740_intr_handle,0,"aha1740",NULL)) {
541
            printk("Unable to allocate IRQ for adaptec controller.\n");
542
            continue;
543
        }
544
        shpnt = scsi_register(tpnt, sizeof(struct aha1740_hostdata));
545
        request_region(slotbase, SLOTSIZE, "aha1740");
546
        shpnt->base = 0;
547
        shpnt->io_port = slotbase;
548
        shpnt->n_io_port = SLOTSIZE;
549
        shpnt->irq = irq_level;
550
        shpnt->dma_channel = 0xff;
551
        host = HOSTDATA(shpnt);
552
        host->slot = slot;
553
        host->translation = translation;
554
        aha_host[irq_level - 9] = shpnt;
555
        count++;
556
    }
557
    return count;
558
}
559
 
560
/* Note:  They following two functions do not apply very well to the Adaptec,
561
   which basically manages its own affairs quite well without our interference,
562
   so I haven't put anything into them.  I can faintly imagine someone with a
563
   *very* badly behaved SCSI target (perhaps an old tape?) wanting the abort(),
564
   but it hasn't happened yet, and doing aborts brings the Adaptec to its
565
   knees.  I cannot (at this moment in time) think of any reason to reset the
566
   card once it's running.  So there. */
567
 
568
int aha1740_abort(Scsi_Cmnd * SCpnt)
569
{
570
    DEB(printk("aha1740_abort called\n"));
571
    return SCSI_ABORT_SNOOZE;
572
}
573
 
574
/* We do not implement a reset function here, but the upper level code assumes
575
   that it will get some kind of response for the command in SCpnt.  We must
576
   oblige, or the command will hang the scsi system */
577
 
578
int aha1740_reset(Scsi_Cmnd * SCpnt, unsigned int ignored)
579
{
580
    DEB(printk("aha1740_reset called\n"));
581
    return SCSI_RESET_PUNT;
582
}
583
 
584
int aha1740_biosparam(Disk * disk, kdev_t dev, int* ip)
585
{
586
    int size = disk->capacity;
587
    int extended = HOSTDATA(disk->device->host)->translation;
588
 
589
    DEB(printk("aha1740_biosparam\n"));
590
    if (extended && (ip[2] > 1024))
591
    {
592
        ip[0] = 255;
593
        ip[1] = 63;
594
        ip[2] = size / (255 * 63);
595
    }
596
    else
597
    {
598
        ip[0] = 64;
599
        ip[1] = 32;
600
        ip[2] = size >> 11;
601
    }
602
    return 0;
603
}
604
 
605
#ifdef MODULE
606
/* Eventually this will go into an include file, but this will be later */
607
Scsi_Host_Template driver_template = AHA1740;
608
 
609
#include "scsi_module.c"
610
#endif
611
 
612
/* Okay, you made it all the way through.  As of this writing, 3/31/93, I'm
613
brad@saturn.gaylord.com or brad@bradpc.gaylord.com.  I'll try to help as time
614
permits if you have any trouble with this driver.  Happy Linuxing! */

powered by: WebSVN 2.1.0

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