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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1626 jcastillo
/* $Id: aha1542.c,v 1.1 2005-12-20 10:17:45 jcastillo Exp $
2
 *  linux/kernel/aha1542.c
3
 *
4
 *  Copyright (C) 1992  Tommy Thorn
5
 *  Copyright (C) 1993, 1994, 1995 Eric Youngdale
6
 *
7
 *  Modified by Eric Youngdale
8
 *        Use request_irq and request_dma to help prevent unexpected conflicts
9
 *        Set up on-board DMA controller, such that we do not have to
10
 *        have the bios enabled to use the aha1542.
11
 *  Modified by David Gentzel
12
 *        Don't call request_dma if dma mask is 0 (for BusLogic BT-445S VL-Bus
13
 *        controller).
14
 *  Modified by Matti Aarnio
15
 *        Accept parameters from LILO cmd-line. -- 1-Oct-94
16
 *  Modified by Mike McLagan <mike.mclagan@linux.org>
17
 *        Recognise extended mode on AHA1542CP, different bit than 1542CF
18
 *        1-Jan-97
19
 *  Modified by Bjorn L. Thordarson and Einar Thor Einarsson
20
 *        Recognize that DMA0 is valid DMA channel -- 13-Jul-98
21
 */
22
 
23
#include <linux/module.h>
24
 
25
#include <linux/kernel.h>
26
#include <linux/head.h>
27
#include <linux/types.h>
28
#include <linux/string.h>
29
#include <linux/ioport.h>
30
#include <linux/delay.h>
31
#include <linux/sched.h>
32
#include <linux/proc_fs.h>
33
#include <asm/dma.h>
34
#include <asm/system.h>
35
#include <asm/io.h>
36
#include <linux/blk.h>
37
#include "scsi.h"
38
#include "hosts.h"
39
 
40
 
41
#include "aha1542.h"
42
 
43
#include<linux/stat.h>
44
 
45
struct proc_dir_entry proc_scsi_aha1542 = {
46
    PROC_SCSI_AHA1542, 7, "aha1542",
47
    S_IFDIR | S_IRUGO | S_IXUGO, 2
48
};
49
 
50
#ifdef DEBUG
51
#define DEB(x) x
52
#else
53
#define DEB(x)
54
#endif
55
/*
56
static const char RCSid[] = "$Header: /home/marcus/revision_ctrl_test/oc_cvs/cvs/or1k/rc203soc/sw/uClinux/drivers/scsi/aha1542.c,v 1.1 2005-12-20 10:17:45 jcastillo Exp $";
57
*/
58
 
59
/* The adaptec can be configured for quite a number of addresses, but
60
I generally do not want the card poking around at random.  We allow
61
two addresses - this allows people to use the Adaptec with a Midi
62
card, which also used 0x330 -- can be overridden with LILO! */
63
 
64
#define MAXBOARDS 2     /* Increase this and the sizes of the
65
                           arrays below, if you need more.. */
66
 
67
static unsigned int bases[MAXBOARDS]={0x330, 0x334};
68
 
69
/* set by aha1542_setup according to the command line */
70
static int setup_called[MAXBOARDS]   = {0,0};
71
static int setup_buson[MAXBOARDS]    = {0,0};
72
static int setup_busoff[MAXBOARDS]   = {0,0};
73
static int setup_dmaspeed[MAXBOARDS] = {-1,-1};
74
 
75
static char *setup_str[MAXBOARDS] = {(char *)NULL,(char *)NULL};
76
 
77
/*
78
 * LILO params:  aha1542=<PORTBASE>[,<BUSON>,<BUSOFF>[,<DMASPEED>]]
79
 *
80
 * Where:  <PORTBASE> is any of the valid AHA addresses:
81
 *                      0x130, 0x134, 0x230, 0x234, 0x330, 0x334
82
 *         <BUSON>  is the time (in microsecs) that AHA spends on the AT-bus
83
 *                  when transferring data.  1542A power-on default is 11us,
84
 *                  valid values are in range: 2..15 (decimal)
85
 *         <BUSOFF> is the time that AHA spends OFF THE BUS after while
86
 *                  it is transferring data (not to monopolize the bus).
87
 *                  Power-on default is 4us, valid range: 1..64 microseconds.
88
 *         <DMASPEED> Default is jumper selected (1542A: on the J1),
89
 *                  but experimenter can alter it with this.
90
 *                  Valid values: 5, 6, 7, 8, 10 (MB/s)
91
 *                  Factory default is 5 MB/s.
92
 */
93
 
94
#define BIOS_TRANSLATION_1632 0  /* Used by some old 1542A boards */
95
#define BIOS_TRANSLATION_6432 1 /* Default case these days */
96
#define BIOS_TRANSLATION_25563 2 /* Big disk case */
97
 
98
struct aha1542_hostdata{
99
        /* This will effectively start both of them at the first mailbox */
100
        int bios_translation;   /* Mapping bios uses - for compatibility */
101
        int aha1542_last_mbi_used;
102
        int aha1542_last_mbo_used;
103
        Scsi_Cmnd * SCint[AHA1542_MAILBOXES];
104
        struct mailbox mb[2*AHA1542_MAILBOXES];
105
        struct ccb ccb[AHA1542_MAILBOXES];
106
};
107
 
108
#define HOSTDATA(host) ((struct aha1542_hostdata *) &host->hostdata)
109
 
110
static struct Scsi_Host * aha_host[7] = {NULL,};  /* One for each IRQ level (9-15) */
111
 
112
 
113
 
114
 
115
#define WAITnexttimeout 3000000
116
 
117
static void setup_mailboxes(int base_io, struct Scsi_Host * shpnt);
118
static int aha1542_restart(struct Scsi_Host * shost);
119
 
120
#define aha1542_intr_reset(base)  outb(IRST, CONTROL(base))
121
 
122
#define WAIT(port, mask, allof, noneof)                                 \
123
 { register int WAITbits;                                                       \
124
   register int WAITtimeout = WAITnexttimeout;                          \
125
   while (1) {                                                          \
126
     WAITbits = inb(port) & (mask);                                     \
127
     if ((WAITbits & (allof)) == (allof) && ((WAITbits & (noneof)) == 0)) \
128
       break;                                                           \
129
     if (--WAITtimeout == 0) goto fail;                                  \
130
   }                                                                    \
131
 }
132
 
133
/* Similar to WAIT, except we use the udelay call to regulate the
134
   amount of time we wait.  */
135
#define WAITd(port, mask, allof, noneof, timeout)                       \
136
 { register int WAITbits;                                                       \
137
   register int WAITtimeout = timeout;                                  \
138
   while (1) {                                                          \
139
     WAITbits = inb(port) & (mask);                                     \
140
     if ((WAITbits & (allof)) == (allof) && ((WAITbits & (noneof)) == 0)) \
141
       break;                                                           \
142
     udelay(1000);                                                      \
143
     if (--WAITtimeout == 0) goto fail;                                  \
144
   }                                                                    \
145
 }
146
 
147
static void aha1542_stat(void)
148
{
149
/*    int s = inb(STATUS), i = inb(INTRFLAGS);
150
  printk("status=%x intrflags=%x\n", s, i, WAITnexttimeout-WAITtimeout); */
151
}
152
 
