[BACK]Return to mmc.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / cdio

Annotation of src/usr.bin/cdio/mmc.c, Revision 1.1

1.1     ! mjc         1: #include <sys/limits.h>
        !             2: #include <sys/types.h>
        !             3: #include <sys/stat.h>
        !             4: #include <sys/scsiio.h>
        !             5: #include <err.h>
        !             6: #include <fcntl.h>
        !             7: #include <stdio.h>
        !             8: #include <string.h>
        !             9: #include <unistd.h>
        !            10: #include "extern.h"
        !            11:
        !            12: #define WAVHDRLEN 44
        !            13: extern int fd;
        !            14: extern char *track_types;
        !            15:
        !            16: int
        !            17: blank(void)
        !            18: {
        !            19:        scsireq_t scr;
        !            20:        int r;
        !            21:
        !            22:        bzero(&scr, sizeof(scr));
        !            23:        scr.cmd[0] = 0xa1;
        !            24:        scr.cmd[1] = 0x01;
        !            25:        scr.cmdlen = 12;
        !            26:        scr.datalen = 0;
        !            27:        scr.timeout = 120000;
        !            28:        scr.flags = SCCMD_ESCAPE;
        !            29:        scr.senselen = SENSEBUFLEN;
        !            30:
        !            31:        r = ioctl(fd, SCIOCCOMMAND, &scr);
        !            32:        return (r == 0 ? scr.retsts : -1);
        !            33: }
        !            34:
        !            35: int
        !            36: unit_ready(void)
        !            37: {
        !            38:        scsireq_t scr;
        !            39:        int r;
        !            40:
        !            41:        bzero(&scr, sizeof(scr));
        !            42:        scr.cmd[0] = 0x00;
        !            43:        scr.cmdlen = 6;
        !            44:        scr.datalen = 0;
        !            45:        scr.timeout = 120000;
        !            46:        scr.flags = SCCMD_ESCAPE;
        !            47:        scr.senselen = SENSEBUFLEN;
        !            48:
        !            49:        r = ioctl(fd, SCIOCCOMMAND, &scr);
        !            50:        return (r == 0 ? scr.retsts : -1);
        !            51: }
        !            52:
        !            53: int
        !            54: synchronize_cache(void)
        !            55: {
        !            56:        scsireq_t scr;
        !            57:        int r;
        !            58:
        !            59:        bzero(&scr, sizeof(scr));
        !            60:        scr.cmd[0] = 0x35;
        !            61:        scr.cmdlen = 10;
        !            62:        scr.datalen = 0;
        !            63:        scr.timeout = 120000;
        !            64:        scr.flags = SCCMD_ESCAPE;
        !            65:        scr.senselen = SENSEBUFLEN;
        !            66:
        !            67:        r = ioctl(fd, SCIOCCOMMAND, &scr);
        !            68:        return (r == 0 ? scr.retsts : -1);
        !            69: }
        !            70:
        !            71: int
        !            72: close_session(void)
        !            73: {
        !            74:        scsireq_t scr;
        !            75:        int r;
        !            76:
        !            77:        bzero(&scr, sizeof(scr));
        !            78:        scr.cmd[0] = 0x5b;
        !            79:        scr.cmd[2] = 0x02; /* close session */
        !            80:        scr.cmd[5] = 0x00; /* track number */
        !            81:        scr.cmdlen = 10;
        !            82:        scr.datalen = 0;
        !            83:        scr.timeout = 120000;
        !            84:        scr.flags = SCCMD_ESCAPE;
        !            85:        scr.senselen = SENSEBUFLEN;
        !            86:
        !            87:        r = ioctl(fd, SCIOCCOMMAND, &scr);
        !            88:        return (r == 0 ? scr.retsts : -1);
        !            89:
        !            90: }
        !            91:
        !            92: int
        !            93: writetao(int ntracks, char *track_files[])
        !            94: {
        !            95:        u_char modebuf[70];
        !            96:        u_int blklen;
        !            97:        u_int t;
        !            98:        int i,r;
        !            99:        u_char bdlen;
        !           100:
        !           101:        if (track_types == NULL)
        !           102:                track_types = strdup("d");
        !           103:        if ((r = mode_sense_write(modebuf)) != SCCMD_OK) {
        !           104:                warnx("mode sense failed: %d", r);
        !           105:                return (r);
        !           106:        }
        !           107:        bdlen = modebuf[7];
        !           108:        modebuf[2+8+bdlen] |= 0x40; /* Buffer Underrun Free Enable */
        !           109:        modebuf[2+8+bdlen] |= 0x01; /* change write type to TAO */
        !           110:
        !           111:        for (i = 0, t = 0; t < ntracks; t++) {
        !           112:                if (track_types[i] == 'd') {
        !           113:                        modebuf[3+8+bdlen] = 0x04; /* track mode = data */
        !           114:                        modebuf[4+8+bdlen] = 0x08; /* 2048 block track mode */
        !           115:                        modebuf[8+8+bdlen] = 0x00; /* turn off XA */
        !           116:                        blklen = 2048;
        !           117:                } else if (track_types[i] == 'a') {
        !           118:                        modebuf[3+8+bdlen] = 0x00; /* track mode = audio */
        !           119:                        modebuf[4+8+bdlen] = 0x00; /* 2352 block track mode */
        !           120:                        modebuf[8+8+bdlen] = 0x00; /* turn off XA */
        !           121:                        blklen = 2352;
        !           122:                } else {
        !           123:                        warnx("invalid track type specified");
        !           124:                        return (1);
        !           125:                }
        !           126:                while (unit_ready() != SCCMD_OK)
        !           127:                        continue;
        !           128:                if ((r = mode_select_write(modebuf)) != SCCMD_OK) {
        !           129:                        warnx("mode select failed: %d",r);
        !           130:                        return (r);
        !           131:                }
        !           132:                writetrack(track_files[t], blklen, t, track_types[i]);
        !           133:                synchronize_cache();
        !           134:                if (track_types[i+1] != '\0')
        !           135:                        i++;
        !           136:        }
        !           137:        fprintf(stderr,"\n");
        !           138:        synchronize_cache();
        !           139:        close_session();
        !           140:        return (0);
        !           141: }
        !           142:
        !           143: int
        !           144: writetrack(char *file, u_int blklen, u_int trackno, char type)
        !           145: {
        !           146:        u_char databuf[65536];
        !           147:        struct stat sb;
        !           148:        scsireq_t scr;
        !           149:        u_int end_lba, lba;
        !           150:        u_int tmp;
        !           151:        int r,rfd;
        !           152:        u_char nblk;
        !           153:
        !           154:        nblk = 65535/blklen;
        !           155:        bzero(&scr, sizeof(scr));
        !           156:        scr.timeout = 300000;
        !           157:        scr.cmd[0] = 0x2a;
        !           158:        scr.cmd[1] = 0x00;
        !           159:        scr.cmd[8] = nblk; /* Transfer length in blocks (LSB) */
        !           160:        scr.cmdlen = 10;
        !           161:        scr.databuf = (caddr_t)databuf;
        !           162:        scr.datalen = nblk * blklen;
        !           163:        scr.senselen = SENSEBUFLEN;
        !           164:        scr.flags = SCCMD_ESCAPE|SCCMD_WRITE;
        !           165:
        !           166:        if (get_nwa(&lba) != SCCMD_OK) {
        !           167:                warnx("cannot get next writable address");
        !           168:                return (-1);
        !           169:        }
        !           170:        tmp = htobe32(lba); /* update lba in cdb */
        !           171:        memcpy(&scr.cmd[2], &tmp, sizeof(tmp));
        !           172:
        !           173:        if (stat(file, &sb) != 0) {
        !           174:                warn("cannot stat file %s",file);
        !           175:                return (-1);
        !           176:        }
        !           177:        if (sb.st_size / blklen + 1 > UINT_MAX || sb.st_size < blklen) {
        !           178:                warnx("file %s has invalid size",file);
        !           179:                return (-1);
        !           180:        }
        !           181:        if (type == 'a')
        !           182:                sb.st_size -= WAVHDRLEN;
        !           183:        if (sb.st_size % blklen) {
        !           184:                warnx("file %s is not multiple of block length %d",file,blklen);
        !           185:                end_lba = sb.st_size / blklen + lba + 1;
        !           186:        } else {
        !           187:                end_lba = sb.st_size / blklen + lba;
        !           188:        }
        !           189:        rfd = open(file, O_RDONLY, 0640);
        !           190:        if (type == 'a') {
        !           191:                if (lseek(rfd, WAVHDRLEN, SEEK_SET) == -1)
        !           192:                        err(1, "seek failed");
        !           193:        }
        !           194:        while ((lba < end_lba) && (nblk != 0)) {
        !           195:                while (lba + nblk <= end_lba) {
        !           196:                        read(rfd, databuf, nblk * blklen);
        !           197:                        scr.cmd[8] = nblk;
        !           198:                        scr.datalen = nblk * blklen;
        !           199:                        r = ioctl(fd, SCIOCCOMMAND, &scr);
        !           200:                        if (r != 0) {
        !           201:                                warn("ioctl failed while attempting to write");
        !           202:                                return (-1);
        !           203:                        }
        !           204:                        if (scr.retsts != SCCMD_OK) {
        !           205:                                warnx("ioctl returned bad status while attempting to write: %d", scr.retsts);
        !           206:                                return (r);
        !           207:                        }
        !           208:                        lba += nblk;
        !           209:                        fprintf(stderr,"\rLBA: 0x%06x/0x%06x",lba,end_lba);
        !           210:                        tmp = htobe32(lba); /* update lba in cdb */
        !           211:                        memcpy(&scr.cmd[2], &tmp, sizeof(tmp));
        !           212:                }
        !           213:                nblk--;
        !           214:        }
        !           215:        close(rfd);
        !           216:        return (0);
        !           217: }
        !           218:
        !           219: int
        !           220: mode_sense_write(unsigned char buf[])
        !           221: {
        !           222:        scsireq_t scr;
        !           223:        int r;
        !           224:
        !           225:        bzero(&scr, sizeof(scr));
        !           226:        scr.timeout = 4000;
        !           227:        scr.senselen = SENSEBUFLEN;
        !           228:        scr.cmd[0] = 0x5a;
        !           229:        scr.cmd[1] = 0x00;
        !           230:        scr.cmd[2] = 0x05; /* Write parameters mode page */
        !           231:        scr.cmd[7] = 0x00;
        !           232:        scr.cmd[8] = 0x46; /* 16 for the header + size from pg. 89 mmc-r10a.pdf */
        !           233:        scr.cmdlen = 10;
        !           234:        scr.datalen= 0x46;
        !           235:        scr.flags = SCCMD_ESCAPE|SCCMD_READ;
        !           236:        scr.databuf = (caddr_t)buf;
        !           237:
        !           238:        r = ioctl(fd, SCIOCCOMMAND, &scr);
        !           239:        return (r == 0 ? scr.retsts : -1);
        !           240: }
        !           241:
        !           242: int
        !           243: mode_select_write(unsigned char buf[])
        !           244: {
        !           245:        scsireq_t scr;
        !           246:        int r;
        !           247:
        !           248:        bzero(&scr, sizeof(scr));
        !           249:        scr.timeout = 4000;
        !           250:        scr.senselen = SENSEBUFLEN;
        !           251:        scr.cmd[0] = 0x55;
        !           252:        scr.cmd[1] = 0x10; /* pages aren't vendor specific */
        !           253:        scr.cmd[2] = 0x00;
        !           254:        scr.cmd[7] = 0x00;
        !           255:        scr.cmd[8] = 2 + buf[1] + 256 * buf[0];
        !           256:        scr.cmdlen = 10;
        !           257:        scr.datalen = 2 + buf[1] + 256 * buf[0];
        !           258:        scr.flags = SCCMD_ESCAPE|SCCMD_WRITE;
        !           259:        scr.databuf = (caddr_t)buf;
        !           260:
        !           261:        r = ioctl(fd, SCIOCCOMMAND, &scr);
        !           262:        return (r == 0 ? scr.retsts : -1);
        !           263: }
        !           264:
        !           265: int
        !           266: get_nwa(int *nwa)
        !           267: {
        !           268:        u_char databuf[28];
        !           269:        scsireq_t scr;
        !           270:        int r,tmp;
        !           271:
        !           272:        bzero(&scr, sizeof(scr));
        !           273:        scr.timeout = 4000;
        !           274:        scr.senselen = SENSEBUFLEN;
        !           275:        scr.cmd[0] = 0x52; /* READ TRACK INFO */
        !           276:        scr.cmd[1] = 0x01;
        !           277:        scr.cmd[5] = 0xff; /* Invisible Track */
        !           278:        scr.cmd[2] = 0x05; /* Write parameters mode page */
        !           279:        scr.cmd[7] = 0x00;
        !           280:        scr.cmd[8] = 0x1c;
        !           281:        scr.cmdlen = 10;
        !           282:        scr.datalen= 0x1c;
        !           283:        scr.flags = SCCMD_ESCAPE|SCCMD_READ;
        !           284:        scr.databuf = (caddr_t)databuf;
        !           285:
        !           286:        r = ioctl(fd, SCIOCCOMMAND, &scr);
        !           287:        memcpy(&tmp, &databuf[12], sizeof(tmp));
        !           288:        *nwa = betoh32(tmp);
        !           289:        return (r == 0 ? scr.retsts : -1);
        !           290: }