Add SCSI-MMC GET CONFIGURATION.

Add Frank Endres' disc type determination via MMC.
Be more careful to suffix with CDIO_MMC which I hope will reduce possible name conflicts.
This commit is contained in:
R. Bernstein
2010-02-07 21:04:21 -05:00
parent aa7f7e1315
commit 2d3b7d28b4
11 changed files with 323 additions and 59 deletions

View File

@@ -231,7 +231,7 @@ set_speed_mmc (void *p_user_data, int i_speed)
{
generic_img_private_t *p_env = p_user_data;
if (!p_env) return DRIVER_OP_UNINIT;
return mmc_set_speed( p_env->cdio, i_speed );
return mmc_set_speed( p_env->cdio, i_speed, 0);
}
/**
@@ -966,7 +966,7 @@ int mmc_get_tray_status(const CdIo_t *p_cdio)
bytes available, <0 in case of internal error.
*/
int
mmc_last_cmd_sense(const CdIo_t *p_cdio, mmc_request_sense_t **pp_sense)
mmc_last_cmd_sense(const CdIo_t *p_cdio, cdio_mmc_request_sense_t **pp_sense)
{
generic_img_private_t *gen;
@@ -1275,6 +1275,99 @@ mmc_have_interface( CdIo_t *p_cdio, cdio_mmc_feature_interface_t e_interface )
return dunno;
}
bool
mmc_is_disctype_bd (cdio_mmc_disctype_t disctype) {
switch (disctype) {
case CDIO_MMC_DISCTYPE_BD_ROM:
case CDIO_MMC_DISCTYPE_BD_R_SR:
case CDIO_MMC_DISCTYPE_BD_R_RR:
case CDIO_MMC_DISCTYPE_BD_RE:
return true;
default:
return false;
}
}
bool
mmc_is_disctype_cdrom (cdio_mmc_disctype_t disctype) {
switch (disctype) {
case CDIO_MMC_DISCTYPE_CD_ROM:
case CDIO_MMC_DISCTYPE_CD_R:
case CDIO_MMC_DISCTYPE_CD_RW:
return true;
default:
return false;
}
}
bool
mmc_is_disctype_dvd (cdio_mmc_disctype_t disctype) {
switch (disctype) {
case CDIO_MMC_DISCTYPE_DVD_ROM:
case CDIO_MMC_DISCTYPE_DVD_RAM:
case CDIO_MMC_DISCTYPE_DVD_R:
case CDIO_MMC_DISCTYPE_DVD_RW_RO:
case CDIO_MMC_DISCTYPE_DVD_RW_SR:
case CDIO_MMC_DISCTYPE_DVD_R_DL_SR:
case CDIO_MMC_DISCTYPE_DVD_R_DL_JR:
case CDIO_MMC_DISCTYPE_DVD_PRW:
case CDIO_MMC_DISCTYPE_DVD_PR:
case CDIO_MMC_DISCTYPE_DVD_PRW_DL:
case CDIO_MMC_DISCTYPE_DVD_PR_DL:
return true;
default:
return false;
}
}
bool
mmc_is_disctype_hd_dvd (cdio_mmc_disctype_t disctype) {
switch (disctype) {
case CDIO_MMC_DISCTYPE_HD_DVD_ROM:
case CDIO_MMC_DISCTYPE_HD_DVD_R:
case CDIO_MMC_DISCTYPE_HD_DVD_RAM:
return true;
default:
return false;
}
}
bool
mmc_is_disctype_overwritable (cdio_mmc_disctype_t disctype) {
switch (disctype) {
case CDIO_MMC_DISCTYPE_DVD_RW_RO:
case CDIO_MMC_DISCTYPE_DVD_R_DL_JR:
case CDIO_MMC_DISCTYPE_DVD_PRW:
case CDIO_MMC_DISCTYPE_DVD_PRW_DL:
case CDIO_MMC_DISCTYPE_BD_R_RR: /* pseudo-overwritable */
case CDIO_MMC_DISCTYPE_BD_RE:
case CDIO_MMC_DISCTYPE_HD_DVD_RAM:
return true;
default:
return false;
}
}
bool
mmc_is_disctype_rewritable (cdio_mmc_disctype_t disctype) {
/* discs that need blanking before re-use */
if (mmc_is_disctype_overwritable (disctype))
return true;
switch (disctype) {
case CDIO_MMC_DISCTYPE_CD_RW:
case CDIO_MMC_DISCTYPE_DVD_RW_SR:
case CDIO_MMC_DISCTYPE_BD_R_SR:
return true;
default:
return false;
}
}
/**
Read sectors using SCSI-MMC GPCMD_READ_CD.
*/
@@ -1340,6 +1433,8 @@ mmc_set_blocksize ( const CdIo_t *p_cdio, uint16_t i_blocksize)
}
/*
* Local variables:

View File

@@ -44,6 +44,68 @@ mmc_eject_media( const CdIo_t *p_cdio )
}
/* From Frank Endres: */
/**
Detects the disc type using the SCSI-MMC GET CONFIGURATION command.
@param p_cdio the CD object to be acted upon.
@param i_status, if not NULL, on return will be set indicate whether
the operation was a success (DRIVER_OP_SUCCESS) or if not to some
other value.
@param p_disctype the disc type set on success.
@return DRIVER_OP_SUCCESS (0) if we got the status.
return codes are the same as driver_return_code_t
*/
driver_return_code_t
mmc_get_disctype( const CdIo_t *p_cdio, unsigned int i_timeout_ms,
cdio_mmc_disctype_t *p_disctype)
{
uint8_t buf[500] = { 0, };
driver_return_code_t i_status;
if (0 == i_timeout_ms) i_timeout_ms = mmc_timeout_ms;
i_status = mmc_get_configuration(p_cdio, &buf, sizeof(buf),
CDIO_MMC_GET_CONF_ALL_FEATURES,
0, i_timeout_ms);
if (DRIVER_OP_SUCCESS == i_status) {
uint8_t *p, *q;
uint8_t profiles_list_length;
uint16_t profile_number;
bool profile_active;
/* there is always a profile list feature listed at the
first place of the features list */
p = buf + 8;
profiles_list_length = p[3];
q = p+4;
*p_disctype = CDIO_MMC_DISCTYPE_NO_DISC;
while ((p_disctype == CDIO_MMC_DISCTYPE_NO_DISC) &&
(q < p + profiles_list_length)) {
profile_number = CDIO_MMC_GET_LEN16(q);
profile_active = q[2] & 0x01;
if (profile_active)
switch (profile_number) {
case 0x08: case 0x09: case 0x0A:
case 0x10: case 0x11: case 0x12:
case 0x13: case 0x14: case 0x15:
case 0x16: case 0x1A: case 0x1B:
case 0x2A: case 0x2B: case 0x40:
case 0x41: case 0x42: case 0x43:
case 0x50: case 0x51: case 0x52:
*p_disctype = (cdio_mmc_disctype_t) profile_number;
break;
}
q += 4;
}
}
return i_status;
}
/**
Run a SCSI-MMC MMC MODE SENSE command (6- or 10-byte version)
and put the results in p_buf
@@ -87,5 +149,5 @@ mmc_mode_sense(CdIo_t *p_cdio, /*out*/ void *p_buf, unsigned int i_size,
driver_return_code_t
mmc_set_drive_speed( const CdIo_t *p_cdio, int i_drive_speed )
{
return mmc_set_speed(p_cdio, i_drive_speed * 176);
return mmc_set_speed(p_cdio, i_drive_speed * 176, 0);
}

