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

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