/* @(#)scsimmc.h	1.6 01/06/27 Copyright 1997 J. Schilling */
/*
 *	Definitions for SCSI/mmc compliant drives
 *
 *	Copyright (c) 1997 J. Schilling
 */
/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; see the file COPYING.  If not, write to
 * the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 */

#ifndef	_SCSIMMC_H
#define	_SCSIMMC_H

#include <utypes.h>
#include <btorder.h>

typedef struct opc {
	Uchar	opc_speed[2];
	Uchar	opc_val[6];
} opc_t;

#if defined(_BIT_FIELDS_LTOH)	/* Intel bitorder */

struct disk_info {
	Uchar	data_len[2];		/* Data len without this info	*/
	Ucbit	disk_status	: 2;	/* Status of the disk		*/
	Ucbit	sess_status	: 2;	/* Status of last session	*/
	Ucbit	erasable	: 1;	/* Disk is erasable		*/
	Ucbit	res2		: 3;	/* Reserved			*/
	Uchar	first_track;		/* # of first track on disk	*/
	Uchar	numsess;		/* # of sessions		*/
	Uchar	first_track_ls;		/* First track in last sessaion	*/
	Uchar	last_track_ls;		/* Last track in last sessaion	*/
	Ucbit	res7_04		: 5;	/* Reserved			*/
	Ucbit	uru		: 1;	/* This is an unrestricted disk	*/
	Ucbit	dbc_v		: 1;	/* Disk bar code valid		*/
	Ucbit	did_v		: 1;	/* Disk id valid		*/
	Uchar	disk_type;		/* Disk type			*/
	Uchar	res9[3];		/* Reserved			*/
	Uchar	disk_id[4];		/* Disk identification		*/
	Uchar	last_lead_in[4];	/* Last session lead in time	*/
	Uchar	last_lead_out[4];	/* Last session lead out time	*/
	Uchar	disk_barcode[8];	/* Disk bar code		*/
	Uchar	res32;			/* Reserved			*/
	Uchar	num_opc_entries;	/* # of OPC table entries	*/
	opc_t	opc_table[1];		/* OPC table 			*/
};

#else				/* Motorola bitorder */

struct disk_info {
	Uchar	data_len[2];		/* Data len without this info	*/
	Ucbit	res2		: 3;	/* Reserved			*/
	Ucbit	erasable	: 1;	/* Disk is erasable		*/
	Ucbit	sess_status	: 2;	/* Status of last session	*/
	Ucbit	disk_status	: 2;	/* Status of the disk		*/
	Uchar	first_track;		/* # of first track on disk	*/
	Uchar	numsess;		/* # of sessions		*/
	Uchar	first_track_ls;		/* First track in last sessaion	*/
	Uchar	last_track_ls;		/* Last track in last sessaion	*/
	Ucbit	did_v		: 1;	/* Disk id valid		*/
	Ucbit	dbc_v		: 1;	/* Disk bar code valid		*/
	Ucbit	uru		: 1;	/* This is an unrestricted disk	*/
	Ucbit	res7_04		: 5;	/* Reserved			*/
	Uchar	disk_type;		/* Disk type			*/
	Uchar	res9[3];		/* Reserved			*/
	Uchar	disk_id[4];		/* Disk identification		*/
	Uchar	last_lead_in[4];	/* Last session lead in time	*/
	Uchar	last_lead_out[4];	/* Last session lead out time	*/
	Uchar	disk_barcode[8];	/* Disk bar code		*/
	Uchar	res32;			/* Reserved			*/
	Uchar	num_opc_entries;	/* # of OPC table entries	*/
	opc_t	opc_table[1];		/* OPC table 			*/
};

#endif

struct cd_mode_data {
	struct scsi_mode_header	header;
	union cd_pagex	{
		struct cd_mode_page_05	page05;
		struct cd_mode_page_2A	page2A;
	} pagex;
};

struct tocheader {
	Uchar	len[2];
	Uchar	first;
	Uchar	last;
};

/*
 * Full TOC entry
 */
