Annotation of coherent/b/STREAMS/io.386/scsi.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * This is the generic SCSI part of the
                      3:  * Adaptec AHA154x host adapter driver for the AT.
                      4:  */
                      5: 
                      6: #include <sys/debug.h>
                      7: 
                      8: #include       <sys/coherent.h>
                      9: #include       <sys/fdisk.h>
                     10: #include       <sys/hdioctl.h>
                     11: #include       <sys/sdioctl.h>
                     12: #include       <sys/buf.h>
                     13: #include       <sys/con.h>
                     14: #include       <sys/stat.h>
                     15: #if    _I386
                     16: #include       <sys/uproc.h>
                     17: #endif /* _I386 */
                     18: #include       <sys/errno.h>
                     19: #include       <sys/scsiwork.h>
                     20: #include       <kernel/typed.h>
                     21: #if    _I386
                     22: #include       <sys/mmu.h>
                     23: #endif /* _I386 */
                     24: 
                     25: #ifndef _I386
                     26: extern saddr_t sds;
                     27: #endif /* _I386 */
                     28: extern short   at_drive_ct;
                     29: 
                     30: /*
                     31:  * Configurable parameters
                     32:  */
                     33: #define DEF_AHA_HDS    64
                     34: #define DEF_AHA_SPT    32
                     35: 
                     36: #define NDRIVE (8 * 4)                 /* 8 SCSI ids and 4 LUNs */
                     37: #define        SDMAJOR 13                      /* Major Device Number */
                     38: 
                     39: /*
                     40:  * Configurable variables - see /etc/conf/aha/Space.c
                     41:  */
                     42: extern int     SDIRQ;          /* Interrupt */
                     43: extern int     SDBASE;         /* Port base */
                     44: extern int     SDDMA;          /* Used for first party DMA */
                     45: 
                     46: extern int     AHA_SD_HDS;
                     47: extern int     AHA_SD_SPT;
                     48: 
                     49: /*
                     50:  *                                     LUN --------++
                     51:  * device macros                       Special-+   ||
                     52:  * minor device bits are of the form:          76543210
                     53:  *                                              |||  ||
                     54:  *                                     SCSI ID--+++  ||
                     55:  *                                     Partition ----++
                     56:  * Partition mapping:
                     57:  *
                     58:  * Description    Special Bit     Partition #          Device          Type
                     59:  * -----------    -----------     -----------          ------          ----
                     60:  * partition a         0               00              /dev/sd??a      disk
                     61:  * partition b         0               01              /dev/sd??b      disk
                     62:  * partition c         0               10              /dev/sd??c      disk
                     63:  * partition d         0               11              /dev/sd??d      disk
                     64:  * partition table     1               00              /dev/sd??x      disk
                     65:  * no rewind tape      1               01              /dev/sd??n      tape
                     66:  * UNALLOCATED         1               10                ---           ????
                     67:  * rewind tape device  1               11              /dev/sd??       tape
                     68:  */
                     69: #define        DRIVENO(minor)  (((minor) >> 2) & 0x1F) /* SCSI ID + LUN */
                     70: #define        SCSIID(minor)   (((minor) >> 4) & 0x7)  /* SCSI ID */
                     71: #define        LUN(minor)      (((minor) >> 2) & 0x3)  /* Logical Unit Number */
                     72: #define        PARTITION(minor) ((minor) & 0x3)        /* Partition */
                     73: #define        sdmkdev(maj, s, drv)    makedev((maj), ((s)|((drv)<<2)))
                     74: 
                     75: /*
                     76:  * Driver configuration.
                     77:  */
                     78: void   sdload();
                     79: void   sdunload();
                     80: void   sdopen();
                     81: void   sdclose();
                     82: void   sdread();
                     83: void   sdwrite();
                     84: int    sdioctl();
                     85: void   sdblock();
                     86: int    sdwatch();
                     87: int    nulldev();
                     88: int    nonedev();
                     89: 
                     90: CON    sdcon   = {
                     91:        DFBLK|DFCHR,                    /* Flags */
                     92:        SDMAJOR,                        /* Major index */
                     93:        sdopen,                         /* Open */
                     94:        sdclose,                        /* Close */
                     95:        sdblock,                        /* Block */
                     96:        sdread,                         /* Read */
                     97:        sdwrite,                        /* Write */
                     98:        sdioctl,                        /* Ioctl */
                     99:        nulldev,                        /* Powerfail */
                    100:        sdwatch,                        /* Timeout */
                    101:        sdload,                         /* Load */
                    102:        sdunload                        /* Unload */
                    103: };
                    104: 
                    105: /*
                    106:  *     host adapter routines
                    107:  */
                    108: int    aha_load();             /* initialize host adapter, DMA */
                    109: void   aha_unload();           /* shutdown the host adapter */
                    110: int    aha_start();            /* see if there's work */
                    111: int    aha_command();
                    112: 
                    113: /*
                    114:  * Partition Parameters - copied from disk.
                    115:  *
                    116:  *     There are NPARTN positions for the user partitions in array PPARM,
                    117:  *     plus 1 additional position to span the entire drive.
                    118:  *     Array pparmp[] contains a pointer to a kalloc()'ed PPARM
                    119:  *     entry if the drive actually exists, is a disk drive and if someone
                    120:  *     has attmpted to read a partition table from the drive.
                    121:  */
                    122: typedef        struct  fdisk_s PPARM[NPARTN + 1];      /* 4 partitions + whole drive */
                    123: static PPARM *pparmp[NDRIVE];                  /* one per possible drive */
                    124: #define        WHOLE_DRIVE     NPARTN                  /* index for whole drive */
                    125: #define        PNULL   ((PPARM *)0)
                    126: 
                    127: /*
                    128:  * Per disk controller data.
                    129:  * Only one host adapter; no more, no less.
                    130:  */
                    131: static
                    132: scsi_work_t    sd;
                    133: 
                    134: static BUF     dbuf;                   /* For raw I/O */
                    135: static int     sw_active;
                    136: 
                    137: /**
                    138:  *
                    139:  * void
                    140:  * sdload()    - load routine.
                    141:  *
                    142:  *     Action: The controller is reset and the interrupt vector is grabbed.
                    143:  *             The drive characteristics are set up at this time.
                    144:  */
                    145: static void
                    146: sdload()
                    147: {
                    148:        FIFO *ffp;
                    149:        typed_space *tp;
                    150:        extern typed_space boot_gift;
                    151: 
                    152:        /*
                    153:         * Initialize Drive Controller.
                    154:         */
                    155:        sw_active = 0;
                    156:        if (aha_load(SDDMA, SDIRQ, SDBASE, &sd) < 0) {
                    157:                SET_U_ERROR(ENXIO, "aha_load() failed.");
                    158:                return;
                    159:        }
                    160: 
                    161:        /*
                    162:         * Set values for # of heads and # of sectors per track.
                    163:         *
                    164:         * AHA translation mode uses the same # of heads
                    165:         * and the same # of sectors per track for all drives.
                    166:         *
                    167:         * If these values are already patched, leave them alone.
                    168:         * Otherwise, look in the data area written by tboot.
                    169:         * If nothing from tboot, use default values.
                    170:         */
                    171:        if (AHA_SD_HDS == 0 || AHA_SD_SPT == 0) {
                    172:                /* heads & spt not both patched */
                    173:                AHA_SD_HDS = DEF_AHA_HDS;
                    174:                AHA_SD_SPT = DEF_AHA_SPT;
                    175:                if (F_NULL != (ffp = fifo_open(&boot_gift, 0))) {
                    176:                        if (tp = fifo_read(ffp)) {
                    177:                                BIOS_DISK *bdp = (BIOS_DISK *)tp->ts_data;
                    178:                                if ((T_BIOS_DISK == tp->ts_type) &&
                    179:                                    (at_drive_ct == bdp->dp_drive) ) {
                    180:                                /* got values from tboot */
                    181:                                        AHA_SD_HDS = bdp->dp_heads;
                    182:                                        AHA_SD_SPT = bdp->dp_sectors;
                    183:                                }
                    184:                        }
                    185:                        fifo_close(ffp);
                    186:                }
                    187:        }
                    188: printf(" AHA_SD_HDS=%d AHA_SD_SPT=%d\n", AHA_SD_HDS, AHA_SD_SPT);
                    189: 
                    190: /*     aha_device_info(); */           /* enable after this gets fixed */
                    191: }
                    192: 
                    193: /**
                    194:  *
                    195:  * void
                    196:  * sdunload()  - unload routine.
                    197:  */
                    198: static void
                    199: sdunload()
                    200: {
                    201:        register int i;
                    202: 
                    203:        if (sw_active > 0)
                    204:                printf("aha154x: sdunload() athough %d active\n", sw_active);
                    205:        aha_unload(SDIRQ);
                    206:        for (i = 0; i < NDRIVE; ++i)
                    207:                if (pparmp[i] != PNULL)
                    208:                        kfree(pparmp[i]);       /* free any partition tables */
                    209: }
                    210: 
                    211: /*
                    212:  * int
                    213:  * sdgetpartitions(dev)        - load partition table for specified drive
                    214:  *
                    215:  *                     - return 1 on success and 0 on failure
                    216:  */
                    217: int sdgetpartitions(dev)
                    218: dev_t  dev;
                    219: {
                    220:        register int    i;
                    221:        scsi_cmd_t      sc;
                    222:        unsigned char   *buffer;
                    223:        struct fdisk_s  *fdp;
                    224:        int     d = DRIVENO(minor(dev));
                    225: 
                    226:        pparmp[d] = kalloc(sizeof *pparmp[0]);
                    227:        fdp = (struct fdisk_s *) pparmp[d];     /* point to first entry */
                    228: #ifdef _I386
                    229:        buffer = palloc(36+1);
                    230: #else /* _I386 */
                    231:        buffer = kalloc(36+1);
                    232: #endif /* _I386 */
                    233: 
                    234:        if (buffer == NULL || pparmp[d] == PNULL) {
                    235:                printf("aha154x: out of kernel memory\n");
                    236: #ifdef _I386
                    237:                SET_U_ERROR(ENOMEM, "aha154x: out of kernel memory");
                    238: #else /* _I386 */
                    239:                u.u_error = EKSPACE;
                    240: #endif /* _I386 */
                    241:                return 0;
                    242:        }
                    243:        kclear(pparmp[d], sizeof *pparmp[0]);
                    244:        sc.unit = d;
                    245:        sc.block = 0L;
                    246:        sc.blklen = 0;
                    247: 
                    248: #ifdef _I386
                    249:        /* sc.buffer is a virtual-physical address (Ciaran Space.) */
                    250:        sc.buffer = vtovp(buffer);
                    251: #else /* _I386 */
                    252:        sc.buffer = VTOP2(buffer, sds);
                    253: #endif /* _I386 */
                    254:        ++drvl[SDMAJOR].d_time;
                    255: 
                    256:        sc.cmd = ScmdREADCAPACITY;
                    257:        sc.buflen = 8;
                    258: 
                    259:        for(i = 0; i < sc.buflen; ++i)
                    260:                buffer[i] = 0;
                    261: 
                    262:        /*
                    263:         * If we call aha_command() only once we get a capacity of
                    264:         * 0.  All ScmdREADCAPACITY calls after the first return a
                    265:         * correct answer.
                    266:         *
                    267:         * This may be a bug in the aha154x.
                    268:         */
                    269:        aha_command(&sc);
                    270:        aha_command(&sc);
                    271: 
                    272:        T_PIGGY( 0x20000, {
                    273:                printf("buffer =");
                    274:                for(i = 0; i < sc.buflen; ++i)
                    275:                        printf(" %x", buffer[i]);
                    276:                printf("\n");
                    277:        });
                    278: 
                    279:        sc.block = (buffer[0]<<8) | buffer[1];
                    280:        sc.block <<= 16;
                    281:        sc.block |= (buffer[2]<<8) | buffer[3];
                    282: 
                    283:        sc.blklen = (buffer[6]<<8) | buffer[7];
                    284: 
                    285:        T_PIGGY( 0x20000, {
                    286:                printf("SCSI %ld. blocks of size %d\n", sc.block, sc.blklen);
                    287:        } );
                    288: 
                    289: #ifdef _I386
                    290:        pfree(buffer);
                    291: #else /* _I386 */
                    292:        kfree(buffer);
                    293: #endif /* _I386 */
                    294:        fdp[WHOLE_DRIVE].p_size = sc.block;
                    295:        if (0 == fdp[WHOLE_DRIVE].p_size) {
                    296:                /*
                    297:                 * If we are just opening this drive, make it so we can
                    298:                 * read the first block without an error.
                    299:                 */
                    300:                fdp[WHOLE_DRIVE].p_size = 1;
                    301:        }
                    302: 
                    303:        --drvl[SDMAJOR].d_time;
                    304:        return fdisk(sdmkdev(major(dev), SDEV, d), pparmp[d]);
                    305: }
                    306: 
                    307: /**
                    308:  *
                    309:  * void
                    310:  * sdopen(dev, mode)
                    311:  * dev_t dev;
                    312:  * int mode;
                    313:  *
                    314:  *     Input:  dev = disk device to be opened.
                    315:  *             mode = access mode [IPR,IPW, IPR+IPW].
                    316:  *
                    317:  *     Action: Validate the minor device.
                    318:  *             Update the paritition table if necessary.
                    319:  */
                    320: static void
                    321: sdopen(dev, mode)
                    322: register dev_t dev;
                    323: {
                    324:        register int p;                 /* partition */
                    325:        register int d;                 /* drive (SCSI ID + LUN) */
                    326:        struct fdisk_s  *fdp;           /* one partition entry */
                    327: 
                    328:        if (minor(dev) & SDEV) {
                    329:                if (PARTITION(minor(dev)) != 0) {       /* tape device ? */
                    330:                                                        /* not yet! */
                    331:                        SET_U_ERROR(ENXIO, "No tape yet");
                    332:                        devmsg(dev, "No tape yet");
                    333:                } else {
                    334:                        ++drvl[SDMAJOR].d_time;
                    335:                        ++sw_active;
                    336:                }
                    337:                return;
                    338:        }
                    339: 
                    340:        d = DRIVENO(minor(dev));
                    341:        p = PARTITION(minor(dev));
                    342: 
                    343:        /*
                    344:         * If partition not defined read partition characteristics.
                    345:         */
                    346:        if (pparmp[d] == PNULL)   /* no entry yet for this drive ? */
                    347:                if (!sdgetpartitions(dev)) {
                    348:                        SET_U_ERROR(ENXIO, "sdgetpartitions() failed.");
                    349:                        return;
                    350:                }
                    351:        /*
                    352:         * Ensure partition lies within drive boundaries and is non-zero size.
                    353:         */
                    354:        fdp = (struct fdisk_s *) pparmp[d];
                    355:        if ((fdp[p].p_base+fdp[p].p_size) > fdp[WHOLE_DRIVE].p_size) {
                    356: #ifdef _I386
                    357:                SET_U_ERROR(EINVAL, "Partition exceeds drive size.");
                    358: #else /* _I386 */
                    359:                u.u_error = EBADFMT;
                    360: #endif /* _I386 */
                    361:        } else if (fdp[p].p_size == 0) {
                    362:                SET_U_ERROR(ENODEV, "No such partition.");
                    363:        } else {
                    364:                ++drvl[SDMAJOR].d_time;
                    365:                ++sw_active;
                    366:        }
                    367: }
                    368: 
                    369: void sdclose(dev)
                    370: {
                    371:        --drvl[SDMAJOR].d_time;
                    372:        --sw_active;
                    373: }
                    374: 
                    375: /**
                    376:  *
                    377:  * void
                    378:  * sdread(dev, iop)    - write a block to the raw disk
                    379:  * dev_t dev;
                    380:  * IO * iop;
                    381:  *
                    382:  *     Input:  dev = disk device to be written to.
                    383:  *             iop = pointer to source I/O structure.
                    384:  *
                    385:  *     Action: Invoke the common raw I/O processing code.
                    386:  */
                    387: static void
                    388: sdread(dev, iop)
                    389: dev_t  dev;
                    390: IO     *iop;
                    391: {
                    392:        ioreq(&dbuf, iop, dev, BREAD, BFRAW|BFBLK|BFIOC);
                    393: }
                    394: 
                    395: /**
                    396:  *
                    397:  * void
                    398:  * sdwrite(dev, iop)   - write a block to the raw disk
                    399:  * dev_t dev;
                    400:  * IO * iop;
                    401:  *
                    402:  *     Input:  dev = disk device to be written to.
                    403:  *             iop = pointer to source I/O structure.
                    404:  *
                    405:  *     Action: Invoke the common raw I/O processing code.
                    406:  */
                    407: static void
                    408: sdwrite(dev, iop)
                    409: dev_t  dev;
                    410: IO     *iop;
                    411: {
                    412:        ioreq(&dbuf, iop, dev, BWRITE, BFRAW|BFBLK|BFIOC);
                    413: }
                    414: 
                    415: /**
                    416:  *
                    417:  * int
                    418:  * sdioctl(dev, cmd, arg)
                    419:  * dev_t dev;
                    420:  * int cmd;
                    421:  * char * vec;
                    422:  *
                    423:  *     Input:  dev = disk device to be operated on.
                    424:  *             cmd = input/output request to be performed.
                    425:  *             vec = (pointer to) optional argument.
                    426:  *
                    427:  *     Action: Validate the minor device.
                    428:  *             Update the paritition table if necessary.
                    429:  */
                    430: static int
                    431: sdioctl(dev, cmd, vec)
                    432: register dev_t dev;
                    433: int cmd;
                    434: char * vec;
                    435: {
                    436:        int i;  /* Integer for abusing.  */
                    437:        int d;  /* Drive number.  */
                    438:        hdparm_t hdparm;
                    439:        struct fdisk_s  *fdp;
                    440:        int do_getpt = 0;       /* 1 if need to call sdgetpartitions() */
                    441: 
                    442:        d = DRIVENO(minor(dev));
                    443: 
                    444:        /*
                    445:         * Identify input/output request.
                    446:         */
                    447:        switch (cmd) {
                    448: 
                    449:        case HDGETA:
                    450:                /*
                    451:                 * If haven't loaded partition table yet for this drive,
                    452:                 * try to do it now.  Note sdgetpartitions() will fail
                    453:                 * if there is a new drive (e.g. no signature).  But all
                    454:                 * we need is allocation of pparmp[d] and capacity read
                    455:                 * properly from the drive.
                    456:                 */
                    457:                if (pparmp[d] == PNULL) {
                    458:                        do_getpt = 1;   /* REALLY just want Read Capacity */
                    459: 
                    460:                        i = sdgetpartitions(dev);
                    461: 
                    462:                        if (pparmp[d] == NULL) {
                    463:                                SET_U_ERROR(ENXIO, "sdgetparitions() failed.");
                    464:                                return -1;
                    465:                        }
                    466:                }
                    467:                fdp = (struct fdisk_s *) pparmp[d];
                    468:                *(short *)&hdparm.landc[0] =
                    469:                *(short *)&hdparm.ncyl[0] = fdp[WHOLE_DRIVE].p_size
                    470:                                                / (AHA_SD_HDS * AHA_SD_SPT);
                    471:                hdparm.nhead = AHA_SD_HDS;
                    472:                hdparm.nspt = AHA_SD_SPT;
                    473:                kucopy(&hdparm, vec, sizeof hdparm);
                    474:                /*
                    475:                 * I know it's ugly.  But it gets around startup Catch-22.
                    476:                 *
                    477:                 * The fdisk command needs HDGETA.  HDGETA invokes
                    478:                 * sdgetpartitions(), but we want to call it again
                    479:                 * after the partition table has been created by the fdisk
                    480:                 * command.
                    481:                 */
                    482:                if (do_getpt) {
                    483:                        kfree(pparmp[d]);
                    484:                        pparmp[d] = PNULL;      /* force re-read of p. table */
                    485:                }
                    486:                return 0;
                    487:        case HDSETA:
                    488:                /*
                    489:                 * Set hard disk attributes.
                    490:                 */
                    491:                fdp = (struct fdisk_s *) pparmp[d];
                    492:                ukcopy(vec, &hdparm, sizeof hdparm);
                    493:                AHA_SD_HDS = hdparm.nhead;
                    494:                AHA_SD_SPT = hdparm.nspt;
                    495:                fdp[WHOLE_DRIVE].p_size =
                    496:                        (long)(*(short *)&hdparm.ncyl[0])
                    497:                        * (long)AHA_SD_HDS * (long)AHA_SD_SPT;
                    498: 
                    499:                return 0;
                    500:        case SCSI_HA_CMD:
                    501:                return aha_ioctl(cmd, vec);
                    502:        case SCSI_CMD:
                    503:                return 0;
                    504:        case SCSI_CMD_IN:
                    505:                return 0;
                    506:        case SCSI_CMD_OUT:
                    507:                return 0;
                    508: 
                    509:        default:
                    510:                SET_U_ERROR( EINVAL, "Illegal SCSI ioctl command." );
                    511:                return -1;
                    512:        }
                    513: }
                    514: 
                    515: /**
                    516:  *
                    517:  * void
                    518:  * sdblock(bp) - queue a block to the disk
                    519:  *
                    520:  *     Input:  bp = pointer to block to be queued.
                    521:  *
                    522:  *     Action: Queue a block to the disk.
                    523:  *             Make sure that the transfer is within the disk partition.
                    524:  */
                    525: static void
                    526: sdblock(bp)
                    527: register BUF   *bp;
                    528: {
                    529:        register scsi_work_t *sw;
                    530:        register int s;
                    531:        struct  fdisk_s *fdp;
                    532: 
                    533:        int p = PARTITION(minor(bp->b_dev));
                    534:        int drv = DRIVENO(minor(bp->b_dev));
                    535: 
                    536:        if (minor(bp->b_dev) & SDEV)
                    537:                p = WHOLE_DRIVE;
                    538:        bp->b_resid = bp->b_count;
                    539: 
                    540:        fdp = (struct fdisk_s *) pparmp[drv];
                    541: 
                    542:        /*
                    543:         * Range check disk region.
                    544:         */
                    545:        if (pparmp[drv] == PNULL) {
                    546:                if (p == WHOLE_DRIVE) {
                    547: #if 0
                    548: /* Why did we only allow people to access the first block of WHOLE_DRIVE?
                    549:    in cases where there was not a valid partition table? */
                    550:                        if ((bp->b_bno != 0) || (bp->b_count != BSIZE)) {
                    551:                                bp->b_flag |= BFERR;
                    552:                                bdone(bp);
                    553:                                return;
                    554:                        }
                    555: #endif
                    556:                } else {
                    557:                        printf("aha154x: no partition table\n");
                    558:                        bp->b_flag |= BFERR;
                    559:                        bdone(bp);
                    560:                        return;
                    561:                }
                    562:        } else if ((bp->b_bno + (bp->b_count/BSIZE)) > fdp[p].p_size) {
                    563: 
                    564:        T_PIGGY( 0x20000 , {
                    565:                printf("\n(bp->b_bno: %x + (bp->b_count: %x /BSIZE): %x): %x > ",
                    566:                        bp->b_bno, bp->b_count, (bp->b_count/BSIZE),
                    567:                        (bp->b_bno + (bp->b_count/BSIZE)));
                    568:                printf(" fdp[p].p_size: %x\n", fdp[p].p_size);
                    569:        } );
                    570: 
                    571:                bp->b_flag |= BFERR;
                    572:                bdone(bp);
                    573:                return;
                    574:        }
                    575: 
                    576:        bp->b_actf = NULL;
                    577: #ifdef _I386
                    578:        sw = (scsi_work_t *)palloc(sizeof(*sw));
                    579:        T_PIGGY(0x100000, printf("sw(%x)", sw); );
                    580: #else /* _I386 */
                    581:        sw = (scsi_work_t *)kalloc(sizeof(*sw));
                    582: #endif /* _I386 */
                    583:        if (sw == (scsi_work_t *)0) {
                    584:                printf("aha154x: out of kernel memory\n");
                    585:                bp->b_flag |= BFERR;
                    586:                bdone(bp);
                    587:                return;
                    588:        }
                    589:        sw->sw_bp = bp;
                    590:        sw->sw_drv = drv;
                    591:        sw->sw_type = 0;
                    592:        if (p != WHOLE_DRIVE)
                    593:                sw->sw_bno   = fdp[p].p_base + bp->b_bno;
                    594:        else
                    595:                sw->sw_bno   = bp->b_bno;
                    596:        sw->sw_retry = 1;
                    597: 
                    598:        T_PIGGY( 0x20000,
                    599:                printf("sdblock: drv %x bno %lx bp=%x, flag = %x\n",
                    600:                        drv, (long) sw->sw_bno, bp, bp->b_flag);
                    601:        );
                    602: 
                    603:        /*
                    604:         * NIGEL: These fields were never filled in before, now that kalloc ()
                    605:         * does as it is supposed to we have to do it properly.
                    606:         */
                    607: 
                    608:        sw->sw_actl = sw->sw_actf = NULL;
                    609: 
                    610:        s = sphi();
                    611:        if (sd.sw_actf == NULL) {
                    612:                ASSERT (sd.sw_actl == NULL);
                    613:                sd.sw_actf = sw;
                    614:        } else {
                    615:                ASSERT  (sd.sw_actl != NULL);
                    616:                sd.sw_actl->sw_actf = sw;
                    617:        }
                    618:        sd.sw_actl = sw;
                    619:        spl(s);
                    620: 
                    621: #ifdef TRACER
                    622:        begin_count (0);
                    623: #endif
                    624:        aha_start();
                    625: }
                    626: 
                    627: sdwatch()
                    628: {
                    629:        register int i;
                    630: 
                    631:        if (0 != (i = aha_start())) {
                    632:                T_PIGGY( 0x20000, printf("sdwatch: started %d actions\n", i); );
                    633:        }
                    634: 
                    635:        if ( 0!= (i = aha_completed())) {
                    636:                T_PIGGY( 0x20000, printf("sdwatch: completed %d actions\n", i); );
                    637:        }
                    638: 
                    639:        T_PIGGY (0x20000, aha_mbox_status ());
                    640: }

unix.superglobalmegacorp.com

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