root/drivers/scsi/aha1542.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. aha1542_stat
  2. aha1542_out
  3. aha1542_in
  4. aha1542_in1
  5. makecode
  6. aha1542_test_port
  7. aha1542_intr_handle
  8. aha1542_queuecommand
  9. internal_done
  10. aha1542_command
  11. setup_mailboxes
  12. aha1542_getconfig
  13. aha1542_mbenable
  14. aha1542_query
  15. aha1542_setup
  16. aha1542_detect
  17. aha1542_restart
  18. aha1542_abort
  19. aha1542_reset
  20. aha1542_biosparam

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

/* [previous][next][first][last][top][bottom][index][help] */