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

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