Annotation of Gnu-Mach/linux/src/drivers/scsi/eata_pio.c, revision 1.1

1.1     ! root        1: /************************************************************
        !             2:  *                                                          *
        !             3:  *               Linux EATA SCSI PIO driver                 *
        !             4:  *                                                          *
        !             5:  *  based on the CAM document CAM/89-004 rev. 2.0c,         *
        !             6:  *  DPT's driver kit, some internal documents and source,   *
        !             7:  *  and several other Linux scsi drivers and kernel docs.   *
        !             8:  *                                                          *
        !             9:  *  The driver currently:                                   *
        !            10:  *      -supports all EATA-PIO boards                       *
        !            11:  *      -only supports DASD devices                         *
        !            12:  *                                                          *
        !            13:  *  (c)1993-96 Michael Neuffer, Alfred Arnold               *
        !            14:  *             [email protected]               *
        !            15:  *             [email protected]                      * 
        !            16:  *                                                          *
        !            17:  *  This program is free software; you can redistribute it  *
        !            18:  *  and/or modify it under the terms of the GNU General     *
        !            19:  *  Public License as published by the Free Software        *
        !            20:  *  Foundation; either version 2 of the License, or         *
        !            21:  *  (at your option) any later version.                     *
        !            22:  *                                                          *
        !            23:  *  This program is distributed in the hope that it will be *
        !            24:  *  useful, but WITHOUT ANY WARRANTY; without even the      *
        !            25:  *  implied warranty of MERCHANTABILITY or FITNESS FOR A    *
        !            26:  *  PARTICULAR PURPOSE.  See the GNU General Public License *
        !            27:  *  for more details.                                       *
        !            28:  *                                                          *
        !            29:  *  You should have received a copy of the GNU General      *
        !            30:  *  Public License along with this kernel; if not, write to *
        !            31:  *  the Free Software Foundation, Inc., 675 Mass Ave,       *
        !            32:  *  Cambridge, MA 02139, USA.                               *
        !            33:  *                                                          *
        !            34:  ************************************************************
        !            35:  *  last change: 96/07/16                  OS: Linux 2.0.8  *
        !            36:  ************************************************************/
        !            37: 
        !            38: /* Look in eata_pio.h for configuration information */
        !            39: 
        !            40: #include <linux/module.h>
        !            41:  
        !            42: #include <linux/kernel.h>
        !            43: #include <linux/sched.h>
        !            44: #include <linux/string.h>
        !            45: #include <linux/ioport.h>
        !            46: #include <linux/malloc.h>
        !            47: #include <linux/in.h>
        !            48: #include <linux/bios32.h>
        !            49: #include <linux/pci.h>
        !            50: #include <linux/proc_fs.h>
        !            51: #include <asm/io.h>
        !            52: #include "eata_pio.h"
        !            53: #include "eata_dma_proc.h"
        !            54: #include "scsi.h"
        !            55: #include "sd.h"
        !            56: 
        !            57: #include <linux/stat.h>
        !            58: #include <linux/config.h>      /* for CONFIG_PCI */
        !            59: 
        !            60: struct proc_dir_entry proc_scsi_eata_pio = {
        !            61:     PROC_SCSI_EATA_PIO, 9, "eata_pio",
        !            62:     S_IFDIR | S_IRUGO | S_IXUGO, 2
        !            63: };
        !            64: 
        !            65: static uint ISAbases[MAXISA] =
        !            66: {0x1F0, 0x170, 0x330, 0x230};
        !            67: static uint ISAirqs[MAXISA] =
        !            68: {14,12,15,11};
        !            69: static unchar EISAbases[] =
        !            70: {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};
        !            71: static uint registered_HBAs = 0;
        !            72: static struct Scsi_Host *last_HBA = NULL;
        !            73: static struct Scsi_Host *first_HBA = NULL;
        !            74: static unchar reg_IRQ[] =
        !            75: {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
        !            76: static unchar reg_IRQL[] =
        !            77: {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
        !            78: 
        !            79: static ulong int_counter = 0;
        !            80: static ulong queue_counter = 0;
        !            81: 
        !            82: #include "eata_pio_proc.c"
        !            83:  
        !            84: #ifdef MODULE
        !            85: int eata_pio_release(struct Scsi_Host *sh)
        !            86: {
        !            87:     if (sh->irq && reg_IRQ[sh->irq] == 1) free_irq(sh->irq, NULL);
        !            88:     else reg_IRQ[sh->irq]--;
        !            89:     if (SD(sh)->channel == 0) {
        !            90:        if (sh->io_port && sh->n_io_port)
        !            91:            release_region(sh->io_port, sh->n_io_port);
        !            92:     }
        !            93:     return(TRUE);
        !            94: }
        !            95: #endif
        !            96: 
        !            97: void IncStat(Scsi_Pointer *SCp, uint Increment)
        !            98: {
        !            99:     SCp->ptr+=Increment; 
        !           100:     if ((SCp->this_residual-=Increment)==0)
        !           101:     {
        !           102:        if ((--SCp->buffers_residual)==0) SCp->Status=FALSE;
        !           103:        else
        !           104:        {
        !           105:            SCp->buffer++;
        !           106:            SCp->ptr=SCp->buffer->address;
        !           107:            SCp->this_residual=SCp->buffer->length;
        !           108:        }
        !           109:     }
        !           110: }
        !           111: 
        !           112: void eata_pio_int_handler(int irq, void *dev_id, struct pt_regs * regs)
        !           113: {
        !           114:     uint eata_stat = 0xfffff;
        !           115:     Scsi_Cmnd *cmd;
        !           116:     hostdata *hd;
        !           117:     struct eata_ccb *cp;
        !           118:     uint base;
        !           119:     ulong flags;
        !           120:     uint x,z;
        !           121:     struct Scsi_Host *sh;
        !           122:     ushort zwickel=0;
        !           123:     unchar stat,odd;
        !           124:     
        !           125:     save_flags(flags);
        !           126:     cli();
        !           127:     
        !           128:     for (x = 1, sh = first_HBA; x <= registered_HBAs; x++, sh = SD(sh)->prev) {
        !           129:        if (sh->irq != irq)
        !           130:            continue;
        !           131:        if (inb((uint)sh->base + HA_RSTATUS) & HA_SBUSY)
        !           132:            continue;
        !           133:        
        !           134:        int_counter++;
        !           135:        
        !           136:        hd=SD(sh);
        !           137:        
        !           138:        cp = &hd->ccb[0];
        !           139:        cmd = cp->cmd;
        !           140:        base = (uint) cmd->host->base;
        !           141:        
        !           142:        do
        !           143:        {
        !           144:            stat=inb(base+HA_RSTATUS);
        !           145:            if (stat&HA_SDRQ)
        !           146:                if (cp->DataIn)
        !           147:                {
        !           148:                    z=256; odd=FALSE;
        !           149:                    while ((cmd->SCp.Status)&&((z>0)||(odd)))
        !           150:                    {
        !           151:                        if (odd) 
        !           152:                        { 
        !           153:                            *(cmd->SCp.ptr)=zwickel>>8; 
        !           154:                            IncStat(&cmd->SCp,1);
        !           155:                            odd=FALSE;
        !           156:                        }
        !           157:                        x=min(z,cmd->SCp.this_residual/2);
        !           158:                        insw(base+HA_RDATA,cmd->SCp.ptr,x);
        !           159:                        z-=x; 
        !           160:                        IncStat(&cmd->SCp,2*x);
        !           161:                        if ((z>0)&&(cmd->SCp.this_residual==1))
        !           162:                        {
        !           163:                            zwickel=inw(base+HA_RDATA); 
        !           164:                            *(cmd->SCp.ptr)=zwickel&0xff;
        !           165:                            IncStat(&cmd->SCp,1); z--; 
        !           166:                            odd=TRUE;
        !           167:                        }
        !           168:                    }
        !           169:                    while (z>0) {
        !           170:                        zwickel=inw(base+HA_RDATA); 
        !           171:                        z--;
        !           172:                    } 
        !           173:                }
        !           174:                else /* cp->DataOut */
        !           175:                {
        !           176:                    odd=FALSE; z=256;
        !           177:                    while ((cmd->SCp.Status)&&((z>0)||(odd)))
        !           178:                    {
        !           179:                        if (odd)
        !           180:                        {
        !           181:                            zwickel+=*(cmd->SCp.ptr)<<8; 
        !           182:                            IncStat(&cmd->SCp,1);
        !           183:                            outw(zwickel,base+HA_RDATA); 
        !           184:                            z--; 
        !           185:                            odd=FALSE; 
        !           186:                        }
        !           187:                        x=min(z,cmd->SCp.this_residual/2);
        !           188:                        outsw(base+HA_RDATA,cmd->SCp.ptr,x);
        !           189:                        z-=x; 
        !           190:                        IncStat(&cmd->SCp,2*x);
        !           191:                        if ((z>0)&&(cmd->SCp.this_residual==1))
        !           192:                        {
        !           193:                            zwickel=*(cmd->SCp.ptr); 
        !           194:                            zwickel&=0xff;
        !           195:                            IncStat(&cmd->SCp,1); 
        !           196:                            odd=TRUE;
        !           197:                        }  
        !           198:                    }
        !           199:                    while (z>0||odd) {
        !           200:                        outw(zwickel,base+HA_RDATA); 
        !           201:                        z--; 
        !           202:                        odd=FALSE;
        !           203:                    }
        !           204:                }
        !           205:        }
        !           206:        while ((stat&HA_SDRQ)||((stat&HA_SMORE)&&hd->moresupport));
        !           207:        
        !           208:        /* terminate handler if HBA goes busy again, i.e. transfers
        !           209:         * more data */
        !           210:        
        !           211:        if (stat&HA_SBUSY) break;
        !           212:        
        !           213:        /* OK, this is quite stupid, but I haven't found any correct
        !           214:         * way to get HBA&SCSI status so far */
        !           215:        
        !           216:        if (!(inb(base+HA_RSTATUS)&HA_SERROR))
        !           217:        {
        !           218:            cmd->result=(DID_OK<<16); 
        !           219:            hd->devflags|=(1<<cp->cp_id);
        !           220:        }
        !           221:        else if (hd->devflags&1<<cp->cp_id) 
        !           222:            cmd->result=(DID_OK<<16)+0x02;
        !           223:        else cmd->result=(DID_NO_CONNECT<<16);
        !           224:        
        !           225:        if (cp->status == LOCKED) {
        !           226:            cp->status = FREE;
        !           227:            eata_stat = inb(base + HA_RSTATUS);
        !           228:            printk(KERN_NOTICE "eata_pio: int_handler, freeing locked "
        !           229:                    "queueslot\n");
        !           230:            DBG(DBG_INTR&&DBG_DELAY,DELAY(1));
        !           231:            restore_flags(flags);
        !           232:            return;
        !           233:        }
        !           234:        
        !           235: #if DBG_INTR2
        !           236:        if (stat != 0x50) 
        !           237:            printk(KERN_DEBUG "stat: %#.2x, result: %#.8x\n", stat, 
        !           238:                    cmd->result); 
        !           239:        DBG(DBG_INTR&&DBG_DELAY,DELAY(1));
        !           240: #endif
        !           241:        
        !           242:        cp->status = FREE;   /* now we can release the slot  */
        !           243:        
        !           244:        restore_flags(flags);
        !           245:        cmd->scsi_done(cmd);
        !           246:        save_flags(flags);
        !           247:        cli();
        !           248:     }
        !           249:     restore_flags(flags);
        !           250:     
        !           251:     return;
        !           252: }
        !           253: 
        !           254: inline uint eata_pio_send_command(uint base, unchar command)
        !           255: {
        !           256:     uint loop = HZ/2;
        !           257:     
        !           258:     while (inb(base + HA_RSTATUS) & HA_SBUSY)
        !           259:        if (--loop == 0)
        !           260:            return(TRUE);
        !           261: 
        !           262:     /* Enable interrupts for HBA.  It is not the best way to do it at this
        !           263:      * place, but I hope that it doesn't interfere with the IDE driver 
        !           264:      * initialization this way */
        !           265: 
        !           266:     outb(HA_CTRL_8HEADS,base+HA_CTRLREG);
        !           267:     
        !           268:     outb(command, base + HA_WCOMMAND);
        !           269:     return(FALSE);
        !           270: }
        !           271: 
        !           272: int eata_pio_queue(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *))
        !           273: {
        !           274:     uint x, y;
        !           275:     long flags;
        !           276:     uint base;
        !           277:     
        !           278:     hostdata *hd;
        !           279:     struct Scsi_Host *sh;
        !           280:     struct eata_ccb *cp;
        !           281:     
        !           282:     save_flags(flags);
        !           283:     cli();
        !           284:     
        !           285:     queue_counter++;
        !           286:     
        !           287:     hd = HD(cmd);
        !           288:     sh = cmd->host;
        !           289:     base = (uint) sh->base;
        !           290:     
        !           291:     /* use only slot 0, as 2001 can handle only one cmd at a time */
        !           292:     
        !           293:     y = x = 0;
        !           294:     
        !           295:     if (hd->ccb[y].status!=FREE) { 
        !           296:        
        !           297:        DBG(DBG_QUEUE, printk(KERN_EMERG "can_queue %d, x %d, y %d\n",
        !           298:                               sh->can_queue,x,y));
        !           299: #if DEBUG_EATA
        !           300:        panic(KERN_EMERG "eata_pio: run out of queue slots cmdno:%ld "
        !           301:               "intrno: %ld\n", queue_counter, int_counter);
        !           302: #else
        !           303:        panic(KERN_EMERG "eata_pio: run out of queue slots....\n");
        !           304: #endif
        !           305:     }
        !           306:     
        !           307:     cp = &hd->ccb[y];
        !           308:     
        !           309:     memset(cp, 0, sizeof(struct eata_ccb));
        !           310:     memset(cmd->sense_buffer, 0, sizeof(cmd->sense_buffer));
        !           311:        
        !           312:     cp->status = USED;      /* claim free slot */
        !           313: 
        !           314:     DBG(DBG_QUEUE, printk(KERN_DEBUG "eata_pio_queue pid %ld, target: %x, lun:"
        !           315:                           " %x, y %d\n", cmd->pid, cmd->target, cmd->lun, y));
        !           316:     DBG(DBG_QUEUE && DBG_DELAY, DELAY(1));
        !           317:     
        !           318:     cmd->scsi_done = (void *)done;
        !           319:     
        !           320:     switch (cmd->cmnd[0]) {
        !           321:     case CHANGE_DEFINITION: case COMPARE:         case COPY:
        !           322:     case COPY_VERIFY:       case LOG_SELECT:      case MODE_SELECT:
        !           323:     case MODE_SELECT_10:    case SEND_DIAGNOSTIC: case WRITE_BUFFER:
        !           324:     case FORMAT_UNIT:       case REASSIGN_BLOCKS: case RESERVE:
        !           325:     case SEARCH_EQUAL:      case SEARCH_HIGH:     case SEARCH_LOW:
        !           326:     case WRITE_6:           case WRITE_10:        case WRITE_VERIFY:
        !           327:     case UPDATE_BLOCK:      case WRITE_LONG:      case WRITE_SAME:      
        !           328:     case SEARCH_HIGH_12:    case SEARCH_EQUAL_12: case SEARCH_LOW_12:
        !           329:     case WRITE_12:          case WRITE_VERIFY_12: case SET_WINDOW: 
        !           330:     case MEDIUM_SCAN:       case SEND_VOLUME_TAG:            
        !           331:     case 0xea:      /* alternate number for WRITE LONG */
        !           332:        cp->DataOut = TRUE; /* Output mode */
        !           333:        break;
        !           334:     case TEST_UNIT_READY:
        !           335:     default:
        !           336:        cp->DataIn = TRUE;  /* Input mode  */
        !           337:     }
        !           338:     
        !           339:     cp->Interpret = (cmd->target == hd->hostid);
        !           340:     cp->cp_datalen = htonl((ulong)cmd->request_bufflen);
        !           341:     cp->Auto_Req_Sen = FALSE;
        !           342:     cp->cp_reqDMA = htonl(0);
        !           343:     cp->reqlen = 0;
        !           344:     
        !           345:     cp->cp_id = cmd->target;
        !           346:     cp->cp_lun = cmd->lun;
        !           347:     cp->cp_dispri = FALSE;
        !           348:     cp->cp_identify = TRUE;
        !           349:     memcpy(cp->cp_cdb, cmd->cmnd, COMMAND_SIZE(*cmd->cmnd));
        !           350:     
        !           351:     cp->cp_statDMA = htonl(0);
        !           352:     
        !           353:     cp->cp_viraddr = cp;
        !           354:     cp->cmd = cmd;
        !           355:     cmd->host_scribble = (char *)&hd->ccb[y];   
        !           356:     
        !           357:     if (cmd->use_sg == 0)
        !           358:     { 
        !           359:        cmd->SCp.buffers_residual=1;
        !           360:        cmd->SCp.ptr = cmd->request_buffer;
        !           361:        cmd->SCp.this_residual = cmd->request_bufflen;
        !           362:        cmd->SCp.buffer = NULL;
        !           363:     } else {
        !           364:        cmd->SCp.buffer = cmd->request_buffer;
        !           365:        cmd->SCp.buffers_residual = cmd->use_sg;
        !           366:        cmd->SCp.ptr = cmd->SCp.buffer->address;
        !           367:        cmd->SCp.this_residual = cmd->SCp.buffer->length;
        !           368:     }
        !           369:     cmd->SCp.Status = (cmd->SCp.this_residual != 0);  /* TRUE as long as bytes 
        !           370:                                                        * are to transfer */ 
        !           371:     
        !           372:     if (eata_pio_send_command(base, EATA_CMD_PIO_SEND_CP)) 
        !           373:     {
        !           374:        cmd->result = DID_BUS_BUSY << 16;
        !           375:        printk(KERN_NOTICE "eata_pio_queue target %d, pid %ld, HBA busy, "
        !           376:                "returning DID_BUS_BUSY, done.\n", cmd->target, cmd->pid);
        !           377:         done(cmd);
        !           378:         cp->status = FREE;      
        !           379:         restore_flags(flags);
        !           380:        return (0);
        !           381:     }
        !           382:     while (!(inb(base + HA_RSTATUS) & HA_SDRQ));
        !           383:     outsw(base + HA_RDATA, cp, hd->cplen);
        !           384:     outb(EATA_CMD_PIO_TRUNC, base + HA_WCOMMAND);
        !           385:     for (x = 0; x < hd->cppadlen; x++) outw(0, base + HA_RDATA);
        !           386:     
        !           387:     DBG(DBG_QUEUE,printk(KERN_DEBUG "Queued base %#.4lx pid: %ld target: %x "
        !           388:                          "lun: %x slot %d irq %d\n", (long)sh->base, cmd->pid, 
        !           389:                         cmd->target, cmd->lun, y, sh->irq));
        !           390:     DBG(DBG_QUEUE && DBG_DELAY, DELAY(1));
        !           391:     
        !           392:     restore_flags(flags);
        !           393:     return (0);
        !           394: }
        !           395: 
        !           396: int eata_pio_abort(Scsi_Cmnd * cmd)
        !           397: {
        !           398:     ulong flags;
        !           399:     uint loop = HZ;
        !           400:     
        !           401:     save_flags(flags);
        !           402:     cli();
        !           403:     
        !           404:     DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_abort called pid: %ld "
        !           405:                            "target: %x lun: %x reason %x\n", cmd->pid, 
        !           406:                            cmd->target, cmd->lun, cmd->abort_reason));
        !           407:     DBG(DBG_ABNORM && DBG_DELAY, DELAY(1));
        !           408:     
        !           409:     
        !           410:     while (inb((uint)(cmd->host->base) + HA_RAUXSTAT) & HA_ABUSY)
        !           411:        if (--loop == 0) {
        !           412:            printk(KERN_WARNING "eata_pio: abort, timeout error.\n");
        !           413:            restore_flags(flags);
        !           414:            DBG(DBG_ABNORM && DBG_DELAY, DELAY(1));
        !           415:            return (SCSI_ABORT_ERROR);
        !           416:        }
        !           417:     if (CD(cmd)->status == FREE) {
        !           418:        DBG(DBG_ABNORM, printk(KERN_WARNING "Returning: SCSI_ABORT_NOT_RUNNING\n")); 
        !           419:        restore_flags(flags);
        !           420:        return (SCSI_ABORT_NOT_RUNNING);
        !           421:     }
        !           422:     if (CD(cmd)->status == USED) {
        !           423:        DBG(DBG_ABNORM, printk(KERN_WARNING "Returning: SCSI_ABORT_BUSY\n"));
        !           424:        restore_flags(flags);
        !           425:        return (SCSI_ABORT_BUSY);  /* SNOOZE */ 
        !           426:     }
        !           427:     if (CD(cmd)->status == RESET) {
        !           428:        restore_flags(flags);
        !           429:        printk(KERN_WARNING "eata_pio: abort, command reset error.\n");
        !           430:        DBG(DBG_ABNORM && DBG_DELAY, DELAY(1));
        !           431:        return (SCSI_ABORT_ERROR);
        !           432:     }
        !           433:     if (CD(cmd)->status == LOCKED) {
        !           434:        restore_flags(flags);
        !           435:        DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio: abort, queue slot "
        !           436:                                "locked.\n"));
        !           437:        DBG(DBG_ABNORM && DBG_DELAY, DELAY(1));
        !           438:        return (SCSI_ABORT_NOT_RUNNING);
        !           439:     }
        !           440:     restore_flags(flags);
        !           441:     panic("eata_pio: abort: invalid slot status\n");
        !           442: }
        !           443: 
        !           444: int eata_pio_reset(Scsi_Cmnd * cmd, unsigned int dummy)
        !           445: {
        !           446:     uint x, time, limit = 0;
        !           447:     ulong flags;
        !           448:     unchar success = FALSE;
        !           449:     Scsi_Cmnd *sp; 
        !           450:     
        !           451:     save_flags(flags);
        !           452:     cli();
        !           453:     DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset called pid:%ld target:"
        !           454:                            " %x lun: %x reason %x\n", cmd->pid, cmd->target, 
        !           455:                            cmd->lun, cmd->abort_reason));
        !           456: 
        !           457:     if (HD(cmd)->state == RESET) {
        !           458:        printk(KERN_WARNING "eata_pio_reset: exit, already in reset.\n");
        !           459:        restore_flags(flags);
        !           460:        DBG(DBG_ABNORM && DBG_DELAY, DELAY(1));
        !           461:        return (SCSI_RESET_ERROR);
        !           462:     }
        !           463:     
        !           464:     /* force all slots to be free */
        !           465:     
        !           466:     for (x = 0; x < cmd->host->can_queue; x++) {
        !           467:        
        !           468:        if (HD(cmd)->ccb[x].status == FREE) 
        !           469:            continue;
        !           470:        
        !           471:        sp = HD(cmd)->ccb[x].cmd;
        !           472:        HD(cmd)->ccb[x].status = RESET;
        !           473:        printk(KERN_WARNING "eata_pio_reset: slot %d in reset, pid %ld.\n", x,
        !           474:                sp->pid);
        !           475:        DBG(DBG_ABNORM && DBG_DELAY, DELAY(1));
        !           476:        
        !           477:        if (sp == NULL)
        !           478:            panic("eata_pio_reset: slot %d, sp==NULL.\n", x);
        !           479:        DBG(DBG_ABNORM && DBG_DELAY, DELAY(1));
        !           480:     }
        !           481:     
        !           482:     /* hard reset the HBA  */
        !           483:     outb(EATA_CMD_RESET, (uint) cmd->host->base+HA_WCOMMAND);
        !           484:     
        !           485:     DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset: board reset done.\n"));
        !           486:     HD(cmd)->state = RESET;
        !           487:     
        !           488:     time = jiffies;
        !           489:     while (jiffies < (time + (3 * HZ)) && limit++ < 10000000);
        !           490:     
        !           491:     DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset: interrupts disabled, "
        !           492:                            "loops %d.\n", limit));
        !           493:     DBG(DBG_ABNORM && DBG_DELAY, DELAY(1));
        !           494:     
        !           495:     for (x = 0; x < cmd->host->can_queue; x++) {
        !           496:        
        !           497:        /* Skip slots already set free by interrupt */
        !           498:        if (HD(cmd)->ccb[x].status != RESET)
        !           499:            continue;
        !           500:        
        !           501:        sp = HD(cmd)->ccb[x].cmd;
        !           502:        sp->result = DID_RESET << 16;
        !           503:        
        !           504:        /* This mailbox is terminated */
        !           505:        printk(KERN_WARNING "eata_pio_reset: reset ccb %d.\n",x);
        !           506:        HD(cmd)->ccb[x].status = FREE;
        !           507:        
        !           508:        restore_flags(flags);
        !           509:        sp->scsi_done(sp);
        !           510:        cli();
        !           511:     }
        !           512:     
        !           513:     HD(cmd)->state = FALSE;
        !           514:     restore_flags(flags);
        !           515:     
        !           516:     if (success) { /* hmmm... */
        !           517:        DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset: exit, success.\n"));
        !           518:        DBG(DBG_ABNORM && DBG_DELAY, DELAY(1));
        !           519:        return (SCSI_RESET_SUCCESS);
        !           520:     } else {
        !           521:        DBG(DBG_ABNORM, printk(KERN_WARNING "eata_pio_reset: exit, wakeup.\n"));
        !           522:        DBG(DBG_ABNORM && DBG_DELAY, DELAY(1));
        !           523:        return (SCSI_RESET_PUNT);
        !           524:     }
        !           525: }
        !           526: 
        !           527: char * get_pio_board_data(ulong base, uint irq, uint id, ulong cplen, ushort cppadlen)
        !           528: {
        !           529:     struct eata_ccb cp;
        !           530:     static char buff[256];
        !           531:     int z;
        !           532:     
        !           533:     memset(&cp, 0, sizeof(struct eata_ccb));
        !           534:     memset(buff, 0, sizeof(buff));
        !           535:     
        !           536:     cp.DataIn = TRUE;     
        !           537:     cp.Interpret = TRUE;   /* Interpret command */
        !           538:     
        !           539:     cp.cp_datalen = htonl(254);  
        !           540:     cp.cp_dataDMA = htonl(0);
        !           541:     
        !           542:     cp.cp_id = id;
        !           543:     cp.cp_lun = 0;
        !           544:     
        !           545:     cp.cp_cdb[0] = INQUIRY;
        !           546:     cp.cp_cdb[1] = 0;
        !           547:     cp.cp_cdb[2] = 0;
        !           548:     cp.cp_cdb[3] = 0;
        !           549:     cp.cp_cdb[4] = 254;
        !           550:     cp.cp_cdb[5] = 0;
        !           551:     
        !           552:     if (eata_pio_send_command((uint) base, EATA_CMD_PIO_SEND_CP)) 
        !           553:         return (NULL);
        !           554:     while (!(inb(base + HA_RSTATUS) & HA_SDRQ));
        !           555:     outsw(base + HA_RDATA, &cp, cplen);
        !           556:     outb(EATA_CMD_PIO_TRUNC, base + HA_WCOMMAND);
        !           557:     for (z = 0; z < cppadlen; z++) outw(0, base + HA_RDATA);
        !           558:     
        !           559:     while (inb(base + HA_RSTATUS) & HA_SBUSY);
        !           560:     if (inb(base + HA_RSTATUS) & HA_SERROR)
        !           561:        return (NULL);
        !           562:     else if (!(inb(base + HA_RSTATUS) & HA_SDRQ))
        !           563:        return (NULL);
        !           564:     else
        !           565:     {
        !           566:        insw(base+HA_RDATA, &buff, 127);
        !           567:        while (inb(base + HA_RSTATUS)&HA_SDRQ) inw(base + HA_RDATA);
        !           568:        return (buff);
        !           569:     }
        !           570: }
        !           571: 
        !           572: int get_pio_conf_PIO(u32 base, struct get_conf *buf)
        !           573: {
        !           574:     ulong loop = HZ/2;
        !           575:     int z;
        !           576:     ushort *p;
        !           577:     
        !           578:     if(check_region(base, 9))  
        !           579:        return (FALSE);
        !           580:     
        !           581:     memset(buf, 0, sizeof(struct get_conf));
        !           582:     
        !           583:     while (inb(base + HA_RSTATUS) & HA_SBUSY)
        !           584:        if (--loop == 0) 
        !           585:            return (FALSE);
        !           586:     
        !           587:     DBG(DBG_PIO && DBG_PROBE,
        !           588:        printk(KERN_DEBUG "Issuing PIO READ CONFIG to HBA at %#x\n", base));
        !           589:     eata_pio_send_command(base, EATA_CMD_PIO_READ_CONFIG);
        !           590: 
        !           591:     loop = HZ/2;
        !           592:     for (p = (ushort *) buf; 
        !           593:         (long)p <= ((long)buf + (sizeof(struct get_conf) / 2)); p++) {
        !           594:        while (!(inb(base + HA_RSTATUS) & HA_SDRQ))
        !           595:            if (--loop == 0)
        !           596:                return (FALSE);
        !           597: 
        !           598:        loop = HZ/2;
        !           599:        *p = inw(base + HA_RDATA);
        !           600:     }
        !           601:     if (!(inb(base + HA_RSTATUS) & HA_SERROR)) {            /* Error ? */
        !           602:        if (htonl(EATA_SIGNATURE) == buf->signature) {
        !           603:            DBG(DBG_PIO&&DBG_PROBE, printk(KERN_NOTICE "EATA Controller found "
        !           604:                                            "at %#4x EATA Level: %x\n", base, 
        !           605:                                           (uint) (buf->version)));
        !           606:            
        !           607:            while (inb(base + HA_RSTATUS) & HA_SDRQ) 
        !           608:                inw(base + HA_RDATA);
        !           609:            if(ALLOW_DMA_BOARDS == FALSE) {
        !           610:                for (z = 0; z < MAXISA; z++)
        !           611:                    if (base == ISAbases[z]) {
        !           612:                        buf->IRQ = ISAirqs[z]; 
        !           613:                        break;
        !           614:                    }
        !           615:            }
        !           616:            return (TRUE);
        !           617:        } 
        !           618:     } else {
        !           619:        DBG(DBG_PROBE, printk("eata_dma: get_conf_PIO, error during transfer "
        !           620:                              "for HBA at %x\n", base));
        !           621:     }
        !           622:     return (FALSE);
        !           623: }
        !           624: 
        !           625: void print_pio_config(struct get_conf *gc)
        !           626: {
        !           627:     printk("Please check values: (read config data)\n");
        !           628:     printk("LEN: %d ver:%d OCS:%d TAR:%d TRNXFR:%d MORES:%d\n",
        !           629:           (uint) ntohl(gc->len), gc->version,
        !           630:           gc->OCS_enabled, gc->TAR_support, gc->TRNXFR, gc->MORE_support);
        !           631:     printk("HAAV:%d SCSIID0:%d ID1:%d ID2:%d QUEUE:%d SG:%d SEC:%d\n",
        !           632:           gc->HAA_valid, gc->scsi_id[3], gc->scsi_id[2],
        !           633:           gc->scsi_id[1], ntohs(gc->queuesiz), ntohs(gc->SGsiz), gc->SECOND);
        !           634:     printk("IRQ:%d IRQT:%d FORCADR:%d MCH:%d RIDQ:%d\n",
        !           635:           gc->IRQ, gc->IRQ_TR, gc->FORCADR, 
        !           636:           gc->MAX_CHAN, gc->ID_qest);
        !           637:     DBG(DPT_DEBUG, DELAY(14));
        !           638: }
        !           639: 
        !           640: static uint print_selftest(uint base)
        !           641: {
        !           642:     unchar buffer[512];
        !           643: #ifdef VERBOSE_SETUP
        !           644:     int z;
        !           645: #endif
        !           646:     
        !           647:     printk("eata_pio: executing controller self test & setup...\n");
        !           648:     while (inb(base + HA_RSTATUS) & HA_SBUSY);
        !           649:     outb(EATA_CMD_PIO_SETUPTEST, base + HA_WCOMMAND);
        !           650:     do {
        !           651:        while (inb(base + HA_RSTATUS) & HA_SBUSY)
        !           652:            /* nothing */ ;
        !           653:        if (inb(base + HA_RSTATUS) & HA_SDRQ)
        !           654:        {
        !           655:            insw(base + HA_RDATA, &buffer, 256);
        !           656: #ifdef VERBOSE_SETUP
        !           657:            /* no beeps please... */
        !           658:            for (z = 0; z < 511 && buffer[z]; z++)
        !           659:                if (buffer[z] != 7) printk("%c", buffer[z]);
        !           660: #endif
        !           661:        }
        !           662:     } while (inb(base+HA_RSTATUS) & (HA_SBUSY|HA_SDRQ));
        !           663:     
        !           664:     return (!(inb(base+HA_RSTATUS) & HA_SERROR)); 
        !           665: }
        !           666: 
        !           667: int register_pio_HBA(long base, struct get_conf *gc, Scsi_Host_Template * tpnt)
        !           668: {
        !           669:     ulong size = 0;
        !           670:     char *buff;
        !           671:     ulong cplen;
        !           672:     ushort cppadlen;
        !           673:     struct Scsi_Host *sh;
        !           674:     hostdata *hd;
        !           675:     
        !           676:     DBG(DBG_REGISTER, print_pio_config(gc));
        !           677:     
        !           678:     if (gc->DMA_support == TRUE) {
        !           679:        printk("HBA at %#.4lx supports DMA. Please use EATA-DMA driver.\n",base);
        !           680:        if(ALLOW_DMA_BOARDS == FALSE)
        !           681:            return (FALSE);
        !           682:     }
        !           683:     
        !           684:     if ((buff = get_pio_board_data((uint)base, gc->IRQ, gc->scsi_id[3], 
        !           685:                               cplen   =(htonl(gc->cplen   )+1)/2, 
        !           686:                               cppadlen=(htons(gc->cppadlen)+1)/2)) == NULL)
        !           687:     {
        !           688:        printk("HBA at %#lx didn't react on INQUIRY. Sorry.\n", (ulong) base);
        !           689:        return (FALSE);
        !           690:     }
        !           691:     
        !           692:     if (print_selftest(base) == FALSE && ALLOW_DMA_BOARDS == FALSE)
        !           693:     {
        !           694:        printk("HBA at %#lx failed while performing self test & setup.\n", 
        !           695:               (ulong) base);
        !           696:        return (FALSE);
        !           697:     }
        !           698:     
        !           699:     if (!reg_IRQ[gc->IRQ]) {    /* Interrupt already registered ? */
        !           700:        if (!request_irq(gc->IRQ, eata_pio_int_handler, SA_INTERRUPT, 
        !           701:                         "EATA-PIO", NULL)){
        !           702:            reg_IRQ[gc->IRQ]++;
        !           703:            if (!gc->IRQ_TR)
        !           704:                reg_IRQL[gc->IRQ] = TRUE;   /* IRQ is edge triggered */
        !           705:        } else {
        !           706:            printk("Couldn't allocate IRQ %d, Sorry.\n", gc->IRQ);
        !           707:            return (FALSE);
        !           708:        }
        !           709:     } else {            /* More than one HBA on this IRQ */
        !           710:        if (reg_IRQL[gc->IRQ] == TRUE) {
        !           711:            printk("Can't support more than one HBA on this IRQ,\n"
        !           712:                   "  if the IRQ is edge triggered. Sorry.\n");
        !           713:            return (FALSE);
        !           714:        } else
        !           715:            reg_IRQ[gc->IRQ]++;
        !           716:     }
        !           717:     
        !           718:     request_region(base, 8, "eata_pio");
        !           719:     
        !           720:     size = sizeof(hostdata) + (sizeof(struct eata_ccb) * ntohs(gc->queuesiz));
        !           721:     
        !           722:     sh = scsi_register(tpnt, size);
        !           723:     hd = SD(sh);                   
        !           724:     
        !           725:     memset(hd->ccb, 0, (sizeof(struct eata_ccb) * ntohs(gc->queuesiz)));
        !           726:     memset(hd->reads, 0, sizeof(ulong) * 26); 
        !           727:     
        !           728:     strncpy(SD(sh)->vendor, &buff[8], 8);
        !           729:     SD(sh)->vendor[8] = 0;
        !           730:     strncpy(SD(sh)->name, &buff[16], 17);
        !           731:     SD(sh)->name[17] = 0;
        !           732:     SD(sh)->revision[0] = buff[32];
        !           733:     SD(sh)->revision[1] = buff[33];
        !           734:     SD(sh)->revision[2] = buff[34];
        !           735:     SD(sh)->revision[3] = '.';
        !           736:     SD(sh)->revision[4] = buff[35];
        !           737:     SD(sh)->revision[5] = 0;
        !           738: 
        !           739:     switch (ntohl(gc->len)) {
        !           740:     case 0x1c:
        !           741:        SD(sh)->EATA_revision = 'a';
        !           742:        break;
        !           743:     case 0x1e:
        !           744:        SD(sh)->EATA_revision = 'b';
        !           745:        break;
        !           746:     case 0x22:
        !           747:        SD(sh)->EATA_revision = 'c';
        !           748:        break;
        !           749:     case 0x24:
        !           750:        SD(sh)->EATA_revision = 'z';            
        !           751:     default:
        !           752:        SD(sh)->EATA_revision = '?';
        !           753:     }
        !           754: 
        !           755:     if(ntohl(gc->len) >= 0x22) {
        !           756:        if (gc->is_PCI == TRUE)
        !           757:            hd->bustype = IS_PCI;
        !           758:        else if (gc->is_EISA == TRUE)
        !           759:            hd->bustype = IS_EISA;
        !           760:        else
        !           761:            hd->bustype = IS_ISA;
        !           762:     } else {
        !           763:        if (buff[21] == '4')
        !           764:            hd->bustype = IS_PCI;
        !           765:        else if (buff[21] == '2')
        !           766:            hd->bustype = IS_EISA;
        !           767:        else
        !           768:            hd->bustype = IS_ISA;
        !           769:     }
        !           770:   
        !           771:     SD(sh)->cplen=cplen;
        !           772:     SD(sh)->cppadlen=cppadlen;
        !           773:     SD(sh)->hostid=gc->scsi_id[3];
        !           774:     SD(sh)->devflags=1<<gc->scsi_id[3];
        !           775:     SD(sh)->moresupport=gc->MORE_support;
        !           776:     sh->unique_id = base;
        !           777:     sh->base = (char *) base;
        !           778:     sh->io_port = base;
        !           779:     sh->n_io_port = 8;
        !           780:     sh->irq = gc->IRQ;
        !           781:     sh->dma_channel = PIO;
        !           782:     sh->this_id = gc->scsi_id[3];
        !           783:     sh->can_queue = 1;
        !           784:     sh->cmd_per_lun = 1;
        !           785:     sh->sg_tablesize = SG_ALL;
        !           786:     
        !           787:     hd->channel = 0;
        !           788:     
        !           789:     sh->max_id = 8;
        !           790:     sh->max_lun = 8;
        !           791: 
        !           792:     if (gc->SECOND)
        !           793:        hd->primary = FALSE;
        !           794:     else
        !           795:        hd->primary = TRUE;
        !           796:     
        !           797:     sh->unchecked_isa_dma = FALSE; /* We can only do PIO */
        !           798:     
        !           799:     hd->next = NULL;    /* build a linked list of all HBAs */
        !           800:     hd->prev = last_HBA;
        !           801:     if(hd->prev != NULL)
        !           802:        SD(hd->prev)->next = sh;
        !           803:     last_HBA = sh;
        !           804:     if (first_HBA == NULL)
        !           805:        first_HBA = sh;
        !           806:     registered_HBAs++;
        !           807:     return (1);
        !           808: }
        !           809: 
        !           810: void find_pio_ISA(struct get_conf *buf, Scsi_Host_Template * tpnt)
        !           811: {
        !           812:     int i;
        !           813:     
        !           814:     for (i = 0; i < MAXISA; i++) {  
        !           815:        if (ISAbases[i]) {  
        !           816:            if (get_pio_conf_PIO(ISAbases[i], buf) == TRUE){
        !           817:                register_pio_HBA(ISAbases[i], buf, tpnt);
        !           818:            }
        !           819:            ISAbases[i] = 0;
        !           820:        }
        !           821:     }
        !           822:     return;
        !           823: }
        !           824: 
        !           825: void find_pio_EISA(struct get_conf *buf, Scsi_Host_Template * tpnt)
        !           826: {
        !           827:     u32 base;
        !           828:     int i;
        !           829: 
        !           830: #if CHECKPAL
        !           831:     u8 pal1, pal2, pal3;
        !           832: #endif
        !           833: 
        !           834:     for (i = 0; i < MAXEISA; i++) {
        !           835:        if (EISAbases[i] == TRUE) { /* Still a possibility ?          */
        !           836: 
        !           837:            base = 0x1c88 + (i * 0x1000);
        !           838: #if CHECKPAL
        !           839:            pal1 = inb((u16)base - 8);
        !           840:            pal2 = inb((u16)base - 7);
        !           841:            pal3 = inb((u16)base - 6);
        !           842: 
        !           843:            if (((pal1 == 0x12) && (pal2 == 0x14)) ||
        !           844:                ((pal1 == 0x38) && (pal2 == 0xa3) && (pal3 == 0x82)) ||
        !           845:                ((pal1 == 0x06) && (pal2 == 0x94) && (pal3 == 0x24))) {
        !           846:                DBG(DBG_PROBE, printk(KERN_NOTICE "EISA EATA id tags found: "
        !           847:                                       "%x %x %x \n",
        !           848:                                      (int)pal1, (int)pal2, (int)pal3));
        !           849: #endif
        !           850:                if (get_pio_conf_PIO(base, buf) == TRUE) {
        !           851:                    DBG(DBG_PROBE && DBG_EISA, print_pio_config(buf));
        !           852:                    if (buf->IRQ) {
        !           853:                        register_pio_HBA(base, buf, tpnt);
        !           854:                    } else
        !           855:                        printk(KERN_NOTICE "eata_dma: No valid IRQ. HBA "
        !           856:                                "removed from list\n");
        !           857:                }
        !           858:                /* Nothing found here so we take it from the list */
        !           859:                EISAbases[i] = 0;
        !           860: #if CHECKPAL
        !           861:            }
        !           862: #endif
        !           863:        }
        !           864:     }
        !           865:     return;
        !           866: }
        !           867: 
        !           868: void find_pio_PCI(struct get_conf *buf, Scsi_Host_Template * tpnt)
        !           869: {
        !           870: 
        !           871: #ifndef CONFIG_PCI
        !           872:     printk(KERN_ERR "eata_pio: kernel PCI support not enabled. Skipping scan "
        !           873:            "for PCI HBAs.\n");
        !           874: #else
        !           875:     
        !           876:     u8 pci_bus, pci_device_fn;
        !           877:     static s16 pci_index = 0;   /* Device index to PCI BIOS calls */
        !           878:     u32 base = 0;
        !           879:     u16 com_adr;
        !           880:     u16 rev_device;
        !           881:     u32 error, i, x;
        !           882: 
        !           883:     if (pcibios_present()) {
        !           884:        for (i = 0; i <= MAXPCI; ++i, ++pci_index) {
        !           885:            if (pcibios_find_device(PCI_VENDOR_ID_DPT, PCI_DEVICE_ID_DPT, 
        !           886:                                    pci_index, &pci_bus, &pci_device_fn))
        !           887:                break;
        !           888:            DBG(DBG_PROBE && DBG_PCI, 
        !           889:                printk("eata_pio: HBA at bus %d, device %d,"
        !           890:                       " function %d, index %d\n", (s32)pci_bus, 
        !           891:                       (s32)((pci_device_fn & 0xf8) >> 3),
        !           892:                       (s32)(pci_device_fn & 7), pci_index));
        !           893:            
        !           894:            if (!(error = pcibios_read_config_word(pci_bus, pci_device_fn, 
        !           895:                                       PCI_CLASS_DEVICE, &rev_device))) {
        !           896:                if (rev_device == PCI_CLASS_STORAGE_SCSI) {
        !           897:                    if (!(error = pcibios_read_config_word(pci_bus, 
        !           898:                                               pci_device_fn, PCI_COMMAND, 
        !           899:                                               (u16 *) & com_adr))) {
        !           900:                        if (!((com_adr & PCI_COMMAND_IO) && 
        !           901:                              (com_adr & PCI_COMMAND_MASTER))) {
        !           902:                            printk("HBA has IO or BUSMASTER mode disabled\n");
        !           903:                            continue;
        !           904:                        }
        !           905:                    } else
        !           906:                        printk("eata_pio: error %x while reading "
        !           907:                               "PCI_COMMAND\n", error);
        !           908:                } else
        !           909:                    printk("DEVICECLASSID %x didn't match\n", rev_device);
        !           910:            } else {
        !           911:                printk("eata_pio: error %x while reading PCI_CLASS_BASE\n", 
        !           912:                       error);
        !           913:                continue;
        !           914:            }
        !           915:            
        !           916:            if (!(error = pcibios_read_config_dword(pci_bus, pci_device_fn,
        !           917:                                       PCI_BASE_ADDRESS_0, (int *) &base))){
        !           918:                
        !           919:                /* Check if the address is valid */
        !           920:                if (base & 0x01) {
        !           921:                    base &= 0xfffffffe;
        !           922:                    /* EISA tag there ? */
        !           923:                    if ((inb(base) == 0x12) && (inb(base + 1) == 0x14))
        !           924:                        continue;   /* Jep, it's forced, so move on  */
        !           925:                    base += 0x10;   /* Now, THIS is the real address */
        !           926:                    if (base != 0x1f8) {
        !           927:                        /* We didn't find it in the primary search */
        !           928:                        if (get_pio_conf_PIO(base, buf) == TRUE) {
        !           929:                            if (buf->FORCADR)   /* If the address is forced */
        !           930:                                continue;       /* we'll find it later      */
        !           931:                            
        !           932:                            /* OK. We made it till here, so we can go now  
        !           933:                             * and register it. We  only have to check and 
        !           934:                             * eventually remove it from the EISA and ISA list 
        !           935:                             */
        !           936:                            
        !           937:                            register_pio_HBA(base, buf, tpnt);
        !           938:                            
        !           939:                            if (base < 0x1000) {
        !           940:                                for (x = 0; x < MAXISA; ++x) {
        !           941:                                    if (ISAbases[x] == base) {
        !           942:                                        ISAbases[x] = 0;
        !           943:                                        break;
        !           944:                                    }
        !           945:                                }
        !           946:                            } else if ((base & 0x0fff) == 0x0c88) {
        !           947:                                x = (base >> 12) & 0x0f;
        !           948:                                EISAbases[x] = 0;
        !           949:                            }
        !           950:                            continue;  /* break; */
        !           951:                        }
        !           952:                    }
        !           953:                }
        !           954:            } else
        !           955:                printk("eata_pio: error %x while reading "
        !           956:                       "PCI_BASE_ADDRESS_0\n", error);
        !           957:        }
        !           958:     } else
        !           959:        printk("eata_pio: No BIOS32 extensions present. This driver release "
        !           960:               "still depends on it.\n"
        !           961:               "          Skipping scan for PCI HBAs.\n");
        !           962: #endif /* #ifndef CONFIG_PCI */
        !           963:     return;
        !           964: }
        !           965: 
        !           966: 
        !           967: int eata_pio_detect(Scsi_Host_Template * tpnt)
        !           968: {
        !           969:     struct Scsi_Host *HBA_ptr;
        !           970:     struct get_conf gc;
        !           971:     int i;
        !           972:     
        !           973:     DBG((DBG_PROBE && DBG_DELAY) || DPT_DEBUG,
        !           974:        printk("Using lots of delays to let you read the debugging output\n"));
        !           975:     
        !           976:     tpnt->proc_dir = &proc_scsi_eata_pio;
        !           977: 
        !           978:     find_pio_PCI(&gc, tpnt);
        !           979: 
        !           980:     find_pio_EISA(&gc, tpnt);
        !           981: 
        !           982:     find_pio_ISA(&gc, tpnt);
        !           983:     
        !           984:     for (i = 0; i <= MAXIRQ; i++)
        !           985:        if (reg_IRQ[i])
        !           986:            request_irq(i, eata_pio_int_handler, SA_INTERRUPT, "EATA-PIO", NULL);
        !           987:     
        !           988:     HBA_ptr = first_HBA;
        !           989:   
        !           990:     if (registered_HBAs != 0) {
        !           991:        printk("EATA (Extended Attachment) PIO driver version: %d.%d%s\n"
        !           992:               "(c) 1993-95 Michael Neuffer, [email protected]\n"
        !           993:               "            Alfred Arnold,   [email protected]\n"
        !           994:               "This release only supports DASD devices (harddisks)\n",
        !           995:               VER_MAJOR, VER_MINOR, VER_SUB);
        !           996:        
        !           997:        printk("Registered HBAs:\n");
        !           998:        printk("HBA no. Boardtype: Revis: EATA: Bus: BaseIO: IRQ: Ch: ID: Pr:"
        !           999:                " QS: SG: CPL:\n");
        !          1000:        for (i = 1; i <= registered_HBAs; i++) {
        !          1001:            printk("scsi%-2d: %.10s v%s 2.0%c  %s %#.4x   %2d   %d   %d   %c"
        !          1002:                    "  %2d  %2d  %2d\n", 
        !          1003:                   HBA_ptr->host_no, SD(HBA_ptr)->name, SD(HBA_ptr)->revision,
        !          1004:                   SD(HBA_ptr)->EATA_revision, (SD(HBA_ptr)->bustype == 'P')?
        !          1005:                   "PCI ":(SD(HBA_ptr)->bustype == 'E')?"EISA":"ISA ",
        !          1006:                   (uint) HBA_ptr->base, HBA_ptr->irq, SD(HBA_ptr)->channel, 
        !          1007:                    HBA_ptr->this_id, (SD(HBA_ptr)->primary == TRUE)?'Y':'N', 
        !          1008:                   HBA_ptr->can_queue, HBA_ptr->sg_tablesize, 
        !          1009:                    HBA_ptr->cmd_per_lun);
        !          1010:            HBA_ptr = SD(HBA_ptr)->next;
        !          1011:        }
        !          1012:     }
        !          1013:     DBG(DPT_DEBUG,DELAY(12));
        !          1014:     
        !          1015:     return (registered_HBAs);
        !          1016: }
        !          1017: 
        !          1018: #ifdef MODULE
        !          1019: /* Eventually this will go into an include file, but this will be later */
        !          1020: Scsi_Host_Template driver_template = EATA_PIO;
        !          1021: 
        !          1022: #include "scsi_module.c"
        !          1023: #endif
        !          1024: 
        !          1025: /*
        !          1026:  * Overrides for Emacs so that we almost follow Linus's tabbing style.
        !          1027:  * Emacs will notice this stuff at the end of the file and automatically
        !          1028:  * adjust the settings for this buffer only.  This must remain at the end
        !          1029:  * of the file.
        !          1030:  * ---------------------------------------------------------------------------
        !          1031:  * Local variables:
        !          1032:  * c-indent-level: 4
        !          1033:  * c-brace-imaginary-offset: 0
        !          1034:  * c-brace-offset: -4
        !          1035:  * c-argdecl-indent: 4
        !          1036:  * c-label-offset: -4
        !          1037:  * c-continued-statement-offset: 4
        !          1038:  * c-continued-brace-offset: 0
        !          1039:  * indent-tabs-mode: nil
        !          1040:  * tab-width: 8
        !          1041:  * End:
        !          1042:  */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.