root/kernel/blk_drv/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. makecode
  5. aha1542_test_port
  6. aha1542_info
  7. aha1542_intr_handle
  8. aha1542_queuecommand
  9. internal_done
  10. aha1542_command
  11. setup_mailboxes
  12. aha1542_getconfig
  13. aha1542_query
  14. aha1542_detect
  15. aha1542_abort
  16. aha1542_reset
  17. 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  *
   6  *  Modified by Eric Youngdale
   7  *        Use request_irq and request_dma to help prevent unexpected conflicts
   8  *        Set up on-board DMA controller, such that we do not have to
   9  *        have the bios enabled to use the aha1542.
  10  *  Modified by David Gentzel
  11  *        Don't call request_dma if dma mask is 0 (for BusLogic BT-445S VL-Bus controller).
  12  */
  13 
  14 #include <linux/kernel.h>
  15 #include <linux/head.h>
  16 #include <linux/types.h>
  17 #include <linux/string.h>
  18 
  19 #include <linux/sched.h>
  20 #include <asm/dma.h>
  21 
  22 #include <asm/system.h>
  23 #include <asm/io.h>
  24 #include "../blk.h"
  25 #include "scsi.h"
  26 #include "hosts.h"
  27 
  28 #include "aha1542.h"
  29 
  30 #ifdef DEBUG
  31 #define DEB(x) x
  32 #else
  33 #define DEB(x)
  34 #endif
  35 /*
  36 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 $";
  37 */
  38 
  39 /* The adaptec can be configured for quite a number of addresses, but
  40 I generally do not want the card poking around at random.  We allow
  41 two addresses - this allows people to use the Adaptec with a Midi
  42 card, which also used 0x330 */
  43 
  44 static unsigned int bases[]={0x330, 0x334};
  45 
  46 static unsigned int base;
  47 static unsigned char dma_chan;
  48 static unsigned char irq_level;
  49 
  50 static int aha_disable = 0;
  51 
  52 /* The DMA-Controller.  We need to fool with this because we want to 
  53    be able to use the aha1542 without having to have the bios enabled */
  54 #define DMA_MODE_REG    0xd6
  55 #define DMA_MASK_REG    0xd4
  56 #define CASCADE         0xc0
  57 
  58 static struct mailbox mb[2*AHA1542_MAILBOXES];
  59 static struct ccb ccb[AHA1542_MAILBOXES];
  60 
  61 static Scsi_Cmnd * SCint[AHA1542_MAILBOXES] = {NULL, };
  62 
  63 /* This will effectively start both of them at the first mailbox */
  64 static int aha1542_last_mbi_used  = (2*AHA1542_MAILBOXES - 1);
  65 static int aha1542_last_mbo_used  = (AHA1542_MAILBOXES - 1);
  66 
  67 
  68 static long WAITnexttimeout = 3000000;
  69 
  70 static int aha1542_host = 0;
  71 static void setup_mailboxes(void);
  72 
  73 #define aha1542_intr_reset()  outb(IRST, CONTROL)
  74 
  75 #define WAIT(port, mask, allof, noneof)                                 \
  76  { register WAITbits;                                                   \
  77    register WAITtimeout = WAITnexttimeout;                              \
  78    while (1) {                                                          \
  79      WAITbits = inb(port) & (mask);                                     \
  80      if ((WAITbits & (allof)) == (allof) && ((WAITbits & (noneof)) == 0)) \
  81        break;                                                           \
  82      if (--WAITtimeout == 0) goto fail;                                 \
  83    }                                                                    \
  84  }
  85 
  86 static void aha1542_stat(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  87 {
  88 /*    int s = inb(STATUS), i = inb(INTRFLAGS);
  89   printk("status=%x intrflags=%x\n", s, i, WAITnexttimeout-WAITtimeout); */
  90 }
  91 
  92 static int aha1542_out(unchar *cmdp, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
  93 {
  94     while (len--)
  95       {
  96           WAIT(STATUS, CDF, 0, CDF);
  97           outb(*cmdp++, DATA);
  98       }
  99     return 0;
 100   fail:
 101     printk("aha1542_out failed(%d): ", len+1); aha1542_stat();
 102     return 1;
 103 }
 104 
 105 static int aha1542_in(unchar *cmdp, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
 106 {
 107     while (len--)
 108       {
 109           WAIT(STATUS, DF, DF, 0);
 110           *cmdp++ = inb(DATA);
 111       }
 112     return 0;
 113   fail:
 114     printk("aha1542_in failed(%d): ", len+1); aha1542_stat();
 115     return 1;
 116 }
 117 int makecode(unsigned hosterr, unsigned scsierr)
     /* [previous][next][first][last][top][bottom][index][help] */
 118 {
 119     switch (hosterr) {
 120       case 0x0:
 121       case 0xa: /* Linked command complete without error and linked normally */
 122       case 0xb: /* Linked command complete without error, interrupt generated */
 123         hosterr = 0;
 124         break;
 125 
 126       case 0x11: /* Selection time out-The initiator selection or target
 127                     reselection was not complete within the SCSI Time out period */
 128         hosterr = DID_TIME_OUT;
 129         break;
 130 
 131       case 0x12: /* Data overrun/underrun-The target attempted to transfer more data
 132                     thean was allocated by the Data Length field or the sum of the
 133                     Scatter / Gather Data Length fields. */
 134 
 135       case 0x13: /* Unexpected bus free-The target dropped the SCSI BSY at an unexpected time. */
 136 
 137       case 0x15: /* MBO command was not 00, 01 or 02-The first byte of the CB was
 138                     invalid. This usually indicates a software failure. */
 139 
 140       case 0x16: /* Invalid CCB Operation Code-The first byte of the CCB was invalid.
 141                     This usually indicates a software failure. */
 142 
 143       case 0x17: /* Linked CCB does not have the same LUN-A subsequent CCB of a set
 144                     of linked CCB's does not specify the same logical unit number as
 145                     the first. */
 146       case 0x18: /* Invalid Target Direction received from Host-The direction of a
 147                     Target Mode CCB was invalid. */
 148 
 149       case 0x19: /* Duplicate CCB Received in Target Mode-More than once CCB was
 150                     received to service data transfer between the same target LUN
 151                     and initiator SCSI ID in the same direction. */
 152 
 153       case 0x1a: /* Invalid CCB or Segment List Parameter-A segment list with a zero
 154                     length segment or invalid segment list boundaries was received.
 155                     A CCB parameter was invalid. */
 156         hosterr = DID_ERROR; /* Couldn't find any better */
 157         break;
 158 
 159       case 0x14: /* Target bus phase sequence failure-An invalid bus phase or bus
 160                     phase sequence was requested by the target. The host adapter
 161                     will generate a SCSI Reset Condition, notifying the host with
 162                     a SCRD interrupt */
 163         hosterr = DID_RESET;
 164         break;
 165       default:
 166         printk("makecode: unknown hoststatus %x\n", hosterr);
 167         break;
 168     }
 169     return scsierr|(hosterr << 16);
 170 }
 171 
 172 int aha1542_test_port(int bse)
     /* [previous][next][first][last][top][bottom][index][help] */
 173 {
 174     volatile int debug = 0;
 175     
 176     base = bse;
 177     /* Reset the adapter. I ought to make a hard reset, but it's not really nessesary */
 178     
 179     /*  DEB(printk("aha1542_test_port called \n")); */
 180     
 181     outb(SRST|IRST/*|SCRST*/, CONTROL);
 182     
 183     debug = 1;
 184     /* Expect INIT and IDLE, any of the others are bad */
 185     WAIT(STATUS, STATMASK, INIT|IDLE, STST|DIAGF|INVDCMD|DF|CDF);
 186     
 187     debug = 2;
 188     /* Shouldn't have generated any interrupts during reset */
 189     if (inb(INTRFLAGS)&INTRMASK) goto fail;
 190     setup_mailboxes();
 191     
 192     debug = 3;
 193     /* Test the basic ECHO command */
 194     outb(CMD_ECHO, DATA);
 195     
 196     debug = 4;
 197     /* Wait for CDF=0. If any of the others are set, it's bad */
 198     WAIT(STATUS, STATMASK, 0, STST|DIAGF|INVDCMD|DF|CDF);
 199     
 200     debug = 5;
 201     /* The meaning of life */
 202     outb(42, DATA);
 203     
 204     debug = 6;
 205     /* Expect only DF, that is, data ready */
 206     WAIT(STATUS, STATMASK, DF, STST|DIAGF|CDF|INVDCMD);
 207     
 208     debug = 7;
 209     /* Is the answer correct? */
 210     if (inb(DATA) != 42) goto fail;
 211     
 212     debug = 8;
 213     /* Reading port should reset DF */
 214     if (inb(STATUS) & DF) goto fail;
 215     
 216     debug = 9;
 217     /* When HACC, command is completed, and we're though testing */
 218     WAIT(INTRFLAGS, HACC, HACC, 0);
 219     /* now initialize adapter */
 220     
 221     debug = 10;
 222     /* Clear interrupts */
 223     outb(IRST, CONTROL);
 224     
 225     debug = 11;
 226     
 227     return debug;                               /* 1 = ok */
 228   fail:
 229     return 0;                                   /* 0 = not ok */
 230 }
 231 
 232 /* What's this little function for? */
 233 const char *aha1542_info(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 234 {
 235     static char buffer[] = "Adaptec 1542";
 236     return buffer;
 237 }
 238 
 239 /* A "high" level interrupt handler */
 240 void aha1542_intr_handle(int foo)
     /* [previous][next][first][last][top][bottom][index][help] */
 241 {
 242     void (*my_done)(Scsi_Cmnd *) = NULL;
 243     int errstatus, mbi, mbo, mbistatus;
 244     int number_serviced;
 245     Scsi_Cmnd * SCtmp;
 246 
 247 #ifdef DEBUG
 248     {
 249     int flag = inb(INTRFLAGS);
 250     printk("aha1542_intr_handle: ");
 251     if (!(flag&ANYINTR)) printk("no interrupt?");
 252     if (flag&MBIF) printk("MBIF ");
 253     if (flag&MBOA) printk("MBOF ");
 254     if (flag&HACC) printk("HACC ");
 255     if (flag&SCRD) printk("SCRD ");
 256     printk("status %02x\n", inb(STATUS));
 257   };
 258 #endif
 259     number_serviced = 0;
 260 
 261     while(1==1){
 262       aha1542_intr_reset();
 263 
 264       cli();
 265       mbi = aha1542_last_mbi_used + 1;
 266       if (mbi >= 2*AHA1542_MAILBOXES) mbi = AHA1542_MAILBOXES;
 267       
 268       do{
 269         if(mb[mbi].status != 0) break;
 270         mbi++;
 271         if (mbi >= 2*AHA1542_MAILBOXES) mbi = AHA1542_MAILBOXES;
 272       } while (mbi != aha1542_last_mbi_used);
 273       
 274       if(mb[mbi].status == 0){
 275         sti();
 276         /* Hmm, no mail.  Must have read it the last time around */
 277         if (number_serviced) return;
 278         printk("aha1542.c: interrupt received, but no mail.\n");
 279         return;
 280       };
 281 
 282       mbo = (scsi2int(mb[mbi].ccbptr) - ((unsigned int) &ccb[0])) / sizeof(struct ccb);
 283       mbistatus = mb[mbi].status;
 284       mb[mbi].status = 0;
 285       aha1542_last_mbi_used = mbi;
 286       sti();
 287       
 288 #ifdef DEBUG
 289       {
 290         if (ccb[mbo].tarstat|ccb[mbo].hastat)
 291           printk("aha1542_command: returning %x (status %d)\n", 
 292                  ccb[mbo].tarstat + ((int) ccb[mbo].hastat << 16), mb[mbi].status);
 293       };
 294 #endif
 295 
 296       if(mbistatus == 3) continue; /* Aborted command not found */
 297 
 298 #ifdef DEBUG
 299       printk("...done %d %d\n",mbo, mbi);
 300 #endif
 301       
 302       SCtmp = SCint[mbo];
 303 
 304       if (!SCtmp || !SCtmp->scsi_done) {
 305         printk("aha1542_intr_handle: Unexpected interrupt\n");
 306         return;
 307       }
 308       
 309       my_done = SCtmp->scsi_done;
 310       if (SCtmp->host_scribble) scsi_free(SCtmp->host_scribble, 512);
 311       
 312       /* Fetch the sense data, and tuck it away, in the required slot.  The
 313          Adaptec automatically fetches it, and there is no guarantee that
 314          we will still have it in the cdb when we come back */
 315       if (ccb[mbo].tarstat == 2)
 316         memcpy(SCtmp->sense_buffer, &ccb[mbo].cdb[ccb[mbo].cdblen], 
 317                sizeof(SCtmp->sense_buffer));
 318       
 319       
 320       /* is there mail :-) */
 321       
 322       /* more error checking left out here */
 323       if (mbistatus != 1)
 324         /* This is surely wrong, but I don't know what's right */
 325         errstatus = makecode(ccb[mbo].hastat, ccb[mbo].tarstat);
 326       else
 327         errstatus = 0;
 328       
 329 #ifdef DEBUG
 330       if(errstatus) printk("(aha1542 error:%x %x %x) ",errstatus, 
 331                            ccb[mbo].hastat, ccb[mbo].tarstat);
 332 #endif
 333 
 334       if (ccb[mbo].tarstat == 2) {
 335 #ifdef DEBUG
 336         int i;
 337 #endif
 338         DEB(printk("aha1542_intr_handle: sense:"));
 339 #ifdef DEBUG
 340         for (i = 0; i < 12; i++)
 341           printk("%02x ", ccb[mbo].cdb[ccb[mbo].cdblen+i]);
 342         printk("\n");
 343 #endif
 344         /*
 345           DEB(printk("aha1542_intr_handle: buf:"));
 346           for (i = 0; i < bufflen; i++)
 347           printk("%02x ", ((unchar *)buff)[i]);
 348           printk("\n");
 349           */
 350       }
 351       DEB(if (errstatus) printk("aha1542_intr_handle: returning %6x\n", errstatus));
 352       SCtmp->result = errstatus;
 353       SCint[mbo] = NULL;  /* This effectively frees up the mailbox slot, as
 354                              far as queuecommand is concerned */
 355       my_done(SCtmp);
 356       number_serviced++;
 357     };
 358 }
 359 
 360 int aha1542_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
     /* [previous][next][first][last][top][bottom][index][help] */
 361 {
 362     unchar ahacmd = CMD_START_SCSI;
 363     unchar direction;
 364     unchar *cmd = (unchar *) SCpnt->cmnd;
 365     unchar target = SCpnt->target;
 366     unchar lun = SCpnt->lun;
 367     void *buff = SCpnt->request_buffer;
 368     int bufflen = SCpnt->request_bufflen;
 369     int mbo;
 370 
 371     DEB(int i);
 372 
 373     DEB(if (target > 1) {
 374       SCpnt->result = DID_TIME_OUT << 16;
 375       done(SCpnt); return 0;});
 376     
 377     if(*cmd == REQUEST_SENSE){
 378 #ifndef DEBUG
 379       if (bufflen != sizeof(SCpnt->sense_buffer)) {
 380         printk("Wrong buffer length supplied for request sense (%d)\n",bufflen);
 381         panic("aha1542.c");
 382       };
 383 #endif
 384       SCpnt->result = 0;
 385       done(SCpnt); 
 386       return 0;
 387     };
 388 
 389 #ifdef DEBUG
 390     if (*cmd == READ_10 || *cmd == WRITE_10)
 391       i = xscsi2int(cmd+2);
 392     else if (*cmd == READ_6 || *cmd == WRITE_6)
 393       i = scsi2int(cmd+2);
 394     else
 395       i = -1;
 396     if (done)
 397       printk("aha1542_queuecommand: dev %d cmd %02x pos %d len %d ", target, *cmd, i, bufflen);
 398     else
 399       printk("aha1542_command: dev %d cmd %02x pos %d len %d ", target, *cmd, i, bufflen);
 400     aha1542_stat();
 401     printk("aha1542_queuecommand: dumping scsi cmd:");
 402     for (i = 0; i < (COMMAND_SIZE(*cmd)); i++) printk("%02x ", cmd[i]);
 403     printk("\n");
 404     if (*cmd == WRITE_10 || *cmd == WRITE_6)
 405       return 0; /* we are still testing, so *don't* write */
 406 #endif
 407 /* Use the outgoing mailboxes in a round-robin fashion, because this
 408    is how the host adapter will scan for them */
 409 
 410     cli();
 411     mbo = aha1542_last_mbo_used + 1;
 412     if (mbo >= AHA1542_MAILBOXES) mbo = 0;
 413 
 414     do{
 415       if(mb[mbo].status == 0 && SCint[mbo] == NULL)
 416         break;
 417       mbo++;
 418       if (mbo >= AHA1542_MAILBOXES) mbo = 0;
 419     } while (mbo != aha1542_last_mbo_used);
 420 
 421     if(mb[mbo].status || SCint[mbo])
 422       panic("Unable to find empty mailbox for aha1542.\n");
 423 
 424     SCint[mbo] = SCpnt;  /* This will effectively prevent someone else from
 425                             screwing with this cdb. */
 426 
 427     aha1542_last_mbo_used = mbo;    
 428     sti();
 429 
 430 #ifdef DEBUG
 431     printk("Sending command (%d %x)...",mbo, done);
 432 #endif
 433 
 434     any2scsi(mb[mbo].ccbptr, &ccb[mbo]); /* This gets trashed for some reason*/
 435 
 436     memset(&ccb[mbo], 0, sizeof(struct ccb));
 437 
 438     ccb[mbo].cdblen = COMMAND_SIZE(*cmd);     /* SCSI Command Descriptor Block Length */
 439 
 440     direction = 0;
 441     if (*cmd == READ_10 || *cmd == READ_6)
 442         direction = 8;
 443     else if (*cmd == WRITE_10 || *cmd == WRITE_6)
 444         direction = 16;
 445 
 446     memcpy(ccb[mbo].cdb, cmd, ccb[mbo].cdblen);
 447 
 448     if (SCpnt->use_sg) {
 449       struct scatterlist * sgpnt;
 450       struct chain * cptr;
 451 #ifdef DEBUG
 452       unsigned char * ptr;
 453 #endif
 454       int i;
 455       ccb[mbo].op = 2;        /* SCSI Initiator Command  w/scatter-gather*/
 456       SCpnt->host_scribble = (unsigned char *) scsi_malloc(512);
 457       sgpnt = (struct scatterlist *) SCpnt->request_buffer;
 458       cptr = (struct chain *) SCpnt->host_scribble; 
 459       if (cptr == NULL) panic("aha1542.c: unable to allocate DMA memory\n");
 460       for(i=0; i<SCpnt->use_sg; i++) {
 461         if(sgpnt[i].length == 0 || SCpnt->use_sg > 16 || 
 462            (((int)sgpnt[i].address) & 1) || (sgpnt[i].length & 1)){
 463           unsigned char * ptr;
 464           printk("Bad segment list supplied to aha1542.c (%d, %d)\n",SCpnt->use_sg,i);
 465           for(i=0;i<SCpnt->use_sg++;i++){
 466             printk("%d: %x %x %d\n",i,sgpnt[i].address, sgpnt[i].alt_address,
 467                    sgpnt[i].length);
 468           };
 469           printk("cptr %x: ",cptr);
 470           ptr = (unsigned char *) &cptr[i];
 471           for(i=0;i<18;i++) printk("%02x ", ptr[i]);
 472           panic("Foooooooood fight!");
 473         };
 474         any2scsi(cptr[i].dataptr, sgpnt[i].address);
 475         if(((unsigned  int) sgpnt[i].address) & 0xff000000) goto baddma;
 476         any2scsi(cptr[i].datalen, sgpnt[i].length);
 477       };
 478       any2scsi(ccb[mbo].datalen, SCpnt->use_sg * sizeof(struct chain));
 479       if(((unsigned int) buff & 0xff000000)) goto baddma;
 480       any2scsi(ccb[mbo].dataptr, cptr);
 481 #ifdef DEBUG
 482       printk("cptr %x: ",cptr);
 483       ptr = (unsigned char *) cptr;
 484       for(i=0;i<18;i++) printk("%02x ", ptr[i]);
 485 #endif
 486     } else {
 487       ccb[mbo].op = 0;        /* SCSI Initiator Command */
 488       SCpnt->host_scribble = NULL;
 489       any2scsi(ccb[mbo].datalen, bufflen);
 490       any2scsi(ccb[mbo].dataptr, buff);
 491     };
 492     ccb[mbo].idlun = (target&7)<<5 | direction | (lun & 7); /*SCSI Target Id*/
 493     ccb[mbo].rsalen = 12;
 494     ccb[mbo].linkptr[0] = ccb[mbo].linkptr[1] = ccb[mbo].linkptr[2] = 0;
 495     ccb[mbo].commlinkid = 0;
 496 
 497 #ifdef DEBUGd
 498     { int i;
 499     printk("aha1542_command: sending.. ");
 500     for (i = 0; i < sizeof(ccb[mbo])-10; i++)
 501       printk("%02x ", ((unchar *)&ccb[mbo])[i]);
 502     };
 503 #endif
 504     
 505     if (done) {
 506         DEB(printk("aha1542_queuecommand: now waiting for interrupt "); aha1542_stat());
 507         SCpnt->scsi_done = done;
 508         mb[mbo].status = 1;
 509         aha1542_out(&ahacmd, 1);                /* start scsi command */
 510         DEB(aha1542_stat());
 511     }
 512     else
 513       printk("aha1542_queuecommand: done can't be NULL\n");
 514     
 515     return 0;
 516  baddma:
 517     panic("Buffer at address  > 16Mb used for 1542B");
 518 }
 519 
 520 static volatile int internal_done_flag = 0;
 521 static volatile int internal_done_errcode = 0;
 522 static void internal_done(Scsi_Cmnd * SCpnt)
     /* [previous][next][first][last][top][bottom][index][help] */
 523 {
 524     internal_done_errcode = SCpnt->result;
 525     ++internal_done_flag;
 526 }
 527 
 528 int aha1542_command(Scsi_Cmnd * SCpnt)
     /* [previous][next][first][last][top][bottom][index][help] */
 529 {
 530     DEB(printk("aha1542_command: ..calling aha1542_queuecommand\n"));
 531 
 532     aha1542_queuecommand(SCpnt, internal_done);
 533 
 534     while (!internal_done_flag);
 535     internal_done_flag = 0;
 536     return internal_done_errcode;
 537 }
 538 
 539 /* Initialize mailboxes */
 540 static void setup_mailboxes(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 541 {
 542     int i;
 543     static unchar cmd[5] = {CMD_MBINIT, AHA1542_MAILBOXES};
 544 
 545     for(i=0; i<AHA1542_MAILBOXES; i++){
 546       mb[i].status = mb[AHA1542_MAILBOXES+i].status = 0;
 547       any2scsi(mb[i].ccbptr, &ccb[i]);
 548     };
 549     aha1542_intr_reset();     /* reset interrupts, so they don't block */       
 550     any2scsi((cmd+2), mb);
 551     aha1542_out(cmd, 5);
 552     WAIT(INTRFLAGS, INTRMASK, HACC, 0);
 553     while (0) {
 554       fail:
 555         printk("aha1542_detect: failed setting up mailboxes\n");
 556     }
 557     aha1542_intr_reset();
 558 }
 559 
 560 static int aha1542_getconfig(int hostnum)
     /* [previous][next][first][last][top][bottom][index][help] */
 561 {
 562   static unchar inquiry_cmd[] = {CMD_RETCONF };
 563   static unchar inquiry_result[3];
 564   int i;
 565   i = inb(STATUS);
 566   if (i & DF) {
 567     i = inb(DATA);
 568   };
 569   aha1542_out(inquiry_cmd, 1);
 570   aha1542_in(inquiry_result, 3);
 571   WAIT(INTRFLAGS, INTRMASK, HACC, 0);
 572   while (0) {
 573   fail:
 574     printk("aha1542_detect: query board settings\n");
 575   }
 576   aha1542_intr_reset();
 577   switch(inquiry_result[0]){
 578   case 0x80:
 579     dma_chan = 7;
 580     break;
 581   case 0x40:
 582     dma_chan = 6;
 583     break;
 584   case 0x20:
 585     dma_chan = 5;
 586     break;
 587   case 0x01:
 588     printk("DMA priority 0 not available for Adaptec driver\n");
 589     return -1;
 590   case 0:
 591     /* This means that the adapter, although Adaptec 1542 compatible, doesn't use a DMA channel.
 592        Currently only aware of the BusLogic BT-445S VL-Bus adapter which needs this. */
 593     dma_chan = 0xFF;
 594     break;
 595   default:
 596     printk("Unable to determine Adaptec DMA priority.  Disabling board\n");
 597     return -1;
 598   };
 599   switch(inquiry_result[1]){
 600   case 0x40:
 601     irq_level = 15;
 602     break;
 603   case 0x20:
 604     irq_level = 14;
 605     break;
 606   case 0x8:
 607     irq_level = 12;
 608     break;
 609   case 0x4:
 610     irq_level = 11;
 611     break;
 612   case 0x2:
 613     irq_level = 10;
 614     break;
 615   case 0x1:
 616     irq_level = 9;
 617     break;
 618   default:
 619     printk("Unable to determine Adaptec IRQ level.  Disabling board\n");
 620     return -1;
 621   };
 622   return 0;
 623 }
 624 
 625 /* Query the board to find out if it is a 1542 or a 1740, or whatever. */
 626 static void aha1542_query(int hostnum)
     /* [previous][next][first][last][top][bottom][index][help] */
 627 {
 628   static unchar inquiry_cmd[] = {CMD_INQUIRY };
 629   static unchar inquiry_result[4];
 630   int i;
 631   i = inb(STATUS);
 632   if (i & DF) {
 633     i = inb(DATA);
 634   };
 635   aha1542_out(inquiry_cmd, 1);
 636   aha1542_in(inquiry_result, 4);
 637   WAIT(INTRFLAGS, INTRMASK, HACC, 0);
 638   while (0) {
 639   fail:
 640     printk("aha1542_detect: query card type\n");
 641   }
 642   aha1542_intr_reset();
 643 
 644 /* For an AHA1740 series board, we ignore the board since there is a
 645    hardware bug which can lead to wrong blocks being returned if the board
 646    is operating in the 1542 emulation mode.  Since there is an extended mode
 647    driver, we simply ignore the board and let the 1740 driver pick it up.
 648 */
 649 
 650   if (inquiry_result[0] == 0x43) {
 651     printk("aha1542.c: Emulation mode not supported for AHA 174N hardware.\n");
 652     aha_disable = 1;
 653   };
 654 }
 655 
 656 /* return non-zero on detection */
 657 int aha1542_detect(int hostnum)
     /* [previous][next][first][last][top][bottom][index][help] */
 658 {
 659     int i;
 660     int indx;
 661 
 662     DEB(printk("aha1542_detect: \n"));
 663     
 664     indx = 0;
 665     while(indx < sizeof(bases)/sizeof(bases[0])){
 666       i = aha1542_test_port(bases[indx]);
 667       if (i) break;
 668       indx++;
 669     }
 670     if (indx == sizeof(bases)/sizeof(bases[0])) return 0;
 671  
 672     /* Set the Bus on/off-times as not to ruin floppy performance */
 673     {
 674         static unchar oncmd[] = {CMD_BUSON_TIME, 7};
 675         static unchar offcmd[] = {CMD_BUSOFF_TIME, 5};
 676 
 677         aha1542_intr_reset();
 678         aha1542_out(oncmd, 2);
 679         WAIT(INTRFLAGS, INTRMASK, HACC, 0);
 680         aha1542_intr_reset();
 681         aha1542_out(offcmd, 2);
 682         WAIT(INTRFLAGS, INTRMASK, HACC, 0);
 683         while (0) {
 684           fail:
 685             printk("aha1542_detect: setting bus on/off-time failed\n");
 686         }
 687         aha1542_intr_reset();
 688     }
 689     aha1542_query(hostnum);
 690 
 691     if (aha_disable) return 0;
 692 
 693     if (aha1542_getconfig(hostnum) == -1) return 0;
 694     
 695     printk("Configuring Adaptec at IO:%x, IRQ %d",base, irq_level);
 696     if (dma_chan != 0xFF)
 697         printk(", DMA priority %d", dma_chan);
 698     printk("\n");
 699 
 700     DEB(aha1542_stat());
 701     setup_mailboxes();
 702 
 703     DEB(aha1542_stat());
 704 
 705     DEB(printk("aha1542_detect: enable interrupt channel %d\n", irq_level));
 706 
 707     if (request_irq(irq_level,aha1542_intr_handle)) {
 708         printk("Unable to allocate IRQ for adaptec controller.\n");
 709         return 0;
 710     }
 711 
 712     if (dma_chan != 0xFF) {
 713         if (request_dma(dma_chan)) {
 714             printk("Unable to allocate DMA channel for Adaptec.\n");
 715             free_irq(irq_level);
 716             return 0;
 717         }
 718 
 719         if (dma_chan >= 5) {
 720             outb((dma_chan - 4) | CASCADE, DMA_MODE_REG);
 721             outb(dma_chan - 4, DMA_MASK_REG);
 722         }
 723     }
 724 
 725 #if 0
 726     DEB(printk(" *** READ CAPACITY ***\n"));
 727 
 728     {
 729         unchar buf[8];
 730         static unchar cmd[] = { READ_CAPACITY, 0, 0, 0, 0, 0, 0, 0, 0, 0};
 731         int i;
 732         
 733         for (i = 0; i < sizeof(buf); ++i) buf[i] = 0x87;
 734         for (i = 0; i < 2; ++i)
 735           if (!aha1542_command(i, cmd, buf, sizeof(buf))) {
 736               printk("aha_detect: LU %d sector_size %d device_size %d\n",
 737                      i, xscsi2int(buf+4), xscsi2int(buf));
 738           }
 739     }
 740 
 741     DEB(printk(" *** NOW RUNNING MY OWN TEST *** \n"));
 742 
 743     for (i = 0; i < 4; ++i)
 744       {
 745           unsigned char cmd[10];
 746           static buffer[512];
 747           
 748           cmd[0] = READ_10;
 749           cmd[1] = 0;
 750           xany2scsi(cmd+2, i);
 751           cmd[6] = 0;
 752           cmd[7] = 0;
 753           cmd[8] = 1;
 754           cmd[9] = 0;
 755           aha1542_command(0, cmd, buffer, 512);
 756       }
 757 #endif
 758     aha1542_host = hostnum;
 759     return 1;
 760 }
 761 
 762 /* The abort command does not leave the device in a clean state where
 763    it is available to be used again.  Until this gets worked out, we will
 764    leave it commented out.  */
 765 
 766 int aha1542_abort(Scsi_Cmnd * SCpnt, int i)
     /* [previous][next][first][last][top][bottom][index][help] */
 767 {
 768 #if 0
 769     unchar ahacmd = CMD_START_SCSI;
 770     int mbo;
 771 #endif
 772     DEB(printk("aha1542_abort\n"));
 773 #if 0
 774     cli();
 775     for(mbo = 0; mbo < AHA1542_MAILBOXES; mbo++)
 776       if (SCpnt == SCint[mbo]){
 777         mb[mbo].status = 2;  /* Abort command */
 778         aha1542_out(&ahacmd, 1);                /* start scsi command */
 779         sti();
 780         break;
 781       };
 782 #endif
 783     return 0;
 784 }
 785 
 786 int aha1542_reset(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 787 {
 788     DEB(printk("aha1542_reset called\n"));
 789     return 0;
 790 }
 791 
 792 int aha1542_biosparam(int size, int dev, int * ip)
     /* [previous][next][first][last][top][bottom][index][help] */
 793 {
 794   ip[0] = 64;
 795   ip[1] = 32;
 796   ip[2] = size >> 11;
 797 /*  if (ip[2] >= 1024) ip[2] = 1024; */
 798   return 0;
 799 }

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