struct ftrackdesc {
	Uchar	sess_number;

#if defined(_BIT_FIELDS_LTOH)		/* Intel byteorder */
	Ucbit	control		: 4;
	Ucbit	adr		: 4;
#else					/* Motorola byteorder */
	Ucbit	adr		: 4;
	Ucbit	control		: 4;
#endif

	Uchar	track;
	Uchar	point;
	Uchar	amin;
	Uchar	asec;
	Uchar	aframe;
	Uchar	res7;
	Uchar	pmin;
	Uchar	psec;
	Uchar	pframe;
};

struct fdiskinfo {
	struct tocheader	hd;
	struct ftrackdesc	desc[1];
};



#if defined(_BIT_FIELDS_LTOH)	/* Intel bitorder */

struct atipdesc {
	Ucbit	ref_speed	: 3;	/* Reference speed		*/
	Ucbit	res4_3		: 1;	/* Reserved			*/
	Ucbit	ind_wr_power	: 3;	/* Indicative tgt writing power	*/
	Ucbit	res4_7		: 1;	/* Reserved (must be "1")	*/
	Ucbit	res5_05		: 6;	/* Reserved			*/
	Ucbit	uru		: 1;	/* Disk is for unrestricted use	*/
	Ucbit	res5_7		: 1;	/* Reserved (must be "0")	*/
	Ucbit	a3_v		: 1;	/* A 3 Values valid		*/
	Ucbit	a2_v		: 1;	/* A 2 Values valid		*/
	Ucbit	a1_v		: 1;	/* A 1 Values valid		*/
	Ucbit	sub_type	: 3;	/* Disc sub type		*/
	Ucbit	erasable	: 1;	/* Disk is erasable		*/
	Ucbit	res6_7		: 1;	/* Reserved (must be "1")	*/
	Uchar	lead_in[4];		/* Lead in time			*/
	Uchar	lead_out[4];		/* Lead out time		*/
	Uchar	res15;			/* Reserved			*/
	Ucbit	clv_high	: 4;	/* Highes usable CLV recording speed */
	Ucbit	clv_low		: 3;	/* Lowest usable CLV recording speed */
	Ucbit	res16_7		: 1;	/* Reserved (must be "0")	*/
	Ucbit	res17_0		: 1;	/* Reserved			*/
	Ucbit	tgt_y_pow	: 3;	/* Tgt y val of the power mod fun */
	Ucbit	power_mult	: 3;	/* Power multiplication factor	*/
	Ucbit	res17_7		: 1;	/* Reserved (must be "0")	*/
	Ucbit	res_18_30	: 4;	/* Reserved			*/
	Ucbit	rerase_pwr_ratio: 3;	/* Recommended erase/write power*/
	Ucbit	res18_7		: 1;	/* Reserved (must be "1")	*/
	Uchar	res19;			/* Reserved			*/
	Uchar	a2[3];			/* A 2 Values			*/
	Uchar	res23;			/* Reserved			*/
	Uchar	a3[3];			/* A 3 Vaules			*/
	Uchar	res27;			/* Reserved			*/
};

#else				/* Motorola bitorder */

