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

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:     
1.1.1.2 ! root      984:     for (i = 0; i < MAXIRQ; i++)
1.1       root      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.