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

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