MS Windows iocontrol SCSI Passthrough fixes. Change test/driver/mmc.c - we
can't that when we get sense data, that we also gegt status back that pass through fails. On MS Windows it doesn't seem to work that way.
This commit is contained in:
@@ -23,8 +23,6 @@
|
|||||||
# include "config.h"
|
# include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const char _rcsid[] = "$Id: win32_ioctl.c,v 1.30 2008/04/21 18:30:21 karl Exp $";
|
|
||||||
|
|
||||||
#ifdef HAVE_WIN32_CDROM
|
#ifdef HAVE_WIN32_CDROM
|
||||||
|
|
||||||
#if defined (_XBOX)
|
#if defined (_XBOX)
|
||||||
@@ -232,8 +230,7 @@ audio_read_subchannel_win32ioctl (void *p_user_data,
|
|||||||
return DRIVER_OP_SUCCESS;
|
return DRIVER_OP_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
/*!
|
|
||||||
Resume playing an audio CD.
|
Resume playing an audio CD.
|
||||||
|
|
||||||
@param p_user_data the CD object to be acted upon.
|
@param p_user_data the CD object to be acted upon.
|
||||||
@@ -256,7 +253,7 @@ audio_resume_win32ioctl (void *p_user_data)
|
|||||||
return DRIVER_OP_SUCCESS;
|
return DRIVER_OP_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/**
|
||||||
Set the volume of an audio CD.
|
Set the volume of an audio CD.
|
||||||
|
|
||||||
@param p_user_data pointer to the CD object to be acted upon.
|
@param p_user_data pointer to the CD object to be acted upon.
|
||||||
@@ -302,7 +299,7 @@ audio_get_volume_win32ioctl (void *p_user_data,
|
|||||||
return DRIVER_OP_SUCCESS;
|
return DRIVER_OP_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/**
|
||||||
Stop playing an audio CD.
|
Stop playing an audio CD.
|
||||||
|
|
||||||
@param p_user_data the CD object to be acted upon.
|
@param p_user_data the CD object to be acted upon.
|
||||||
@@ -325,7 +322,7 @@ audio_stop_win32ioctl (void *p_user_data)
|
|||||||
return DRIVER_OP_SUCCESS;
|
return DRIVER_OP_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/**
|
||||||
Close the tray of a CD-ROM
|
Close the tray of a CD-ROM
|
||||||
|
|
||||||
@param p_user_data the CD object to be acted upon.
|
@param p_user_data the CD object to be acted upon.
|
||||||
@@ -340,7 +337,7 @@ close_tray_win32ioctl (const char *psz_win32_drive)
|
|||||||
|
|
||||||
OSVERSIONINFO ov;
|
OSVERSIONINFO ov;
|
||||||
HANDLE h_device_handle;
|
HANDLE h_device_handle;
|
||||||
bool b_success;
|
BOOL b_success;
|
||||||
|
|
||||||
memset(&ov,0,sizeof(OSVERSIONINFO));
|
memset(&ov,0,sizeof(OSVERSIONINFO));
|
||||||
ov.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
|
ov.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
|
||||||
@@ -356,7 +353,7 @@ close_tray_win32ioctl (const char *psz_win32_drive)
|
|||||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
NULL,
|
NULL,
|
||||||
OPEN_EXISTING,
|
OPEN_EXISTING,
|
||||||
FILE_ATTRIBUTE_NORMAL,
|
0,
|
||||||
NULL );
|
NULL );
|
||||||
|
|
||||||
if( h_device_handle == INVALID_HANDLE_VALUE ) {
|
if( h_device_handle == INVALID_HANDLE_VALUE ) {
|
||||||
@@ -370,7 +367,7 @@ close_tray_win32ioctl (const char *psz_win32_drive)
|
|||||||
|
|
||||||
CloseHandle(h_device_handle);
|
CloseHandle(h_device_handle);
|
||||||
|
|
||||||
if ( ! b_success ) {
|
if ( b_success != 0 ) {
|
||||||
windows_error(CDIO_LOG_INFO, GetLastError());
|
windows_error(CDIO_LOG_INFO, GetLastError());
|
||||||
return DRIVER_OP_ERROR;
|
return DRIVER_OP_ERROR;
|
||||||
}
|
}
|
||||||
@@ -380,7 +377,7 @@ close_tray_win32ioctl (const char *psz_win32_drive)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/**
|
||||||
Produce a text composed from the system SCSI address tuple
|
Produce a text composed from the system SCSI address tuple
|
||||||
"Port,Path,Target,Lun" and store
|
"Port,Path,Target,Lun" and store
|
||||||
it in generic_img_private_t.scsi_tuple.
|
it in generic_img_private_t.scsi_tuple.
|
||||||
@@ -428,7 +425,7 @@ set_scsi_tuple_win32ioctl(_img_private_t *env)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*!
|
/**
|
||||||
Run a SCSI MMC command.
|
Run a SCSI MMC command.
|
||||||
|
|
||||||
env private CD structure
|
env private CD structure
|
||||||
@@ -443,7 +440,7 @@ set_scsi_tuple_win32ioctl(_img_private_t *env)
|
|||||||
|
|
||||||
Return 0 if command completed successfully.
|
Return 0 if command completed successfully.
|
||||||
*/
|
*/
|
||||||
#if 0
|
#if 1
|
||||||
int
|
int
|
||||||
run_mmc_cmd_win32ioctl( void *p_user_data,
|
run_mmc_cmd_win32ioctl( void *p_user_data,
|
||||||
unsigned int i_timeout_ms,
|
unsigned int i_timeout_ms,
|
||||||
@@ -452,66 +449,55 @@ run_mmc_cmd_win32ioctl( void *p_user_data,
|
|||||||
unsigned int i_buf, /*in/out*/ void *p_buf )
|
unsigned int i_buf, /*in/out*/ void *p_buf )
|
||||||
{
|
{
|
||||||
_img_private_t *p_env = p_user_data;
|
_img_private_t *p_env = p_user_data;
|
||||||
SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER sptdwb;
|
SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER swb;
|
||||||
|
|
||||||
bool b_success;
|
BOOL b_success;
|
||||||
unsigned long length = 0;
|
|
||||||
DWORD dw_bytes_returned;
|
DWORD dw_bytes_returned;
|
||||||
|
|
||||||
memset(&sptdwb, 0, sizeof(sptdwb));
|
memset(&swb, 0, sizeof(swb));
|
||||||
|
|
||||||
sptdwb.sptd.Length = sizeof(sptdwb.sptd);
|
swb.sptd.Length = sizeof(SCSI_PASS_THROUGH_DIRECT);
|
||||||
sptdwb.sptd.PathId = 0; /* SCSI card ID will be filled in
|
swb.sptd.PathId = 0; /* SCSI card ID will be filled in
|
||||||
automatically */
|
automatically */
|
||||||
sptdwb.sptd.TargetId= 0; /* SCSI target ID will also be filled in */
|
swb.sptd.TargetId= 0; /* SCSI target ID will also be filled in */
|
||||||
sptdwb.sptd.Lun = 0; /* SCSI lun ID will also be filled in */
|
swb.sptd.Lun = 0; /* SCSI lun ID will also be filled in */
|
||||||
sptdwb.sptd.CdbLength = i_cdb;
|
swb.sptd.CdbLength = i_cdb;
|
||||||
sptdwb.sptd.SenseInfoLength = sizeof(sptdwb.ucSenseBuf);
|
swb.sptd.SenseInfoLength = sizeof(swb.ucSenseBuf);
|
||||||
sptdwb.sptd.DataIn =
|
swb.sptd.DataIn =
|
||||||
(SCSI_MMC_DATA_READ == e_direction) ? SCSI_IOCTL_DATA_IN :
|
(SCSI_MMC_DATA_READ == e_direction) ? SCSI_IOCTL_DATA_IN :
|
||||||
(SCSI_MMC_DATA_WRITE == e_direction) ? SCSI_IOCTL_DATA_OUT :
|
(SCSI_MMC_DATA_WRITE == e_direction) ? SCSI_IOCTL_DATA_OUT :
|
||||||
SCSI_IOCTL_DATA_UNSPECIFIED;
|
SCSI_IOCTL_DATA_UNSPECIFIED;
|
||||||
sptdwb.sptd.DataTransferLength= i_buf;
|
swb.sptd.DataBuffer = p_buf;
|
||||||
sptdwb.sptd.TimeOutValue = msecs2secs(i_timeout_ms);
|
swb.sptd.DataTransferLength= i_buf;
|
||||||
|
swb.sptd.TimeOutValue = msecs2secs(i_timeout_ms);
|
||||||
|
swb.sptd.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, ucSenseBuf);
|
||||||
|
|
||||||
sptdwb.sptd.DataBuffer = (void *) p_buf;
|
memcpy(swb.sptd.Cdb, p_cdb, i_cdb);
|
||||||
/*
|
|
||||||
sptdwb.sptd.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER,
|
|
||||||
ucSenseBuf);
|
|
||||||
*/
|
|
||||||
sptdwb.sptd.SenseInfoOffset = 0;
|
|
||||||
|
|
||||||
memcpy(sptdwb.sptd.Cdb, p_cdb, i_cdb);
|
|
||||||
length = offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER,DataBuf) +
|
|
||||||
sptdwb.sptd.DataTransferLength;
|
|
||||||
|
|
||||||
/* Send the command to drive */
|
/* Send the command to drive */
|
||||||
b_success = DeviceIoControl(p_env->h_device_handle,
|
b_success = DeviceIoControl(p_env->h_device_handle,
|
||||||
IOCTL_SCSI_PASS_THROUGH,
|
IOCTL_SCSI_PASS_THROUGH_DIRECT,
|
||||||
(void *)&sptdwb,
|
(void *)&swb,
|
||||||
sizeof(SCSI_PASS_THROUGH),
|
sizeof(swb),
|
||||||
NULL, 0,
|
&swb,
|
||||||
/*
|
sizeof(swb),
|
||||||
&sptdwb,
|
|
||||||
length,
|
|
||||||
*/
|
|
||||||
&dw_bytes_returned,
|
&dw_bytes_returned,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if ( !b_success ) {
|
if ( 0 == b_success ) {
|
||||||
windows_error(CDIO_LOG_INFO, GetLastError());
|
windows_error(CDIO_LOG_INFO, GetLastError());
|
||||||
return DRIVER_OP_ERROR;
|
return DRIVER_OP_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Record SCSI sense reply for API call mmc_last_cmd_sense().
|
/* Record SCSI sense reply for API call mmc_last_cmd_sense().
|
||||||
*/
|
*/
|
||||||
if (sptdwb.ucSenseBuf[7]) {
|
if (swb.ucSenseBuf[7]) {
|
||||||
int sense_size = sptdwb.ucSenseBuf[7] + 8; /* SPC 4.5.3, Table 26:
|
int sense_size = swb.ucSenseBuf[7] + 8; /* SPC 4.5.3, Table 26:
|
||||||
252 bytes legal, 263 bytes
|
252 bytes legal, 263 bytes
|
||||||
possible */
|
possible */
|
||||||
if (sense_size > sizeof(sptdwb.ucSenseBuf))
|
if (sense_size > sizeof(swb.ucSenseBuf))
|
||||||
sense_size = sizeof(sptdwb.ucSenseBuf);
|
sense_size = sizeof(swb.ucSenseBuf);
|
||||||
memcpy((void *) p_env->gen.scsi_mmc_sense, &sptdwb.ucSenseBuf, sense_size);
|
memcpy((void *) p_env->gen.scsi_mmc_sense, &swb.ucSenseBuf, sense_size);
|
||||||
p_env->gen.scsi_mmc_sense_valid = sense_size;
|
p_env->gen.scsi_mmc_sense_valid = sense_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -528,7 +514,7 @@ run_mmc_cmd_win32ioctl( void *p_user_data,
|
|||||||
_img_private_t *p_env = p_user_data;
|
_img_private_t *p_env = p_user_data;
|
||||||
SCSI_PASS_THROUGH_WITH_BUFFER sptwb;
|
SCSI_PASS_THROUGH_WITH_BUFFER sptwb;
|
||||||
|
|
||||||
bool b_success;
|
BOOL b_success;
|
||||||
unsigned long length = 0;
|
unsigned long length = 0;
|
||||||
DWORD dw_bytes_returned;
|
DWORD dw_bytes_returned;
|
||||||
|
|
||||||
@@ -571,7 +557,7 @@ run_mmc_cmd_win32ioctl( void *p_user_data,
|
|||||||
&dw_bytes_returned,
|
&dw_bytes_returned,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if ( !b_success ) {
|
if ( 0 == b_success ) {
|
||||||
windows_error(CDIO_LOG_INFO, GetLastError());
|
windows_error(CDIO_LOG_INFO, GetLastError());
|
||||||
return DRIVER_OP_ERROR;
|
return DRIVER_OP_ERROR;
|
||||||
}
|
}
|
||||||
@@ -594,7 +580,7 @@ run_mmc_cmd_win32ioctl( void *p_user_data,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*!
|
/**
|
||||||
Get disc type associated with cd object.
|
Get disc type associated with cd object.
|
||||||
*/
|
*/
|
||||||
static discmode_t
|
static discmode_t
|
||||||
@@ -627,7 +613,7 @@ dvd_discmode_win32ioctl (_img_private_t *p_env)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/**
|
||||||
Get disc type associated with cd object.
|
Get disc type associated with cd object.
|
||||||
*/
|
*/
|
||||||
discmode_t
|
discmode_t
|
||||||
@@ -738,7 +724,7 @@ is_cdrom_win32ioctl(const char c_drive_letter)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/**
|
||||||
Reads an audio device using the DeviceIoControl method into data
|
Reads an audio device using the DeviceIoControl method into data
|
||||||
starting from lsn. Returns 0 if no error.
|
starting from lsn. Returns 0 if no error.
|
||||||
*/
|
*/
|
||||||
@@ -767,7 +753,7 @@ read_audio_sectors_win32ioctl (_img_private_t *p_env, void *data, lsn_t lsn,
|
|||||||
return DRIVER_OP_SUCCESS;
|
return DRIVER_OP_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/**
|
||||||
Reads a single raw sector using the DeviceIoControl method into
|
Reads a single raw sector using the DeviceIoControl method into
|
||||||
data starting from lsn. Returns 0 if no error.
|
data starting from lsn. Returns 0 if no error.
|
||||||
*/
|
*/
|
||||||
@@ -789,7 +775,7 @@ read_raw_sector (_img_private_t *p_env, void *p_buf, lsn_t lsn)
|
|||||||
CDIO_CD_FRAMESIZE_RAW, p_buf);
|
CDIO_CD_FRAMESIZE_RAW, p_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/**
|
||||||
Reads a single mode2 sector using the DeviceIoControl method into
|
Reads a single mode2 sector using the DeviceIoControl method into
|
||||||
data starting from lsn. Returns 0 if no error.
|
data starting from lsn. Returns 0 if no error.
|
||||||
*/
|
*/
|
||||||
@@ -810,7 +796,7 @@ read_mode2_sector_win32ioctl (_img_private_t *p_env, void *p_data,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/**
|
||||||
Reads a single mode2 sector using the DeviceIoControl method into
|
Reads a single mode2 sector using the DeviceIoControl method into
|
||||||
data starting from lsn. Returns 0 if no error.
|
data starting from lsn. Returns 0 if no error.
|
||||||
*/
|
*/
|
||||||
@@ -831,7 +817,7 @@ read_mode1_sector_win32ioctl (_img_private_t *env, void *data,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/**
|
||||||
Initialize internal structures for CD device.
|
Initialize internal structures for CD device.
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
@@ -897,7 +883,7 @@ init_win32ioctl (_img_private_t *env)
|
|||||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||||
NULL,
|
NULL,
|
||||||
OPEN_EXISTING,
|
OPEN_EXISTING,
|
||||||
FILE_ATTRIBUTE_NORMAL,
|
0,
|
||||||
NULL );
|
NULL );
|
||||||
|
|
||||||
if( env->h_device_handle == INVALID_HANDLE_VALUE )
|
if( env->h_device_handle == INVALID_HANDLE_VALUE )
|
||||||
@@ -909,7 +895,7 @@ init_win32ioctl (_img_private_t *env)
|
|||||||
FILE_SHARE_READ,
|
FILE_SHARE_READ,
|
||||||
NULL,
|
NULL,
|
||||||
OPEN_EXISTING,
|
OPEN_EXISTING,
|
||||||
FILE_ATTRIBUTE_NORMAL,
|
0,
|
||||||
NULL );
|
NULL );
|
||||||
if (env->h_device_handle == NULL)
|
if (env->h_device_handle == NULL)
|
||||||
return false;
|
return false;
|
||||||
@@ -922,7 +908,7 @@ init_win32ioctl (_img_private_t *env)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/**
|
||||||
Read and cache the CD's Track Table of Contents and track info.
|
Read and cache the CD's Track Table of Contents and track info.
|
||||||
via a SCSI MMC READ_TOC (FULTOC). Return true if successful or
|
via a SCSI MMC READ_TOC (FULTOC). Return true if successful or
|
||||||
false if an error.
|
false if an error.
|
||||||
@@ -1026,7 +1012,7 @@ read_fulltoc_win32mmc (_img_private_t *p_env)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/**
|
||||||
Read and cache the CD's Track Table of Contents and track info.
|
Read and cache the CD's Track Table of Contents and track info.
|
||||||
Return true if successful or false if an error.
|
Return true if successful or false if an error.
|
||||||
*/
|
*/
|
||||||
@@ -1114,7 +1100,7 @@ read_toc_win32ioctl (_img_private_t *p_env)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/**
|
||||||
Return the media catalog number MCN.
|
Return the media catalog number MCN.
|
||||||
|
|
||||||
Note: string is malloc'd so caller should free() then returned
|
Note: string is malloc'd so caller should free() then returned
|
||||||
@@ -1148,7 +1134,7 @@ get_mcn_win32ioctl (const _img_private_t *p_env) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/**
|
||||||
Get the format (XA, DATA, AUDIO) of a track.
|
Get the format (XA, DATA, AUDIO) of a track.
|
||||||
*/
|
*/
|
||||||
track_format_t
|
track_format_t
|
||||||
|
|||||||
@@ -146,14 +146,14 @@ tmmc_test_unit_ready(CdIo_t *p_cdio,
|
|||||||
{
|
{
|
||||||
int i_status;
|
int i_status;
|
||||||
mmc_cdb_t cdb = {{0, }};
|
mmc_cdb_t cdb = {{0, }};
|
||||||
char buf[1]; /* just to have an address to pass to mmc_run_cmd() */
|
char buf[2]; /* just to have an address to pass to mmc_run_cmd() */
|
||||||
|
|
||||||
memset(cdb.field, 0, 6);
|
memset(cdb.field, 0, 6);
|
||||||
cdb.field[0] = 0x00; /* TEST UNIT READY, SPC-3 6.33 */
|
cdb.field[0] = 0x00; /* TEST UNIT READY, SPC-3 6.33 */
|
||||||
|
|
||||||
if (flag & 1)
|
if (flag & 1)
|
||||||
fprintf(stderr, "tmmc_test_unit_ready ... ");
|
fprintf(stderr, "tmmc_test_unit_ready ... ");
|
||||||
i_status = mmc_run_cmd(p_cdio, 10000, &cdb, SCSI_MMC_DATA_NONE, 0, buf);
|
i_status = mmc_run_cmd(p_cdio, 10000, &cdb, SCSI_MMC_DATA_NONE, 2, buf);
|
||||||
|
|
||||||
return tmmc_handle_outcome(p_cdio, i_status, sense_avail, sense_reply,
|
return tmmc_handle_outcome(p_cdio, i_status, sense_avail, sense_reply,
|
||||||
flag & 1);
|
flag & 1);
|
||||||
@@ -635,100 +635,90 @@ tmmc_test(char *drive_path, int flag)
|
|||||||
/* Cause sense reply failure by requesting inappropriate mode page 3Eh */
|
/* Cause sense reply failure by requesting inappropriate mode page 3Eh */
|
||||||
ret = tmmc_mode_sense(p_cdio, &sense_avail, sense,
|
ret = tmmc_mode_sense(p_cdio, &sense_avail, sense,
|
||||||
0x3e, 0, alloc_len, buf, &buf_fill, !!verbose);
|
0x3e, 0, alloc_len, buf, &buf_fill, !!verbose);
|
||||||
if (ret != 0 && sense_avail < 18) {
|
if (sense_avail < 18) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Error: An illegal command yields only %d sense bytes. Expected >= 18.\n",
|
"Error: An illegal command yields only %d sense bytes. Expected >= 18.\n",
|
||||||
sense_avail);
|
sense_avail);
|
||||||
{ret = 2; goto ex;}
|
{ret = 2; goto ex;}
|
||||||
} else if(ret == 0) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"Warning: tmmc_mode_sense() cannot cause a failure via mode page 3Eh\n");
|
|
||||||
fprintf(stderr,
|
|
||||||
"Consider to set in tmmc_test(): with_tray_dance = 1\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Test availability of sense reply in case of unready drive.
|
/* Test availability of sense reply in case of unready drive.
|
||||||
E.g. if the tray is already ejected.
|
E.g. if the tray is already ejected.
|
||||||
*/
|
*/
|
||||||
ret = tmmc_test_unit_ready(p_cdio, &sense_avail, sense, !!verbose);
|
ret = tmmc_test_unit_ready(p_cdio, &sense_avail, sense, !!verbose);
|
||||||
if (ret != 0 && sense_avail < 18) {
|
if (sense_avail < 18) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Error: Drive not ready. Only %d sense bytes. Expected >= 18.\n",
|
"Error: Drive not ready. Only %d sense bytes. Expected >= 18.\n",
|
||||||
sense_avail);
|
sense_avail);
|
||||||
{ret = 2; goto ex;}
|
{ret = 2; goto ex;}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Provoke sense reply by requesting inappropriate mode page 3Eh */
|
/* Cause sense reply failure by requesting inappropriate mode page 3Eh */
|
||||||
ret = tmmc_mode_sense(p_cdio, &sense_avail, sense,
|
ret = tmmc_mode_sense(p_cdio, &sense_avail, sense,
|
||||||
0x3e, 0, alloc_len, buf, &buf_fill, !!verbose);
|
0x3e, 0, alloc_len, buf, &buf_fill, !!verbose);
|
||||||
if (ret != 0 && sense_avail < 18) {
|
if (sense_avail < 18) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Error: Deliberately illegal command yields only %d sense bytes. Expected >= 18.\n",
|
"Error: Deliberately illegal command yields only %d sense bytes. Expected >= 18.\n",
|
||||||
sense_avail);
|
sense_avail);
|
||||||
{ret = 2; goto ex;}
|
{ret = 2; goto ex;}
|
||||||
} else if(ret == 0) {
|
}
|
||||||
fprintf(stderr,
|
|
||||||
"Warning: tmmc_mode_sense() cannot cause failure via mode page 3Eh\n");
|
|
||||||
fprintf(stderr,
|
if (emul_lack_of_wperm) { /* To check behavior with lack of w-permission */
|
||||||
"Consider to set in tmmc_test(): with_tray_dance = 1\n");
|
fprintf(stderr,
|
||||||
|
"tmmc_test: SIMULATING LACK OF WRITE CAPABILITIES by access mode IOCTL\n");
|
||||||
|
cdio_destroy(p_cdio);
|
||||||
|
p_cdio = cdio_open_am(drive_path, DRIVER_DEVICE, "IOCTL");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Test write permission */ /* Try whether a mode page 2Ah can be set */
|
||||||
|
ret = tmmc_rwr_mode_page(p_cdio, !!verbose);
|
||||||
|
if (ret <= 0) {
|
||||||
|
if (ret < 0) {
|
||||||
|
fprintf(stderr, "Error: tmmc_rwr_mode_page() had severe failure.\n");
|
||||||
|
{ret = 3; goto ex;}
|
||||||
}
|
}
|
||||||
|
fprintf(stderr, "Warning: tmmc_rwr_mode_page() had minor failure.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if (emul_lack_of_wperm) { /* To check behavior with lack of w-permission */
|
if (with_tray_dance) {
|
||||||
fprintf(stderr,
|
/* More surely provoke a non-trivial sense reply */
|
||||||
"tmmc_test: SIMULATING LACK OF WRITE CAPABILITIES by access mode IOCTL\n");
|
if (test_cycle_with_media) {
|
||||||
cdio_destroy(p_cdio);
|
/* Eject, wait, load, watch by test unit ready loop */
|
||||||
p_cdio = cdio_open_am(drive_path, DRIVER_DEVICE, "IOCTL");
|
ret = tmmc_eject_load_cycle(p_cdio, 2 | !!verbose);
|
||||||
}
|
if (ret <= 0) {
|
||||||
|
if (ret < 0) {
|
||||||
|
|
||||||
/* Test write permission */ /* Try whether a mode page 2Ah can be set */
|
|
||||||
ret = tmmc_rwr_mode_page(p_cdio, !!verbose);
|
|
||||||
if (ret <= 0) {
|
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr, "Error: tmmc_rwr_mode_page() had severe failure.\n");
|
|
||||||
{ret = 3; goto ex;}
|
|
||||||
}
|
|
||||||
fprintf(stderr, "Warning: tmmc_rwr_mode_page() had minor failure.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (with_tray_dance) {
|
|
||||||
/* More surely provoke a non-trivial sense reply */
|
|
||||||
if (test_cycle_with_media) {
|
|
||||||
/* Eject, wait, load, watch by test unit ready loop */
|
|
||||||
ret = tmmc_eject_load_cycle(p_cdio, 2 | !!verbose);
|
|
||||||
if (ret <= 0) {
|
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"Error: tmmc_eject_load_cycle() had severe failure.\n");
|
|
||||||
{ret = 4; goto ex;}
|
|
||||||
}
|
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Warning: tmmc_eject_load_cycle() had minor failure.\n");
|
"Error: tmmc_eject_load_cycle() had severe failure.\n");
|
||||||
|
{ret = 4; goto ex;}
|
||||||
}
|
}
|
||||||
} else {
|
fprintf(stderr,
|
||||||
/* Eject, test for proper unreadiness, load */
|
"Warning: tmmc_eject_load_cycle() had minor failure.\n");
|
||||||
ret = tmmc_eject_test_load(p_cdio, !!verbose);
|
|
||||||
if (ret <= 0) {
|
|
||||||
if (ret < 0) {
|
|
||||||
fprintf(stderr,
|
|
||||||
"Error: tmmc_eject_test_load() had severe failure.\n");
|
|
||||||
{ret = 5; goto ex;}
|
|
||||||
}
|
|
||||||
fprintf(stderr,
|
|
||||||
"Warning: tmmc_eject_test_load() had minor failure.\n");
|
|
||||||
}
|
|
||||||
/* Wait for drive attention */
|
|
||||||
tmmc_wait_for_drive(p_cdio, 15, 2 | !!verbose);
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
/* Eject, test for proper unreadiness, load */
|
||||||
|
ret = tmmc_eject_test_load(p_cdio, !!verbose);
|
||||||
|
if (ret <= 0) {
|
||||||
|
if (ret < 0) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Error: tmmc_eject_test_load() had severe failure.\n");
|
||||||
|
{ret = 5; goto ex;}
|
||||||
|
}
|
||||||
|
fprintf(stderr,
|
||||||
|
"Warning: tmmc_eject_test_load() had minor failure.\n");
|
||||||
|
}
|
||||||
|
/* Wait for drive attention */
|
||||||
|
tmmc_wait_for_drive(p_cdio, 15, 2 | !!verbose);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* How are we, finally ? */
|
/* How are we, finally ? */
|
||||||
ret = tmmc_test_unit_ready(p_cdio, &sense_valid, sense, !!verbose);
|
ret = tmmc_test_unit_ready(p_cdio, &sense_valid, sense, !!verbose);
|
||||||
if ((flag & 1) && ret != 0 && sense[2] == 2 && sense[12] == 0x3a)
|
if ((flag & 1) && ret != 0 && sense[2] == 2 && sense[12] == 0x3a)
|
||||||
fprintf(stderr, "tmmc_test: Note: No loaded media detected.\n");
|
fprintf(stderr, "tmmc_test: Note: No loaded media detected.\n");
|
||||||
ret = 0;
|
ret = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ex:;
|
ex:;
|
||||||
@@ -785,8 +775,7 @@ main(int argc, const char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( psz_have_mmc
|
if ( psz_have_mmc
|
||||||
&& 0 == strncmp("true", psz_have_mmc, sizeof("true"))
|
&& 0 == strncmp("true", psz_have_mmc, sizeof("true")) ) {
|
||||||
&& (DRIVER_WIN32 != cdio_get_driver_id(p_cdio)) ) {
|
|
||||||
scsi_tuple = cdio_get_arg(p_cdio, "scsi-tuple");
|
scsi_tuple = cdio_get_arg(p_cdio, "scsi-tuple");
|
||||||
if (scsi_tuple == NULL) {
|
if (scsi_tuple == NULL) {
|
||||||
fprintf(stderr, "cdio_get_arg(\"scsi-tuple\") returns NULL.\n");
|
fprintf(stderr, "cdio_get_arg(\"scsi-tuple\") returns NULL.\n");
|
||||||
|
|||||||
Reference in New Issue
Block a user