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

@@ -397,7 +397,7 @@ void mmcSetBlocksize ( uint16_t i_blocksize)
*/ */
void mmcSetSpeed( int i_speed ) void mmcSetSpeed( int i_speed )
{ {
driver_return_code_t drc = mmc_set_speed( p_cdio, i_speed ); driver_return_code_t drc = mmc_set_speed( p_cdio, i_speed, 0);
possible_throw_device_exception(drc); possible_throw_device_exception(drc);
} }

View File

@@ -65,7 +65,7 @@ extern "C" {
include this for direct MMC access. include this for direct MMC access.
See SCSI Primary Commands-2 (SPC-3) table 26 page 38. See SCSI Primary Commands-2 (SPC-3) table 26 page 38.
*/ */
typedef struct mmc_request_sense { typedef struct cdio_mmc_request_sense {
#if defined(__MMC_BIG_ENDIAN_BITFIELD) #if defined(__MMC_BIG_ENDIAN_BITFIELD)
uint8_t valid : 1; /**< valid bit is 1 if info is valid */ uint8_t valid : 1; /**< valid bit is 1 if info is valid */
uint8_t error_code : 7; uint8_t error_code : 7;
@@ -101,27 +101,27 @@ extern "C" {
uint8_t fruc; /**< Field replaceable unit code */ uint8_t fruc; /**< Field replaceable unit code */
uint8_t sks[3]; /**< Sense-key specific */ uint8_t sks[3]; /**< Sense-key specific */
uint8_t asb[46]; /**< Additional sense bytes */ uint8_t asb[46]; /**< Additional sense bytes */
} mmc_request_sense_t; } cdio_mmc_request_sense_t;
/** /**
Meanings of the values of mmc_request_sense.sense_key Meanings of the values of mmc_request_sense.sense_key
*/ */
typedef enum { typedef enum {
MMC_SENSE_KEY_NO_SENSE = 0, CDIO_MMC_SENSE_KEY_NO_SENSE = 0,
MMC_SENSE_KEY_RECOVERED_ERROR = 1, CDIO_MMC_SENSE_KEY_RECOVERED_ERROR = 1,
MMC_SENSE_KEY_NOT_READY = 2, CDIO_MMC_SENSE_KEY_NOT_READY = 2,
MMC_SENSE_KEY_MEDIUM_ERROR = 3, CDIO_MMC_SENSE_KEY_MEDIUM_ERROR = 3,
MMC_SENSE_KEY_HARDWARE_ERROR = 4, CDIO_MMC_SENSE_KEY_HARDWARE_ERROR = 4,
MMC_SENSE_KEY_ILLEGAL_REQUEST = 5, CDIO_MMC_SENSE_KEY_ILLEGAL_REQUEST = 5,
MMC_SENSE_KEY_UNIT_ATTENTION = 6, CDIO_MMC_SENSE_KEY_UNIT_ATTENTION = 6,
MMC_SENSE_KEY_DATA_PROTECT = 7, CDIO_MMC_SENSE_KEY_DATA_PROTECT = 7,
MMC_SENSE_KEY_BLANK_CHECK = 8, CDIO_MMC_SENSE_KEY_BLANK_CHECK = 8,
MMC_SENSE_KEY_VENDOR_SPECIFIC = 9, CDIO_MMC_SENSE_KEY_VENDOR_SPECIFIC = 9,
MMC_SENSE_KEY_COPY_ABORTED = 10, CDIO_MMC_SENSE_KEY_COPY_ABORTED = 10,
MMC_SENSE_KEY_ABORTED_COMMAND = 11, CDIO_MMC_SENSE_KEY_ABORTED_COMMAND = 11,
MMC_SENSE_KEY_OBSOLTE = 12, CDIO_MMC_SENSE_KEY_OBSOLTE = 12,
} mmc_sense_key_t; } cdio_mmc_sense_key_t;
/** /**
Maps a mmc_sense_key_t into a string name. Maps a mmc_sense_key_t into a string name.
@@ -419,7 +419,7 @@ typedef enum {
/** /**
Profile profile codes used in GET_CONFIGURATION - PROFILE LIST. */ Profile profile codes used in GET_CONFIGURATION - PROFILE LIST. */
typedef enum { typedef enum {
CDIO_MMC_FEATURE_PROF_NON_REMOVABLE = 0x0001, /**< Re-writable disk, capable CDIO_MMC_FEATURE_PROF_NON_REMOVABLE = 0x0001, /**< Re-writable disc, capable
of changing behavior */ of changing behavior */
CDIO_MMC_FEATURE_PROF_REMOVABLE = 0x0002, /**< disk Re-writable; with CDIO_MMC_FEATURE_PROF_REMOVABLE = 0x0002, /**< disk Re-writable; with
removable media */ removable media */
@@ -483,6 +483,37 @@ typedef enum {
} cdio_mmc_feature_interface_t; } cdio_mmc_feature_interface_t;
typedef enum {
CDIO_MMC_DISCTYPE_NO_DISC = 0x00,
CDIO_MMC_DISCTYPE_CD_ROM = 0x08,
CDIO_MMC_DISCTYPE_CD_R = 0x09,
CDIO_MMC_DISCTYPE_CD_RW = 0x0A,
CDIO_MMC_DISCTYPE_DVD_ROM = 0x10,
CDIO_MMC_DISCTYPE_DVD_R = 0x11,
CDIO_MMC_DISCTYPE_DVD_RAM = 0x12,
CDIO_MMC_DISCTYPE_DVD_RW_RO = 0x13, /**< DVD-RW Restricted Overwrite */
CDIO_MMC_DISCTYPE_DVD_RW_SR = 0x14, /**< DVD-RW Sequential Recording */
CDIO_MMC_DISCTYPE_DVD_R_DL_SR = 0x15, /**< DVD-R Dual Layer Sequential
Recording */
CDIO_MMC_DISCTYPE_DVD_R_DL_JR = 0x16, /**< DVD-R Dual Layer Jump
Recording */
CDIO_MMC_DISCTYPE_DVD_PRW = 0x1A, /**< DVD+RW */
CDIO_MMC_DISCTYPE_DVD_PR = 0x1B, /**< DVD+R */
CDIO_MMC_DISCTYPE_DVD_PRW_DL = 0x2A, /**< DVD+RW Dual Layer */
CDIO_MMC_DISCTYPE_DVD_PR_DL = 0x2B, /**< DVD+R Dual Layer */
CDIO_MMC_DISCTYPE_BD_ROM = 0x40,
CDIO_MMC_DISCTYPE_BD_R_SR = 0x41, /**< Sequential Recording */
CDIO_MMC_DISCTYPE_BD_R_RR = 0x42, /**< Random Recording */
CDIO_MMC_DISCTYPE_BD_RE = 0x43,
CDIO_MMC_DISCTYPE_HD_DVD_ROM = 0x50,
CDIO_MMC_DISCTYPE_HD_DVD_R = 0x51,
CDIO_MMC_DISCTYPE_HD_DVD_RAM = 0x52
} cdio_mmc_disctype_t;
/** /**
The largest Command Descriptor Block (CDB) size. The largest Command Descriptor Block (CDB) size.
The possible sizes are 6, 10, and 12 bytes. The possible sizes are 6, 10, and 12 bytes.
@@ -760,7 +791,7 @@ mmc_audio_read_subchannel (CdIo_t *p_cdio,
string when done with it. string when done with it.
*/ */
char * mmc_get_mcn ( const CdIo_t *p_cdio ); char * mmc_get_mcn(const CdIo_t *p_cdio);
/** /**
Report if CD-ROM has a praticular kind of interface (ATAPI, SCSCI, ...) Report if CD-ROM has a praticular kind of interface (ATAPI, SCSCI, ...)
@@ -770,8 +801,16 @@ mmc_audio_read_subchannel (CdIo_t *p_cdio,
@param e_interface @param e_interface
@return true if we have the interface and false if not. @return true if we have the interface and false if not.
*/ */
bool_3way_t mmc_have_interface( CdIo_t *p_cdio, bool_3way_t mmc_have_interface(CdIo_t *p_cdio,
cdio_mmc_feature_interface_t e_interface ); cdio_mmc_feature_interface_t e_interface );
bool mmc_is_disctype_bd(cdio_mmc_disctype_t disctype);
bool mmc_is_disctype_cdrom(cdio_mmc_disctype_t disctype);
bool mmc_is_disctype_dvd(cdio_mmc_disctype_t disctype);
bool mmc_is_disctype_hd_dvd (cdio_mmc_disctype_t disctype);
bool mmc_is_disctype_overwritable (cdio_mmc_disctype_t disctype);
bool mmc_is_disctype_rewritable(cdio_mmc_disctype_t disctype);
/** /**
Read just the user data part of some sort of data sector (via Read just the user data part of some sort of data sector (via
@@ -867,7 +906,8 @@ mmc_audio_read_subchannel (CdIo_t *p_cdio,
@return number of valid bytes in sense, 0 in case of no sense @return number of valid bytes in sense, 0 in case of no sense
bytes available, <0 in case of internal error. bytes available, <0 in case of internal error.
*/ */
int mmc_last_cmd_sense ( const CdIo_t *p_cdio, mmc_request_sense_t **pp_sense); int mmc_last_cmd_sense ( const CdIo_t *p_cdio,
cdio_mmc_request_sense_t **pp_sense);
/** /**
Set the block size for subsequest read requests, via MMC. Set the block size for subsequest read requests, via MMC.
@@ -875,26 +915,6 @@ mmc_audio_read_subchannel (CdIo_t *p_cdio,
driver_return_code_t mmc_set_blocksize ( const CdIo_t *p_cdio, driver_return_code_t mmc_set_blocksize ( const CdIo_t *p_cdio,
uint16_t i_blocksize); uint16_t i_blocksize);
/**
Set the drive speed in CD-ROM speed units.
@param p_cdio CD structure set by cdio_open().
@param i_drive_speed speed in CD-ROM speed units. Note this
not Kbs as would be used in the MMC spec or
in mmc_set_speed(). To convert CD-ROM speed units
to Kbs, multiply the number by 176 (for raw data)
and by 150 (for filesystem data). On many CD-ROM
drives, specifying a value too large will result
in using the fastest speed.
@return the drive speed if greater than 0. -1 if we had an error. is -2
returned if this is not implemented for the current driver.
@see cdio_set_speed and mmc_set_speed
*/
driver_return_code_t mmc_set_drive_speed( const CdIo_t *p_cdio,
int i_drive_speed );
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */

View File

@@ -35,10 +35,42 @@
#ifndef __CDIO_MMC_CMDS_H__ #ifndef __CDIO_MMC_CMDS_H__
#define __CDIO_MMC_CMDS_H__ #define __CDIO_MMC_CMDS_H__
#include <cdio/mmc.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
/**
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);
/**
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);
/** /**
Eject using MMC commands. If CD-ROM is "locked" we'll unlock it. Eject using MMC commands. If CD-ROM is "locked" we'll unlock it.
Command is not "immediate" -- we'll wait for the command to complete. Command is not "immediate" -- we'll wait for the command to complete.
@@ -251,6 +283,26 @@ extern "C" {
uint8_t subchannel_selection, uint16_t i_blocksize, uint8_t subchannel_selection, uint16_t i_blocksize,
uint32_t i_blocks ); uint32_t i_blocks );
/**
Set the drive speed in CD-ROM speed units.
@param p_cdio CD structure set by cdio_open().
@param i_drive_speed speed in CD-ROM speed units. Note this
not Kbs as would be used in the MMC spec or
in mmc_set_speed(). To convert CD-ROM speed units
to Kbs, multiply the number by 176 (for raw data)
and by 150 (for filesystem data). On many CD-ROM
drives, specifying a value too large will result
in using the fastest speed.
@return the drive speed if greater than 0. -1 if we had an error. is -2
returned if this is not implemented for the current driver.
@see cdio_set_speed and mmc_set_speed
*/
driver_return_code_t mmc_set_drive_speed( const CdIo_t *p_cdio,
int i_drive_speed );
/** /**
Set the drive speed in K bytes per second using SCSI-MMC SET SPEED. Set the drive speed in K bytes per second using SCSI-MMC SET SPEED.
. .
@@ -268,13 +320,18 @@ extern "C" {
specifying a value too large will result in using specifying a value too large will result in using
the fastest speed. the fastest speed.
@param i_timeout_ms value in milliseconds to use on timeout. Setting
to 0 uses the default time-out value stored in
mmc_timeout_ms.
@return the drive speed if greater than 0. -1 if we had an error. is -2 @return the drive speed if greater than 0. -1 if we had an error. is -2
returned if this is not implemented for the current driver. returned if this is not implemented for the current driver.
@see cdio_set_speed and mmc_set_drive_speed @see cdio_set_speed and mmc_set_drive_speed
*/ */
driver_return_code_t mmc_set_speed( const CdIo_t *p_cdio, driver_return_code_t mmc_set_speed( const CdIo_t *p_cdio,
int i_Kbs_speed ); int i_Kbs_speed,
unsigned int i_timeout_ms);
/** /**
Load or Unload media using a MMC START STOP UNIT command. Load or Unload media using a MMC START STOP UNIT command.

View File

@@ -103,14 +103,14 @@ typedef struct _CDROM_TOC_FULL {
typedef struct { typedef struct {
SCSI_PASS_THROUGH_DIRECT sptd; SCSI_PASS_THROUGH_DIRECT sptd;
ULONG Filler; /* Realign buffer to double-word boundary */ ULONG Filler; /* Realign buffer to double-word boundary */
mmc_request_sense_t SenseBuf; cdio_mmc_request_sense_t SenseBuf;
UCHAR DataBuf[512]; UCHAR DataBuf[512];
} SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER; } SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER;
typedef struct _SCSI_PASS_THROUGH_WITH_BUFFER { typedef struct _SCSI_PASS_THROUGH_WITH_BUFFER {
SCSI_PASS_THROUGH Spt; SCSI_PASS_THROUGH Spt;
ULONG Filler; /* realign buffer to double-word boundary */ ULONG Filler; /* realign buffer to double-word boundary */
mmc_request_sense_t SenseBuf; cdio_mmc_request_sense_t SenseBuf;
UCHAR DataBuf[512]; UCHAR DataBuf[512];
} SCSI_PASS_THROUGH_WITH_BUFFER; } SCSI_PASS_THROUGH_WITH_BUFFER;

View File

@@ -34,7 +34,6 @@ static const char _rcsid[] = "$Id: gnu_linux.c,v 1.33 2008/06/25 07:46:21 rocky
#include <cdio/sector.h> #include <cdio/sector.h>
#include <cdio/util.h> #include <cdio/util.h>
#include <cdio/types.h> #include <cdio/types.h>
#include <cdio/mmc.h>
#include <cdio/mmc_cmds.h> #include <cdio/mmc_cmds.h>
#include <cdio/audio.h> #include <cdio/audio.h>
#include <cdio/cdtext.h> #include <cdio/cdtext.h>
@@ -1251,7 +1250,7 @@ run_mmc_cmd_linux(void *p_user_data,
{ {
_img_private_t *p_env = p_user_data; _img_private_t *p_env = p_user_data;
struct cdrom_generic_command cgc; struct cdrom_generic_command cgc;
mmc_request_sense_t sense; cdio_mmc_request_sense_t sense;
unsigned char *u_sense = (unsigned char *) &sense; unsigned char *u_sense = (unsigned char *) &sense;
p_env->gen.scsi_mmc_sense_valid = 0; p_env->gen.scsi_mmc_sense_valid = 0;

View File

@@ -200,19 +200,28 @@ mmc_feature2str
mmc_feature_profile2str mmc_feature_profile2str
mmc_get_blocksize mmc_get_blocksize
mmc_get_cmd_len mmc_get_cmd_len
mmc_get_configuration
mmc_get_discmode mmc_get_discmode
mmc_get_drive_mmc_cap mmc_get_drive_mmc_cap
mmc_get_dvd_struct_physical mmc_get_dvd_struct_physical
mmc_get_event_status
mmc_get_hwinfo mmc_get_hwinfo
mmc_get_last_lsn mmc_get_last_lsn
mmc_get_mcn mmc_get_mcn
mmc_get_media_changed mmc_get_media_changed
mmc_get_tray_status mmc_get_tray_status
mmc_have_interface mmc_have_interface
mmc_is_disctype_bd
mmc_is_disctype_cdrom
mmc_is_disctype_dvd
mmc_is_disctype_hd_dvd
mmc_is_disctype_overwritable
mmc_last_cmd_sense mmc_last_cmd_sense
mmc_mode_select_10
mmc_mode_sense mmc_mode_sense
mmc_mode_sense_10 mmc_mode_sense_10
mmc_mode_sense_6 mmc_mode_sense_6
mmc_prevent_allow_meduim_removal
mmc_read_cd mmc_read_cd
mmc_read_data_sectors mmc_read_data_sectors
mmc_read_sectors mmc_read_sectors
@@ -221,6 +230,6 @@ mmc_run_cmd
mmc_run_cmd_len mmc_run_cmd_len
mmc_set_blocksize mmc_set_blocksize
mmc_set_speed mmc_set_speed
mmc_start_stop_media mmc_start_stop_unit
mmc_timeout_ms mmc_timeout_ms
track_format2str track_format2str

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; generic_img_private_t *p_env = p_user_data;
if (!p_env) return DRIVER_OP_UNINIT; 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. bytes available, <0 in case of internal error.
*/ */
int 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; 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; 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. 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: * 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) Run a SCSI-MMC MMC MODE SENSE command (6- or 10-byte version)
and put the results in p_buf 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 driver_return_code_t
mmc_set_drive_speed( const CdIo_t *p_cdio, int i_drive_speed ) 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, }; uint8_t buf[8] = { 0, };
void *p_buf = &buf; void *p_buf = &buf;
const unsigned int i_size = 0; const unsigned int i_size = 0;
driver_return_code_t i_status;
MMC_CMD_SETUP(CDIO_MMC_GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL); MMC_CMD_SETUP(CDIO_MMC_GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL);
if (0 == i_timeout_ms) i_timeout_ms = mmc_timeout_ms; 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); 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 Return results of media status
@param p_cdio the CD object to be acted upon. @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. @return DRIVER_OP_SUCCESS if we ran the command ok.
*/ */
int 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, }; uint8_t buf[14] = { 0, };
void * p_buf = &buf; void * p_buf = &buf;
const unsigned int i_size = sizeof(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); 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. the maximum allowable speed.
*/ */
CDIO_MMC_SET_LEN16(cdb.field, 4, 0xffff); 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);
} }
/** /**

View File

@@ -437,7 +437,7 @@ main(int argc, char *argv[])
const operation_t *p_op = &operation[i]; const operation_t *p_op = &operation[i];
switch (p_op->op) { switch (p_op->op) {
case OP_SPEED: case OP_SPEED:
rc = mmc_set_speed(p_cdio, p_op->arg.i_num); rc = mmc_set_speed(p_cdio, p_op->arg.i_num, 0);
report(stdout, "%s (mmc_set_speed): %s\n", program_name, report(stdout, "%s (mmc_set_speed): %s\n", program_name,
cdio_driver_errmsg(rc)); cdio_driver_errmsg(rc));
break; break;

View File

@@ -55,7 +55,7 @@ static int tmmc_handle_outcome(CdIo_t *p_cdio, int i_status,
unsigned char sense_reply[18], int flag); unsigned char sense_reply[18], int flag);
static void tmmc_print_status_sense(int i_status, int sense_valid, static void tmmc_print_status_sense(int i_status, int sense_valid,
mmc_request_sense_t *, int flag); cdio_mmc_request_sense_t *, int flag);
static int tmmc_load_eject(CdIo_t *p_cdio, int *sense_avail, static int tmmc_load_eject(CdIo_t *p_cdio, int *sense_avail,
unsigned char sense_reply[18], int flag); unsigned char sense_reply[18], int flag);
@@ -98,7 +98,7 @@ tmmc_get_disc_erasable(const CdIo_t *p_cdio, const char *psz_source,
*/ */
static void static void
tmmc_print_status_sense(int i_status, int sense_valid, tmmc_print_status_sense(int i_status, int sense_valid,
mmc_request_sense_t *p_sense, int flag) cdio_mmc_request_sense_t *p_sense, int flag)
{ {
if (!(flag & 1)) if (!(flag & 1))
return; return;
@@ -119,7 +119,7 @@ static int
tmmc_handle_outcome(CdIo_t *p_cdio, int i_status, tmmc_handle_outcome(CdIo_t *p_cdio, int i_status,
int *sense_avail, unsigned char sense_reply[18], int flag) int *sense_avail, unsigned char sense_reply[18], int flag)
{ {
mmc_request_sense_t *p_sense = NULL; cdio_mmc_request_sense_t *p_sense = NULL;
*sense_avail = mmc_last_cmd_sense(p_cdio, &p_sense); *sense_avail = mmc_last_cmd_sense(p_cdio, &p_sense);
tmmc_print_status_sense(i_status, *sense_avail, p_sense, flag & 1); tmmc_print_status_sense(i_status, *sense_avail, p_sense, flag & 1);
@@ -295,7 +295,7 @@ tmmc_wait_for_drive(CdIo_t *p_cdio, int max_tries, int flag)
{ {
int ret, i, sense_avail; int ret, i, sense_avail;
unsigned char sense_reply[18]; unsigned char sense_reply[18];
mmc_request_sense_t *p_sense_reply = (mmc_request_sense_t *) sense_reply; cdio_mmc_request_sense_t *p_sense_reply = (cdio_mmc_request_sense_t *) sense_reply;
for (i = 0; i < max_tries; i++) { for (i = 0; i < max_tries; i++) {
ret = tmmc_test_unit_ready(p_cdio, &sense_avail, sense_reply, flag & 1); ret = tmmc_test_unit_ready(p_cdio, &sense_avail, sense_reply, flag & 1);