153
/* This is a bit complicated, but we need to make sure that an interrupt
154
   routine does not send something out while we are in the middle of this.
155
   Fortunately, it is only at boot time that multi-byte messages
156
   are ever sent. */
157
static int aha1542_out(unsigned int base, unchar *cmdp, int len)
158
{
159
  unsigned long flags = 0;
160
 
161
  save_flags(flags);
162
  if(len == 1) {
163
    while(1==1){
164
        WAIT(STATUS(base), CDF, 0, CDF);
165
        cli();
166
        if(inb(STATUS(base)) & CDF) {restore_flags(flags); continue;}
167
        outb(*cmdp, DATA(base));
168
        restore_flags(flags);
169
        return 0;
170
      }
171
  } else {
172
    cli();
173
    while (len--)
174
      {
175
        WAIT(STATUS(base), CDF, 0, CDF);
176
        outb(*cmdp++, DATA(base));
177
      }
178
    restore_flags(flags);
179
  }
180
    return 0;
181
  fail:
182
    restore_flags(flags);
183
    printk("aha1542_out failed(%d): ", len+1); aha1542_stat();
184
    return 1;
185
}
186
 
187
/* Only used at boot time, so we do not need to worry about latency as much
188
   here */
189
static int aha1542_in(unsigned int base, unchar *cmdp, int len)
190
{
191
    unsigned long flags;
192
 
193
    save_flags(flags);
194
    cli();
195
    while (len--)
196
      {
197
          WAIT(STATUS(base), DF, DF, 0);
198
          *cmdp++ = inb(DATA(base));
199
      }
200
    restore_flags(flags);
201
    return 0;
202
  fail:
203
    restore_flags(flags);
204
    printk("aha1542_in failed(%d): ", len+1); aha1542_stat();
205
    return 1;
206
}
207
 
208
/* Similar to aha1542_in, except that we wait a very short period of time.
209
   We use this if we know the board is alive and awake, but we are not sure
210
   if the board will respond to the command we are about to send or not */
211
static int aha1542_in1(unsigned int base, unchar *cmdp, int len)
212
{
213
    unsigned long flags;
214
 
215
    save_flags(flags);
216
    cli();
217
    while (len--)
218
      {
219
          WAITd(STATUS(base), DF, DF, 0, 100);
220
          *cmdp++ = inb(DATA(base));
221
      }
222
    restore_flags(flags);
223
    return 0;
224
  fail:
225
    restore_flags(flags);
226
    return 1;
227
}
228
 
229
static int makecode(unsigned hosterr, unsigned scsierr)
230
{
231
    switch (hosterr) {
232
      case 0x0:
233
      case 0xa: /* Linked command complete without error and linked normally */
234
      case 0xb: /* Linked command complete without error, interrupt generated */
235
        hosterr = 0;
236
        break;
237
 
238
      case 0x11: /* Selection time out-The initiator selection or target
239
                    reselection was not complete within the SCSI Time out period */
240
        hosterr = DID_TIME_OUT;
241
        break;
242
 
243
      case 0x12: /* Data overrun/underrun-The target attempted to transfer more data
244
                    than was allocated by the Data Length field or the sum of the
245
                    Scatter / Gather Data Length fields. */
246
 
247
      case 0x13: /* Unexpected bus free-The target dropped the SCSI BSY at an unexpected time. */
248
 
249
      case 0x15: /* MBO command was not 00, 01 or 02-The first byte of the CB was
250
                    invalid. This usually indicates a software failure. */
251
 
252
      case 0x16: /* Invalid CCB Operation Code-The first byte of the CCB was invalid.
253
                    This usually indicates a software failure. */
254
 
255
      case 0x17: /* Linked CCB does not have the same LUN-A subsequent CCB of a set
256
                    of linked CCB's does not specify the same logical unit number as
257
                    the first. */
258
      case 0x18: /* Invalid Target Direction received from Host-The direction of a
259
                    Target Mode CCB was invalid. */
260
 
261
      case 0x19: /* Duplicate CCB Received in Target Mode-More than once CCB was
262
                    received to service data transfer between the same target LUN
263
                    and initiator SCSI ID in the same direction. */
264
 
265
      case 0x1a: /* Invalid CCB or Segment List Parameter-A segment list with a zero
266
                    length segment or invalid segment list boundaries was received.
267
                    A CCB parameter was invalid. */
268
        DEB(printk("Aha1542: %x %x\n", hosterr, scsierr));
269
        hosterr = DID_ERROR; /* Couldn't find any better */
270
        break;
271
 
272
      case 0x14: /* Target bus phase sequence failure-An invalid bus phase or bus
273
                    phase sequence was requested by the target. The host adapter
274
                    will generate a SCSI Reset Condition, notifying the host with
275
                    a SCRD interrupt */
276
        hosterr = DID_RESET;
277
        break;
278
      default:
279
        printk("makecode: unknown hoststatus %x\n", hosterr);
280
        break;
281
    }
282
    return scsierr|(hosterr << 16);
283
}
284
 
285
static int aha1542_test_port(int bse, struct Scsi_Host * shpnt)
286
{
287
    int i;
288
    unchar inquiry_cmd[] = {CMD_INQUIRY };
289
    unchar inquiry_result[4];
290
    unchar *cmdp;
291
    int len;
292
    volatile int debug = 0;
293
 
294
    /* Quick and dirty test for presence of the card. */
295
    if(inb(STATUS(bse)) == 0xff) return 0;
296
 
297
    /* Reset the adapter. I ought to make a hard reset, but it's not really necessary */
298
 
299
    /*  DEB(printk("aha1542_test_port called \n")); */
300
 
301
    /* In case some other card was probing here, reset interrupts */
302
    aha1542_intr_reset(bse);     /* reset interrupts, so they don't block */
303
 
304
    outb(SRST|IRST/*|SCRST*/, CONTROL(bse));
305
 
306
    i = jiffies + 2;
307
    while (i>jiffies); /* Wait a little bit for things to settle down. */
308
 
309
    debug = 1;
310
    /* Expect INIT and IDLE, any of the others are bad */
311
    WAIT(STATUS(bse), STATMASK, INIT|IDLE, STST|DIAGF|INVDCMD|DF|CDF);
312
 
313
    debug = 2;
314
    /* Shouldn't have generated any interrupts during reset */
315
    if (inb(INTRFLAGS(bse))&INTRMASK) goto fail;
316
 
317
 
318
    /* Perform a host adapter inquiry instead so we do not need to set
319
       up the mailboxes ahead of time */
320
 
321
    aha1542_out(bse, inquiry_cmd, 1);
322
 
323
    debug = 3;
324
    len = 4;
325
    cmdp = &inquiry_result[0];
326
 
327
    while (len--)
328
      {
329
          WAIT(STATUS(bse), DF, DF, 0);
330
          *cmdp++ = inb(DATA(bse));
331
      }
332
 
333
    debug = 8;
334
    /* Reading port should reset DF */
335
    if (inb(STATUS(bse)) & DF) goto fail;
336
 
337
    debug = 9;
338
    /* When HACC, command is completed, and we're though testing */
339
    WAIT(INTRFLAGS(bse), HACC, HACC, 0);
340
    /* now initialize adapter */
341
 
342
    debug = 10;
343
    /* Clear interrupts */
344
    outb(IRST, CONTROL(bse));
345
 
346
    debug = 11;
347
 
348
    return debug;                               /* 1 = ok */
349
  fail:
350
    return 0;                                    /* 0 = not ok */
351
}
352
 
