mmc.h: TEST_UNIT_READY MMC command opcode

device.h: Add DRIVER_OP_MMC_SENSE to driver_return_code_t.

win32_ioctl.c: work around MS bug where buffer sizes are 0 or 1. Set
return code status if sense data passed back. Translate bad parameter
MS Windows error into a driver_return_code_t error.

test/driver/mmc.c: Reinstate old logic now that the MS Windows driver
has been made to work more like other drivers and copes with some of
the MS Windows causing failure here.
This commit is contained in:
R. Bernstein
2010-02-03 21:43:05 -05:00
parent 8083e17683
commit e3a5e16cbb
4 changed files with 437 additions and 354 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -113,6 +113,8 @@ extern "C" {
*/
typedef enum {
CDIO_MMC_TEST_UNIT_READY = 0x00, /**< Request drive
information. */
CDIO_MMC_GPCMD_INQUIRY = 0x12, /**< Request drive
information. */
CDIO_MMC_GPCMD_MODE_SELECT_6 = 0x15, /**< Select medium

View File

@@ -453,6 +453,8 @@ run_mmc_cmd_win32ioctl( void *p_user_data,
BOOL b_success;
DWORD dw_bytes_returned;
char dummy_buf[2]; /* Used if we can't use p_buf. See below. */
int rc = DRIVER_OP_SUCCESS;
memset(&swb, 0, sizeof(swb));
@@ -467,8 +469,20 @@ run_mmc_cmd_win32ioctl( void *p_user_data,
(SCSI_MMC_DATA_READ == e_direction) ? SCSI_IOCTL_DATA_IN :
(SCSI_MMC_DATA_WRITE == e_direction) ? SCSI_IOCTL_DATA_OUT :
SCSI_IOCTL_DATA_UNSPECIFIED;
swb.sptd.DataBuffer = p_buf;
swb.sptd.DataTransferLength= i_buf;
/* MS Windows seems to flip out of the size of the buffer is 0 or
1. For the 1 byte case see: BUG: SCSI Pass Through Fails with
Invalid User Buffer Error http://support.microsoft.com/kb/259573
So in those cases we will provide our own.
*/
if (i_buf <= 1) {
swb.sptd.DataBuffer = &dummy_buf;
swb.sptd.DataTransferLength = 2;
} else {
swb.sptd.DataBuffer = p_buf;
swb.sptd.DataTransferLength = i_buf;
}
swb.sptd.TimeOutValue = msecs2secs(i_timeout_ms);
swb.sptd.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER,
SenseBuf);
@@ -485,9 +499,18 @@ run_mmc_cmd_win32ioctl( void *p_user_data,
&dw_bytes_returned,
NULL);
if (i_buf == 1) memcpy(p_buf, &dummy_buf[0], 1);
if ( 0 == b_success ) {
windows_error(CDIO_LOG_INFO, GetLastError());
return DRIVER_OP_ERROR;
long int last_error = GetLastError();
windows_error(CDIO_LOG_INFO, last_error);
switch (last_error) {
case 87:
rc = DRIVER_OP_BAD_PARAMETER;
break;
default:
rc = DRIVER_OP_ERROR;
}
}
/* Record SCSI sense reply for API call mmc_last_cmd_sense().
@@ -500,9 +523,10 @@ run_mmc_cmd_win32ioctl( void *p_user_data,
sense_size = sizeof(swb.SenseBuf);
memcpy((void *) p_env->gen.scsi_mmc_sense, &swb.SenseBuf, sense_size);
p_env->gen.scsi_mmc_sense_valid = sense_size;
if (DRIVER_OP_SUCCESS == rc)
rc = DRIVER_OP_MMC_SENSE_DATA;
}
return DRIVER_OP_SUCCESS;
return rc;
}
#else
int

View File

@@ -146,21 +146,21 @@ tmmc_test_unit_ready(CdIo_t *p_cdio,
{
int i_status;
mmc_cdb_t cdb = {{0, }};
char buf[2]; /* just to have an address to pass to mmc_run_cmd() */
char buf[1]; /* just to have an address to pass to mmc_run_cmd() */
memset(cdb.field, 0, 6);
cdb.field[0] = 0x00; /* TEST UNIT READY, SPC-3 6.33 */
cdb.field[0] = CDIO_MMC_TEST_UNIT_READY; /* SPC-3 6.33 */
if (flag & 1)
fprintf(stderr, "tmmc_test_unit_ready ... ");
i_status = mmc_run_cmd(p_cdio, 10000, &cdb, SCSI_MMC_DATA_NONE, 2, buf);
i_status = mmc_run_cmd(p_cdio, 10000, &cdb, SCSI_MMC_DATA_NONE, 0, buf);
return tmmc_handle_outcome(p_cdio, i_status, sense_avail, sense_reply,
flag & 1);
}
/* OBTRUSIVE , PHYSICAL EFFECT , DANGER OF HUMAN INJURY */
/* OBTRUSIVE. PHYSICAL EFFECT: DANGER OF HUMAN INJURY */
/* @param flag bit0= verbose
bit1= Asynchronous operation
bit2= Load (else Eject)
@@ -188,7 +188,7 @@ tmmc_load_eject(CdIo_t *p_cdio, int *sense_avail,
}
/* BARELY OBTRUSIVE, MIGHT SPOIL BURN RUNS */
/* BARELY OBTRUSIVE: MIGHT SPOIL BURN RUNS */
/* Fetch a mode page or a part of it from the drive.
@param alloc_len The number of bytes to be requested from the drive and to
be copied into parameter buf.
@@ -241,7 +241,8 @@ tmmc_mode_sense(CdIo_t *p_cdio, int *sense_avail,unsigned char sense_reply[18],
}
/* OBTRUSIVE, SPOILS BURN RUNS , might return minor failure with -ROM drives */
/* OBTRUSIVE. SPOILS BURN RUNS and might return minor failure with
-ROM drives */
/* Send a mode page to the drive.
@param buf Contains the payload bytes. The first 8 shall be a Mode
Parameter Header as of SPC-3 7.4.3, table 240.
@@ -622,7 +623,6 @@ tmmc_test(char *drive_path, int flag)
drive_path, scsi_tuple);
#if 0
/* Test availability of sense reply in case of unready drive.
E.g. if the tray is already ejected.
*/
@@ -633,35 +633,32 @@ tmmc_test(char *drive_path, int flag)
sense_avail);
{ret = 2; goto ex;}
}
#endif
/* Cause sense reply failure by requesting inappropriate mode page 3Eh */
ret = tmmc_mode_sense(p_cdio, &sense_avail, sense,
0x3e, 0, alloc_len, buf, &buf_fill, !!verbose);
if (sense_avail < 18) {
if (ret != 0 && sense_avail < 18) {
fprintf(stderr,
"Error: An illegal command yields only %d sense bytes. Expected >= 18.\n",
sense_avail);
{ret = 2; goto ex;}
}
#if 0
/* Test availability of sense reply in case of unready drive.
E.g. if the tray is already ejected.
*/
ret = tmmc_test_unit_ready(p_cdio, &sense_avail, sense, !!verbose);
if (sense_avail < 18) {
if (ret != 0 && sense_avail < 18) {
fprintf(stderr,
"Error: Drive not ready. Only %d sense bytes. Expected >= 18.\n",
sense_avail);
{ret = 2; goto ex;}
}
#endif
/* Cause sense reply failure by requesting inappropriate mode page 3Eh */
ret = tmmc_mode_sense(p_cdio, &sense_avail, sense,
0x3e, 0, alloc_len, buf, &buf_fill, !!verbose);
if (sense_avail < 18) {
if (ret != 0 && sense_avail < 18) {
fprintf(stderr,
"Error: Deliberately illegal command yields only %d sense bytes. Expected >= 18.\n",
sense_avail);