struct atipdesc {
	Ucbit	res4_7		: 1;	/* Reserved (must be "1")	*/
	Ucbit	ind_wr_power	: 3;	/* Indicative tgt writing power	*/
	Ucbit	res4_3		: 1;	/* Reserved			*/
	Ucbit	ref_speed	: 3;	/* Reference speed		*/
	Ucbit	res5_7		: 1;	/* Reserved (must be "0")	*/
	Ucbit	uru		: 1;	/* Disk is for unrestricted use	*/
	Ucbit	res5_05		: 6;	/* Reserved			*/
	Ucbit	res6_7		: 1;	/* Reserved (must be "1")	*/
	Ucbit	erasable	: 1;	/* Disk is erasable		*/
	Ucbit	sub_type	: 3;	/* Disc sub type		*/
	Ucbit	a1_v		: 1;	/* A 1 Values valid		*/
	Ucbit	a2_v		: 1;	/* A 2 Values valid		*/
	Ucbit	a3_v		: 1;	/* A 3 Values valid		*/
	Uchar	lead_in[4];		/* Lead in time			*/
	Uchar	lead_out[4];		/* Lead out time		*/
	Uchar	res15;			/* Reserved			*/
	Ucbit	res16_7		: 1;	/* Reserved (must be "0")	*/
	Ucbit	clv_low		: 3;	/* Lowest usable CLV recording speed */
	Ucbit	clv_high	: 4;	/* Highes usable CLV recording speed */
	Ucbit	res17_7		: 1;	/* Reserved (must be "0")	*/
	Ucbit	power_mult	: 3;	/* Power multiplication factor	*/
	Ucbit	tgt_y_pow	: 3;	/* Tgt y val of the power mod fun */
	Ucbit	res17_0		: 1;	/* Reserved			*/
	Ucbit	res18_7		: 1;	/* Reserved (must be "1")	*/
	Ucbit	rerase_pwr_ratio: 3;	/* Recommended erase/write power*/
	Ucbit	res_18_30	: 4;	/* Reserved			*/
	Uchar	res19;			/* Reserved			*/
	Uchar	a2[3];			/* A 2 Values			*/
	Uchar	res23;			/* Reserved			*/
	Uchar	a3[3];			/* A 3 Vaules			*/
	Uchar	res27;			/* Reserved			*/
};

#endif

struct atipinfo {
	struct tocheader	hd;
	struct atipdesc		desc;
};

#if defined(_BIT_FIELDS_LTOH)	/* Intel bitorder */

struct track_info {
	Uchar	data_len[2];		/* Data len without this info	*/
	Uchar	track_number;		/* Track number for this info	*/
	Uchar	session_number;		/* Session number for this info	*/
	Uchar	res4;			/* Reserved			*/
	Ucbit	track_mode	: 4;	/* Track mode (Q-sub control)	*/
	Ucbit	copy		: 1;	/* This track is a higher copy	*/
	Ucbit	damage		: 1;	/* if 1 & nwa_valid 0: inc track*/
	Ucbit	res5_67		: 2;	/* Reserved			*/
	Ucbit	data_mode	: 4;	/* Data mode of this track	*/
	Ucbit	fp		: 1;	/* This is a fixed packet track	*/
	Ucbit	packet		: 1;	/* This track is in packet mode	*/
	Ucbit	blank		: 1;	/* This is an invisible track	*/
	Ucbit	rt		: 1;	/* This is a reserved track	*/
	Ucbit	nwa_valid	: 1;	/* Next writable addr valid	*/
	Ucbit	res7_17		: 7;	/* Reserved			*/
	Uchar	track_start[4];		/* Track start address		*/
	Uchar	next_writable_addr[4];	/* Next writable address	*/
	Uchar	free_blocks[4];		/* Free usr blocks in this track*/
	Uchar	packet_size[4];		/* Packet size if in fixed mode	*/
	Uchar	track_size[4];		/* # of user data blocks in trk	*/
};

#else				/* Motorola bitorder */

struct track_info {
	Uchar	data_len[2];		/* Data len without this info	*/
	Uchar	track_number;		/* Track number for this info	*/
	Uchar	session_number;		/* Session number for this info	*/
	Uchar	res4;			/* Reserved			*/
	Ucbit	res5_67		: 2;	/* Reserved			*/
	Ucbit	damage		: 1;	/* if 1 & nwa_valid 0: inc track*/
	Ucbit	copy		: 1;	/* This track is a higher copy	*/
	Ucbit	track_mode	: 4;	/* Track mode (Q-sub control)	*/
	Ucbit	rt		: 1;	/* This is a reserved track	*/
	Ucbit	blank		: 1;	/* This is an invisible track	*/
	Ucbit	packet		: 1;	/* This track is in packet mode	*/
	Ucbit	fp		: 1;	/* This is a fixed packet track	*/
	Ucbit	data_mode	: 4;	/* Data mode of this track	*/
	Ucbit	res7_17		: 7;	/* Reserved			*/
	Ucbit	nwa_valid	: 1;	/* Next writable addr valid	*/
	Uchar	track_start[4];		/* Track start address		*/
	Uchar	next_writable_addr[4];	/* Next writable address	*/
	Uchar	free_blocks[4];		/* Free usr blocks in this track*/
	Uchar	packet_size[4];		/* Packet size if in fixed mode	*/
	Uchar	track_size[4];		/* # of user data blocks in trk	*/
};