353
/* A "high" level interrupt handler */
354
static void aha1542_intr_handle(int irq, void *dev_id, struct pt_regs *regs)
355
{
356
    void (*my_done)(Scsi_Cmnd *) = NULL;
357
    int errstatus, mbi, mbo, mbistatus;
358
    int number_serviced;
359
    unsigned int flags;
360
    struct Scsi_Host * shost;
361
    Scsi_Cmnd * SCtmp;
362
    int flag;
363
    int needs_restart;
364
    struct mailbox * mb;
365
    struct ccb  *ccb;
366
 
367
    shost = aha_host[irq - 9];
368
    if(!shost) panic("Splunge!");
369
 
370
    mb = HOSTDATA(shost)->mb;
371
    ccb = HOSTDATA(shost)->ccb;
372
 
373
#ifdef DEBUG
374
    {
375
    flag = inb(INTRFLAGS(shost->io_port));
376
    printk("aha1542_intr_handle: ");
377
    if (!(flag&ANYINTR)) printk("no interrupt?");
378
    if (flag&MBIF) printk("MBIF ");
379
    if (flag&MBOA) printk("MBOF ");
380
    if (flag&HACC) printk("HACC ");
381
    if (flag&SCRD) printk("SCRD ");
382
    printk("status %02x\n", inb(STATUS(shost->io_port)));
383
  };
384
#endif
385
    number_serviced = 0;
386
    needs_restart = 0;
387
 
388
    while(1==1){
389
      flag = inb(INTRFLAGS(shost->io_port));
390
 
391
      /* Check for unusual interrupts.  If any of these happen, we should
392
         probably do something special, but for now just printing a message
393
         is sufficient.  A SCSI reset detected is something that we really
394
         need to deal with in some way. */
395
      if (flag & ~MBIF) {
396
        if (flag&MBOA) printk("MBOF ");
397
        if (flag&HACC) printk("HACC ");
398
        if (flag&SCRD) {
399
          needs_restart = 1;
400
          printk("SCRD ");
401
        }
402
      }
403
 
404
      aha1542_intr_reset(shost->io_port);
405
 
406
      save_flags(flags);
407
      cli();
408
      mbi = HOSTDATA(shost)->aha1542_last_mbi_used + 1;
409
      if (mbi >= 2*AHA1542_MAILBOXES) mbi = AHA1542_MAILBOXES;
410
 
411
      do{
412
        if(mb[mbi].status != 0) break;
413
        mbi++;
414
        if (mbi >= 2*AHA1542_MAILBOXES) mbi = AHA1542_MAILBOXES;
415
      } while (mbi != HOSTDATA(shost)->aha1542_last_mbi_used);
416
 
417
      if(mb[mbi].status == 0){
418
        restore_flags(flags);
419
        /* Hmm, no mail.  Must have read it the last time around */
420
        if (!number_serviced && !needs_restart)
421
          printk("aha1542.c: interrupt received, but no mail.\n");
422
        /* We detected a reset.  Restart all pending commands for
423
           devices that use the hard reset option */
424
        if(needs_restart) aha1542_restart(shost);
425
        return;
426
      };
427
 
428
      mbo = (scsi2int(mb[mbi].ccbptr) - ((unsigned int) &ccb[0])) / sizeof(struct ccb);
429
      mbistatus = mb[mbi].status;
430
      mb[mbi].status = 0;
431
      HOSTDATA(shost)->aha1542_last_mbi_used = mbi;
432
      restore_flags(flags);
433
 
434
#ifdef DEBUG
435
      {
436
        if (ccb[mbo].tarstat|ccb[mbo].hastat)
437
          printk("aha1542_command: returning %x (status %d)\n",
438
                 ccb[mbo].tarstat + ((int) ccb[mbo].hastat << 16), mb[mbi].status);
439
      };
440
#endif
441
 
442
      if(mbistatus == 3) continue; /* Aborted command not found */
443
 
444
#ifdef DEBUG
445
      printk("...done %d %d\n",mbo, mbi);
446
#endif
447
 
448
      SCtmp = HOSTDATA(shost)->SCint[mbo];
449
 
450
      if (!SCtmp || !SCtmp->scsi_done) {
451
        printk("aha1542_intr_handle: Unexpected interrupt\n");
452
        printk("tarstat=%x, hastat=%x idlun=%x ccb#=%d \n", ccb[mbo].tarstat,
453
               ccb[mbo].hastat, ccb[mbo].idlun, mbo);
454
        return;
455
      }
456
 
457
      my_done = SCtmp->scsi_done;
458
      if (SCtmp->host_scribble) scsi_free(SCtmp->host_scribble, 512);
459
 
460
      /* Fetch the sense data, and tuck it away, in the required slot.  The
461
         Adaptec automatically fetches it, and there is no guarantee that
462
         we will still have it in the cdb when we come back */
463
      if (ccb[mbo].tarstat == 2)
464
        memcpy(SCtmp->sense_buffer, &ccb[mbo].cdb[ccb[mbo].cdblen],
465
               sizeof(SCtmp->sense_buffer));
466
 
467
 
468
      /* is there mail :-) */
469
 
470
      /* more error checking left out here */
471
      if (mbistatus != 1)
472
        /* This is surely wrong, but I don't know what's right */
473
        errstatus = makecode(ccb[mbo].hastat, ccb[mbo].tarstat);
474
      else
475
        errstatus = 0;
476
 
477
#ifdef DEBUG
478
      if(errstatus) printk("(aha1542 error:%x %x %x) ",errstatus,
479
                           ccb[mbo].hastat, ccb[mbo].tarstat);
480
#endif
481
 
482
      if (ccb[mbo].tarstat == 2) {
483
#ifdef DEBUG
484
        int i;
485
#endif
486
        DEB(printk("aha1542_intr_handle: sense:"));
487
#ifdef DEBUG
488
        for (i = 0; i < 12; i++)
489
          printk("%02x ", ccb[mbo].cdb[ccb[mbo].cdblen+i]);
490
        printk("\n");
491
#endif
492
        /*
493
          DEB(printk("aha1542_intr_handle: buf:"));
494
          for (i = 0; i < bufflen; i++)
495
          printk("%02x ", ((unchar *)buff)[i]);
496
          printk("\n");
497
          */
498
      }
499
      DEB(if (errstatus) printk("aha1542_intr_handle: returning %6x\n", errstatus));
500
      SCtmp->result = errstatus;
501
      HOSTDATA(shost)->SCint[mbo] = NULL;  /* This effectively frees up the mailbox slot, as
502
                             far as queuecommand is concerned */
503
      my_done(SCtmp);
504
      number_serviced++;
505
    };
506
}
507
 
