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:
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user