示例#1
0
文件: mmc.c 项目: AustenConrad/plan-9
static int
mmcsetpage6(Drive *drive, int page, void *v)
{
	uchar cmd[6], *p, *pagedata;
	int len, n;

	if (vflag)
		print("mmcsetpage6 called!\n");
	pagedata = v;
	assert(pagedata[0] == page);
	len = Mode6parmhdrlen + Modepaghdrlen + pagedata[1];
	p = emalloc(len);
	memmove(p + Mode6parmhdrlen, pagedata, pagedata[1]);

	memset(cmd, 0, sizeof(cmd));
	cmd[0] = ScmdMselect6;
	cmd[1] = 0x10;			/* format not vendor-specific */
	cmd[4] = len;

	n = scsi(drive, cmd, sizeof(cmd), p, len, Swrite);
	free(p);
	if(n < len)
		return -1;
	return 0;
}
示例#2
0
/*
 * issue the SCSI command via scsi(2).  lun must already be in cmd[1].
 */
static int
doscsi(Target* tp, int rw, uchar* cmd, int cbytes, void* data, int* dbytes)
{
	int lun, db = 0;
	uchar reqcmd[6], reqdata[Nsense], dummy[1];
	Scsi *sc;

	sc = tp->sc;
	if (sc == nil)
		panic("doscsi: nil tp->sc");
	lun = cmd[1] >> 5;	/* save lun in case we need it for reqsense */

	/* cope with zero arguments */
	if (dbytes != nil)
		db = *dbytes;
	if (data == nil)
		data = dummy;

	if (scsi(sc, cmd, cbytes, data, db, rw) >= 0)
		return STok;

	/* cmd failed, get whatever sense data we can */
	memset(reqcmd, 0, sizeof reqcmd);
	reqcmd[0] = CMDreqsense;
	reqcmd[1] = lun<<5;
	reqcmd[4] = Nsense;
	memset(reqdata, 0, sizeof reqdata);
	if (scsicmd(sc, reqcmd, sizeof reqcmd, reqdata, sizeof reqdata,
	    Sread) < 0)
		return STharderr;

	/* translate sense data to ST* codes */
	return sense2stcode(reqdata);
}
示例#3
0
文件: mmc.c 项目: Requaos/harvey
static int
mmcsetpage10(Drive *drive, int page, void *v)
{
	uint8_t cmd[10], *p, *pagedata;
	int len, n;

	/* allocate parameter list, copy in mode page, fill in header */
	pagedata = v;
	assert(pagedata[0] == page);
	len = Mode10parmhdrlen + Modepaghdrlen + pagedata[1];
	p = emalloc(len);
	memmove(p + Mode10parmhdrlen, pagedata, pagedata[1]);
	/* parameter list header */
	p[0] = 0;
	p[1] = len - 2;

	/* set up CDB */
	initcdb(cmd, sizeof cmd, ScmdMselect10);
	cmd[1] = 0x10;			/* format not vendor-specific */
	cmd[8] = len;

	n = scsi(&drive->scsi, cmd, sizeof(cmd), p, len, Swrite);

	free(p);
	if(n < len)
		return -1;
	return 0;
}
示例#4
0
文件: mmc.c 项目: AustenConrad/plan-9
static int
mmcgetpage10(Drive *drive, int page, void *v)
{
	uchar cmd[10], resp[512];
	int n, r;

	memset(cmd, 0, sizeof(cmd));
	cmd[0] = ScmdMsense10;
	cmd[2] = page;
	cmd[8] = 255;			/* allocation length: buffer size */

//	print("get: sending cmd\n");
//	hexdump(cmd, 10);

	n = scsi(drive, cmd, sizeof(cmd), resp, sizeof(resp), Sread);
	if(n < Mode10parmhdrlen)
		return -1;

	r = (resp[6]<<8) | resp[7];	/* block descriptor length */
	n -= Mode10parmhdrlen + r;

	if(n < 0)
		return -1;
	if(n > Pagesz)
		n = Pagesz;

	memmove(v, &resp[Mode10parmhdrlen + r], n);

//	print("get: got cmd\n");
//	hexdump(cmd, 10);
//	print("page\n");
//	hexdump(v, n);

	return n;
}
示例#5
0
文件: mmc.c 项目: AustenConrad/plan-9
int
mmcstatus(Drive *drive)
{
	uchar cmd[12];

	initcdb(cmd, sizeof cmd, ScmdCDstatus);		/* mechanism status */
	return scsi(drive, cmd, sizeof(cmd), nil, 0, Sread);
}
示例#6
0
文件: mmc.c 项目: Requaos/harvey
static int
start(Drive *drive, int code)
{
	uint8_t cmd[6];

	initcdb(cmd, sizeof cmd, ScmdStart);
	cmd[4] = code;
	return scsi(&drive->scsi, cmd, sizeof(cmd), cmd, 0, Snone);
}
示例#7
0
文件: mmc.c 项目: npe9/harvey
int
stop(Drive *d)
{
	uchar cmd[12];

	memset(cmd, 0, sizeof cmd);
	cmd[0] = 0x4E;
	return scsi(d->scsi, cmd, sizeof cmd, nil, 0, Snone);
}
示例#8
0
文件: mmc.c 项目: AustenConrad/plan-9
static int
start(Drive *drive, int code)
{
	uchar cmd[6];

	initcdb(cmd, sizeof cmd, ScmdStart);
	cmd[4] = code;
	return scsi(drive, cmd, sizeof(cmd), cmd, 0, Snone);
}
示例#9
0
文件: mmc.c 项目: npe9/harvey
static void
ping(Drive *d)
{
	uchar cmd[12];

	memset(cmd, 0, sizeof cmd);
	cmd[0] = 0x43;
	scsi(d->scsi, cmd, sizeof(cmd), nil, 0, Snone);
}
示例#10
0
文件: mmc.c 项目: npe9/harvey
static int
status(Drive *d)
{
	uchar cmd[12];

	memset(cmd, 0, sizeof cmd);
	cmd[0] = 0xBD;
	return scsi(d->scsi, cmd, sizeof cmd, nil, 0, Snone);
}
示例#11
0
文件: mmc.c 项目: npe9/harvey
int
resume(Drive *d)
{
	uchar cmd[12];

	memset(cmd, 0, sizeof cmd);
	cmd[0] = 0x4B;
	cmd[8] = 0x01;
	return scsi(d->scsi, cmd, sizeof cmd, nil, 0, Snone);
}
示例#12
0
文件: mmc.c 项目: npe9/harvey
int
eject(Drive *d)
{
	uchar cmd[12];

	memset(cmd, 0, sizeof cmd);
	cmd[0] = 0x1B;
	cmd[1] = 1;
	cmd[4] = 2;
	return scsi(d->scsi, cmd, sizeof cmd, nil, 0, Snone);
}
示例#13
0
文件: mmc.c 项目: Requaos/harvey
/* 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;
}
示例#14
0
文件: mmc.c 项目: AustenConrad/plan-9
static int
getdevtype(Drive *drive)
{
	int n;
	uchar cmd[6], resp[Pagesz];

	initcdb(cmd, sizeof cmd, ScmdInq);
	cmd[3] = sizeof resp >> 8;
	cmd[4] = sizeof resp;
	n = scsi(drive, cmd, sizeof(cmd), resp, sizeof resp, Sread);
	if (n < 8)
		return -1;
	return resp[0] & 037;
}
示例#15
0
void konamigq_state::konamigq(machine_config &config)
{
	/* basic machine hardware */
	CXD8530BQ(config, m_maincpu, XTAL(67'737'600));
	m_maincpu->set_addrmap(AS_PROGRAM, &konamigq_state::konamigq_map);
	m_maincpu->subdevice<psxdma_device>("dma")->install_read_handler(5, psxdma_device::read_delegate(&konamigq_state::scsi_dma_read, this));
	m_maincpu->subdevice<psxdma_device>("dma")->install_write_handler(5, psxdma_device::write_delegate(&konamigq_state::scsi_dma_write, this));
	m_maincpu->subdevice<ram_device>("ram")->set_default_size("4M");

	M68000(config, m_soundcpu, XTAL(32'000'000)/4); /* 8MHz - measured */
	m_soundcpu->set_addrmap(AS_PROGRAM, &konamigq_state::konamigq_sound_map);

	TMS57002(config, m_dasp, XTAL(48'000'000)/2); /* 24MHz - measured */
	m_dasp->set_addrmap(AS_DATA, &konamigq_state::konamigq_dasp_map);
	m_dasp->set_periodic_int(FUNC(konamigq_state::tms_sync), attotime::from_hz(48000));

	MB89371(config, "mb89371", 0);

	EEPROM_93C46_16BIT(config, "eeprom").default_data(konamigq_def_eeprom, 128);

	scsi_port_device &scsi(SCSI_PORT(config, "scsi", 0));
	scsi.set_slot_device(1, "harddisk", SCSIHD, DEVICE_INPUT_DEFAULTS_NAME(SCSI_ID_0));

	AM53CF96(config, m_am53cf96, 0);
	m_am53cf96->set_scsi_port("scsi");
	m_am53cf96->irq_handler().set("maincpu:irq", FUNC(psxirq_device::intin10));

	/* video hardware */
	CXD8538Q(config, "gpu", XTAL(53'693'175), 0x200000, subdevice<psxcpu_device>("maincpu")).set_screen("screen");

	SCREEN(config, "screen", SCREEN_TYPE_RASTER);

	/* sound hardware */
	SPEAKER(config, "lspeaker").front_left();
	SPEAKER(config, "rspeaker").front_right();

	K056800(config, m_k056800, XTAL(18'432'000));
	m_k056800->int_callback().set_inputline(m_soundcpu, M68K_IRQ_1);

	k054539_device &k054539_1(K054539(config, "k054539_1", XTAL(18'432'000)));
	k054539_1.set_addrmap(0, &konamigq_state::konamigq_k054539_map);
	k054539_1.timer_handler().set(FUNC(konamigq_state::k054539_irq_gen));
	k054539_1.add_route(0, "lspeaker", 1.0);
	k054539_1.add_route(1, "rspeaker", 1.0);

	k054539_device &k054539_2(K054539(config, "k054539_2", XTAL(18'432'000)));
	k054539_2.set_addrmap(0, &konamigq_state::konamigq_k054539_map);
	k054539_2.add_route(0, "lspeaker", 1.0);
	k054539_2.add_route(1, "rspeaker", 1.0);
}
示例#16
0
文件: mmc.c 项目: npe9/harvey
static int
playmsf(Drive *d, Msf start, Msf end)
{
	uchar cmd[12];

	memset(cmd, 0, sizeof cmd);
	cmd[0] = 0x47;
	cmd[3] = start.m;
	cmd[4] = start.s;
	cmd[5] = start.f;
	cmd[6] = end.m;
	cmd[7] = end.s;
	cmd[8] = end.f;

	return scsi(d->scsi, cmd, sizeof cmd, nil, 0, Snone);
}
示例#17
0
文件: mmc.c 项目: AustenConrad/plan-9
static int
getbdstruct(Drive *drive)
{
	int n;
	uchar cmd[12], resp[4100];

	initcdb(cmd, sizeof cmd, ScmdReadDVD); /* actually, read disc structure */
	cmd[1] = 1;			/* media type: bd */
	cmd[7] = 0;			/* format code: disc info */
	cmd[8] = sizeof resp >> 8;	/* allocation length */
	cmd[9] = sizeof resp;
	n = scsi(drive, cmd, sizeof(cmd), resp, sizeof resp, Sread);
	/*
	 * resp[0..1] is resp length.
	 * resp[4+8..4+8+2] is bd type (disc type identifier):
	 * BDO|BDW|BDR, MMC-6 §6.22.3.3.1.  The above command should
	 * fail on DVD drives, but some seem to ignore media type
	 * and return successfully, so verify that it's a BD drive.
	 */
	if (n < 4+8+3 || resp[4+8] != 'B' || resp[4+8+1] != 'D')
		return -1;
	if (vflag)
		fprint(2, "read disc structure (bd) succeeded\n");
	drive->erasable = drive->recordable = 0;
	switch (resp[4+8+2]) {
	case 'O':
		drive->blank = 0;
		drive->blankset = 1;
		break;
	case 'R':				/* Recordable */
		drive->recordable = 1;
		break;
	case 'W':				/* reWritable */
		drive->erasable = 1;
		break;
	default:
		fprint(2, "%s: unknown bd type BD%c\n", argv0, resp[4+8+2]);
		return -1;
	}
	drive->erasableset = drive->recordableset = 1;
	drive->mmctype = Mmcbd;
	return 0;
}
示例#18
0
文件: mmc.c 项目: AustenConrad/plan-9
static int
mmcreaddiscinfo(Drive *drive, void *data, int nbytes)
{
	uchar cmd[10];
	int n;

	memset(cmd, 0, sizeof(cmd));
	cmd[0] = ScmdRdiscinfo;
	cmd[7] = nbytes>>8;
	cmd[8] = nbytes;
	n = scsi(drive, cmd, sizeof(cmd), data, nbytes, Sread);
	if(n < 24) {
		if(n >= 0)
			werrstr("rdiscinfo returns %d", n);
		return -1;
	}

	return n;
}
示例#19
0
文件: mmc.c 项目: Requaos/harvey
/* this may fail for blank media */
static int
mmcreadtoc(Drive *drive, int type, int track, void *data, int nbytes)
{
	uint8_t cmd[10];

	initcdb(cmd, sizeof cmd, ScmdRTOC);
	cmd[1] = type;				/* msf bit & reserved */
	cmd[2] = Tocfmttoc;
	cmd[6] = track;				/* track/session */
	cmd[7] = nbytes>>8;
	cmd[8] = nbytes;

	/*
	 * printing iounit(drive->scsi.rawfd) here yields
	 *	iounit(3) = 0;		# for local access
	 *	iounit(3) = 65512;	# for remote access via /mnt/term
	 */
	return scsi(&drive->scsi, cmd, sizeof(cmd), data, nbytes, Sread);
}
示例#20
0
文件: mmc.c 项目: AustenConrad/plan-9
static int
getdvdstruct(Drive *drive)
{
	int n, cat;
	uchar cmd[12], resp[Pagesz];

	initcdb(cmd, sizeof cmd, ScmdReadDVD); /* actually, read disc structure */
	cmd[1] = 0;			/* media type: dvd */
	cmd[7] = 0;			/* format code: physical format */
	cmd[8] = sizeof resp >> 8;	/* allocation length */
	cmd[9] = sizeof resp;
	n = scsi(drive, cmd, sizeof(cmd), resp, sizeof resp, Sread);
	if (n < 7)
		return -1;

//	print("dvd structure:\n");
//	hexdump(resp, n);

	/* resp[0..1] is resp length */
	cat = (resp[4] & 0xf0) >> 4;	/* disk category, MMC-6 §6.22.3.2.1 */
	if (vflag)
		fprint(2, "dvd type is %s\n", dvdtype[cat]);
	drive->dvdtype = dvdtype[cat];
	/* write parameters mode page may suffice to compute writeok for dvd */
	drive->erasable = drive->recordable = 0;
	/*
	 * the layer-type field is a *bit array*,
	 * though an enumeration of types would make more sense,
	 * since the types are exclusive, not orthogonal.
	 */
	if (resp[6] & (1<<2))			/* rewritable? */
		drive->erasable = 1;
	else if (resp[6] & (1<<1))		/* recordable once? */
		drive->recordable = 1;
	else {					/* factory-pressed disk */
		drive->blank = 0;
		drive->blankset = 1;
	}
	drive->erasableset = drive->recordableset = 1;
	drive->mmctype = (cat >= 8? Mmcdvdplus: Mmcdvdminus);
	return 0;
}
示例#21
0
文件: mmc.c 项目: npe9/harvey
static int
playstatus(Drive *d, Cdstatus *stat)
{
	uchar cmd[12], resp[16];

	memset(cmd, 0, sizeof cmd);
	cmd[0] = 0x42;
	cmd[1] = 0x02;
	cmd[2] = 0x40;
	cmd[3] = 0x01;
	cmd[7] = sizeof(resp)>>8;
	cmd[8] = sizeof(resp);
	if(scsi(d->scsi, cmd, sizeof(cmd), resp, sizeof(resp), Sread) < 0)
		return -1;

	switch(resp[1]){
	case 0x11:
		stat->state = Splaying;
		break;
	case 0x12:
		stat->state = Spaused;
		break;
	case 0x13:
		stat->state = Scompleted;
		break;
	case 0x14:
		stat->state = Serror;
		break;
	case 0x00:	/* not supported */
	case 0x15:	/* no current status to return */
	default:
		stat->state = Sunknown;
		break;
	}

	stat->track = resp[6];
	stat->index = resp[7];
	stat->abs = rdmsf(resp+9);
	stat->rel = rdmsf(resp+13);
	return 0;
}
示例#22
0
文件: mmc.c 项目: AustenConrad/plan-9
static int
mmcsetpage10(Drive *drive, int page, void *v)
{
	uchar cmd[10], *p, *pagedata;
	int len, n;

	/* allocate parameter list, copy in mode page, fill in header */
	pagedata = v;
	assert(pagedata[0] == page);
	len = Mode10parmhdrlen + Modepaghdrlen + pagedata[1];
	p = emalloc(len);
	memmove(p + Mode10parmhdrlen, pagedata, pagedata[1]);
	/* parameter list header */
	p[0] = 0;
	p[1] = len - 2;

	/* set up CDB */
	memset(cmd, 0, sizeof(cmd));
	cmd[0] = ScmdMselect10;
	cmd[1] = 0x10;			/* format not vendor-specific */
	cmd[8] = len;

//	print("set: sending cmd\n");
//	hexdump(cmd, 10);
//	print("parameter list header\n");
//	hexdump(p, Mode10parmhdrlen);
//	print("page\n");
//	hexdump(p + Mode10parmhdrlen, len - Mode10parmhdrlen);

	n = scsi(drive, cmd, sizeof(cmd), p, len, Swrite);

//	print("set: got cmd\n");
//	hexdump(cmd, 10);

	free(p);
	if(n < len)
		return -1;
	return 0;
}
示例#23
0
文件: mmc.c 项目: Requaos/harvey
static int
mmcgetpage6(Drive *drive, int page, void *v)
{
	uint8_t cmd[6], resp[512];
	int n;

	initcdb(cmd, sizeof cmd, ScmdMsense6);
	cmd[2] = page;
	cmd[4] = 255;			/* allocation length */

	n = scsi(&drive->scsi, cmd, sizeof(cmd), resp, sizeof(resp), Sread);
	if(n < Mode6parmhdrlen)
		return -1;

	n -= Mode6parmhdrlen + resp[3];
	if(n < 0)
		return -1;
	if(n > Pagesz)
		n = Pagesz;

	memmove(v, &resp[Mode6parmhdrlen + resp[3]], n);
	return n;
}
示例#24
0
文件: mmc.c 项目: Requaos/harvey
static int
getdiscinfo(Drive *drive, uint8_t resp[], int resplen)
{
	int n;
	uint8_t cmd[10];

	initcdb(cmd, sizeof cmd, ScmdRdiscinfo);
	cmd[7] = resplen>>8;
	cmd[8] = resplen;
	n = scsi(&drive->scsi, cmd, sizeof(cmd), resp, resplen, Sread);
	if(n < 24) {
		if(n >= 0)
			werrstr("rdiscinfo returns %d", n);
		else if (vflag)
			fprint(2, "read disc info failed\n");
		return -1;
	}
	if (vflag)
		fprint(2, "read disc info succeeded\n");
	assert((resp[2] & 0340) == 0);			/* data type 0 */
	drive->erasable = ((resp[2] & 0x10) != 0);	/* -RW? */
	return n;
}
示例#25
0
文件: mmc.c 项目: Requaos/harvey
static int
mmcgetpage10(Drive *drive, int page, void *v)
{
	uint8_t cmd[10], resp[512];
	int n, r;

	initcdb(cmd, sizeof cmd, ScmdMsense10);
	cmd[2] = page;
	cmd[8] = 255;			/* allocation length: buffer size */
	n = scsi(&drive->scsi, cmd, sizeof(cmd), resp, sizeof(resp), Sread);
	if(n < Mode10parmhdrlen)
		return -1;

	r = (resp[6]<<8) | resp[7];	/* block descriptor length */
	n -= Mode10parmhdrlen + r;

	if(n < 0)
		return -1;
	if(n > Pagesz)
		n = Pagesz;

	memmove(v, &resp[Mode10parmhdrlen + r], n);
	return n;
}
示例#26
0
文件: mmc.c 项目: AustenConrad/plan-9
static int
mmcgetpage6(Drive *drive, int page, void *v)
{
	uchar cmd[6], resp[512];
	int n;

	memset(cmd, 0, sizeof(cmd));
	cmd[0] = ScmdMsense6;
	cmd[2] = page;
	cmd[4] = 255;			/* allocation length */

	n = scsi(drive, cmd, sizeof(cmd), resp, sizeof(resp), Sread);
	if(n < Mode6parmhdrlen)
		return -1;

	n -= Mode6parmhdrlen + resp[3];
	if(n < 0)
		return -1;
	if(n > Pagesz)
		n = Pagesz;

	memmove(v, &resp[Mode6parmhdrlen + resp[3]], n);
	return n;
}
示例#27
0
文件: mmc.c 项目: Requaos/harvey
static int
getconfcmd(Drive *drive, uint8_t *resp, int respsz)
{
	int n;
	uint32_t datalen;
	uint8_t cmd[10];

	initcdb(cmd, sizeof cmd, Scmdgetconf);
	cmd[3] = 0;			/* start with profile list feature */
	cmd[7] = respsz >> 8;
	cmd[8] = respsz;
	n = scsi(&drive->scsi, cmd, sizeof cmd, resp, respsz, Sread);
	if (n < 0) {
		if(vflag)
			fprint(2, "get config cmd failed\n");
		return -1;
	}
	if (n < 4)
		return -1;
	datalen = GETBELONG(resp+0);
	if (datalen < 8)
		return -1;
	return datalen;
}
示例#28
0
文件: mmc.c 项目: AustenConrad/plan-9
/* 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;
}
示例#29
0
文件: mmc.c 项目: npe9/harvey
/* not a Drive, so that we don't accidentally touch Drive.toc */
int
gettoc(Scsi *s, Toc *t)
{
	int i, n;
	uchar cmd[12];
	uchar resp[1024];

Again:
	memset(t, 0, sizeof(*t));
	memset(cmd, 0, sizeof cmd);
	cmd[0] = 0x43;
	cmd[1] = 0x02;
	cmd[7] = sizeof(resp)>>8;
	cmd[8] = sizeof(resp);

	s->changetime = 1;
	/* scsi sets nchange, changetime */
	if(scsi(s, cmd, sizeof cmd, resp, sizeof(resp), Sread) < 4)
		return -1;

	if(s->changetime == 0) {
		t->ntrack = 0;
		werrstr("no media");
		return -1;
	}

	if(t->nchange == s->nchange && t->changetime != 0)
		return 0;

	t->nchange = s->nchange;
	t->changetime = s->changetime;

	if(t->ntrack > MTRACK)
		t->ntrack = MTRACK;

DPRINT(2, "%d %d\n", resp[3], resp[2]);
	t->ntrack = resp[3]-resp[2]+1;
	t->track0 = resp[2];

	n = ((resp[0]<<8) | resp[1])+2;
	if(n < 4+8*(t->ntrack+1)) {
		werrstr("bad read0 %d %d", n, 4+8*(t->ntrack+1));
		return -1;
	}

	for(i=0; i<=t->ntrack; i++)		/* <=: track[ntrack] = end */
		t->track[i].start = rdmsf(resp+4+i*8+5);

	for(i=0; i<t->ntrack; i++)
		t->track[i].end = t->track[i+1].start;

	memset(cmd, 0, sizeof cmd);
	cmd[0] = 0x43;
	cmd[7] = sizeof(resp)>>8;
	cmd[8] = sizeof(resp);
	if(scsi(s, cmd, sizeof cmd, resp, sizeof(resp), Sread) < 4)
		return -1;

	if(s->changetime != t->changetime || s->nchange != t->nchange) {
		fprint(2, "disk changed underfoot; repeating\n");
		goto Again;
	}

	n = ((resp[0]<<8) | resp[1])+2;
	if(n < 4+8*(t->ntrack+1)) {
		werrstr("bad read");
		return -1;
	}

	for(i=0; i<=t->ntrack; i++)
		t->track[i].bstart = rdlba(resp+4+i*8+5);

	for(i=0; i<t->ntrack; i++)
		t->track[i].bend = t->track[i+1].bstart;

	return 0;
}
示例#30
0
文件: mmc.c 项目: Requaos/harvey
static int
getbdstruct(Drive *drive)
{
	int n;
	uint8_t cmd[12], resp[4+4096];
	uint8_t *di, *body;

	initcdb(cmd, sizeof cmd, ScmdReadDVD); /* actually, read disc structure */
	cmd[1] = 1;			/* media type: bd */
	/* cmd[6] is layer #, 0 is first */
	cmd[7] = 0;			/* format code: disc info */
	cmd[8] = sizeof resp >> 8;	/* allocation length */
	cmd[9] = (int8_t)sizeof resp;
	n = scsi(&drive->scsi, cmd, sizeof(cmd), resp, sizeof resp, Sread);
	if(n < 0) {
		if(vflag)
			fprint(2, "read disc structure (bd) cmd failed\n");
		return -1;
	}

	/*
	 * resp[0..1] is resp length (4100); 2 & 3 are reserved.
	 * there may be multiple disc info structs of 112 bytes each.
	 * disc info (di) starts at 4.  di[0..7] are header, followed by body.
	 * body[0..2] is bd type (disc type identifier):
	 * BDO|BDW|BDR, MMC-6 §6.22.3.3.1.  The above scsi command should
	 * fail on DVD drives, but some seem to ignore media type
	 * and return successfully, so verify that it's a BD drive.
	 */
	di = resp + 4;
	body = di + 8;
	n -= 4 + 8;
	if (n < 3 || di[0] != 'D' || di[1] != 'I' ||
	    body[0] != 'B' || body[1] != 'D') {
		if(vflag)
			fprint(2, "it's not a bd\n");
		return -1;
	}
	if (vflag)
		fprint(2, "read disc structure (bd) succeeded; di format %d\n",
			di[2]);

	drive->erasable = drive->recordable = No;
	switch (body[2]) {
	case 'O':				/* read-Only */
		break;
	case 'R':				/* Recordable */
		drive->recordable = Yes;
		break;
	case 'W':				/* reWritable */
		drive->erasable = Yes;
		break;
	default:
		fprint(2, "%s: unknown bd type BD%c\n", argv0, body[2]);
		return -1;
	}
	/* printed  getbdstruct: di bytes 98 di units/layers 32 */
	// fprint(2, "getbdstruct: di bytes %d di units/layers %d\n", di[6], di[3]);
	drive->mmctype = Mmcbd;
	return 0;
}