508
int aha1542_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
509
{
510
    unchar ahacmd = CMD_START_SCSI;
511
    unchar direction;
512
    unchar *cmd = (unchar *) SCpnt->cmnd;
513
    unchar target = SCpnt->target;
514
    unchar lun = SCpnt->lun;
515
    unsigned long flags;
516
    void *buff = SCpnt->request_buffer;
517
    int bufflen = SCpnt->request_bufflen;
518
    int mbo;
519
    struct mailbox * mb;
520
    struct ccb  *ccb;
521
 
522
    DEB(int i);
523
 
524
    mb = HOSTDATA(SCpnt->host)->mb;
525
    ccb = HOSTDATA(SCpnt->host)->ccb;
526
 
527
    DEB(if (target > 1) {
528
      SCpnt->result = DID_TIME_OUT << 16;
529
      done(SCpnt); return 0;});
530
 
531
    if(*cmd == REQUEST_SENSE){
532
#ifndef DEBUG
533
      if (bufflen != sizeof(SCpnt->sense_buffer)) {
534
        printk("Wrong buffer length supplied for request sense (%d)\n",bufflen);
535
      };
536
#endif
537
      SCpnt->result = 0;
538
      done(SCpnt);
539
      return 0;
540
    };
541
 
542
#ifdef DEBUG
543
    if (*cmd == READ_10 || *cmd == WRITE_10)
544
      i = xscsi2int(cmd+2);
545
    else if (*cmd == READ_6 || *cmd == WRITE_6)
546
      i = scsi2int(cmd+2);
547
    else
548
      i = -1;
549
    if (done)
550
      printk("aha1542_queuecommand: dev %d cmd %02x pos %d len %d ", target, *cmd, i, bufflen);
551
    else
552
      printk("aha1542_command: dev %d cmd %02x pos %d len %d ", target, *cmd, i, bufflen);
553
    aha1542_stat();
554
    printk("aha1542_queuecommand: dumping scsi cmd:");
555
    for (i = 0; i < SCpnt->cmd_len; i++) printk("%02x ", cmd[i]);
556
    printk("\n");
557
    if (*cmd == WRITE_10 || *cmd == WRITE_6)
558
      return 0; /* we are still testing, so *don't* write */
559
#endif
560
/* Use the outgoing mailboxes in a round-robin fashion, because this
561
   is how the host adapter will scan for them */
562
 
563
    save_flags(flags);
564
    cli();
565
    mbo = HOSTDATA(SCpnt->host)->aha1542_last_mbo_used + 1;
566
    if (mbo >= AHA1542_MAILBOXES) mbo = 0;
567
 
568
    do{
569
      if(mb[mbo].status == 0 && HOSTDATA(SCpnt->host)->SCint[mbo] == NULL)
570
        break;
571
      mbo++;
572
      if (mbo >= AHA1542_MAILBOXES) mbo = 0;
573
    } while (mbo != HOSTDATA(SCpnt->host)->aha1542_last_mbo_used);
574
 
575
    if(mb[mbo].status || HOSTDATA(SCpnt->host)->SCint[mbo])
576
      panic("Unable to find empty mailbox for aha1542.\n");
577
 
578
    HOSTDATA(SCpnt->host)->SCint[mbo] = SCpnt;  /* This will effectively prevent someone else from
579
                            screwing with this cdb. */
580
 
581
    HOSTDATA(SCpnt->host)->aha1542_last_mbo_used = mbo;
582
    restore_flags(flags);
583
 
584
#ifdef DEBUG
585
    printk("Sending command (%d %x)...",mbo, done);
586
#endif
587
 
588
    any2scsi(mb[mbo].ccbptr, &ccb[mbo]); /* This gets trashed for some reason*/
589
 
590
    memset(&ccb[mbo], 0, sizeof(struct ccb));
591
 
592
    ccb[mbo].cdblen = SCpnt->cmd_len;
593
 
594
    direction = 0;
595
    if (*cmd == READ_10 || *cmd == READ_6)
596
        direction = 8;
597
    else if (*cmd == WRITE_10 || *cmd == WRITE_6)
598
        direction = 16;
599
 
600
    memcpy(ccb[mbo].cdb, cmd, ccb[mbo].cdblen);
601
 
602
    if (SCpnt->use_sg) {
603
      struct scatterlist * sgpnt;
604
      struct chain * cptr;
605
#ifdef DEBUG
606
      unsigned char * ptr;
607
#endif
608
      int i;
609
      ccb[mbo].op = 2;        /* SCSI Initiator Command  w/scatter-gather*/
610
      SCpnt->host_scribble = (unsigned char *) scsi_malloc(512);
611
      sgpnt = (struct scatterlist *) SCpnt->request_buffer;
612
      cptr = (struct chain *) SCpnt->host_scribble;
613
      if (cptr == NULL) panic("aha1542.c: unable to allocate DMA memory\n");
614
      for(i=0; i<SCpnt->use_sg; i++) {
615
        if(sgpnt[i].length == 0 || SCpnt->use_sg > 16 ||
616
           (((int)sgpnt[i].address) & 1) || (sgpnt[i].length & 1)){
617
          unsigned char * ptr;
618
          printk("Bad segment list supplied to aha1542.c (%d, %d)\n",SCpnt->use_sg,i);
619
          for(i=0;i<SCpnt->use_sg;i++){
620
            printk("%d: %x %x %d\n",i,(unsigned int) sgpnt[i].address, (unsigned int) sgpnt[i].alt_address,
621
                   sgpnt[i].length);
622
          };
623
          printk("cptr %x: ",(unsigned int) cptr);
624
          ptr = (unsigned char *) &cptr[i];
625
          for(i=0;i<18;i++) printk("%02x ", ptr[i]);
626
          panic("Foooooooood fight!");
627
        };
628
        any2scsi(cptr[i].dataptr, sgpnt[i].address);
629
        if(((unsigned  int) sgpnt[i].address) & 0xff000000) goto baddma;
630
        any2scsi(cptr[i].datalen, sgpnt[i].length);
631
      };
632
      any2scsi(ccb[mbo].datalen, SCpnt->use_sg * sizeof(struct chain));
633
      any2scsi(ccb[mbo].dataptr, cptr);
634
#ifdef DEBUG
635
      printk("cptr %x: ",cptr);
636
      ptr = (unsigned char *) cptr;
637
      for(i=0;i<18;i++) printk("%02x ", ptr[i]);
638
#endif
639
    } else {
640
      ccb[mbo].op = 0;         /* SCSI Initiator Command */
641
      SCpnt->host_scribble = NULL;
642
      any2scsi(ccb[mbo].datalen, bufflen);
643
      if(((unsigned int) buff & 0xff000000)) goto baddma;
644
      any2scsi(ccb[mbo].dataptr, buff);
645
    };
646
    ccb[mbo].idlun = (target&7)<<5 | direction | (lun & 7); /*SCSI Target Id*/
647
    ccb[mbo].rsalen = 16;
648
    ccb[mbo].linkptr[0] = ccb[mbo].linkptr[1] = ccb[mbo].linkptr[2] = 0;
649
    ccb[mbo].commlinkid = 0;
650
 
651
#ifdef DEBUG
652
    { int i;
653
    printk("aha1542_command: sending.. ");
654
    for (i = 0; i < sizeof(ccb[mbo])-10; i++)
655
      printk("%02x ", ((unchar *)&ccb[mbo])[i]);
656
    };
657
#endif
658
 
659
    if (done) {
660
        DEB(printk("aha1542_queuecommand: now waiting for interrupt "); aha1542_stat());
661
        SCpnt->scsi_done = done;
662
        mb[mbo].status = 1;
663
        aha1542_out(SCpnt->host->io_port, &ahacmd, 1);          /* start scsi command */
664
        DEB(aha1542_stat());
665
    }
666
    else
667
      printk("aha1542_queuecommand: done can't be NULL\n");
668
 
669
    return 0;
670
 baddma:
671
    panic("Buffer at address  > 16Mb used for 1542B");
672
}
673
 
