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. 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 "../block/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 /* The DMA-Controller.  We need to fool with this because we want to 
  48    be able to use the aha1542 without having to have the bios enabled */
  49 #define DMA_MODE_REG    0xd6
  50 #define DMA_MASK_REG    0xd4
  51 #define CASCADE         0xc0
  52 
  53 struct aha1542_hostdata{
  54         /* This will effectively start both of them at the first mailbox */
  55         int aha1542_last_mbi_used;
  56         int aha1542_last_mbo_used;
  57         Scsi_Cmnd * SCint[AHA1542_MAILBOXES];
  58         struct mailbox mb[2*AHA1542_MAILBOXES];
  59         struct ccb ccb[AHA1542_MAILBOXES];
  60 };
  61 
  62 #define HOSTDATA(host) ((struct aha1542_hostdata *) &host->hostdata)
  63 
  64 static struct Scsi_Host * aha_host[7] = {NULL,};  /* One for each IRQ level (9-15) */
  65 
  66 
  67 
  68 
  69 #define WAITnexttimeout 3000000
  70 
  71 static void setup_mailboxes(int base_io, struct Scsi_Host * shpnt);
  72 
  73 #define aha1542_intr_reset(base)  outb(IRST, CONTROL(base))
  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(unsigned int base, unchar *cmdp, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
  93 {
  94     while (len--)
  95       {
  96           WAIT(STATUS(base), CDF, 0, CDF);
  97           outb(*cmdp++, DATA(base));
  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(unsigned int base, unchar *cmdp, int len)
     /* [previous][next][first][last][top][bottom][index][help] */
 106 {
 107     while (len--)
 108       {
 109           WAIT(STATUS(base), DF, DF, 0);
 110           *cmdp++ = inb(DATA(base));
 111       }
 112     return 0;
 113   fail:
 114     printk("aha1542_in failed(%d): ", len+1); aha1542_stat();
 115     return 1;
 116 }
 117 
 118 static 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         DEB(printk("Aha1542: %x %x\n", hosterr, scsierr));
 158         hosterr = DID_ERROR; /* Couldn't find any better */
 159         break;
 160 
 161       case 0x14: /* Target bus phase sequence failure-An invalid bus phase or bus
 162                     phase sequence was requested by the target. The host adapter
 163                     will generate a SCSI Reset Condition, notifying the host with
 164                     a SCRD interrupt */
 165         hosterr = DID_RESET;
 166         break;
 167       default:
 168         printk("makecode: unknown hoststatus %x\n", hosterr);
 169         break;
 170     }
 171     return scsierr|(hosterr << 16);
 172 }
 173 
 174 static int aha1542_test_port(int bse, struct Scsi_Host * shpnt)
     /* [previous][next][first][last][top][bottom][index][help] */
 175 {
 176     int i;
 177     volatile int debug = 0;
 178     
 179     /* Quick and dirty test for presence of the card. */
 180     if(inb(STATUS(bse)) == 0xff) return 0;
 181 
 182     /* Reset the adapter. I ought to make a hard reset, but it's not really nessesary */
 183     
 184     /*  DEB(printk("aha1542_test_port called \n")); */
 185     
 186     outb(SRST|IRST/*|SCRST*/, CONTROL(bse));
 187 
 188     i = jiffies + 2;
 189     while (i>jiffies); /* Wait a little bit for things to settle down. */
 190     
 191     debug = 1;
 192     /* Expect INIT and IDLE, any of the others are bad */
 193     WAIT(STATUS(bse), STATMASK, INIT|IDLE, STST|DIAGF|INVDCMD|DF|CDF);
 194     
 195     debug = 2;
 196     /* Shouldn't have generated any interrupts during reset */
 197     if (inb(INTRFLAGS(bse))&INTRMASK) goto fail;
 198     setup_mailboxes(bse, shpnt);
 199     
 200     debug = 3;
 201     /* Test the basic ECHO command */
 202     outb(CMD_ECHO, DATA(bse));
 203     
 204     debug = 4;
 205     /* Wait for CDF=0. If any of the others are set, it's bad */
 206     WAIT(STATUS(bse), STATMASK, 0, STST|DIAGF|INVDCMD|DF|CDF);
 207     
 208     debug = 5;
 209     /* The meaning of life */
 210     outb(42, DATA(bse));
 211     
 212     debug = 6;
 213     /* Expect only DF, that is, data ready */
 214     WAIT(STATUS(bse), STATMASK, DF, STST|DIAGF|CDF|INVDCMD);
 215     
 216     debug = 7;
 217     /* Is the answer correct? */
 218     if (inb(DATA(bse)) != 42) goto fail;
 219     
 220     debug = 8;
 221     /* Reading port should reset DF */
 222     if (inb(STATUS(bse)) & DF) goto fail;
 223     
 224     debug = 9;
 225     /* When HACC, command is completed, and we're though testing */
 226     WAIT(INTRFLAGS(bse), HACC, HACC, 0);
 227     /* now initialize adapter */
 228     
 229     debug = 10;
 230     /* Clear interrupts */
 231     outb(IRST, CONTROL(bse));
 232     
 233     debug = 11;
 234     
 235     return debug;                               /* 1 = ok */
 236   fail:
 237     return 0;                                   /* 0 = not ok */
 238 }
 239 
 240 static const char aha_ident[] = "Adaptec 1542";
 241 
 242 /* What's this little function for? */
 243 const char *aha1542_info(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 244 {
 245     return aha_ident;
 246 }
 247 
 248 /* A "high" level interrupt handler */
 249 static void aha1542_intr_handle(int foo)
     /* [previous][next][first][last][top][bottom][index][help] */
 250 {
 251     void (*my_done)(Scsi_Cmnd *) = NULL;
 252     int errstatus, mbi, mbo, mbistatus;
 253     int number_serviced;
 254     struct Scsi_Host * shost;
 255     Scsi_Cmnd * SCtmp;
 256     int irqno, * irqp;
 257     struct mailbox * mb;
 258     struct ccb  *ccb;
 259 
 260     irqp = (int *) foo;
 261     irqp -= 2;  /* Magic - this is only required for slow interrupt handlers */
 262     irqno = *irqp;
 263 
 264     shost = aha_host[irqno - 9];
 265     mb = HOSTDATA(shost)->mb;
 266     ccb = HOSTDATA(shost)->ccb;
 267 
 268     if(!shost) panic("Splunge!");
 269 
 270 #ifdef DEBUG
 271     {
 272     int flag = inb(INTRFLAGS(shost->io_port));
 273     printk("aha1542_intr_handle: ");
 274     if (!(flag&ANYINTR)) printk("no interrupt?");
 275     if (flag&MBIF) printk("MBIF ");
 276     if (flag&MBOA) printk("MBOF ");
 277     if (flag&HACC) printk("HACC ");
 278     if (flag&SCRD) printk("SCRD ");
 279     printk("status %02x\n", inb(STATUS(shost->io_port)));
 280   };
 281 #endif
 282     number_serviced = 0;
 283 
 284     while(1==1){
 285       aha1542_intr_reset(shost->io_port);
 286 
 287       cli();
 288       mbi = HOSTDATA(shost)->aha1542_last_mbi_used + 1;
 289       if (mbi >= 2*AHA1542_MAILBOXES) mbi = AHA1542_MAILBOXES;
 290       
 291       do{
 292         if(mb[mbi].status != 0) break;
 293         mbi++;
 294         if (mbi >= 2*AHA1542_MAILBOXES) mbi = AHA1542_MAILBOXES;
 295       } while (mbi != HOSTDATA(shost)->aha1542_last_mbi_used);
 296       
 297       if(mb[mbi].status == 0){
 298         sti();
 299         /* Hmm, no mail.  Must have read it the last time around */
 300         if (number_serviced) return;
 301         /* Virtually all of the time, this turns out to be the problem */
 302         printk("aha1542.c: Unsupported BIOS options enabled."
 303                 "  Please turn off.\n");
 304 /*      printk("aha1542.c: interrupt received, but no mail.\n"); */
 305         return;
 306       };
 307 
 308       mbo = (scsi2int(mb[mbi].ccbptr) - ((unsigned int) &ccb[0])) / sizeof(struct ccb);
 309       mbistatus = mb[mbi].status;
 310       mb[mbi].status = 0;
 311       HOSTDATA(shost)->aha1542_last_mbi_used = mbi;
 312       sti();
 313       
 314 #ifdef DEBUG
 315       {
 316         if (ccb[mbo].tarstat|ccb[mbo].hastat)
 317           printk("aha1542_command: returning %x (status %d)\n", 
 318                  ccb[mbo].tarstat + ((int) ccb[mbo].hastat << 16), mb[mbi].status);
 319       };
 320 #endif
 321 
 322       if(mbistatus == 3) continue; /* Aborted command not found */
 323 
 324 #ifdef DEBUG
 325       printk("...done %d %d\n",mbo, mbi);
 326 #endif
 327       
 328       SCtmp = HOSTDATA(shost)->SCint[mbo];
 329 
 330       if (!SCtmp || !SCtmp->scsi_done) {
 331         printk("aha1542_intr_handle: Unexpected interrupt\n");
 332         return;
 333       }
 334       
 335       my_done = SCtmp->scsi_done;
 336       if (SCtmp->host_scribble) scsi_free(SCtmp->host_scribble, 512);
 337       
 338       /* Fetch the sense data, and tuck it away, in the required slot.  The
 339          Adaptec automatically fetches it, and there is no guarantee that
 340          we will still have it in the cdb when we come back */
 341       if (ccb[mbo].tarstat == 2)
 342         memcpy(SCtmp->sense_buffer, &ccb[mbo].cdb[ccb[mbo].cdblen], 
 343                sizeof(SCtmp->sense_buffer));
 344       
 345       
 346       /* is there mail :-) */
 347       
 348       /* more error checking left out here */
 349       if (mbistatus != 1)
 350         /* This is surely wrong, but I don't know what's right */
 351         errstatus = makecode(ccb[mbo].hastat, ccb[mbo].tarstat);
 352       else
 353         errstatus = 0;
 354       
 355 #ifdef DEBUG
 356       if(errstatus) printk("(aha1542 error:%x %x %x) ",errstatus, 
 357                            ccb[mbo].hastat, ccb[mbo].tarstat);
 358 #endif
 359 
 360       if (ccb[mbo].tarstat == 2) {
 361 #ifdef DEBUG
 362         int i;
 363 #endif
 364         DEB(printk("aha1542_intr_handle: sense:"));
 365 #ifdef DEBUG
 366         for (i = 0; i < 12; i++)
 367           printk("%02x ", ccb[mbo].cdb[ccb[mbo].cdblen+i]);
 368         printk("\n");
 369 #endif
 370         /*
 371           DEB(printk("aha1542_intr_handle: buf:"));
 372           for (i = 0; i < bufflen; i++)
 373           printk("%02x ", ((unchar *)buff)[i]);
 374           printk("\n");
 375           */
 376       }
 377       DEB(if (errstatus) printk("aha1542_intr_handle: returning %6x\n", errstatus));
 378       SCtmp->result = errstatus;
 379       HOSTDATA(shost)->SCint[mbo] = NULL;  /* This effectively frees up the mailbox slot, as
 380                              far as queuecommand is concerned */
 381       my_done(SCtmp);
 382       number_serviced++;
 383     };
 384 }
 385 
 386 int aha1542_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
     /* [previous][next][first][last][top][bottom][index][help] */
 387 {
 388     unchar ahacmd = CMD_START_SCSI;
 389     unchar direction;
 390     unchar *cmd = (unchar *) SCpnt->cmnd;
 391     unchar target = SCpnt->target;
 392     unchar lun = SCpnt->lun;
 393     void *buff = SCpnt->request_buffer;
 394     int bufflen = SCpnt->request_bufflen;
 395     int mbo;
 396     struct mailbox * mb;
 397     struct ccb  *ccb;
 398 
 399     DEB(int i);
 400 
 401     mb = HOSTDATA(SCpnt->host)->mb;
 402     ccb = HOSTDATA(SCpnt->host)->ccb;
 403 
 404     DEB(if (target > 1) {
 405       SCpnt->result = DID_TIME_OUT << 16;
 406       done(SCpnt); return 0;});
 407     
 408     if(*cmd == REQUEST_SENSE){
 409 #ifndef DEBUG
 410       if (bufflen != sizeof(SCpnt->sense_buffer)) {
 411         printk("Wrong buffer length supplied for request sense (%d)\n",bufflen);
 412         panic("aha1542.c");
 413       };
 414 #endif
 415       SCpnt->result = 0;
 416       done(SCpnt); 
 417       return 0;
 418     };
 419 
 420 #ifdef DEBUG
 421     if (*cmd == READ_10 || *cmd == WRITE_10)
 422       i = xscsi2int(cmd+2);
 423     else if (*cmd == READ_6 || *cmd == WRITE_6)
 424       i = scsi2int(cmd+2);
 425     else
 426       i = -1;
 427     if (done)
 428       printk("aha1542_queuecommand: dev %d cmd %02x pos %d len %d ", target, *cmd, i, bufflen);
 429     else
 430       printk("aha1542_command: dev %d cmd %02x pos %d len %d ", target, *cmd, i, bufflen);
 431     aha1542_stat();
 432     printk("aha1542_queuecommand: dumping scsi cmd:");
 433     for (i = 0; i < (COMMAND_SIZE(*cmd)); i++) printk("%02x ", cmd[i]);
 434     printk("\n");
 435     if (*cmd == WRITE_10 || *cmd == WRITE_6)
 436       return 0; /* we are still testing, so *don't* write */
 437 #endif
 438 /* Use the outgoing mailboxes in a round-robin fashion, because this
 439    is how the host adapter will scan for them */
 440 
 441     cli();
 442     mbo = HOSTDATA(SCpnt->host)->aha1542_last_mbo_used + 1;
 443     if (mbo >= AHA1542_MAILBOXES) mbo = 0;
 444 
 445     do{
 446       if(mb[mbo].status == 0 && HOSTDATA(SCpnt->host)->SCint[mbo] == NULL)
 447         break;
 448       mbo++;
 449       if (mbo >= AHA1542_MAILBOXES) mbo = 0;
 450     } while (mbo != HOSTDATA(SCpnt->host)->aha1542_last_mbo_used);
 451 
 452     if(mb[mbo].status || HOSTDATA(SCpnt->host)->SCint[mbo])
 453       panic("Unable to find empty mailbox for aha1542.\n");
 454 
 455     HOSTDATA(SCpnt->host)->SCint[mbo] = SCpnt;  /* This will effectively prevent someone else from
 456                             screwing with this cdb. */
 457 
 458     HOSTDATA(SCpnt->host)->aha1542_last_mbo_used = mbo;    
 459     sti();
 460 
 461 #ifdef DEBUG
 462     printk("Sending command (%d %x)...",mbo, done);
 463 #endif
 464 
 465     any2scsi(mb[mbo].ccbptr, &ccb[mbo]); /* This gets trashed for some reason*/
 466 
 467     memset(&ccb[mbo], 0, sizeof(struct ccb));
 468 
 469     ccb[mbo].cdblen = COMMAND_SIZE(*cmd);     /* SCSI Command Descriptor Block Length */
 470 
 471     direction = 0;
 472     if (*cmd == READ_10 || *cmd == READ_6)
 473         direction = 8;
 474     else if (*cmd == WRITE_10 || *cmd == WRITE_6)
 475         direction = 16;
 476 
 477     memcpy(ccb[mbo].cdb, cmd, ccb[mbo].cdblen);
 478 
 479     if (SCpnt->use_sg) {
 480       struct scatterlist * sgpnt;
 481       struct chain * cptr;
 482 #ifdef DEBUG
 483       unsigned char * ptr;
 484 #endif
 485       int i;
 486       ccb[mbo].op = 2;        /* SCSI Initiator Command  w/scatter-gather*/
 487       SCpnt->host_scribble = (unsigned char *) scsi_malloc(512);
 488       sgpnt = (struct scatterlist *) SCpnt->request_buffer;
 489       cptr = (struct chain *) SCpnt->host_scribble; 
 490       if (cptr == NULL) panic("aha1542.c: unable to allocate DMA memory\n");
 491       for(i=0; i<SCpnt->use_sg; i++) {
 492         if(sgpnt[i].length == 0 || SCpnt->use_sg > 16 || 
 493            (((int)sgpnt[i].address) & 1) || (sgpnt[i].length & 1)){
 494           unsigned char * ptr;
 495           printk("Bad segment list supplied to aha1542.c (%d, %d)\n",SCpnt->use_sg,i);
 496           for(i=0;i<SCpnt->use_sg;i++){
 497             printk("%d: %x %x %d\n",i,(unsigned int) sgpnt[i].address, (unsigned int) sgpnt[i].alt_address,
 498                    sgpnt[i].length);
 499           };
 500           printk("cptr %x: ",(unsigned int) cptr);
 501           ptr = (unsigned char *) &cptr[i];
 502           for(i=0;i<18;i++) printk("%02x ", ptr[i]);
 503           panic("Foooooooood fight!");
 504         };
 505         any2scsi(cptr[i].dataptr, sgpnt[i].address);
 506         if(((unsigned  int) sgpnt[i].address) & 0xff000000) goto baddma;
 507         any2scsi(cptr[i].datalen, sgpnt[i].length);
 508       };
 509       any2scsi(ccb[mbo].datalen, SCpnt->use_sg * sizeof(struct chain));
 510       if(((unsigned int) buff & 0xff000000)) goto baddma;
 511       any2scsi(ccb[mbo].dataptr, cptr);
 512 #ifdef DEBUG
 513       printk("cptr %x: ",cptr);
 514       ptr = (unsigned char *) cptr;
 515       for(i=0;i<18;i++) printk("%02x ", ptr[i]);
 516 #endif
 517     } else {
 518       ccb[mbo].op = 0;        /* SCSI Initiator Command */
 519       SCpnt->host_scribble = NULL;
 520       any2scsi(ccb[mbo].datalen, bufflen);
 521       any2scsi(ccb[mbo].dataptr, buff);
 522     };
 523     ccb[mbo].idlun = (target&7)<<5 | direction | (lun & 7); /*SCSI Target Id*/
 524     ccb[mbo].rsalen = 12;
 525     ccb[mbo].linkptr[0] = ccb[mbo].linkptr[1] = ccb[mbo].linkptr[2] = 0;
 526     ccb[mbo].commlinkid = 0;
 527 
 528 #ifdef DEBUGd
 529     { int i;
 530     printk("aha1542_command: sending.. ");
 531     for (i = 0; i < sizeof(ccb[mbo])-10; i++)
 532       printk("%02x ", ((unchar *)&ccb[mbo])[i]);
 533     };
 534 #endif
 535     
 536     if (done) {
 537         DEB(printk("aha1542_queuecommand: now waiting for interrupt "); aha1542_stat());
 538         SCpnt->scsi_done = done;
 539         mb[mbo].status = 1;
 540         aha1542_out(SCpnt->host->io_port, &ahacmd, 1);          /* start scsi command */
 541         DEB(aha1542_stat());
 542     }
 543     else
 544       printk("aha1542_queuecommand: done can't be NULL\n");
 545     
 546     return 0;
 547  baddma:
 548     panic("Buffer at address  > 16Mb used for 1542B");
 549 }
 550 
 551 static void internal_done(Scsi_Cmnd * SCpnt)
     /* [previous][next][first][last][top][bottom][index][help] */
 552 {
 553         SCpnt->SCp.Status++;
 554 }
 555 
 556 int aha1542_command(Scsi_Cmnd * SCpnt)
     /* [previous][next][first][last][top][bottom][index][help] */
 557 {
 558     DEB(printk("aha1542_command: ..calling aha1542_queuecommand\n"));
 559 
 560     aha1542_queuecommand(SCpnt, internal_done);
 561 
 562     SCpnt->SCp.Status = 0;
 563     while (!SCpnt->SCp.Status);
 564     return SCpnt->result;
 565 }
 566 
 567 /* Initialize mailboxes */
 568 static void setup_mailboxes(int bse, struct Scsi_Host * shpnt)
     /* [previous][next][first][last][top][bottom][index][help] */
 569 {
 570     int i;
 571     struct mailbox * mb;
 572     struct ccb  *ccb;
 573 
 574     unchar cmd[5] = {CMD_MBINIT, AHA1542_MAILBOXES};
 575 
 576     mb = HOSTDATA(shpnt)->mb;
 577     ccb = HOSTDATA(shpnt)->ccb;
 578 
 579     for(i=0; i<AHA1542_MAILBOXES; i++){
 580       mb[i].status = mb[AHA1542_MAILBOXES+i].status = 0;
 581       any2scsi(mb[i].ccbptr, &ccb[i]);
 582     };
 583     aha1542_intr_reset(bse);     /* reset interrupts, so they don't block */    
 584     any2scsi((cmd+2), mb);
 585     aha1542_out(bse, cmd, 5);
 586     WAIT(INTRFLAGS(bse), INTRMASK, HACC, 0);
 587     while (0) {
 588       fail:
 589         printk("aha1542_detect: failed setting up mailboxes\n");
 590     }
 591     aha1542_intr_reset(bse);
 592 }
 593 
 594 static int aha1542_getconfig(int base_io, unsigned char * irq_level, unsigned char * dma_chan)
     /* [previous][next][first][last][top][bottom][index][help] */
 595 {
 596   unchar inquiry_cmd[] = {CMD_RETCONF };
 597   unchar inquiry_result[3];
 598   int i;
 599   i = inb(STATUS(base_io));
 600   if (i & DF) {
 601     i = inb(DATA(base_io));
 602   };
 603   aha1542_out(base_io, inquiry_cmd, 1);
 604   aha1542_in(base_io, inquiry_result, 3);
 605   WAIT(INTRFLAGS(base_io), INTRMASK, HACC, 0);
 606   while (0) {
 607   fail:
 608     printk("aha1542_detect: query board settings\n");
 609   }
 610   aha1542_intr_reset(base_io);
 611   switch(inquiry_result[0]){
 612   case 0x80:
 613     *dma_chan = 7;
 614     break;
 615   case 0x40:
 616     *dma_chan = 6;
 617     break;
 618   case 0x20:
 619     *dma_chan = 5;
 620     break;
 621   case 0x01:
 622     printk("DMA priority 0 not available for Adaptec driver\n");
 623     return -1;
 624   case 0:
 625     /* This means that the adapter, although Adaptec 1542 compatible, doesn't use a DMA channel.
 626        Currently only aware of the BusLogic BT-445S VL-Bus adapter which needs this. */
 627     *dma_chan = 0xFF;
 628     break;
 629   default:
 630     printk("Unable to determine Adaptec DMA priority.  Disabling board\n");
 631     return -1;
 632   };
 633   switch(inquiry_result[1]){
 634   case 0x40:
 635     *irq_level = 15;
 636     break;
 637   case 0x20:
 638     *irq_level = 14;
 639     break;
 640   case 0x8:
 641     *irq_level = 12;
 642     break;
 643   case 0x4:
 644     *irq_level = 11;
 645     break;
 646   case 0x2:
 647     *irq_level = 10;
 648     break;
 649   case 0x1:
 650     *irq_level = 9;
 651     break;
 652   default:
 653     printk("Unable to determine Adaptec IRQ level.  Disabling board\n");
 654     return -1;
 655   };
 656   return 0;
 657 }
 658 
 659 /* Query the board to find out if it is a 1542 or a 1740, or whatever. */
 660 static int aha1542_query(int base_io)
     /* [previous][next][first][last][top][bottom][index][help] */
 661 {
 662   unchar inquiry_cmd[] = {CMD_INQUIRY };
 663   unchar inquiry_result[4];
 664   int i;
 665   i = inb(STATUS(base_io));
 666   if (i & DF) {
 667     i = inb(DATA(base_io));
 668   };
 669   aha1542_out(base_io, inquiry_cmd, 1);
 670   aha1542_in(base_io, inquiry_result, 4);
 671   WAIT(INTRFLAGS(base_io), INTRMASK, HACC, 0);
 672   while (0) {
 673   fail:
 674     printk("aha1542_detect: query card type\n");
 675   }
 676   aha1542_intr_reset(base_io);
 677 
 678 /* For an AHA1740 series board, we ignore the board since there is a
 679    hardware bug which can lead to wrong blocks being returned if the board
 680    is operating in the 1542 emulation mode.  Since there is an extended mode
 681    driver, we simply ignore the board and let the 1740 driver pick it up.
 682 */
 683 
 684   if (inquiry_result[0] == 0x43) {
 685     printk("aha1542.c: Emulation mode not supported for AHA 174N hardware.\n");
 686     return 1;
 687   };
 688   return 0;
 689 }
 690 
 691 /* return non-zero on detection */
 692 int aha1542_detect(int hostnum)
     /* [previous][next][first][last][top][bottom][index][help] */
 693 {
 694     unsigned char dma_chan;
 695     unsigned char irq_level;
 696     unsigned int base_io;
 697     struct Scsi_Host * shpnt = NULL;
 698     int count = 0;
 699     int indx;
 700 
 701     DEB(printk("aha1542_detect: \n"));
 702     
 703     for(indx = 0; indx < sizeof(bases)/sizeof(bases[0]); indx++)
 704             if(!check_region(bases[indx], 4)) { 
 705                     shpnt = scsi_register(hostnum,
 706                                           sizeof(struct aha1542_hostdata));
 707 
 708                     if(!aha1542_test_port(bases[indx], shpnt)) goto unregister;
 709 
 710 
 711                     base_io = bases[indx];
 712                     
 713                     /* Set the Bus on/off-times as not to ruin floppy performance */
 714             {
 715                     unchar oncmd[] = {CMD_BUSON_TIME, 7};
 716                     unchar offcmd[] = {CMD_BUSOFF_TIME, 5};
 717                     
 718                     aha1542_intr_reset(base_io);
 719                     aha1542_out(base_io, oncmd, 2);
 720                     WAIT(INTRFLAGS(base_io), INTRMASK, HACC, 0);
 721                     aha1542_intr_reset(base_io);
 722                     aha1542_out(base_io, offcmd, 2);
 723                     WAIT(INTRFLAGS(base_io), INTRMASK, HACC, 0);
 724                     while (0) {
 725                     fail:
 726                             printk("aha1542_detect: setting bus on/off-time failed\n");
 727                     }
 728                     aha1542_intr_reset(base_io);
 729             }
 730                     if(aha1542_query(base_io))  goto unregister;
 731                     
 732                     if (aha1542_getconfig(base_io, &irq_level, &dma_chan) == -1)  goto unregister;
 733                     
 734                     printk("Configuring Adaptec at IO:%x, IRQ %d",base_io, irq_level);
 735                     if (dma_chan != 0xFF)
 736                             printk(", DMA priority %d", dma_chan);
 737                     printk("\n");
 738                     
 739                     DEB(aha1542_stat());
 740                     setup_mailboxes(base_io, shpnt);
 741                     
 742                     DEB(aha1542_stat());
 743                     
 744                     DEB(printk("aha1542_detect: enable interrupt channel %d\n", irq_level));
 745                     cli();
 746                     if (request_irq(irq_level,aha1542_intr_handle)) {
 747                             printk("Unable to allocate IRQ for adaptec controller.\n");
 748                             goto unregister;
 749                     }
 750                     
 751                     if (dma_chan != 0xFF) {
 752                             if (request_dma(dma_chan)) {
 753                                     printk("Unable to allocate DMA channel for Adaptec.\n");
 754                                     free_irq(irq_level);
 755                                     goto unregister;
 756                             }
 757                             
 758                             if (dma_chan >= 5) {
 759                                     outb((dma_chan - 4) | CASCADE, DMA_MODE_REG);
 760                                     outb(dma_chan - 4, DMA_MASK_REG);
 761                             }
 762                     }
 763                     aha_host[irq_level - 9] = shpnt;
 764                     shpnt->io_port = base_io;
 765                     shpnt->dma_channel = dma_chan;
 766                     shpnt->irq = irq_level;
 767                     HOSTDATA(shpnt)->aha1542_last_mbi_used  = (2*AHA1542_MAILBOXES - 1);
 768                     HOSTDATA(shpnt)->aha1542_last_mbo_used  = (AHA1542_MAILBOXES - 1);
 769                     memset(HOSTDATA(shpnt)->SCint, 0, sizeof(HOSTDATA(shpnt)->SCint));
 770                     sti();
 771 #if 0
 772                     DEB(printk(" *** READ CAPACITY ***\n"));
 773                     
 774             {
 775                     unchar buf[8];
 776                     static unchar cmd[] = {     READ_CAPACITY, 0, 0, 0, 0, 0, 0, 0, 0, 0};
 777                     int i;
 778                     
 779                     for (i = 0; i < sizeof(buf); ++i) buf[i] = 0x87;
 780                     for (i = 0; i < 2; ++i)
 781                             if (!aha1542_command(i, cmd, buf, sizeof(buf))) {
 782                                     printk("aha_detect: LU %d sector_size %d device_size %d\n",
 783                                            i, xscsi2int(buf+4), xscsi2int(buf));
 784                             }
 785             }
 786                     
 787                     DEB(printk(" *** NOW RUNNING MY OWN TEST *** \n"));
 788                     
 789                     for (i = 0; i < 4; ++i)
 790                     {
 791                             unsigned char cmd[10];
 792                             static buffer[512];
 793                             
 794                             cmd[0] = READ_10;
 795                             cmd[1] = 0;
 796                             xany2scsi(cmd+2, i);
 797                             cmd[6] = 0;
 798                             cmd[7] = 0;
 799                             cmd[8] = 1;
 800                             cmd[9] = 0;
 801                             aha1542_command(0, cmd, buffer, 512);
 802                     }
 803 #endif    
 804                     snarf_region(bases[indx], 4);  /* Register the IO ports that we use */
 805                     count++;
 806                     continue;
 807             unregister:
 808                     scsi_unregister(shpnt, sizeof(struct aha1542_hostdata));
 809                     continue;
 810                     
 811             };
 812     return count;
 813 }
 814 
 815 /* The abort command does not leave the device in a clean state where
 816    it is available to be used again.  Until this gets worked out, we will
 817    leave it commented out.  */
 818 
 819 int aha1542_abort(Scsi_Cmnd * SCpnt, int i)
     /* [previous][next][first][last][top][bottom][index][help] */
 820 {
 821 #if 0
 822     unchar ahacmd = CMD_START_SCSI;
 823     int mbo;
 824 #endif
 825     DEB(printk("aha1542_abort\n"));
 826 #if 0
 827     cli();
 828     for(mbo = 0; mbo < AHA1542_MAILBOXES; mbo++)
 829       if (SCpnt == HOSTDATA(SCpnt->host)->SCint[mbo]){
 830         mb[mbo].status = 2;  /* Abort command */
 831         aha1542_out(&ahacmd, 1);                /* start scsi command */
 832         sti();
 833         break;
 834       };
 835 #endif
 836     return 0;
 837 }
 838 
 839 /* We do not implement a reset function here, but the upper level code assumes
 840    that it will get some kind of response for the command in SCpnt.  We must
 841    oblige, or the command will hang the scsi system */
 842 
 843 int aha1542_reset(Scsi_Cmnd * SCpnt)
     /* [previous][next][first][last][top][bottom][index][help] */
 844 {
 845     DEB(printk("aha1542_reset called\n"));
 846     if(SCpnt) SCpnt->flags |= NEEDS_JUMPSTART;
 847     return 0;
 848 }
 849 
 850 int aha1542_biosparam(int size, int dev, int * ip)
     /* [previous][next][first][last][top][bottom][index][help] */
 851 {
 852   ip[0] = 64;
 853   ip[1] = 32;
 854   ip[2] = size >> 11;
 855 /*  if (ip[2] >= 1024) ip[2] = 1024; */
 856   return 0;
 857 }

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