Annotation of lucent/sys/src/9/pc/devsbcd.c, revision 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.