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

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