674
static void internal_done(Scsi_Cmnd * SCpnt)
675
{
676
        SCpnt->SCp.Status++;
677
}
678
 
679
int aha1542_command(Scsi_Cmnd * SCpnt)
680
{
681
    DEB(printk("aha1542_command: ..calling aha1542_queuecommand\n"));
682
 
683
    aha1542_queuecommand(SCpnt, internal_done);
684
 
685
    SCpnt->SCp.Status = 0;
686
    while (!SCpnt->SCp.Status)
687
        barrier();
688
    return SCpnt->result;
689
}
690
 
691
/* Initialize mailboxes */
692
static void setup_mailboxes(int bse, struct Scsi_Host * shpnt)
693
{
694
    int i;
695
    struct mailbox * mb;
696
    struct ccb  *ccb;
697
 
698
    unchar cmd[5] = {CMD_MBINIT, AHA1542_MAILBOXES, 0, 0, 0};
699
 
700
    mb = HOSTDATA(shpnt)->mb;
701
    ccb = HOSTDATA(shpnt)->ccb;
702
 
703
    for(i=0; i<AHA1542_MAILBOXES; i++){
704
      mb[i].status = mb[AHA1542_MAILBOXES+i].status = 0;
705
      any2scsi(mb[i].ccbptr, &ccb[i]);
706
    };
707
    aha1542_intr_reset(bse);     /* reset interrupts, so they don't block */
708
    any2scsi((cmd+2), mb);
709
    aha1542_out(bse, cmd, 5);
710
    WAIT(INTRFLAGS(bse), INTRMASK, HACC, 0);
711
    while (0) {
712
      fail:
713
        printk("aha1542_detect: failed setting up mailboxes\n");
714
    }
715
    aha1542_intr_reset(bse);
716
}
717
 
718
static int aha1542_getconfig(int base_io, unsigned char * irq_level, unsigned char * dma_chan, unsigned char * scsi_id)
719
{
720
  unchar inquiry_cmd[] = {CMD_RETCONF };
721
  unchar inquiry_result[3];
722
  int i;
723
  i = inb(STATUS(base_io));
724
  if (i & DF) {
725
    i = inb(DATA(base_io));
726
  };
727
  aha1542_out(base_io, inquiry_cmd, 1);
728
  aha1542_in(base_io, inquiry_result, 3);
729
  WAIT(INTRFLAGS(base_io), INTRMASK, HACC, 0);
730
  while (0) {
731
  fail:
732
    printk("aha1542_detect: query board settings\n");
733
  }
734
  aha1542_intr_reset(base_io);
735
  switch(inquiry_result[0]){
736
  case 0x80:
737
    *dma_chan = 7;
738
    break;
739
  case 0x40:
740
    *dma_chan = 6;
741
    break;
742
  case 0x20:
743
    *dma_chan = 5;
744
    break;
745
  case 0x01:
746
    *dma_chan = 0;
747
    break;
748
  case 0:
749
    /* This means that the adapter, although Adaptec 1542 compatible, doesn't use a DMA channel.
750
       Currently only aware of the BusLogic BT-445S VL-Bus adapter which needs this. */
751
    *dma_chan = 0xFF;
752
    break;
753
  default:
754
    printk("Unable to determine Adaptec DMA priority.  Disabling board\n");
755
    return -1;
756
  };
757
  switch(inquiry_result[1]){
758
  case 0x40:
759
    *irq_level = 15;
760
    break;
761
  case 0x20:
762
    *irq_level = 14;
763
    break;
764
  case 0x8:
765
    *irq_level = 12;
766
    break;
767
  case 0x4:
768
    *irq_level = 11;
769
    break;
770
  case 0x2:
771
    *irq_level = 10;
772
    break;
773
  case 0x1:
774
    *irq_level = 9;
775
    break;
776
  default:
777
    printk("Unable to determine Adaptec IRQ level.  Disabling board\n");
778
    return -1;
779
  };
780
  *scsi_id=inquiry_result[2] & 7;
781
  return 0;
782
}
783
 
784
/* This function should only be called for 1542C boards - we can detect
785
   the special firmware settings and unlock the board */
786
 
787
static int aha1542_mbenable(int base)
788
{
789
  static unchar mbenable_cmd[3];
790
  static unchar mbenable_result[2];
791
  int retval;
792
 
793
  retval = BIOS_TRANSLATION_6432;
794
 
795
  mbenable_cmd[0]=CMD_EXTBIOS;
796
  aha1542_out(base,mbenable_cmd,1);
797
  if(aha1542_in1(base,mbenable_result,2))
798
    return retval;
799
  WAITd(INTRFLAGS(base),INTRMASK,HACC,0,100);
800
  aha1542_intr_reset(base);
801
 
802
  if ((mbenable_result[0] & 0x08) || mbenable_result[1]) {
803
     mbenable_cmd[0]=CMD_MBENABLE;
804
     mbenable_cmd[1]=0;
805
     mbenable_cmd[2]=mbenable_result[1];
806
 
807
     if((mbenable_result[0] & 0x08) && (mbenable_result[1] & 0x03)) retval = BIOS_TRANSLATION_25563;
808
 
809
     aha1542_out(base,mbenable_cmd,3);
810
     WAIT(INTRFLAGS(base),INTRMASK,HACC,0);
811
  };
812
  while(0) {
813
fail:
814
    printk("aha1542_mbenable: Mailbox init failed\n");
815
  }
816
aha1542_intr_reset(base);
817
return retval;
818
}
819
 
820
/* Query the board to find out if it is a 1542 or a 1740, or whatever. */
821
static int aha1542_query(int base_io, int * transl)
822
{
823
  unchar inquiry_cmd[] = {CMD_INQUIRY };
824
  unchar inquiry_result[4];
825
  int i;
826
  i = inb(STATUS(base_io));
827
  if (i & DF) {
828
    i = inb(DATA(base_io));
829
  };
830
  aha1542_out(base_io, inquiry_cmd, 1);
831
  aha1542_in(base_io, inquiry_result, 4);
832
  WAIT(INTRFLAGS(base_io), INTRMASK, HACC, 0);
833
  while (0) {
834
  fail:
835
    printk("aha1542_detect: query card type\n");
836
  }
837
  aha1542_intr_reset(base_io);
838
 
839
  *transl = BIOS_TRANSLATION_6432; /* Default case */
840
 
841
/* For an AHA1740 series board, we ignore the board since there is a
842
   hardware bug which can lead to wrong blocks being returned if the board
843
   is operating in the 1542 emulation mode.  Since there is an extended mode
844
   driver, we simply ignore the board and let the 1740 driver pick it up.
845
*/
846
 
847
  if (inquiry_result[0] == 0x43) {
848
    printk("aha1542.c: Emulation mode not supported for AHA 174N hardware.\n");
849
    return 1;
850
  };
851
 
852
  /* Always call this - boards that do not support extended bios translation
853
     will ignore the command, and we will set the proper default */
854
 
855
  *transl = aha1542_mbenable(base_io);
856
 
857
  return 0;
858
}
859
 