#endif

#if defined(_BIT_FIELDS_LTOH)	/* Intel bitorder */

struct rzone_info {
	Uchar	data_len[2];		/* Data len without this info	*/
	Uchar	rzone_num_lsb;		/* RZone number LSB		*/
	Uchar	border_num_lsb;		/* Border number LSB		*/
	Uchar	res_4;			/* Reserved			*/
	Ucbit	res5_04		: 5;	/* Reserved			*/
	Ucbit	damage		: 1;	/* Damaged RZone		*/
	Ucbit	res5_67		: 2;	/* Reserved			*/
	Ucbit	res6_04		: 5;	/* Reserved			*/
	Ucbit	incremental	: 1;	/* RZone is to be written incremental */
	Ucbit	blank		: 1;	/* RZone is blank		*/
	Ucbit	rt		: 1;	/* RZone is reserved		*/
	Ucbit	nwa_v		: 1;	/* Next WR address is valid	*/
	Ucbit	res7_17		: 7;	/* Reserved			*/
	Uchar	rzone_start[4];		/* RZone start address		*/
	Uchar	next_recordable_addr[4];/* Next recordable address	*/
	Uchar	free_blocks[4];		/* Free blocks in RZone		*/
	Uchar	block_factor[4];	/* # of sectors of disc acc unit */
	Uchar	rzone_size[4];		/* RZone size			*/
	Uchar	last_recorded_addr[4];	/* Last Recorded addr in RZone	*/
	Uchar	rzone_num_msb;		/* RZone number MSB		*/
	Uchar	border_num_msb;		/* Border number MSB		*/
	Uchar	res_34_35[2];		/* Reserved			*/
};

#else				/* Motorola bitorder */

struct rzone_info {
	Uchar	data_len[2];		/* Data len without this info	*/
	Uchar	rzone_num_lsb;		/* RZone number LSB		*/
	Uchar	border_num_lsb;		/* Border number LSB		*/
	Uchar	res_4;			/* Reserved			*/
	Ucbit	res5_67		: 2;	/* Reserved			*/
	Ucbit	damage		: 1;	/* Damaged RZone		*/
	Ucbit	res5_04		: 5;	/* Reserved			*/
	Ucbit	rt		: 1;	/* RZone is reserved		*/
	Ucbit	blank		: 1;	/* RZone is blank		*/
	Ucbit	incremental	: 1;	/* RZone is to be written incremental */
	Ucbit	res6_04		: 5;	/* Reserved			*/
	Ucbit	res7_17		: 7;	/* Reserved			*/
	Ucbit	nwa_v		: 1;	/* Next WR address is valid	*/
	Uchar	rzone_start[4];		/* RZone start address		*/
	Uchar	next_recordable_addr[4];/* Next recordable address	*/
	Uchar	free_blocks[4];		/* Free blocks in RZone		*/
	Uchar	block_factor[4];	/* # of sectors of disc acc unit */
	Uchar	rzone_size[4];		/* RZone size			*/
	Uchar	last_recorded_addr[4];	/* Last Recorded addr in RZone	*/
	Uchar	rzone_num_msb;		/* RZone number MSB		*/
	Uchar	border_num_msb;		/* Border number MSB		*/
	Uchar	res_34_35[2];		/* Reserved			*/
};

#endif

#if defined(_BIT_FIELDS_LTOH)	/* Intel bitorder */

