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

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