860
/* called from init/main.c */
861
void aha1542_setup( char *str, int *ints)
862
{
863
    const char *ahausage = "aha1542: usage: aha1542=<PORTBASE>[,<BUSON>,<BUSOFF>[,<DMASPEED>]]\n";
864
    static int setup_idx = 0;
865
    int setup_portbase;
866
 
867
    if(setup_idx >= MAXBOARDS)
868
      {
869
        printk("aha1542: aha1542_setup called too many times! Bad LILO params ?\n");
870
        printk("   Entryline 1: %s\n",setup_str[0]);
871
        printk("   Entryline 2: %s\n",setup_str[1]);
872
        printk("   This line:   %s\n",str);
873
        return;
874
      }
875
    if (ints[0] < 1 || ints[0] > 4)
876
      {
877
        printk("aha1542: %s\n", str );
878
        printk(ahausage);
879
        printk("aha1542: Wrong parameters may cause system malfunction.. We try anyway..\n");
880
      }
881
 
882
    setup_called[setup_idx]=ints[0];
883
    setup_str[setup_idx]=str;
884
 
885
    setup_portbase             = ints[0] >= 1 ? ints[1] : 0; /* Preserve the default value.. */
886
    setup_buson   [setup_idx]  = ints[0] >= 2 ? ints[2] : 7;
887
    setup_busoff  [setup_idx]  = ints[0] >= 3 ? ints[3] : 5;
888
    if (ints[0] >= 4) {
889
      int atbt = -1;
890
      switch (ints[4]) {
891
        case 5:
892
            atbt = 0x00;
893
            break;
894
        case 6:
895
            atbt = 0x04;
896
            break;
897
        case 7:
898
            atbt = 0x01;
899
            break;
900
        case 8:
901
            atbt = 0x02;
902
            break;
903
        case 10:
904
            atbt = 0x03;
905
            break;
906
        default:
907
            printk("aha1542: %s\n", str );
908
            printk(ahausage);
909
            printk("aha1542: Valid values for DMASPEED are 5-8, 10 MB/s.  Using jumper defaults.\n");
910
            break;
911
      }
912
      setup_dmaspeed[setup_idx]  = atbt;
913
    }
914
 
915
    if (setup_portbase != 0)
916
      bases[setup_idx] = setup_portbase;
917
 
918
    ++setup_idx;
919
}
920
 
921
/* return non-zero on detection */
922
int aha1542_detect(Scsi_Host_Template * tpnt)
923
{
924
    unsigned char dma_chan;
925
    unsigned char irq_level;
926
    unsigned char scsi_id;
927
    unsigned long flags;
928
    unsigned int base_io;
929
    int trans;
930
    struct Scsi_Host * shpnt = NULL;
931
    int count = 0;
932
    int indx;
933
 
934
    DEB(printk("aha1542_detect: \n"));
935
 
936
    tpnt->proc_dir = &proc_scsi_aha1542;
937
 
938
    for(indx = 0; indx < sizeof(bases)/sizeof(bases[0]); indx++)
939
            if(bases[indx] != 0 && !check_region(bases[indx], 4)) {
940
                    shpnt = scsi_register(tpnt,
941
                                          sizeof(struct aha1542_hostdata));
942
 
943
                    /* For now we do this - until kmalloc is more intelligent
944
                       we are resigned to stupid hacks like this */
945
                    if ((unsigned int) shpnt > 0xffffff) {
946
                      printk("Invalid address for shpnt with 1542.\n");
947
                      goto unregister;
948
                    }
949
 
950
                    if(!aha1542_test_port(bases[indx], shpnt)) goto unregister;
951
 
952
 
953
                    base_io = bases[indx];
954
 
955
                    /* Set the Bus on/off-times as not to ruin floppy performance */
956
            {
957
                    unchar oncmd[] = {CMD_BUSON_TIME, 7};
958
                    unchar offcmd[] = {CMD_BUSOFF_TIME, 5};
959
 
960
                    if(setup_called[indx])
961
                      {
962
                        oncmd[1]  = setup_buson[indx];
963
                        offcmd[1] = setup_busoff[indx];
964
                      }
965
 
966
                    aha1542_intr_reset(base_io);
967
                    aha1542_out(base_io, oncmd, 2);
968
                    WAIT(INTRFLAGS(base_io), INTRMASK, HACC, 0);
969
                    aha1542_intr_reset(base_io);
970
                    aha1542_out(base_io, offcmd, 2);
971
                    WAIT(INTRFLAGS(base_io), INTRMASK, HACC, 0);
972
                    if (setup_dmaspeed[indx] >= 0)
973
                      {
974
                        unchar dmacmd[] = {CMD_DMASPEED, 0};
975
                        dmacmd[1] = setup_dmaspeed[indx];
976
                        aha1542_intr_reset(base_io);
977
                        aha1542_out(base_io, dmacmd, 2);
978
                        WAIT(INTRFLAGS(base_io), INTRMASK, HACC, 0);
979
                      }
980
                    while (0) {
981
                    fail:
982
                            printk("aha1542_detect: setting bus on/off-time failed\n");
983
                    }
984
                    aha1542_intr_reset(base_io);
985
            }
986
                    if(aha1542_query(base_io, &trans))  goto unregister;
987
 
988
                    if (aha1542_getconfig(base_io, &irq_level, &dma_chan, &scsi_id) == -1)  goto unregister;
989
 
990
                    printk("Configuring Adaptec (SCSI-ID %d) at IO:%x, IRQ %d", scsi_id, base_io, irq_level);
991
                    if (dma_chan != 0xFF)
992
                            printk(", DMA priority %d", dma_chan);
993
                    printk("\n");
994
 
995
                    DEB(aha1542_stat());
996
                    setup_mailboxes(base_io, shpnt);
997
 
998
                    DEB(aha1542_stat());
999
 
1000
                    DEB(printk("aha1542_detect: enable interrupt channel %d\n", irq_level));
1001
                    save_flags(flags);
1002
                    cli();
1003
                    if (request_irq(irq_level,aha1542_intr_handle, 0, "aha1542", NULL)) {
1004
                            printk("Unable to allocate IRQ for adaptec controller.\n");
1005
                            restore_flags(flags);
1006
                            goto unregister;
1007
                    }
1008
 
1009
                    if (dma_chan != 0xFF) {
1010
                            if (request_dma(dma_chan,"aha1542")) {
1011
                                    printk("Unable to allocate DMA channel for Adaptec.\n");
1012
                                    free_irq(irq_level, NULL);
1013
                                    restore_flags(flags);
1014
                                    goto unregister;
1015
                            }
1016
 
1017
                            if (dma_chan == 0 || dma_chan >= 5) {
1018
                                    set_dma_mode(dma_chan, DMA_MODE_CASCADE);
1019
                                    enable_dma(dma_chan);
1020
                            }
1021
                    }
1022
                    aha_host[irq_level - 9] = shpnt;
1023
                    shpnt->this_id = scsi_id;
1024
                    shpnt->unique_id = base_io;
1025
                    shpnt->io_port = base_io;
1026
                    shpnt->n_io_port = 4;  /* Number of bytes of I/O space used */
1027
                    shpnt->dma_channel = dma_chan;
1028
                    shpnt->irq = irq_level;
1029
                    HOSTDATA(shpnt)->bios_translation  = trans;
1030
                    if(trans == BIOS_TRANSLATION_25563)
1031
                      printk("aha1542.c: Using extended bios translation\n");
1032
                    HOSTDATA(shpnt)->aha1542_last_mbi_used  = (2*AHA1542_MAILBOXES - 1);
1033
                    HOSTDATA(shpnt)->aha1542_last_mbo_used  = (AHA1542_MAILBOXES - 1);
1034
                    memset(HOSTDATA(shpnt)->SCint, 0, sizeof(HOSTDATA(shpnt)->SCint));
1035
                    restore_flags(flags);
1036
#if 0
1037
                    DEB(printk(" *** READ CAPACITY ***\n"));
1038
 
1039
            {
1040
                    unchar buf[8];
1041
                    static unchar cmd[] = {     READ_CAPACITY, 0, 0, 0, 0, 0, 0, 0, 0, 0};
1042
                    int i;
1043
 
1044
                    for (i = 0; i < sizeof(buf); ++i) buf[i] = 0x87;
1045
                    for (i = 0; i < 2; ++i)
1046
                            if (!aha1542_command(i, cmd, buf, sizeof(buf))) {
1047
                                    printk("aha_detect: LU %d sector_size %d device_size %d\n",
1048
                                           i, xscsi2int(buf+4), xscsi2int(buf));
1049
                            }
1050
            }
1051
 
1052
                    DEB(printk(" *** NOW RUNNING MY OWN TEST *** \n"));
1053
 
1054
                    for (i = 0; i < 4; ++i)
1055
                    {
1056
                            unsigned char cmd[10];
1057
                            static buffer[512];
1058
 
1059
                            cmd[0] = READ_10;
1060
                            cmd[1] = 0;
1061
                            xany2scsi(cmd+2, i);
1062
                            cmd[6] = 0;
1063
                            cmd[7] = 0;
1064
                            cmd[8] = 1;
1065
                            cmd[9] = 0;
1066
                            aha1542_command(0, cmd, buffer, 512);
1067
                    }
1068
#endif    
1069
                    request_region(bases[indx], 4,"aha1542");  /* Register the IO ports that we use */
1070
                    count++;
1071
                    continue;
1072
            unregister:
1073
                    scsi_unregister(shpnt);
1074
                    continue;
1075
 
1076
            };
1077
 
1078
    return count;
1079
}
1080
 
