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

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