Exemple #1
0
void
mmcgetspeed(Drive *drive)
{
	int n, maxread, curread, maxwrite, curwrite;
	uchar buf[Pagesz];

	memset(buf, 0, 22);
	n = mmcgetpage(drive, Pagcapmechsts, buf);	/* legacy page */
	if (n < 22) {
		if (vflag)
			fprint(2, "no Pagcapmechsts mode page!\n");
		return;
	}
	maxread =   (buf[8]<<8)|buf[9];
	curread =  (buf[14]<<8)|buf[15];
	maxwrite = (buf[18]<<8)|buf[19];
	curwrite = (buf[20]<<8)|buf[21];

	if(maxread && maxread < 170 || curread && curread < 170)
		return;			/* bogus data */

	drive->readspeed = curread;
	drive->writespeed = curwrite;
	drive->maxreadspeed = maxread;
	drive->maxwritespeed = maxwrite;
}
Exemple #2
0
static int
setcaching(Drive *drive)
{
	int n;
	uint8_t buf[Pagesz];

	/*
	 * we can't actually control caching much.
	 * see SBC-2 §6.3.3 but also MMC-6 §7.6.
	 *
	 * should set read ahead, MMC-6 §6.37; seems to control caching.
	 */
	n = mmcgetpage(drive, Pagcache, buf);
	if (n < 3)
		return -1;
	/* n == 255; buf[1] == 10 (10 bytes after buf[1]) */
	buf[0] &= 077;		/* clear reserved bits, MMC-6 §7.2.3 */
	assert(buf[0] == Pagcache);
	assert(buf[1] >= 10);
	buf[2] = Ccwce;
	if (mmcsetpage(drive, Pagcache, buf) < 0) {
		if (vflag)
			print("mmcprobe: cache control NOT set\n");
		return -1;
	}
	return 0;
}
Exemple #3
0
/*
 * set read-write error recovery mode page 1 (10 bytes), mmc-6 §7.3.
 *
 * requires defect management feature (0x24) mmc-6 §5.3.13 (mandatory on bd,
 * but has to be enabled by allocating spares with FORMAT UNIT command)
 * or enhanced defect reporting feature (0x29) mmc-6 §5.3.17,
 * and they are mutually exclusive.
 */
