This source file includes following definitions.
- aha1740_makecode
 
- aha1740_test_port
 
- aha1740_intr_handle
 
- aha1740_queuecommand
 
- internal_done
 
- aha1740_command
 
- aha1740_getconfig
 
- aha1740_detect
 
- aha1740_abort
 
- aha1740_reset
 
- aha1740_biosparam
 
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 
  17 
  18 
  19 
  20 #ifdef MODULE
  21 #include <linux/module.h>
  22 #endif
  23 
  24 #include <linux/kernel.h>
  25 #include <linux/head.h>
  26 #include <linux/types.h>
  27 #include <linux/string.h>
  28 #include <linux/ioport.h>
  29 #include <linux/proc_fs.h>
  30 #include <linux/sched.h>
  31 #include <asm/dma.h>
  32 
  33 #include <asm/system.h>
  34 #include <asm/io.h>
  35 #include <linux/blk.h>
  36 #include "scsi.h"
  37 #include "hosts.h"
  38 #include "sd.h"
  39 
  40 #include "aha1740.h"
  41 #include<linux/stat.h>
  42 
  43 struct proc_dir_entry proc_scsi_aha1740 = {
  44     PROC_SCSI_AHA1740, 7, "aha1740",
  45     S_IFDIR | S_IRUGO | S_IXUGO, 2
  46 };
  47 
  48 
  49 
  50 
  51 
  52 #ifdef DEBUG
  53 #define DEB(x) x
  54 #else
  55 #define DEB(x)
  56 #endif
  57 
  58 
  59 
  60 
  61 
  62 static unsigned int slot, base;
  63 static unsigned char irq_level;
  64 
  65 static struct ecb ecb[AHA1740_ECBS];    
  66 
  67 static int aha1740_last_ecb_used  = 0;  
  68 
  69 int aha1740_makecode(unchar *sense, unchar *status)
     
  70 {
  71     struct statusword
  72     {
  73         ushort  don:1,  
  74                 du:1,   
  75         :1,     qf:1,   
  76                 sc:1,   
  77                 dor:1,  
  78                 ch:1,   
  79                 intr:1, 
  80                 asa:1,  
  81                 sns:1,  
  82         :1,     ini:1,  
  83                 me:1,   
  84         :1,     eca:1,  
  85         :1;
  86     } status_word;
  87     int retval = DID_OK;
  88 
  89     status_word = * (struct statusword *) status;
  90 #ifdef DEBUG
  91 printk("makecode from %x,%x,%x,%x %x,%x,%x,%x",status[0],status[1],status[2],status[3],
  92 sense[0],sense[1],sense[2],sense[3]);
  93 #endif
  94     if (!status_word.don) 
  95     {
  96         if ( (status[1]&0x18) || status_word.sc ) 
  97         {
  98             
  99             switch ( status[2] )
 100             {
 101             case 0x12:
 102                 if ( status_word.dor )
 103                     retval=DID_ERROR;   
 104                 
 105             case 0x00: 
 106                 break;
 107             case 0x11:
 108             case 0x21:
 109                 retval=DID_TIME_OUT;
 110                 break;
 111             case 0x0a:
 112                 retval=DID_BAD_TARGET;
 113                 break;
 114             case 0x04:
 115             case 0x05:
 116                 retval=DID_ABORT; 
 117 
 118                 break;
 119             default:
 120                 retval=DID_ERROR; 
 121             } 
 122         }
 123         else
 124         { 
 125             if ( status_word.qf )
 126             {
 127                 retval = DID_TIME_OUT; 
 128                 
 129                 printk("aha1740.c: WARNING: AHA1740 queue overflow!\n");
 130             }
 131             else if ( status[0]&0x60 )
 132             {
 133                 retval = DID_ERROR; 
 134             }
 135             
 136 
 137 
 138         }
 139     }
 140     
 141     return status[3] | retval << 16;
 142 }
 143 
 144 int aha1740_test_port(void)
     
 145 {
 146     char    name[4],tmp;
 147 
 148     
 149     name[0]= 'A' -1 + ((tmp = inb(HID0)) >> 2); 
 150     name[1]= 'A' -1 + ((tmp & 3) << 3);
 151     name[1]+= ((tmp = inb(HID1)) >> 5)&0x7;     
 152     name[2]= 'A' -1 + (tmp & 0x1f);             
 153     name[3]=0;
 154     tmp = inb(HID2);
 155     if ( strcmp ( name, HID_MFG ) || inb(HID2) != HID_PRD )
 156         return 0;   
 157 
 158 
 159 
 160 
 161 
 162     if ( inb(EBCNTRL) != EBCNTRL_VALUE )
 163     {
 164         printk("aha1740: Board detected, but EBCNTRL = %x, so disabled it.\n",
 165             inb(EBCNTRL));
 166         return 0;
 167     }
 168 
 169     if ( inb(PORTADR) & PORTADDR_ENH )
 170         return 1;   
 171         
 172     printk("aha1740: Board detected, but not in enhanced mode, so disabled it.\n");
 173     return 0;
 174 }
 175 
 176 
 177 void aha1740_intr_handle(int irq, struct pt_regs * regs)
     
 178 {
 179     void (*my_done)(Scsi_Cmnd *);
 180     int errstatus, adapstat;
 181     int number_serviced;
 182     struct ecb *ecbptr;
 183     Scsi_Cmnd *SCtmp;
 184 
 185     number_serviced = 0;
 186 
 187     while(inb(G2STAT) & G2STAT_INTPEND)
 188     {
 189         DEB(printk("aha1740_intr top of loop.\n"));
 190         adapstat = inb(G2INTST);
 191         ecbptr = (struct ecb *) bus_to_virt(inl(MBOXIN0));
 192         outb(G2CNTRL_IRST,G2CNTRL); 
 193       
 194         switch ( adapstat & G2INTST_MASK )
 195         {
 196         case    G2INTST_CCBRETRY:
 197         case    G2INTST_CCBERROR:
 198         case    G2INTST_CCBGOOD:
 199             outb(G2CNTRL_HRDY,G2CNTRL); 
 200             if (!ecbptr)
 201             {
 202                 printk("Aha1740 null ecbptr in interrupt (%x,%x,%x,%d)\n",
 203                         inb(G2STAT),adapstat,inb(G2INTST),number_serviced++);
 204                 continue;
 205             }
 206             SCtmp = ecbptr->SCpnt;
 207             if (!SCtmp)
 208             {
 209                 printk("Aha1740 null SCtmp in interrupt (%x,%x,%x,%d)\n",
 210                         inb(G2STAT),adapstat,inb(G2INTST),number_serviced++);
 211                 continue;
 212             }
 213             if (SCtmp->host_scribble)
 214                 scsi_free(SCtmp->host_scribble, 512);
 215           
 216 
 217 
 218             if ( (adapstat & G2INTST_MASK) == G2INTST_CCBERROR )
 219               {
 220                 memcpy(SCtmp->sense_buffer, ecbptr->sense, 
 221                        sizeof(SCtmp->sense_buffer));
 222                 errstatus = aha1740_makecode(ecbptr->sense,ecbptr->status);
 223               }
 224             else
 225                 errstatus = 0;
 226             DEB(if (errstatus) printk("aha1740_intr_handle: returning %6x\n", errstatus));
 227             SCtmp->result = errstatus;
 228             my_done = ecbptr->done;
 229             memset(ecbptr,0,sizeof(struct ecb)); 
 230             if ( my_done )
 231                 my_done(SCtmp);
 232             break;
 233         case    G2INTST_HARDFAIL:
 234             printk("aha1740 hardware failure!\n");
 235             panic("aha1740.c"); 
 236         case    G2INTST_ASNEVENT:
 237             printk("aha1740 asynchronous event: %02x %02x %02x %02x %02x\n",adapstat,
 238                 inb(MBOXIN0),inb(MBOXIN1),inb(MBOXIN2),inb(MBOXIN3)); 
 239             outb(G2CNTRL_HRDY,G2CNTRL); 
 240             break;
 241         case    G2INTST_CMDGOOD:
 242             
 243             break;
 244         case    G2INTST_CMDERROR:
 245             
 246             break;
 247         }
 248       number_serviced++;
 249     }
 250 }
 251 
 252 int aha1740_queuecommand(Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
     
 253 {
 254     unchar direction;
 255     unchar *cmd = (unchar *) SCpnt->cmnd;
 256     unchar target = SCpnt->target;
 257     unsigned long flags;
 258     void *buff = SCpnt->request_buffer;
 259     int bufflen = SCpnt->request_bufflen;
 260     int ecbno;
 261     DEB(int i);
 262 
 263     
 264     if(*cmd == REQUEST_SENSE)
 265     {
 266         if (bufflen != sizeof(SCpnt->sense_buffer))
 267         {
 268             printk("Wrong buffer length supplied for request sense (%d)\n",bufflen);
 269         }
 270         SCpnt->result = 0;
 271         done(SCpnt); 
 272         return 0;
 273     }
 274 
 275 #ifdef DEBUG
 276     if (*cmd == READ_10 || *cmd == WRITE_10)
 277         i = xscsi2int(cmd+2);
 278     else if (*cmd == READ_6 || *cmd == WRITE_6)
 279         i = scsi2int(cmd+2);
 280     else
 281         i = -1;
 282     printk("aha1740_queuecommand: dev %d cmd %02x pos %d len %d ", target, *cmd, i, bufflen);
 283     printk("scsi cmd:");
 284     for (i = 0; i < SCpnt->cmd_len; i++) printk("%02x ", cmd[i]);
 285     printk("\n");
 286 #endif
 287 
 288     
 289 
 290     save_flags(flags);
 291     cli();
 292     ecbno = aha1740_last_ecb_used + 1;          
 293     if (ecbno >= AHA1740_ECBS) ecbno = 0;
 294 
 295     do{
 296       if( ! ecb[ecbno].cmdw )
 297         break;
 298       ecbno++;
 299       if (ecbno >= AHA1740_ECBS ) ecbno = 0;
 300     } while (ecbno != aha1740_last_ecb_used);
 301 
 302     if( ecb[ecbno].cmdw )
 303       panic("Unable to find empty ecb for aha1740.\n");
 304 
 305     ecb[ecbno].cmdw = AHA1740CMD_INIT;  
 306 
 307     aha1740_last_ecb_used = ecbno;    
 308     restore_flags(flags);
 309 
 310 #ifdef DEBUG
 311     printk("Sending command (%d %x)...",ecbno, done);
 312 #endif
 313 
 314     ecb[ecbno].cdblen = SCpnt->cmd_len; 
 315 
 316     direction = 0;
 317     if (*cmd == READ_10 || *cmd == READ_6)
 318         direction = 1;
 319     else if (*cmd == WRITE_10 || *cmd == WRITE_6)
 320         direction = 0;
 321 
 322     memcpy(ecb[ecbno].cdb, cmd, ecb[ecbno].cdblen);
 323 
 324     if (SCpnt->use_sg)
 325     {
 326         struct scatterlist * sgpnt;
 327         struct aha1740_chain * cptr;
 328         int i;
 329 #ifdef DEBUG
 330         unsigned char * ptr;
 331 #endif
 332         ecb[ecbno].sg = 1;        
 333         SCpnt->host_scribble = (unsigned char *) scsi_malloc(512);
 334         sgpnt = (struct scatterlist *) SCpnt->request_buffer;
 335         cptr = (struct aha1740_chain *) SCpnt->host_scribble; 
 336         if (cptr == NULL) panic("aha1740.c: unable to allocate DMA memory\n");
 337         for(i=0; i<SCpnt->use_sg; i++)
 338         {
 339             cptr[i].dataptr = (long) sgpnt[i].address;
 340             cptr[i].datalen = sgpnt[i].length;
 341         }
 342         ecb[ecbno].datalen = SCpnt->use_sg * sizeof(struct aha1740_chain);
 343         ecb[ecbno].dataptr = (long) cptr;
 344 #ifdef DEBUG
 345         printk("cptr %x: ",cptr);
 346         ptr = (unsigned char *) cptr;
 347         for(i=0;i<24;i++) printk("%02x ", ptr[i]);
 348 #endif
 349     }
 350     else
 351     {
 352         SCpnt->host_scribble = NULL;
 353         ecb[ecbno].datalen = bufflen;
 354         ecb[ecbno].dataptr = (long) buff;
 355     }
 356     ecb[ecbno].lun = SCpnt->lun;
 357     ecb[ecbno].ses = 1; 
 358     ecb[ecbno].dir= direction;
 359     ecb[ecbno].ars=1;  
 360     ecb[ecbno].senselen = 12;
 361     ecb[ecbno].senseptr = (long) ecb[ecbno].sense;
 362     ecb[ecbno].statusptr = (long) ecb[ecbno].status;
 363     ecb[ecbno].done = done;
 364     ecb[ecbno].SCpnt = SCpnt;
 365 #ifdef DEBUG
 366     {
 367         int i;
 368         printk("aha1740_command: sending.. ");
 369         for (i = 0; i < sizeof(ecb[ecbno])-10; i++)
 370             printk("%02x ", ((unchar *)&ecb[ecbno])[i]);
 371     }
 372     printk("\n");
 373 #endif
 374     if (done)
 375     { 
 376 
 377 
 378 
 379 
 380 
 381 
 382 
 383 
 384 
 385         DEB(printk("aha1740[%d] critical section\n",ecbno));
 386         save_flags(flags);
 387         cli();
 388         if ( ! (inb(G2STAT) & G2STAT_MBXOUT) )
 389         {
 390             printk("aha1740[%d]_mbxout wait!\n",ecbno);
 391             cli(); 
 392         }
 393         mb();
 394         while ( ! (inb(G2STAT) & G2STAT_MBXOUT) );      
 395         outl(virt_to_bus(ecb+ecbno), MBOXOUT0);
 396         if ( inb(G2STAT) & G2STAT_BUSY )
 397         {
 398             printk("aha1740[%d]_attn wait!\n",ecbno);
 399             cli();
 400         }
 401         while ( inb(G2STAT) & G2STAT_BUSY );            
 402         outb(ATTN_START | (target & 7), ATTN);  
 403         restore_flags(flags);
 404         DEB(printk("aha1740[%d] request queued.\n",ecbno));
 405     }
 406     else
 407       printk("aha1740_queuecommand: done can't be NULL\n");
 408     
 409     return 0;
 410 }
 411 
 412 static volatile int internal_done_flag = 0;
 413 static volatile int internal_done_errcode = 0;
 414 
 415 static void internal_done(Scsi_Cmnd * SCpnt)
     
 416 {
 417     internal_done_errcode = SCpnt->result;
 418     ++internal_done_flag;
 419 }
 420 
 421 int aha1740_command(Scsi_Cmnd * SCpnt)
     
 422 {
 423     aha1740_queuecommand(SCpnt, internal_done);
 424 
 425     while (!internal_done_flag);
 426     internal_done_flag = 0;
 427     return internal_done_errcode;
 428 }
 429 
 430 
 431 
 432 
 433 void aha1740_getconfig(void)
     
 434 {
 435   static int intab[] = { 9,10,11,12,0,14,15,0 };
 436 
 437   irq_level = intab [ inb(INTDEF)&0x7 ];
 438   outb(inb(INTDEF) | 0x10, INTDEF);
 439 }
 440 
 441 int aha1740_detect(Scsi_Host_Template * tpnt)
     
 442 {
 443     tpnt->proc_dir = &proc_scsi_aha1740;
 444 
 445     memset(&ecb, 0, sizeof(struct ecb));
 446     DEB(printk("aha1740_detect: \n"));
 447     
 448     for ( slot=MINEISA; slot <= MAXEISA; slot++ )
 449     {
 450         base = SLOTBASE(slot);
 451         
 452 
 453 
 454 
 455 
 456         if(check_region(base, 0x5c)) continue;  
 457         if ( aha1740_test_port())  break;
 458     }
 459     if ( slot > MAXEISA )
 460         return 0;
 461 
 462     aha1740_getconfig();
 463 
 464     if ( (inb(G2STAT) & (G2STAT_MBXOUT | G2STAT_BUSY) ) != G2STAT_MBXOUT )
 465     {   
 466         outb(G2CNTRL_HRST,G2CNTRL);
 467         outb(0,G2CNTRL);    
 468     }
 469 
 470     printk("Configuring Adaptec at IO:%x, IRQ %d\n",base,
 471            irq_level);
 472 
 473     DEB(printk("aha1740_detect: enable interrupt channel %d\n", irq_level));
 474 
 475     if (request_irq(irq_level,aha1740_intr_handle, 0, "aha1740"))
 476     {
 477         printk("Unable to allocate IRQ for adaptec controller.\n");
 478         return 0;
 479     }
 480     request_region(base, 0x5c,"aha1740");  
 481     return 1;
 482 }
 483 
 484 
 485 
 486 
 487 
 488 
 489 
 490 
 491 
 492 int aha1740_abort(Scsi_Cmnd * SCpnt)
     
 493 {
 494     DEB(printk("aha1740_abort called\n"));
 495     return SCSI_ABORT_SNOOZE;
 496 }
 497 
 498 
 499 
 500 
 501 
 502 int aha1740_reset(Scsi_Cmnd * SCpnt)
     
 503 {
 504     DEB(printk("aha1740_reset called\n"));
 505     return SCSI_RESET_PUNT;
 506 }
 507 
 508 int aha1740_biosparam(Disk * disk, kdev_t dev, int* ip)
     
 509 {
 510   int size = disk->capacity;
 511 DEB(printk("aha1740_biosparam\n"));
 512   ip[0] = 64;
 513   ip[1] = 32;
 514   ip[2] = size >> 11;
 515 
 516   return 0;
 517 }
 518 
 519 #ifdef MODULE
 520 
 521 Scsi_Host_Template driver_template = AHA1740;
 522 
 523 #include "scsi_module.c"
 524 #endif
 525 
 526 
 527 
 528