Beispiel #1
0
/*
 * infer endings from the beginnings of other tracks.
 */
static int
mmcinfertracks(Drive *drive, int first, int last)
{
	int i;
	uint8_t resp[1024];
	uint32_t tot;
	Track *t;

	if (vflag)
		fprint(2, "inferring tracks from toc\n");
	for(i = first; i <= last; i++) {
		memset(resp, 0, sizeof(resp));
		if(mmcreadtoc(drive, 0, i, resp, sizeof(resp)) < 0) {
			last = i - 1;
			if (last < 1)
				last = 1;
			break;
		}
		t = &drive->track[i-first];
		t->mtime = drive->changetime;
		t->type = TypeData;
		t->bs = BScdrom;
		t->beg = bige(resp+8);
		if(!(resp[5] & 4)) {
			t->type = TypeAudio;
			t->bs = BScdda;
		}
	}

	if((int32_t)drive->track[0].beg < 0)  /* i've seen negative track 0's */
		drive->track[0].beg = 0;

	tot = 0;
	memset(resp, 0, sizeof(resp));
	/* 0xAA is lead-out */
	if(mmcreadtoc(drive, 0, 0xAA, resp, sizeof(resp)) < 0)
		print("bad mmcreadtoc\n");
	if(resp[6])
		tot = bige(resp+8);

	t = nil;
	for(i=last; i>=first; i--) {
		t = &drive->track[i-first];
		t->end = tot;
		tot = t->beg;
		if(t->end <= t->beg)
			t->beg = t->end = 0;
		/* -2: skip lead out */
		t->size = (t->end - t->beg - 2) * (int64_t)t->bs;
	}
	fprint(2, "infertracks: nwa should be %,lld; tot = %,ld\n", t->size, tot);
	return last;
}
Beispiel #2
0
/* t is a track number on disc, i is an index into drive->track[] for result */
static int
mmctrackinfo(Drive *drive, int t, int i)
{
	int n, type, bs;
	uint32_t beg, size;
	uint8_t tmode;
	uint8_t cmd[10], resp[255];
	Track *track;

	initcdb(cmd, sizeof cmd, ScmdRtrackinfo);
	cmd[1] = 1;			/* address below is logical track # */
	cmd[2] = t>>24;
	cmd[3] = t>>16;
	cmd[4] = t>>8;
	cmd[5] = t;
	cmd[7] = sizeof(resp)>>8;
	cmd[8] = sizeof(resp);
	n = scsi(&drive->scsi, cmd, sizeof(cmd), resp, sizeof(resp), Sread);
	if(n < 28) {
		if(vflag)
			print("trackinfo %d fails n=%d: %r\n", t, n);
		return -1;
	}

	tmode = resp[5] & 0x0D;
//	dmode = resp[6] & 0x0F;

	gettypebs(tmode, t, i, &type, &bs);

	beg  = bige(&resp[8]);
	size = bige(&resp[24]);

	track = &drive->track[i];
	track->mtime = drive->changetime;
	track->beg = beg;
	track->end = beg + size;
	track->type = type;
	track->bs = bs;
	track->size = (int64_t)(size-2) * bs;	/* -2: skip lead out */

	if(resp[6] & (1<<6)) {			/* blank? */
		track->type = TypeBlank;
		drive->writeok = Yes;
	}

	if(vflag)
		print(" start %lu end %lu", beg, beg + size - 1);
	gettracknwa(drive, t, beg, resp);
	if (vflag)
		print("\n");
	return 0;
}
Beispiel #3
0
/*
 * figure out the first writable block, if we can, into drive->aux->mmcnwa.
 * resp must be from ScmdRtrackinfo.
 */
static int32_t
gettracknwa(Drive *drive, int t, uint32_t beg, uint8_t *resp)
{
	int32_t newnwa;
	Mmcaux *aux;

	aux = drive->aux;
	if(resp[7] & 1) {			/* nwa valid? */
		newnwa = bige(&resp[12]);
		if (newnwa >= 0)
			if (aux->mmcnwa < 0)
				aux->mmcnwa = newnwa;
			else if (aux->mmcnwa != newnwa)
				fprint(2, "nwa is %ld but invis track starts blk %ld\n",
					newnwa, aux->mmcnwa);
	}
	/* resp[6] & (1<<7) of zero: invisible track */
	if(t == Invistrack || t == drive->invistrack)
		if (aux->mmcnwa < 0)
			aux->mmcnwa = beg;
		else if (aux->mmcnwa != beg)
			fprint(2, "invis track starts blk %ld but nwa is %ld\n",
				beg, aux->mmcnwa);
	if (vflag && aux->mmcnwa >= 0)
		print(" nwa %lu", aux->mmcnwa);
	return 0;
}
Beispiel #4
0
/*
 * infer endings from the beginnings of other tracks.
 */