struct dvd_structure_00 {
	Uchar	data_len[2];		/* Data len without this info	*/
	Uchar	res23[2];		/* Reserved			*/
	Ucbit	book_version	: 4;	/* DVD Book version		*/
	Ucbit	book_type	: 4;	/* DVD Book type		*/
	Ucbit	minimum_rate	: 4;	/* Minimum data rate (coded)	*/
	Ucbit	disc_size	: 4;	/* Disc size (coded)		*/
	Ucbit	layer_type	: 4;	/* Layer type			*/
	Ucbit	track_path	: 1;	/* 0 = parallel, 1 = opposit dir*/
	Ucbit	numlayers	: 2;	/* Number of Layers (0 == 1)	*/
	Ucbit	res2_7		: 1;	/* Reserved			*/
	Ucbit	track_density	: 4;	/* Track density (coded)	*/
	Ucbit	linear_density	: 4;	/* Linear data density (coded)	*/
	Uchar	res8;			/* Reserved			*/
	Uchar	phys_start[3];		/* Starting Physical sector #	*/
	Uchar	res12;			/* Reserved			*/
	Uchar	phys_end[3];		/* End physical data sector #	*/
	Uchar	res16;			/* Reserved			*/
	Uchar	end_layer0[3];		/* End sector # in layer	*/
	Ucbit	res20		: 7;	/* Reserved			*/
	Ucbit	bca		: 1;	/* BCA flag bit			*/
};

#else				/* Motorola bitorder */

struct dvd_structure_00 {
	Uchar	data_len[2];		/* Data len without this info	*/
	Uchar	res23[2];		/* Reserved			*/
	Ucbit	book_type	: 4;	/* DVD Book type		*/
	Ucbit	book_version	: 4;	/* DVD Book version		*/
	Ucbit	disc_size	: 4;	/* Disc size (coded)		*/
	Ucbit	minimum_rate	: 4;	/* Minimum data rate (coded)	*/
	Ucbit	res2_7		: 1;	/* Reserved			*/
	Ucbit	numlayers	: 2;	/* Number of Layers (0 == 1)	*/
	Ucbit	track_path	: 1;	/* 0 = parallel, 1 = opposit dir*/
	Ucbit	layer_type	: 4;	/* Layer type			*/
	Ucbit	linear_density	: 4;	/* Linear data density (coded)	*/
	Ucbit	track_density	: 4;	/* Track density (coded)	*/
	Uchar	res8;			/* Reserved			*/
	Uchar	phys_start[3];		/* Starting Physical sector #	*/
	Uchar	res12;			/* Reserved			*/
	Uchar	phys_end[3];		/* End physical data sector #	*/
	Uchar	res16;			/* Reserved			*/
	Uchar	end_layer0[3];		/* End sector # in layer	*/
	Ucbit	bca		: 1;	/* BCA flag bit			*/
	Ucbit	res20		: 7;	/* Reserved			*/
};

#endif

struct dvd_structure_01 {
	Uchar	data_len[2];		/* Data len without this info	*/
	Uchar	res23[2];		/* Reserved			*/
	Uchar	copyr_prot_type;	/* Copyright prot system type	*/
	Uchar	region_mgt_info;	/* Region management info	*/
	Uchar	res67[2];		/* Reserved			*/
};

struct dvd_structure_02 {
	Uchar	data_len[2];		/* Data len without this info	*/
	Uchar	res23[2];		/* Reserved			*/
	Uchar	key_data[2048];		/* Disc Key data		*/
};

struct dvd_structure_03 {
	Uchar	data_len[2];		/* Data len without this info	*/
	Uchar	res23[2];		/* Reserved			*/
	Uchar	bca_info[1];		/* BCA information (12-188 bytes)*/
};

struct dvd_structure_04 {
	Uchar	data_len[2];		/* Data len without this info	*/
	Uchar	res23[2];		/* Reserved			*/
	Uchar	man_info[2048];		/* Disc manufacturing info	*/
};

#if defined(_BIT_FIELDS_LTOH)	/* Intel bitorder */

struct dvd_structure_05 {
	Uchar	data_len[2];		/* Data len without this info	*/
	Uchar	res23[2];		/* Reserved			*/
	Ucbit	res4_03		: 4;	/* Reserved			*/
	Ucbit	cgms		: 2;	/* CGMS (see below)		*/
	Ucbit	res4_6		: 1;	/* Reserved			*/
	Ucbit	cpm		: 1;	/* This is copyrighted material	*/
	Uchar	res57[3];		/* Reserved			*/
};

