This source file includes following definitions.
- aha1542_stat
 
- aha1542_out
 
- aha1542_in
 
- aha1542_in1
 
- makecode
 
- aha1542_test_port
 
- aha1542_intr_handle
 
- aha1542_queuecommand
 
- internal_done
 
- aha1542_command
 
- setup_mailboxes
 
- aha1542_getconfig
 
- aha1542_mbenable
 
- aha1542_query
 
- aha1542_setup
 
- aha1542_detect
 
- aha1542_restart
 
- aha1542_abort
 
- aha1542_reset
 
- aha1542_biosparam
 
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  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 
  52 
  53 
  54 
  55 
  56 
  57 
  58 
  59 #define MAXBOARDS 2     
  60 
  61 
  62 static unsigned int bases[MAXBOARDS]={0x330, 0x334};
  63 
  64 
  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 
  74 
  75 
  76 
  77 
  78 
  79 
  80 
  81 
  82 
  83 
  84 
  85 
  86 
  87 
  88 
  89 
  90 
  91 
  92 #define DMA_MODE_REG    0xd6
  93 #define DMA_MASK_REG    0xd4
  94 #define CASCADE         0xc0
  95 
  96 #define BIOS_TRANSLATION_1632 0  
  97 #define BIOS_TRANSLATION_6432 1 
  98 #define BIOS_TRANSLATION_25563 2 
  99 
 100 struct aha1542_hostdata{
 101         
 102         int bios_translation;   
 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,};  
 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 
 136 
 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)
     
 150 {
 151 
 152 
 153 }
 154 
 155 
 156 
 157 
 158 
 159 static int aha1542_out(unsigned int base, unchar *cmdp, int len)
     
 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 
 190 
 191 static int aha1542_in(unsigned int base, unchar *cmdp, int len)
     
 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 
 211 
 212 
 213 static int aha1542_in1(unsigned int base, unchar *cmdp, int len)
     
 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)
     
 232 {
 233     switch (hosterr) {
 234       case 0x0:
 235       case 0xa: 
 236       case 0xb: 
 237         hosterr = 0;
 238         break;
 239 
 240       case 0x11: 
 241 
 242         hosterr = DID_TIME_OUT;
 243         break;
 244 
 245       case 0x12: 
 246 
 247 
 248 
 249       case 0x13: 
 250 
 251       case 0x15: 
 252 
 253 
 254       case 0x16: 
 255 
 256 
 257       case 0x17: 
 258 
 259 
 260       case 0x18: 
 261 
 262 
 263       case 0x19: 
 264 
 265 
 266 
 267       case 0x1a: 
 268 
 269 
 270         DEB(printk("Aha1542: %x %x\n", hosterr, scsierr));
 271         hosterr = DID_ERROR; 
 272         break;
 273 
 274       case 0x14: 
 275 
 276 
 277 
 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)
     
 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     
 297     if(inb(STATUS(bse)) == 0xff) return 0;
 298 
 299     
 300     
 301     
 302 
 303     
 304     aha1542_intr_reset(bse);         
 305 
 306     outb(SRST|IRST, CONTROL(bse));
 307 
 308     i = jiffies + 2;
 309     while (i>jiffies); 
 310     
 311     debug = 1;
 312     
 313     WAIT(STATUS(bse), STATMASK, INIT|IDLE, STST|DIAGF|INVDCMD|DF|CDF);
 314     
 315     debug = 2;
 316     
 317     if (inb(INTRFLAGS(bse))&INTRMASK) goto fail;
 318 
 319 
 320     
 321 
 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     
 337     if (inb(STATUS(bse)) & DF) goto fail;
 338     
 339     debug = 9;
 340     
 341     WAIT(INTRFLAGS(bse), HACC, HACC, 0);
 342     
 343     
 344     debug = 10;
 345     
 346     outb(IRST, CONTROL(bse));
 347     
 348     debug = 11;
 349 
 350     return debug;                               
 351   fail:
 352     return 0;                                   
 353 }
 354 
 355 
 356 static void aha1542_intr_handle(int irq, struct pt_regs *regs)
     
 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       
 394 
 395 
 396 
 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         
 422         if (!number_serviced && !needs_restart)
 423           printk("aha1542.c: interrupt received, but no mail.\n");
 424         
 425 
 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; 
 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       
 463 
 464 
 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       
 471       
 472       
 473       if (mbistatus != 1)
 474         
 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 
 496 
 497 
 498 
 499 
 500       }
 501       DEB(if (errstatus) printk("aha1542_intr_handle: returning %6x\n", errstatus));
 502       SCtmp->result = errstatus;
 503       HOSTDATA(shost)->SCint[mbo] = NULL;  
 504 
 505       my_done(SCtmp);
 506       number_serviced++;
 507     };
 508 }
 509 
 510 int aha1542_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
     
 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; 
 561 #endif
 562 
 563 
 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;  
 581 
 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]); 
 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;        
 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;        
 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); 
 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);          
 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)
     
 677 {
 678         SCpnt->SCp.Status++;
 679 }
 680 
 681 int aha1542_command(Scsi_Cmnd * SCpnt)
     
 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 
 694 static void setup_mailboxes(int bse, struct Scsi_Host * shpnt)
     
 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);         
 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)
     
 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     
 752 
 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 
 787 
 788 
 789 static int aha1542_mbenable(int base)
     
 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 
 821 static int aha1542_query(int base_io, int * transl)
     
 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; 
 840 
 841 
 842 
 843 
 844 
 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   
 853 
 854 
 855   *transl = aha1542_mbenable(base_io);
 856 
 857   return 0;
 858 }
 859 
 860 
 861 void aha1542_setup( char *str, int *ints)
     
 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; 
 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 
 922 int aha1542_detect(Scsi_Host_Template * tpnt)
     
 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                     
 944 
 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                     
 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")) {
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);
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;  
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");  
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)
     
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; 
1093 #endif
1094         count++;
1095      }     
1096 
1097   printk("Potential to restart %d stalled commands...\n", count);
1098 #if 0
1099   
1100   if (count) aha1542_out(shost->io_port, &ahacmd, 1);
1101 #endif
1102   return 0;
1103 }
1104 
1105 
1106 
1107 
1108 
1109 int aha1542_abort(Scsi_Cmnd * SCpnt)
     
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   
1142 
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;  
1168         aha1542_out(SCpnt->host->io_port, &ahacmd, 1); 
1169         restore_flags(flags);
1170         break;
1171       };
1172 #endif
1173     return SCSI_ABORT_SNOOZE;
1174 }
1175 
1176 
1177 
1178 
1179 
1180 
1181 
1182 int aha1542_reset(Scsi_Cmnd * SCpnt)
     
