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

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