#else				/* Motorola bitorder */

struct dvd_structure_05 {
	Uchar	data_len[2];		/* Data len without this info	*/
	Uchar	res23[2];		/* Reserved			*/
	Ucbit	cpm		: 1;	/* This is copyrighted material	*/
	Ucbit	res4_6		: 1;	/* Reserved			*/
	Ucbit	cgms		: 2;	/* CGMS (see below)		*/
	Ucbit	res4_03		: 4;	/* Reserved			*/
	Uchar	res57[3];		/* Reserved			*/
};

#endif

#define	CGMS_PERMITTED		0	/* Unlimited copy permitted	*/
#define	CGMS_RES		1	/* Reserved			*/
#define	CGMS_ONE_COPY		2	/* One copy permitted		*/
#define	CGMS_NO_COPY		3	/* No copy permitted		*/

struct dvd_structure_0D {
	Uchar	data_len[2];		/* Data len without this info	*/
	Uchar	res23[2];		/* Reserved			*/
	Uchar	last_rma_sector[2];	/* Last recorded RMA sector #	*/
	Uchar	rmd_bytes[1];		/* Content of Record man area	*/
};

struct dvd_structure_0E {
	Uchar	data_len[2];		/* Data len without this info	*/
	Uchar	res23[2];		/* Reserved			*/
	Uchar	field_id;		/* Field ID (1)			*/
	Uchar	application_code;	/* Disc Application code	*/
	Uchar	phys_data;		/* Disc Phisical Data		*/
	Uchar	last_recordable_addr[3];/* Last addr of recordable area	*/
	Uchar	res_a[2];		/* Reserved			*/
	Uchar	field_id_2;		/* Field ID (2)			*/
	Uchar	ind_wr_power;		/* Recommended writing power	*/
	Uchar	ind_wavelength;		/* Wavelength for ind_wr_power	*/
	Uchar	opt_wr_strategy;	/* Optimum write Strategy	*/
	Uchar	res_b[4];		/* Reserved			*/
	Uchar	field_id_3;		/* Field ID (3)			*/
	Uchar	man_id[6];		/* Manufacturer ID		*/
	Uchar	res;			/* Reserved			*/
};

struct dvd_structure_0F {
	Uchar	data_len[2];		/* Data len without this info	*/
	Uchar	res23[2];		/* Reserved			*/
	Uchar	res45[2];		/* Reserved			*/
	Uchar	random[2];		/* Random number		*/
	Uchar	year[4];		/* Year (ascii)			*/
	Uchar	month[2];		/* Month (ascii)		*/
	Uchar	day[2];			/* Day (ascii)			*/
	Uchar	hour[2];		/* Hour (ascii)			*/
	Uchar	minute[2];		/* Minute (ascii)		*/
	Uchar	second[2];		/* Second (ascii)		*/	
};

struct dvd_structure_0F_w {
	Uchar	data_len[2];		/* Data len without this info	*/
	Uchar	res23[2];		/* Reserved			*/
	Uchar	res45[2];		/* Reserved			*/
	Uchar	year[4];		/* Year (ascii)			*/
	Uchar	month[2];		/* Month (ascii)		*/
	Uchar	day[2];			/* Day (ascii)			*/
	Uchar	hour[2];		/* Hour (ascii)			*/
	Uchar	minute[2];		/* Minute (ascii)		*/
	Uchar	second[2];		/* Second (ascii)		*/	
};

struct mmc_cue {
	Uchar	cs_ctladr;		/* CTL/ADR for this track	*/
	Uchar	cs_tno;			/* This track number		*/
	Uchar	cs_index;		/* Index within this track	*/
	Uchar	cs_dataform;		/* Data form 			*/
	Uchar	cs_scms;		/* Serial copy management	*/
	Uchar	cs_min;			/* Absolute time minutes	*/
	Uchar	cs_sec;			/* Absolute time seconds	*/
	Uchar	cs_frame;		/* Absolute time frames		*/
};

#endif	/* _SCSIMMC_H */