1081
static int aha1542_restart(struct Scsi_Host * shost)
1082
{
1083
  int i;
1084
  int count = 0;
1085
#if 0
1086
  unchar ahacmd = CMD_START_SCSI;
1087
#endif
1088
 
1089
  for(i=0; i< AHA1542_MAILBOXES; i++)
1090
   if(HOSTDATA(shost)->SCint[i] &&
1091
      !(HOSTDATA(shost)->SCint[i]->device->soft_reset))
1092
     {
1093
#if 0
1094
        HOSTDATA(shost)->mb[i].status = 1; /* Indicate ready to restart... */
1095
#endif
1096
        count++;
1097
     }
1098
 
1099
  printk("Potential to restart %d stalled commands...\n", count);
1100
#if 0
1101
  /* start scsi command */
1102
  if (count) aha1542_out(shost->io_port, &ahacmd, 1);
1103
#endif
1104
  return 0;
1105
}
1106
 
1107
/* The abort command does not leave the device in a clean state where
1108
   it is available to be used again.  Until this gets worked out, we will
1109
   leave it commented out.  */
1110
 
1111
int aha1542_abort(Scsi_Cmnd * SCpnt)
1112
{
1113
#if 0
1114
  unchar ahacmd = CMD_START_SCSI;
1115
  unsigned long flags;
1116
  struct mailbox * mb;
1117
  int mbi, mbo, i;
1118
 
1119
  printk("In aha1542_abort: %x %x\n",
1120
         inb(STATUS(SCpnt->host->io_port)),
1121
         inb(INTRFLAGS(SCpnt->host->io_port)));
1122
 
1123
  save_flags(flags);
1124
  cli();
1125
  mb = HOSTDATA(SCpnt->host)->mb;
1126
  mbi = HOSTDATA(SCpnt->host)->aha1542_last_mbi_used + 1;
1127
  if (mbi >= 2*AHA1542_MAILBOXES) mbi = AHA1542_MAILBOXES;
1128
 
1129
  do{
1130
    if(mb[mbi].status != 0) break;
1131
    mbi++;
1132
    if (mbi >= 2*AHA1542_MAILBOXES) mbi = AHA1542_MAILBOXES;
1133
  } while (mbi != HOSTDATA(SCpnt->host)->aha1542_last_mbi_used);
1134
  restore_flags(flags);
1135
 
1136
  if(mb[mbi].status) {
1137
    printk("Lost interrupt discovered on irq %d - attempting to recover\n",
1138
           SCpnt->host->irq);
1139
    aha1542_intr_handle(SCpnt->host->irq, NULL);
1140
    return 0;
1141
  }
1142
 
1143
  /* OK, no lost interrupt.  Try looking to see how many pending commands
1144
     we think we have. */
1145
 
1146
  for(i=0; i< AHA1542_MAILBOXES; i++)
1147
   if(HOSTDATA(SCpnt->host)->SCint[i])
1148
     {
1149
       if(HOSTDATA(SCpnt->host)->SCint[i] == SCpnt) {
1150
         printk("Timed out command pending for %s\n",
1151
                kdevname(SCpnt->request.rq_dev));
1152
         if (HOSTDATA(SCpnt->host)->mb[i].status) {
1153
           printk("OGMB still full - restarting\n");
1154
           aha1542_out(SCpnt->host->io_port, &ahacmd, 1);
1155
         };
1156
       } else
1157
         printk("Other pending command %s\n",
1158
                kdevname(SCpnt->request.rq_dev));
1159
     }
1160
 
1161
#endif
1162
 
1163
    DEB(printk("aha1542_abort\n"));
1164
#if 0
1165
    save_flags(flags);
1166
    cli();
1167
    for(mbo = 0; mbo < AHA1542_MAILBOXES; mbo++)
1168
      if (SCpnt == HOSTDATA(SCpnt->host)->SCint[mbo]){
1169
        mb[mbo].status = 2;  /* Abort command */
1170
        aha1542_out(SCpnt->host->io_port, &ahacmd, 1); /* start scsi command */
1171
        restore_flags(flags);
1172
        break;
1173
      };
1174
#endif
1175
    return SCSI_ABORT_SNOOZE;
1176
}
1177
 