1183 {
1184     unchar ahacmd = CMD_START_SCSI;
1185     int i;
1186 
1187     
1188 
1189 
1190     if( SCpnt->host->suggest_bus_reset )
1191       {
1192         
1193 
1194 
1195 
1196 
1197 
1198         outb(HRST | SCRST, CONTROL(SCpnt->host->io_port));
1199 
1200         
1201 
1202 
1203 
1204 
1205 
1206 
1207         WAIT(STATUS(SCpnt->host->io_port), 
1208              STATMASK, INIT|IDLE, STST|DIAGF|INVDCMD|DF|CDF);
1209 
1210         
1211 
1212 
1213 
1214         setup_mailboxes(SCpnt->host->io_port, SCpnt->host);
1215 
1216         
1217 
1218 
1219 
1220 
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 
1239 
1240 
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         
1253         
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;  
1258               
1259               aha1542_out(SCpnt->host->io_port, &ahacmd, 1);
1260               
1261               
1262 
1263 
1264 
1265               printk("Sent BUS DEVICE RESET to target %d\n", SCpnt->target);
1266               
1267               
1268 
1269 
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     
1288 
1289 
1290     return SCSI_RESET_PUNT;
1291 }
1292 
1293 #include "sd.h"
1294 
1295 int aha1542_biosparam(Scsi_Disk * disk, kdev_t dev, int * ip)
     
1296 {
1297   int translation_algorithm;
1298   int size = disk->capacity;
1299 
1300   translation_algorithm = HOSTDATA(disk->device->host)->bios_translation;
1301   
1302   if((size>>11) > 1024 && translation_algorithm == 2) {
1303     
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 
1313   return 0;
1314 }
1315 
1316 
1317 #ifdef MODULE
1318 
1319 Scsi_Host_Template driver_template = AHA1542;
1320 
1321 #include "scsi_module.c"
1322 #endif
1323