static void
mmcinfertracks(Drive *drive, int first, int last)
{
	int i;
	uchar resp[1024];
	ulong tot;
	Track *t;

	if (vflag)
		fprint(2, "inferring tracks\n");
	for(i = first; i <= last; i++) {
		memset(resp, 0, sizeof(resp));
		if(mmcreadtoc(drive, 0, i, resp, sizeof(resp)) < 0)
			break;
		t = &drive->track[i-first];
		t->mtime = drive->changetime;
		t->type = TypeData;
		t->bs = BScdrom;
		t->beg = bige(resp+8);
		if(!(resp[5] & 4)) {
			t->type = TypeAudio;
			t->bs = BScdda;
		}
	}

	if((long)drive->track[0].beg < 0)  /* i've seen negative track 0's */
		drive->track[0].beg = 0;

	tot = 0;
	memset(resp, 0, sizeof(resp));
	/* 0xAA is lead-out */
	if(mmcreadtoc(drive, 0, 0xAA, resp, sizeof(resp)) < 0)
		print("bad\n");
	if(resp[6])
		tot = bige(resp+8);

	for(i=last; i>=first; i--) {
		t = &drive->track[i-first];
		t->end = tot;
		tot = t->beg;
		if(t->end <= t->beg)
			t->beg = t->end = 0;
		/* -2: skip lead out */
		t->size = (t->end - t->beg - 2) * (vlong)t->bs;
	}
}
Beispiel #5
0
/* t is a track number on disc, i is an index into drive->track[] for result */
static int
mmctrackinfo(Drive *drive, int t, int i)
{
	int n, type, bs;
	ulong beg, size;
	uchar tmode;
	uchar cmd[10], resp[255];
	Mmcaux *aux;

	aux = drive->aux;
	memset(cmd, 0, sizeof(cmd));
	cmd[0] = ScmdRtrackinfo;
	cmd[1] = 1;			/* address below is logical track # */
	cmd[2] = t>>24;
	cmd[3] = t>>16;
	cmd[4] = t>>8;
	cmd[5] = t;
	cmd[7] = sizeof(resp)>>8;
	cmd[8] = sizeof(resp);
	n = scsi(drive, cmd, sizeof(cmd), resp, sizeof(resp), Sread);
	if(n < 28) {
		if(vflag)
			print("trackinfo %d fails n=%d: %r\n", t, n);
		return -1;
	}

	beg = bige(&resp[8]);
	size = bige(&resp[24]);

	tmode = resp[5] & 0x0D;
//	dmode = resp[6] & 0x0F;

	if(vflag)
		print("track %d type %d (%s)", t, tmode,
			(tmode < nelem(tracktype)? tracktype[tmode]: "**GOK**"));
	type = TypeNone;
	bs = BScdda;
	switch(tmode){
	case Tmcdda:
		type = TypeAudio;
		bs = BScdda;
		break;
	case Tm2audio:	/* 2 audio channels, with pre-emphasis 50/15 μs */
		if(vflag)
			print("audio channels with preemphasis on track %d "
				"(u%.3d)\n", t, i);
		type = TypeNone;
		break;
	case Tmunintr:		/* data track, recorded uninterrupted */
	case Tmintr:		/* data track, recorded interrupted */
		/* treat Tmintr (5) as cdrom; it's probably dvd or bd */
		type = TypeData;
		bs = BScdrom;
		break;
	default:
		if(vflag)
			print("unknown track type %d\n", tmode);
		break;
	}

	drive->track[i].mtime = drive->changetime;
	drive->track[i].beg = beg;
	drive->track[i].end = beg+size;
	drive->track[i].type = type;
	drive->track[i].bs = bs;
	drive->track[i].size = (vlong)(size-2) * bs;	/* -2: skip lead out */

	if(resp[6] & (1<<6)) {			/* blank? */
		drive->track[i].type = TypeBlank;
		drive->writeok = 1;
	}

	if(vflag)
		print(" start %lud end %lud", beg, beg + size - 1);
	/* resp[6] & (1<<7) of zero: invisible track */
	/* t == getinvistrack(): invisible track */
	if(t == Invistrack || resp[7] & 1) {	/* invis or nwa valid? */
		aux->mmcnwa = bige(&resp[12]);
		if ((long)aux->mmcnwa < 0)	/* implausible? */
			aux->mmcnwa = 0;
		if (vflag)
			print(" nwa %lud", aux->mmcnwa);
	}
	if (vflag)
		print("\n");
	return 0;
}