Пример #1
0
static int
findntracks(Drive *drive, int *firstp, int *lastp)
{
	int i, n, first, last;
	uint8_t resp[1024];

	if((n = mmcreadtoc(drive, Msfbit, 0, resp, sizeof(resp))) < 4) {
		/*
		 * it could be a blank disc.  in case it's a blank disc in a
		 * cd-rw drive, use readdiscinfo to try to find the track info.
		 */
		if(getdiscinfo(drive, resp, sizeof(resp)) < 7)
			return -1;
		assert((resp[2] & 0340) == 0);	/* data type 0 */
		if(resp[4] != 1)
			print("multi-session disc %d\n", resp[4]);
		drive->writeok = Yes;

		/*
		 * some drives (e.g., LG's BDs) report only 1 track on an
		 * unfinalized disc, so probe every track.  the nwa reported
		 * by such drives may be wrong (e.g., 0), so compute that too.
		 */
		first = resp[3];
		last = resp[6];
		if(vflag)
			print("rdiscinfo tracks %d-%d (last==1 means TBD)\n",
				first, last);
		if(last == 1)
			last = Maxresptracks;	/* probe the tracks */
	} else {
		first = resp[2];
		last = resp[3];
		if(vflag)
			print("toc tracks %d-%d (last==1 means TBD)\n",
				first, last);
		if(last == 1)
			last = Maxresptracks;	/* probe the tracks */

		if(n >= 4+8*(last-first+2)) {
			/* resp[4 + i*8 + 2] is track # */
			/* <=: track[last-first+1] = end */
			for(i=0; i<=last-first+1; i++)
				drive->track[i].mbeg = rdmsf(resp+4+i*8+5);
			for(i=0; i<last-first+1; i++)
				drive->track[i].mend = drive->track[i+1].mbeg;
		}
	}
	*firstp = first;
	*lastp = last;
	return 0;
}
Пример #2
0
/* this gets called a lot from main.c's 9P routines */
static int
mmcgettoc(Drive *drive)
{
	int i, n, first, last;
	uchar resp[1024];
	Mmcaux *aux;

	/*
	 * if someone has swapped the cd,
	 * mmcreadtoc will get ``medium changed'' and the
	 * scsi routines will set nchange and changetime in the
	 * scsi device.
	 */
	mmcreadtoc(drive, 0, 0, resp, sizeof(resp));
	if(drive->Scsi.changetime == 0) {	/* no media present */
		drive->mmctype = Mmcnone;
		drive->ntrack = 0;
		return 0;
	}
	/*
	 * if the disc doesn't appear to be have been changed, and there
	 * is a disc in this drive, there's nothing to do (the common case).
	 */
	if(drive->nchange == drive->Scsi.nchange && drive->changetime != 0)
		return 0;

	/*
	 * the disc in the drive may have just been changed,
	 * so rescan it and relearn all about it.
	 */

	drive->ntrack = 0;
	drive->nameok = 0;
	drive->nchange = drive->Scsi.nchange;
	drive->changetime = drive->Scsi.changetime;
	drive->writeok = drive->erasable = drive->recordable = drive->blank = 0;
	drive->erasableset = drive->recordableset = drive->blankset = 0;
	aux = drive->aux;
	aux->mmcnwa = 0;
	aux->nropen = aux->nwopen = 0;
	aux->ntotby = aux->ntotbk = 0;

	for(i=0; i<nelem(drive->track); i++){
		memset(&drive->track[i].mbeg, 0, sizeof(Msf));
		memset(&drive->track[i].mend, 0, sizeof(Msf));
	}

	/*
	 * TODO: set read ahead, MMC-6 §6.37, seems to control caching.
	 */

	/*
	 * find number of tracks
	 */
	if((n = mmcreadtoc(drive, Msfbit, 0, resp, sizeof(resp))) < 4) {
		/*
		 * on a blank disc in a cd-rw, use readdiscinfo
		 * to find the track info.
		 */
		if(getdiscinfo(drive, resp, sizeof(resp)) < 7)
			return -1;
		assert((resp[2] & 0340) == 0);	/* data type 0 */
		if(resp[4] != 1)
			print("multi-session disc %d\n", resp[4]);
		first = resp[3];
		last = resp[6];
		if(vflag)
			print("blank disc %d %d\n", first, last);
		/* the assumption of blankness may be unwarranted */
		drive->writeok = drive->blank = drive->blankset = 1;
	} else {
		first = resp[2];
		last = resp[3];

		if(n >= 4+8*(last-first+2)) {
			/* resp[4 + i*8 + 2] is track # */
			/* <=: track[last-first+1] = end */
			for(i=0; i<=last-first+1; i++)
				drive->track[i].mbeg = rdmsf(resp+4+i*8+5);
			for(i=0; i<last-first+1; i++)
				drive->track[i].mend = drive->track[i+1].mbeg;
		}
	}

	drive->mmctype = Mmcnone;
	drive->dvdtype = nil;
	getdvdstruct(drive);
	getbdstruct(drive);
	if (drive->mmctype == Mmcnone)
		drive->mmctype = Mmccd;		/* by default */
	if (drive->recordable || drive->erasable)
		drive->writeok = 1;

	if (vflag) {
		fprint(2, "writeok %d", drive->writeok);
		/* drive->blank is never used and hard to figure out */
//		if (drive->blankset)
//			fprint(2, " blank %d", drive->blank);
		if (drive->recordableset)
			fprint(2, " recordable %d", drive->recordable);
		if (drive->erasableset)
			fprint(2, " erasable %d", drive->erasable);
		fprint(2, "\n");
		print("first %d last %d\n", first, last);
	}

	if(first == 0 && last == 0)
		first = 1;

	if(first <= 0 || first >= Maxtrack) {
		werrstr("first table %d not in range", first);
		return -1;
	}
	if(last <= 0 || last >= Maxtrack) {
		werrstr("last table %d not in range", last);
		return -1;
	}

	if(drive->cap & Cwrite)			/* CDR drives are easy */
		for(i = first; i <= last; i++)
			mmctrackinfo(drive, i, i - first);
	else
		/*
		 * otherwise we need to infer endings from the
		 * beginnings of other tracks.
		 */
		mmcinfertracks(drive, first, last);

	drive->firsttrack = first;
	drive->ntrack = last+1-first;
	return 0;
}