1178
/* We do not implement a reset function here, but the upper level code
1179
   assumes that it will get some kind of response for the command in
1180
   SCpnt.  We must oblige, or the command will hang the scsi system.
1181
   For a first go, we assume that the 1542 notifies us with all of the
1182
   pending commands (it does implement soft reset, after all). */
1183
 
1184
int aha1542_reset(Scsi_Cmnd * SCpnt, unsigned int reset_flags)
1185
{
1186
    unchar ahacmd = CMD_START_SCSI;
1187
    int i;
1188
 
1189
    /*
1190
     * See if a bus reset was suggested.
1191
     */
1192
    if( reset_flags & SCSI_RESET_SUGGEST_BUS_RESET )
1193
      {
1194
        /*
1195
         * This does a scsi reset for all devices on the bus.
1196
         * In principle, we could also reset the 1542 - should
1197
         * we do this?  Try this first, and we can add that later
1198
         * if it turns out to be useful.
1199
         */
1200
        outb(HRST | SCRST, CONTROL(SCpnt->host->io_port));
1201
 
1202
        /*
1203
         * Wait for the thing to settle down a bit.  Unfortunately
1204
         * this is going to basically lock up the machine while we
1205
         * wait for this to complete.  To be 100% correct, we need to
1206
         * check for timeout, and if we are doing something like this
1207
         * we are pretty desperate anyways.
1208
         */
1209
        WAIT(STATUS(SCpnt->host->io_port),
1210
             STATMASK, INIT|IDLE, STST|DIAGF|INVDCMD|DF|CDF);
1211
 
1212
        /*
1213
         * We need to do this too before the 1542 can interact with
1214
         * us again.
1215
         */
1216
        setup_mailboxes(SCpnt->host->io_port, SCpnt->host);
1217
 
1218
        /*
1219
         * Now try to pick up the pieces.  Restart all commands
1220
         * that are currently active on the bus, and reset all of
1221
         * the datastructures.  We have some time to kill while
1222
         * things settle down, so print a nice message.
1223
         */
1224
        printk("Sent BUS RESET to scsi host %d\n", SCpnt->host->host_no);
1225
 
1226
        for(i=0; i< AHA1542_MAILBOXES; i++)
1227
          if(HOSTDATA(SCpnt->host)->SCint[i] != NULL)
1228
            {
1229
              Scsi_Cmnd * SCtmp;
1230
              SCtmp = HOSTDATA(SCpnt->host)->SCint[i];
1231
              SCtmp->result = DID_RESET << 16;
1232
              if (SCtmp->host_scribble) scsi_free(SCtmp->host_scribble, 512);
1233
              printk("Sending DID_RESET for target %d\n", SCpnt->target);
1234
              SCtmp->scsi_done(SCpnt);
1235
 
1236
              HOSTDATA(SCpnt->host)->SCint[i] = NULL;
1237
              HOSTDATA(SCpnt->host)->mb[i].status = 0;
1238
            }
1239
        /*
1240
         * Now tell the mid-level code what we did here.  Since
1241
         * we have restarted all of the outstanding commands,
1242
         * then report SUCCESS.
1243
         */
1244
        return (SCSI_RESET_SUCCESS | SCSI_RESET_BUS_RESET);
1245
fail:
1246
        printk("aha1542.c: Unable to perform hard reset.\n");
1247
        printk("Power cycle machine to reset\n");
1248
        return (SCSI_RESET_ERROR | SCSI_RESET_BUS_RESET);
1249
 
1250
 
1251
      }
1252
    else
1253
      {
1254
        /* This does a selective reset of just the one device */
1255
        /* First locate the ccb for this command */
1256
        for(i=0; i< AHA1542_MAILBOXES; i++)
1257
          if(HOSTDATA(SCpnt->host)->SCint[i] == SCpnt)
1258
            {
1259
              HOSTDATA(SCpnt->host)->ccb[i].op = 0x81;  /* BUS DEVICE RESET */
1260
              /* Now tell the 1542 to flush all pending commands for this target */
1261
              aha1542_out(SCpnt->host->io_port, &ahacmd, 1);
1262
 
1263
              /* Here is the tricky part.  What to do next.  Do we get an interrupt
1264
                 for the commands that we aborted with the specified target, or
1265
                 do we generate this on our own?  Try it without first and see
1266
                 what happens */
1267
              printk("Sent BUS DEVICE RESET to target %d\n", SCpnt->target);
1268
 
1269
              /* If the first does not work, then try the second.  I think the
1270
                 first option is more likely to be correct. Free the command
1271
                 block for all commands running on this target... */
1272
              for(i=0; i< AHA1542_MAILBOXES; i++)
1273
                if(HOSTDATA(SCpnt->host)->SCint[i] &&
1274
                   HOSTDATA(SCpnt->host)->SCint[i]->target == SCpnt->target)
1275
                  {
1276
                    Scsi_Cmnd * SCtmp;
1277
                    SCtmp = HOSTDATA(SCpnt->host)->SCint[i];
1278
                    SCtmp->result = DID_RESET << 16;
1279
                    if (SCtmp->host_scribble) scsi_free(SCtmp->host_scribble, 512);
1280
                    printk("Sending DID_RESET for target %d\n", SCpnt->target);
1281
                    SCtmp->scsi_done(SCpnt);
1282
 
1283
                    HOSTDATA(SCpnt->host)->SCint[i] = NULL;
1284
                    HOSTDATA(SCpnt->host)->mb[i].status = 0;
1285
                  }
1286
              return SCSI_RESET_SUCCESS;
1287
            }
1288
      }
1289
    /* No active command at this time, so this means that each time we got
1290
       some kind of response the last time through.  Tell the mid-level code
1291
       to request sense information in order to decide what to do next. */
1292
    return SCSI_RESET_PUNT;
1293
}
1294
 
1295
#include "sd.h"
1296
 
1297
int aha1542_biosparam(Scsi_Disk * disk, kdev_t dev, int * ip)
1298
{
1299
  int translation_algorithm;
1300
  int size = disk->capacity;
1301
 
1302
  translation_algorithm = HOSTDATA(disk->device->host)->bios_translation;
1303
 
1304
  if((size>>11) > 1024 && translation_algorithm == BIOS_TRANSLATION_25563) {
1305
    /* Please verify that this is the same as what DOS returns */
1306
    ip[0] = 255;
1307
    ip[1] = 63;
1308
    ip[2] = size /255/63;
1309
  } else {
1310
    ip[0] = 64;
1311
    ip[1] = 32;
1312
    ip[2] = size >> 11;
1313
  }
1314
 
1315
  return 0;
1316
}
1317
 
1318
 
1319
#ifdef MODULE
1320
/* Eventually this will go into an include file, but this will be later */
1321
Scsi_Host_Template driver_template = AHA1542;
1322
 
1323
#include "scsi_module.c"
1324
#endif
1325
 

powered by: WebSVN 2.1.0

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