View File

@@ -50,7 +50,6 @@ mmc_prevent_allow_medium_removal(const CdIo_t *p_cdio,
uint8_t buf[8] = { 0, };
void *p_buf = &buf;
const unsigned int i_size = 0;
driver_return_code_t i_status;
MMC_CMD_SETUP(CDIO_MMC_GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL);
if (0 == i_timeout_ms) i_timeout_ms = mmc_timeout_ms;
@@ -60,6 +59,28 @@ mmc_prevent_allow_medium_removal(const CdIo_t *p_cdio,
return MMC_RUN_CMD(SCSI_MMC_DATA_WRITE, i_timeout_ms);
}
/**
Get drive capabilities vis SCSI-MMC GET CONFIGURATION
@param p_cdio the CD object to be acted upon.
@return DRIVER_OP_SUCCESS (0) if we got the status.
return codes are the same as driver_return_code_t
*/
driver_return_code_t
mmc_get_configuration(const CdIo_t *p_cdio, void *p_buf,
unsigned int i_size,
unsigned int return_type,
unsigned int i_starting_feature_number,
unsigned int i_timeout_ms)
{
MMC_CMD_SETUP(CDIO_MMC_GPCMD_GET_CONFIGURATION);
if (0 == i_timeout_ms) i_timeout_ms = mmc_timeout_ms;
cdb.field[1] = return_type & 0x3;
CDIO_MMC_SET_LEN16(cdb.field, 2, i_starting_feature_number);
return MMC_RUN_CMD(SCSI_MMC_DATA_READ, i_timeout_ms);
}
/**
Return results of media status
@param p_cdio the CD object to be acted upon.
@@ -335,12 +356,13 @@ mmc_read_cd(const CdIo_t *p_cdio, void *p_buf1, lsn_t i_lsn,
@return DRIVER_OP_SUCCESS if we ran the command ok.
*/
int
mmc_set_speed(const CdIo_t *p_cdio, int i_Kbs_speed)
mmc_set_speed(const CdIo_t *p_cdio, int i_Kbs_speed, unsigned int i_timeout_ms)
{
uint8_t buf[14] = { 0, };
void * p_buf = &buf;
const unsigned int i_size = sizeof(buf);
if (0 == i_timeout_ms) i_timeout_ms = mmc_timeout_ms;
MMC_CMD_SETUP(CDIO_MMC_GPCMD_SET_SPEED);
@@ -357,7 +379,7 @@ mmc_set_speed(const CdIo_t *p_cdio, int i_Kbs_speed)
the maximum allowable speed.
*/
CDIO_MMC_SET_LEN16(cdb.field, 4, 0xffff);
return MMC_RUN_CMD(SCSI_MMC_DATA_WRITE, mmc_timeout_ms);
return MMC_RUN_CMD(SCSI_MMC_DATA_WRITE, i_timeout_ms);
}
/**