Annotation of lucent/sys/src/9/pc/devsbcd.c, revision 1.1.1.1

1.1       root        1: #include       "u.h"
                      2: #include       "../port/lib.h"
                      3: #include       "mem.h"
                      4: #include       "dat.h"
                      5: #include       "fns.h"
                      6: #include       "../port/error.h"
                      7: #include       "devtab.h"
                      8: #include       "io.h"
                      9: /*
                     10:  * CD-ROM driver for Panasonic and Mitsumi drives on SB16 and SBPRO cards
                     11:  */
                     12: 
                     13: 
                     14: typedef struct Drive           Drive;
                     15: 
                     16: enum
                     17: {
                     18:        FRAMESIZE       = 2048,         /* max in a transfer */
                     19:        Panasonic       = 1,
                     20:        Mitsumi         = 2,
                     21: 
                     22:        Qdir            = 0,
                     23:        Qcd,
                     24:        Qcdctl,
                     25: 
                     26:        CMDLEN          = 7,
                     27: 
                     28:        DTEN            = 0x02,         /* Status register */
                     29:        STEN            = 0x04,
                     30: 
                     31:        DRIVE0          = 0,
                     32: 
                     33:        CMD             = 0,            /* Ports */
                     34:        DATA            = 0,
                     35:        PHASE           = 1,
                     36:        STATUS          = 1,
                     37:        RESET           = 2,
                     38:        SELECT          = 3,
                     39: 
                     40:        ABORT           = 0x08,
                     41:        BLOCKPARAM      = 0x00,
                     42:        DOORCLOSE       = 0x07,
                     43:        DOOROPEN        = 0x06,
                     44:        LOCK            = 0x0c,
                     45:        MODESELECT      = 0x09,
                     46:        NOP             = 0x05,
                     47:        PAUSE           = 0x0d,
                     48:        PLAYBLOCKS      = 0x0e,
                     49:        PLAYTRKS        = 0x0f,
                     50:        READ            = 0x10,
                     51:        READDINFO       = 0x8b,
                     52:        READERROR       = 0x82,
                     53:        READID          = 0x83,
                     54:        RESUME          = 0x80,
                     55: 
                     56:        ST_DOOROPEN     = 0x80,
                     57:        ST_DSKIN        = 0x40,
                     58:        ST_SPIN         = 0x20,
                     59:        ST_ERROR        = 0x10,
                     60:        ST_BUSY         = 0x04,
                     61:        ST_AUDIOBSY     = 0x02,
                     62: 
                     63:        MEDIA_CHANGED   = 0x11,
                     64:        NOT_READY       = 0x03,
                     65:        HARD_RESET      = 0x12,
                     66:        DISC_OUT        = 0x15,
                     67: 
                     68:        MST_CMD_CHECK   = 0x01,         /* command error */
                     69:        MST_BUSY        = 0x02,         /* now playing */
                     70:        MST_READ_ERR    = 0x04,         /* read error */
                     71:        MST_DSK_TYPE    = 0x08,         /* cdda */
                     72:        MST_SERVO_CHECK = 0x10,
                     73:        MST_DSK_CHG     = 0x20,         /* disk removed or changed */
                     74:        MST_READY       = 0x40,         /* disk in the drive */
                     75:        MST_DOOR_OPEN   = 0x80,         /* door is open */
                     76: 
                     77:        MFL_DATA        = 0x02,         /* data available */
                     78:        MFL_STATUS      = 0x04,         /* status available */
                     79: 
                     80:        MCMD_RESET              = 0x00,
                     81:        MCMD_GET_DISK_INFO      = 0x10,         /* read info from disk */
                     82:        MCMD_GET_Q_CHANNEL      = 0x20,         /* read info from q channel */
                     83:        MCMD_GET_STATUS         = 0x40,
                     84:        MCMD_SET_MODE           = 0x50,
                     85:        MCMD_SOFT_RESET         = 0x60,
                     86:        MCMD_STOP               = 0x70,         /* stop play */
                     87:        MCMD_CONFIG_DRIVE       = 0x90,
                     88:        MCMD_SET_VOLUME         = 0xAE,         /* set audio level */
                     89:        MCMD_PLAY_READ          = 0xC0,         /* play or read data */
                     90:        MCMD_GET_VERSION        = 0xDC,
                     91:        MCMD_EJECT              = 0xF6,         /* eject (FX drive) */
                     92: 
                     93:        MSTAT_DOOR              = 1,
                     94:        MSTAT_CHNG,
                     95:        MSTAT_CDDA,
                     96:        MSTAT_READY,
                     97:        MSTAT_ERROR,
                     98: };
                     99: 
                    100: static char *etable[] =
                    101: {
                    102:        "no error",
                    103:        "soft read error after retry",
                    104:        "soft read error after error correction",
                    105:        "not ready",
                    106:        "unable to read TOC",
                    107:        "hard read error of data track",
                    108:        "seek failed",
                    109:        "tracking servo failure",
                    110:        "drive RAM failure",
                    111:        "drive self-test failed",
                    112:        "focusing servo failure",
                    113:        "spindle servo failure",
                    114:        "data path failure",
                    115:        "illegal logical block address",
                    116:        "illegal field in CDB",
                    117:        "end of user encountered on this track",
                    118:        "illegal data mode for this track",
                    119:        "media changed",
                    120:        "power-on or drive reset occurred",
                    121:        "drive ROM failure",
                    122:        "illegal drive command received from host",
                    123:        "disc removed during operation",
                    124:        "drive Hardware error",
                    125:        "illegal request from host"
                    126: };
                    127: 
                    128: static char *metable[] =
                    129: {
                    130:        [MSTAT_DOOR]    = "cdrom door is open",
                    131:        [MSTAT_CHNG]    = "cdrom media changed",
                    132:        [MSTAT_CDDA]    = "cd is not a cdrom",
                    133:        [MSTAT_READY]   = "cdrom is not ready",
                    134:        [MSTAT_ERROR]   = "cannot get cd status",
                    135: };
                    136: 
                    137: struct Drive
                    138: {
                    139:        int             type;
                    140:        Ref             opens;
                    141:        QLock;
                    142:        Rendez          rendez;
                    143:        ulong           blocks;                 /* blocks on disk */
                    144:        int             port;
                    145:        uchar           buf[FRAMESIZE];
                    146: 
                    147:        void            (*sbcdio)(int, ulong);
                    148:        void            (*initdrive)(int);
                    149: };
                    150: 
                    151: Dirtab
                    152: cdtab[] =
                    153: {
                    154:        "cd",           {Qcd},                  0,      0666,
                    155:        "cdctl",        {Qcdctl},               0,      0666,
                    156: };
                    157: #define        Ncdtab          (sizeof cdtab/sizeof(Dirtab))
                    158: #define CDFILE         0               /* Array index of Qcd direntry */
                    159: 
                    160: static Drive   sbcd;
                    161: 
                    162: static void    pansbcdio(int, ulong);
                    163: static void    mitsbcdio(int, ulong);
                    164: static void    paninitdrive(int);
                    165: static void    mitinitdrive(int);
                    166: 
                    167: static void
                    168: drain(int port)
                    169: {
                    170:        outb(port+STATUS, 1);
                    171:        while((inb(port+STATUS) & (DTEN|STEN)) == STEN)
                    172:                inb(port+DATA);
                    173:        outb(port+STATUS,0);
                    174: }
                    175: 
                    176: static int
                    177: status(int port)
                    178: {
                    179:        int sr;
                    180: 
                    181:        sr = inb(port+DATA);
                    182: 
                    183:        for(;;) {
                    184:                if(inb(port+STATUS) == 0xff)
                    185:                        break;
                    186:                if((sr&DTEN|STEN) == STEN)
                    187:                        drain(port);
                    188: 
                    189:                print("devsbcd: busy for sr\n");
                    190:                sr = inb(port+DATA);
                    191:        }
                    192: 
                    193:        return sr;
                    194: }
                    195: 
                    196: static void
                    197: issue(int port, uchar *cmd)
                    198: {
                    199:        ulong s;
                    200:        uchar sr;
                    201:        int i, len;
                    202: 
                    203:        i = inb(port+STATUS);
                    204:        if(i != 0xff) {
                    205:                if ((i & DTEN|STEN) == STEN)
                    206:                        drain(port);
                    207:                i = status(port);
                    208:                USED(i);
                    209:                sr = inb(port+STATUS);
                    210:                if(sr != 0xff) {
                    211:                        print("devsbcd: device wedged, sr=%2.2ux\n", inb(port+STATUS));
                    212:                        outb(port+RESET, 0);
                    213:                        tsleep(&sbcd.rendez, return0, 0, 500);
                    214:                }
                    215:        }
                    216: 
                    217:        outb(port+SELECT, DRIVE0);
                    218: 
                    219:        len = CMDLEN;
                    220:        if(cmd[0] == ABORT)
                    221:                len=1;
                    222: 
                    223:        s = splhi();
                    224:        for (i = 0; i < len; i++)
                    225:                outb(port+CMD,*cmd++);
                    226:        splx(s);
                    227: }
                    228: 
                    229: void
                    230: sbcdreset(void)
                    231: {
                    232: }
                    233: 
                    234: void
                    235: sbcdinit(void)
                    236: {
                    237:        ISAConf sbconf;
                    238: 
                    239:        sbconf.port = 0;
                    240:        if(isaconfig("cdrom", 0, &sbconf) == 0)
                    241:                return;
                    242:        if(strcmp(sbconf.type, "panasonic") == 0 || strcmp(sbconf.type, "matsushita") == 0) {
                    243:                sbcd.sbcdio = pansbcdio;
                    244:                sbcd.initdrive = paninitdrive;
                    245:                if(sbconf.port == 0)
                    246:                        sbconf.port = 0x230;
                    247:        }
                    248:        else
                    249:        if(strcmp(sbconf.type, "mitsumi") == 0) {
                    250:                sbcd.sbcdio = mitsbcdio;
                    251:                sbcd.initdrive = mitinitdrive;
                    252:                if(sbconf.port == 0)
                    253:                        sbconf.port = 0x340;
                    254:        }
                    255:        if(sbcd.sbcdio == 0) {
                    256:                print("devsbcd: %s is not a valid cd-rom type\n", sbconf.type);
                    257:                return;
                    258:        }
                    259:        switch(sbconf.port) {
                    260:        case 0x230:
                    261:        case 0x250:
                    262:        case 0x270:
                    263:        case 0x290:
                    264:        case 0x340:
                    265:                break;
                    266:        default:
                    267:                print("devsbcd: bad port 0x%x\n", sbconf.port);
                    268:                return;
                    269:        }
                    270:        sbcd.port = sbconf.port;        
                    271: }
                    272: 
                    273: Chan*
                    274: sbcdattach(char *param)
                    275: {
                    276:        if(sbcd.port == 0)
                    277:                error("no cd-rom configured");
                    278: 
                    279:        return devattach('m', param);
                    280: }
                    281: 
                    282: Chan*
                    283: sbcdclone(Chan *c, Chan *nc)
                    284: {
                    285:        return devclone(c, nc);
                    286: }
                    287: 
                    288: int
                    289: sbcdwalk(Chan *c, char *name)
                    290: {
                    291:        return devwalk(c, name, cdtab, Ncdtab, devgen);
                    292: }
                    293: 
                    294: void
                    295: sbcdstat(Chan *c, char *dp)
                    296: {
                    297:        devstat(c, dp, cdtab, Ncdtab, devgen);
                    298: }
                    299: 
                    300: static int
                    301: poll(int timeo, int state, int port, int delay)
                    302: {
                    303:        int i, sr;
                    304: 
                    305:        sr = 0;
                    306:        for(i = 0; i < timeo; i++) {
                    307:                sr = inb(port+STATUS) & (STEN|DTEN);
                    308:                if(sr != (STEN|DTEN))
                    309:                        break;
                    310:                if(delay != 0)
                    311:                        tsleep(&sbcd.rendez, return0, 0, TK2MS(1));
                    312:        }
                    313:        return sr != state;
                    314: }
                    315: 
                    316: static int
                    317: reqsense(int port)
                    318: {
                    319:        int i;
                    320:        uchar cmd[CMDLEN], data[12];
                    321: 
                    322:        memset(cmd, 0, sizeof(cmd));
                    323:        cmd[0] = READERROR;
                    324:        issue(port, cmd);
                    325:        i = poll(2000, DTEN, port, 0);
                    326:        if(i < 0) {
                    327:                print("devsbcd: get error failed\n");
                    328:                error(Eio);
                    329:        }
                    330:        insb(port, data, 8);
                    331:        status(port);
                    332: 
                    333:        return data[2];
                    334: }
                    335: 
                    336: static void
                    337: getcap(Drive *d)
                    338: {
                    339:        int port, i, sr, retry;
                    340:        uchar cmd[CMDLEN], data[12];
                    341: 
                    342:        port = d->port;
                    343: 
                    344:        for(retry = 0; retry < 10; retry++) {
                    345:                memset(cmd, 0, sizeof(cmd));
                    346:                cmd[0] = READDINFO;
                    347:                issue(port, cmd);
                    348:                i = poll(10, DTEN, port, 1);
                    349:                if(i < 0) {
                    350:                        print("devsbcd: cmd error, sr=%2.2ux\n", status(port));
                    351:                        error(Eio);
                    352:                }
                    353:                insb(port, data, 6);
                    354:                sr = status(port);
                    355: 
                    356:                sbcd.blocks = (data[3]*4500) + (data[4]*75) + data[5];
                    357:                sbcd.blocks -= 150;     
                    358:                cdtab[CDFILE].length = sbcd.blocks*FRAMESIZE;
                    359: 
                    360:                if((sr & ST_ERROR) == 0)        
                    361:                        break;
                    362:        }
                    363:        if(retry >= 10)
                    364:                error(Eio);
                    365: }
                    366: 
                    367: Chan*
                    368: sbcdopen(Chan *c, int omode)
                    369: {
                    370:        switch(c->qid.path) {
                    371:        case Qcd:
                    372:                if(incref(&sbcd.opens) == 1) {
                    373:                        if(waserror()) {
                    374:                                decref(&sbcd.opens);
                    375:                                nexterror();
                    376:                        }
                    377:                        sbcd.initdrive(sbcd.port);
                    378:                        poperror();
                    379:                }
                    380:                break;
                    381:        }
                    382:        return devopen(c, omode, cdtab, Ncdtab, devgen);
                    383: }
                    384: 
                    385: void
                    386: sbcdcreate(Chan *c, char *name, int omode, ulong perm)
                    387: {
                    388:        USED(c, name, omode, perm);
                    389:        error(Eperm);
                    390: }
                    391: 
                    392: void
                    393: sbcdclose(Chan *c)
                    394: {
                    395:        switch(c->qid.path) {
                    396:        default:
                    397:                break;
                    398:        case Qcd:
                    399:                if(c->flag & COPEN)
                    400:                        decref(&sbcd.opens);
                    401:                break;
                    402:        }
                    403: }
                    404: 
                    405: void
                    406: sbcdremove(Chan *c)
                    407: {
                    408:        USED(c);
                    409:        error(Eperm);
                    410: }
                    411: 
                    412: void
                    413: sbcdwstat(Chan *c, char *dp)
                    414: {
                    415:        USED(c, dp);
                    416:        error(Eperm);
                    417: }
                    418: 
                    419: long
                    420: sbcdread(Chan *c, char *a, long n, ulong offset)
                    421: {
                    422:        char *t, buf[64];
                    423:        long m, o, n0, bn;
                    424: 
                    425:        if(c->qid.path & CHDIR)
                    426:                return devdirread(c, a, n, cdtab, Ncdtab, devgen);
                    427: 
                    428:        n0 = n;
                    429:        switch(c->qid.path) {
                    430:        case Qcdctl:
                    431:                t = "panasonic";
                    432:                if(sbcd.sbcdio != pansbcdio)
                    433:                        t = "mitsumi";
                    434:                sprint(buf, "port=0x%ux drive=%s\n", sbcd.port, t);
                    435:                return readstr(offset, a, n, buf);
                    436:        case Qcd:
                    437:                qlock(&sbcd);
                    438:                if(waserror()) {
                    439:                        qunlock(&sbcd);
                    440:                        nexterror();
                    441:                }
                    442:                while(n > 0) {
                    443:                        bn = offset / FRAMESIZE;
                    444:                        o = offset % FRAMESIZE;
                    445:                        m = FRAMESIZE - o;
                    446:                        if(m > n)
                    447:                                m = n;
                    448:                        if(bn >= sbcd.blocks)
                    449:                                break;
                    450:                        sbcd.sbcdio(sbcd.port, bn);
                    451:                        memmove(a, sbcd.buf+o, m);
                    452:                        n -= m;
                    453:                        offset += m;
                    454:                        a += m;
                    455:                }
                    456:                qunlock(&sbcd);
                    457:                poperror();
                    458:                break;
                    459:        }
                    460:        return n0-n;
                    461: }
                    462: 
                    463: long
                    464: sbcdwrite(Chan *c, char *a, long n, ulong offset)
                    465: {
                    466: 
                    467:        USED(c, a, n, offset);
                    468:        error(Eperm);
                    469:        return 0;
                    470: }
                    471: 
                    472: static void
                    473: bin2bcd(uchar *p)
                    474: {
                    475:        int u, t;
                    476: 
                    477:        u = *p % 10;
                    478:        t = *p / 10;
                    479:        *p = u | (t << 4);
                    480: }
                    481: 
                    482: static void
                    483: bin2msf(uchar *msf, long addr)
                    484: {
                    485:        addr += 150;
                    486:        msf[0] = addr / 4500;
                    487:        addr %= 4500;
                    488:        msf[1] = addr / 75;
                    489:        msf[2] = addr % 75;
                    490: }
                    491: 
                    492: static int
                    493: bcd2bin(uchar bcd)
                    494: {
                    495:        return (bcd >> 4) * 10 + (bcd & 0xF);
                    496: }
                    497: 
                    498: /*
                    499:  * panasonic specific
                    500:  */
                    501: static void
                    502: paninitdrive(int port)
                    503: {
                    504:        int i, sr;
                    505:        uchar cmd[CMDLEN];
                    506: 
                    507:        qlock(&sbcd);
                    508:        if(waserror()) {
                    509:                qunlock(&sbcd);
                    510:                nexterror();
                    511:        }
                    512: 
                    513:        memset(cmd, 0, sizeof(cmd));
                    514:        cmd[0] = NOP;
                    515:        issue(port, cmd);
                    516:        i = poll(10, DTEN, port, 1);
                    517:        if(i < 0)
                    518:                error("cd not responding");
                    519: 
                    520:        sr = status(port);
                    521:        if((sr&ST_DSKIN) == 0)
                    522:                error("no cd in drive");
                    523: 
                    524:        if(sr&ST_ERROR) {
                    525:                i = reqsense(port);
                    526:                switch(i) {
                    527:                case NOT_READY:                 /* Just media changes */
                    528:                case MEDIA_CHANGED:
                    529:                case HARD_RESET:
                    530:                case DISC_OUT:
                    531:                        break;
                    532:                default:
                    533:                        error(etable[i]);       /* Real errors */
                    534:                }
                    535:        }
                    536: 
                    537:        getcap(&sbcd);
                    538: 
                    539:        qunlock(&sbcd);
                    540:        poperror();
                    541: }
                    542: 
                    543: static void
                    544: pansbcdio(int port, ulong adr)
                    545: {
                    546:        int sr, i, try, errno;
                    547:        uchar *p, msf[3], cmd[CMDLEN];
                    548: 
                    549:        bin2msf(msf, adr);
                    550: 
                    551: retry:
                    552:        memset(cmd, 0, sizeof(cmd));
                    553:        cmd[0] = READ;
                    554:        cmd[1] = msf[0];
                    555:        cmd[2] = msf[1];
                    556:        cmd[3] = msf[2];
                    557:        cmd[6] = 1;
                    558:        issue(port, cmd);
                    559: 
                    560:        for(try = 0; try < 100; try++) {
                    561:                sr = inb(port+STATUS) & (STEN|DTEN);
                    562:                switch(sr) {
                    563:                case DTEN|STEN:
                    564:                        tsleep(&sbcd.rendez, return0, 0, TK2MS(1));
                    565:                        break;
                    566: 
                    567:                case 0:
                    568:                case STEN:
                    569:                        outb(port+STATUS, 1);
                    570:                        p = sbcd.buf;
                    571:                        for(i = 0; i < sizeof(sbcd.buf); i++) {
                    572:                                if(inb(port+STATUS) != 0xfd)
                    573:                                        break;
                    574:                                *p++ = inb(port+DATA);
                    575:                        }
                    576:                        outb(port+STATUS,0);
                    577:                        while((inb(port+STATUS)&(DTEN|STEN)) != DTEN)
                    578:                                ;
                    579:                        sr = status(port);
                    580:                        if(sr & ST_ERROR) {
                    581:                                errno = reqsense(port);
                    582:                                error(etable[errno]);
                    583:                        }
                    584:                        return;
                    585: 
                    586:                case DTEN:
                    587:                        i = status(port);
                    588:                        errno = reqsense(port);
                    589:                        print("devsbcd: %s reading block %d\n", etable[errno], adr);
                    590: 
                    591:                        switch(errno) {
                    592:                        case NOT_READY:
                    593:                        case MEDIA_CHANGED:
                    594:                        case HARD_RESET:
                    595:                        case DISC_OUT:
                    596:                                error(etable[i]);
                    597:                        }
                    598:                        goto retry;
                    599:                }
                    600:        }
                    601: }
                    602: 
                    603: /*
                    604:  * mitsumi specific
                    605:  */
                    606: static int
                    607: statmap(int s)
                    608: {
                    609:        if(s & MST_DOOR_OPEN)
                    610:                return MSTAT_DOOR;      /* door is open */
                    611:        if(s & MST_DSK_CHG)
                    612:                return MSTAT_CHNG;      /* disk was changed */
                    613:        if(s & MST_DSK_TYPE)
                    614:                return MSTAT_CDDA;      /* not cdrom type disk */
                    615:        if((s & MST_READY) == 0)
                    616:                return MSTAT_READY;     /* not ready */
                    617:        return 0;
                    618: }
                    619: 
                    620: static int
                    621: mitdata(int port, uchar *d, long n)
                    622: {
                    623:        int j, f;
                    624: 
                    625:        for(j=500; j; j--) {
                    626:                f = inb(port+1) & (MFL_DATA|MFL_STATUS);
                    627:                if(f == (MFL_DATA|MFL_STATUS)) {
                    628:                        if(j > 400)
                    629:                                sched();
                    630:                        else
                    631:                                tsleep(&sbcd.rendez, return0, 0, TK2MS(1));
                    632:                        continue;
                    633:                }
                    634:                if(f == MFL_STATUS) {
                    635:                        *d++ = inb(port+0);
                    636:                        if(n == 1)
                    637:                                return 0;
                    638:                        n--;
                    639:                        j = 500;
                    640:                        continue;
                    641:                }
                    642:                break;
                    643:        }
                    644:        return MSTAT_ERROR;
                    645: }
                    646: 
                    647: static int
                    648: mitstatus(int port, uchar *d, long n)
                    649: {
                    650:        int j, f;
                    651: 
                    652:        for(j=500; j; j--) {
                    653:                f = inb(port+1) & (MFL_DATA|MFL_STATUS);
                    654:                if(f == (MFL_DATA|MFL_STATUS)) {
                    655:                        if(j > 400)
                    656:                                sched();
                    657:                        else
                    658:                                tsleep(&sbcd.rendez, return0, 0, TK2MS(1));
                    659:                        continue;
                    660:                }
                    661:                if(f == MFL_DATA) {
                    662:                        *d++ = inb(port+0);
                    663:                        if(n == 1)
                    664:                                return 0;
                    665:                        n--;
                    666:                        j = 500;
                    667:                        continue;
                    668:                }
                    669:                break;
                    670:        }
                    671:        return MSTAT_ERROR;
                    672: }
                    673: 
                    674: static void
                    675: mitinitdrive(int port)
                    676: {
                    677:        int i, e;
                    678:        uchar dat[10];
                    679: 
                    680:        qlock(&sbcd);
                    681:        if(waserror()) {
                    682:                qunlock(&sbcd);
                    683:                nexterror();
                    684:        }
                    685: 
                    686:        sbcd.blocks = 0;
                    687:        for(i=0; i<5; i++) {
                    688:                outb(port+0, MCMD_GET_DISK_INFO);
                    689:                if(mitstatus(port, dat, 9))
                    690:                        continue;
                    691:                e = statmap(dat[0]);
                    692:                if(e)
                    693:                        continue;
                    694:                sbcd.blocks = bcd2bin(dat[3])*4500 +
                    695:                                bcd2bin(dat[4])*75 +
                    696:                                bcd2bin(dat[5]) -
                    697:                                150;
                    698:                cdtab[CDFILE].length = sbcd.blocks*FRAMESIZE;
                    699: 
                    700:                break;
                    701:        }
                    702:        if(sbcd.blocks == 0)
                    703:                error("cant issue capacity");
                    704: 
                    705:        qunlock(&sbcd);
                    706:        poperror();
                    707: }
                    708: 
                    709: static void
                    710: del(void)
                    711: {
                    712:        int i;
                    713: 
                    714:        for(i=0; i<10; i++)
                    715:                ;
                    716: }
                    717: 
                    718: static void
                    719: mitsbcdio(int port, ulong adr)
                    720: {
                    721:        int i, e;
                    722:        ulong s;
                    723:        uchar status, msf[3];
                    724: 
                    725:        bin2msf(msf, adr);
                    726:        bin2bcd(msf+0);         /* convert to BCD */
                    727:        bin2bcd(msf+1);
                    728:        bin2bcd(msf+2);
                    729: 
                    730:        e = 0;
                    731:        for(i=0; i<5; i++) {
                    732: 
                    733:                s = splhi();
                    734:                outb(port+0, MCMD_SET_MODE);
                    735:                outb(port+0, 1);        /* cooked data */
                    736:                splx(s);
                    737: 
                    738:                if(mitstatus(port, &status, 1))
                    739:                        continue;
                    740:                e = statmap(status);
                    741:                if(e)
                    742:                        continue;
                    743: 
                    744:                s = splhi();
                    745:                outb(port+0, MCMD_PLAY_READ);
                    746:                outb(port+0, msf[0]);
                    747:                outb(port+0, msf[1]);
                    748:                outb(port+0, msf[2]);
                    749:                outb(port+0, 0);
                    750:                outb(port+0, 0);
                    751:                outb(port+0, 1);
                    752:                splx(s);
                    753: 
                    754:                if(mitdata(port, sbcd.buf, FRAMESIZE) == 0) {
                    755:                        if(mitstatus(port, &status, 1))
                    756:                                continue;
                    757:                        e = statmap(status);
                    758:                        if(e)
                    759:                                continue;
                    760:                        return;
                    761:                }
                    762:        }
                    763:        if(e == 0)
                    764:                e = MSTAT_ERROR;
                    765:        error(metable[e]);
                    766: }

unix.superglobalmegacorp.com

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