static int
seterrrecov(Drive *drive)
{
	int n;
	uint8_t buf[Pagesz];

	if (!isbitset(Featdfctmgmt, drive->features) &&
	    !isbitset(Featedfctrpt, drive->features)) {
		fprint(2, "defect mgmt. and enhanced defect reporting disabled!\n");
		return -1;
	}
	n = mmcgetpage(drive, Pagerrrecov, buf);
	if (n < 3)
		return -1;
	/* n == 255; buf[1] == 10 (10 bytes after buf[1]) */
	/*
	 * error recovery page as read:
	 * 0: 01 (page: error recovery)
	 * 1: 0a (length: 10)
	 * 2: c0 (error control bits: 0300 == Erawre|Erarre)
	 * 3: 20 (read retry count: 32)
	 * 4: 00
	 * 5: 00
	 * 6: 00
	 * 7: 00
	 * 8: 01 (write retry count: 1)
	 * 9: 00 00 00 (error reporting window size)
	 */
	buf[0] &= ~(1<<6);			/* clear reserved bit */
	assert((buf[0] & 077) == Pagerrrecov);
	assert(buf[1] >= 10);

	buf[2] = Erawre | Erarre;	/* default: Erawre; can't set Ertb */
	if (isbitset(Featedfctrpt, drive->features))
		buf[7] = 1;  /* emcdr: 1==recover, don't tell us; default 0 */

//	buf[3] = 32;	/* rd retry count; default 32; arbitrary */
//	buf[8] = 1;	/* wr retry count; default 1; arbitrary */
//	memset(buf+9, 0, 3); /* err reporting win siz: 0 == no tsr; default 0 */

	if (mmcsetpage(drive, Pagerrrecov, buf) < 0) {
		if (vflag)
			fprint(2, "error recovery NOT set\n");
		return -1;
	}
	if (vflag)
		fprint(2, "error recovery set\n");
	return 0;
}
Exemple #4
0
Drive*
mmcprobe(Scsi *scsi)
{
	Mmcaux *aux;
	Drive *drive;
	uchar buf[Pagesz];
	int cap, n;

	if (vflag)
		print("mmcprobe: inquiry: %s\n", scsi->inquire);
	drive = emalloc(sizeof(Drive));
	drive->Scsi = *scsi;
	drive->Dev = mmcdev;
	aux = emalloc(sizeof(Mmcaux));
	drive->aux = aux;
	scsiready(drive);
	drive->type = getdevtype(drive);
	if (drive->type != TypeCD) {
		werrstr("not an mmc device");
		free(aux);
		free(drive);
		return nil;
	}

	/*
	 * drive is an mmc device; learn what we can about it
	 * (as opposed to the disc in it).
	 */

	start(drive, 1);
	/* attempt to read CD capabilities page, but it's now legacy */
	if(mmcgetpage10(drive, Pagcapmechsts, buf) >= 0)
		aux->pagecmdsz = 10;
	else if(mmcgetpage6(drive, Pagcapmechsts, buf) >= 0)
		aux->pagecmdsz = 6;
	else {
		if (vflag)
			fprint(2, "no Pagcapmechsts mode page!\n");
		werrstr("can't read mode page %d!", Pagcapmechsts);
		free(aux);
		free(drive);
		return nil;
	}

	cap = 0;
	if(buf[Capwrite] & (Capcdr|Capcdrw|Capdvdr|Capdvdram) ||
	    buf[Capmisc] & Caprw)
		cap |= Cwrite;
	if(buf[Capmisc] & Capcdda)	/* CD-DA commands supported? */
		cap |= Ccdda;		/* not used anywhere else */

//	print("read %d max %d\n", biges(buf+14), biges(buf+8));
//	print("write %d max %d\n", biges(buf+20), biges(buf+18));

	/* cache optional page 05 (write parameter page) */
	if(/* (cap & Cwrite) && */
	    mmcgetpage(drive, Pagwrparams, aux->page05) >= 0) {
		aux->page05ok = 1;
		cap |= Cwrite;
		if (vflag)
			fprint(2, "mmcprobe: got page 5, assuming drive can write\n");
	} else {
		if (vflag)
			fprint(2, "no Pagwrparams mode page!\n");
		cap &= ~Cwrite;
	}
	drive->cap = cap;

	mmcgetspeed(drive);

	/*
	 * we can't actually control caching much.
	 * see SBC-2 §6.3.3 but also MMC-6 §7.6.
	 */
	n = mmcgetpage(drive, Pagcache, buf);
	if (n >= 3) {
		/* n == 255; buf[1] == 10 (10 bytes after buf[1]) */
		buf[0] &= 077;		/* clear reserved bits, MMC-6 §7.2.3 */
		assert(buf[0] == Pagcache);
		assert(buf[1] >= 10);
		buf[2] = Ccwce;
		if (mmcsetpage(drive, Pagcache, buf) < 0)
			if (vflag)
				print("mmcprobe: cache control NOT set\n");
	}
	return drive;
}
Exemple #5
0
Drive*
mmcprobe(Scsi *scsi)
{
	Mmcaux *aux;
	Drive *drive;
	uint8_t buf[Pagesz];
	int cap;

	if (vflag)
		print("mmcprobe: inquiry: %s\n", scsi->inquire);

	drive = emalloc(sizeof(Drive));
	drive->scsi = *scsi;
	drive->Dev = mmcdev;
	drive->invistrack = -1;
	getinvistrack(drive);

	aux = emalloc(sizeof(Mmcaux));
	drive->aux = aux;

	scsiready(&drive->scsi);
	drive->type = getdevtype(drive);
	if (drive->type != TypeCD) {
		werrstr("not an mmc device");
		free(aux);
		free(drive);
		return nil;
	}

	/*
	 * drive is an mmc device; learn what we can about it
	 * (as opposed to the disc in it).
	 */

	start(drive, 1);
	/* attempt to read CD capabilities page, but it's now legacy */
	if(mmcgetpage10(drive, Pagcapmechsts, buf) >= 0)
		aux->pagecmdsz = 10;
	else if(mmcgetpage6(drive, Pagcapmechsts, buf) >= 0)
		aux->pagecmdsz = 6;
	else {
		if (vflag)
			fprint(2, "no Pagcapmechsts mode page!\n");
		werrstr("can't read mode page %d!", Pagcapmechsts);
		free(aux);
		free(drive);
		return nil;
	}

	cap = 0;
	if(buf[Capwrite] & (Capcdr|Capcdrw|Capdvdr|Capdvdram) ||
	    buf[Capmisc] & Caprw)
		cap |= Cwrite;
	if(buf[Capmisc] & Capcdda)	/* CD-DA commands supported? */
		cap |= Ccdda;		/* not used anywhere else */

	/* cache optional page 05 (write parameter page) */
	if(/* (cap & Cwrite) && */
	    mmcgetpage(drive, Pagwrparams, aux->page05) >= 0) {
		aux->page05ok = 1;
		cap |= Cwrite;
		if (vflag)
			fprint(2, "mmcprobe: got page 5, assuming drive can write\n");
	} else {
		if (vflag)
			fprint(2, "no Pagwrparams mode page!\n");
		cap &= ~Cwrite;
	}
	drive->cap = cap;

	mmcgetspeed(drive);
	setcaching(drive);
	return drive;
}