Recording and retrieval of SCSI sense reply for GNU/Linux.

This commit is contained in:
R. Bernstein
2009-12-25 08:45:48 -05:00
parent c498cec5e1
commit a3ed634fe5
4 changed files with 62 additions and 28 deletions

1
NEWS
View File

@@ -2,6 +2,7 @@ version 0.83 (git)
- Add Recording and retrieval of SCSI sense reply. - Add Recording and retrieval of SCSI sense reply.
- Add Write/burning interface. - Add Write/burning interface.
- MMC bug fixes
- Tolerance for OS's without timezone in their struct tm (e.g. Solaris) - Tolerance for OS's without timezone in their struct tm (e.g. Solaris)
added iso9660_set_{d,l}time_with_timezone added iso9660_set_{d,l}time_with_timezone

1
THANKS
View File

@@ -64,6 +64,7 @@ xboxmediacenter team (www.xboxmediacenter.de)
Thomas Schmitt Thomas Schmitt
Recording and retrieval of SCSI sense reply. Write/burning interface. Recording and retrieval of SCSI sense reply. Write/burning interface.
MMC bug fixes
Daniel Schwarz Daniel Schwarz
log-summary option in cd-paranoia. log-summary option in cd-paranoia.

View File

@@ -1,6 +1,4 @@
/* /*
$Id: gnu_linux.c,v 1.33 2008/06/25 07:46:21 rocky Exp $
Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org> Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org>
Copyright (C) 2002, 2003, 2004, 2005, 2006, 2008, 2009 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2008, 2009
Rocky Bernstein <rocky@gnu.org> Rocky Bernstein <rocky@gnu.org>
@@ -86,7 +84,8 @@ typedef enum {
_AM_IOCTL, _AM_IOCTL,
_AM_READ_CD, _AM_READ_CD,
_AM_READ_10, _AM_READ_10,
_AM_MMC_RDWR _AM_MMC_RDWR,
_AM_MMC_RDWR_EXCL,
} access_mode_t; } access_mode_t;
typedef struct { typedef struct {
@@ -135,6 +134,8 @@ str_to_access_mode_linux(const char *psz_access_mode)
return _AM_READ_10; return _AM_READ_10;
else if (!strcmp(psz_access_mode, "MMC_RDWR")) else if (!strcmp(psz_access_mode, "MMC_RDWR"))
return _AM_MMC_RDWR; return _AM_MMC_RDWR;
else if (!strcmp(psz_access_mode, "MMC_RDWR_EXCL"))
return _AM_MMC_RDWR_EXCL;
else { else {
cdio_warn ("unknown access type: %s. Default IOCTL used.", cdio_warn ("unknown access type: %s. Default IOCTL used.",
psz_access_mode); psz_access_mode);
@@ -379,6 +380,8 @@ get_arg_linux (void *env, const char key[])
return "READ_10"; return "READ_10";
case _AM_MMC_RDWR: case _AM_MMC_RDWR:
return "MMC_RDWR"; return "MMC_RDWR";
case _AM_MMC_RDWR_EXCL:
return "MMC_RDWR_EXCL";
case _AM_NONE: case _AM_NONE:
return "no access method"; return "no access method";
} }
@@ -958,7 +961,7 @@ _read_mode2_sectors (_img_private_t *p_env, void *p_buf, lba_t lba,
*/ */
static driver_return_code_t static driver_return_code_t
_read_mode1_sector_linux (void *p_user_data, void *p_data, lsn_t lsn, _read_mode1_sector_linux (void *p_user_data, void *p_data, lsn_t lsn,
bool b_form2) bool b_form2)
{ {
#if 0 #if 0
@@ -1029,7 +1032,7 @@ _read_mode1_sector_linux (void *p_user_data, void *p_data, lsn_t lsn,
*/ */
static driver_return_code_t static driver_return_code_t
_read_mode1_sectors_linux (void *p_user_data, void *p_data, lsn_t lsn, _read_mode1_sectors_linux (void *p_user_data, void *p_data, lsn_t lsn,
bool b_form2, uint32_t i_blocks) bool b_form2, uint32_t i_blocks)
{ {
_img_private_t *p_env = p_user_data; _img_private_t *p_env = p_user_data;
unsigned int i; unsigned int i;
@@ -1074,6 +1077,7 @@ _read_mode2_sector_linux (void *p_user_data, void *p_data, lsn_t lsn,
case _AM_IOCTL: case _AM_IOCTL:
case _AM_MMC_RDWR: case _AM_MMC_RDWR:
case _AM_MMC_RDWR_EXCL:
if (ioctl (p_env->gen.fd, CDROMREADMODE2, &buf) == -1) if (ioctl (p_env->gen.fd, CDROMREADMODE2, &buf) == -1)
{ {
perror ("ioctl()"); perror ("ioctl()");
@@ -1120,7 +1124,7 @@ _read_mode2_sector_linux (void *p_user_data, void *p_data, lsn_t lsn,
*/ */
static driver_return_code_t static driver_return_code_t
_read_mode2_sectors_linux (void *p_user_data, void *data, lsn_t lsn, _read_mode2_sectors_linux (void *p_user_data, void *data, lsn_t lsn,
bool b_form2, uint32_t i_blocks) bool b_form2, uint32_t i_blocks)
{ {
_img_private_t *p_env = p_user_data; _img_private_t *p_env = p_user_data;
unsigned int i; unsigned int i;
@@ -1221,26 +1225,51 @@ read_toc_linux (void *p_user_data)
We return true if command completed successfully and false if not. We return true if command completed successfully and false if not.
*/ */
static driver_return_code_t static driver_return_code_t
run_mmc_cmd_linux( void *p_user_data, run_mmc_cmd_linux(void *p_user_data,
unsigned int i_timeout_ms, unsigned int i_timeout_ms,
unsigned int i_cdb, const mmc_cdb_t *p_cdb, unsigned int i_cdb, const mmc_cdb_t *p_cdb,
cdio_mmc_direction_t e_direction, cdio_mmc_direction_t e_direction,
unsigned int i_buf, /*in/out*/ void *p_buf ) unsigned int i_buf, /*in/out*/ void *p_buf)
{ {
const _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;
struct request_sense sense;
unsigned char *u_sense = (unsigned char *) &sense;
int sense_size;
p_env->gen.scsi_mmc_sense_valid = 0;
memset (&cgc, 0, sizeof (struct cdrom_generic_command)); memset (&cgc, 0, sizeof (struct cdrom_generic_command));
memcpy(&cgc.cmd, p_cdb, i_cdb); memcpy(&cgc.cmd, p_cdb, i_cdb);
cgc.buflen = i_buf; cgc.buflen = i_buf;
cgc.buffer = p_buf; cgc.buffer = p_buf;
cgc.data_direction = (SCSI_MMC_DATA_READ == e_direction)
? CGC_DATA_READ : CGC_DATA_WRITE; cgc.sense = &sense;
#ifdef HAVE_LINUX_CDROM_TIMEOUT
if (SCSI_MMC_DATA_NONE == e_direction)
i_buf = 0;
cgc.data_direction = (SCSI_MMC_DATA_READ == e_direction) ? CGC_DATA_READ :
(SCSI_MMC_DATA_WRITE == e_direction) ? CGC_DATA_WRITE :
CGC_DATA_NONE;
#ifdef HAVE_LINUX_CDROM_TIMEOUT
cgc.timeout = i_timeout_ms; cgc.timeout = i_timeout_ms;
#endif #endif
memset(u_sense, 0, sizeof(sense));
{ {
int i_rc = ioctl (p_env->gen.fd, CDROM_SEND_PACKET, &cgc); int i_rc = ioctl (p_env->gen.fd, CDROM_SEND_PACKET, &cgc);
/* Record SCSI sense reply for API call mmc_last_cmd_sense().
*/
if (u_sense[7]) {
sense_size = u_sense[7] + 8; /* SPC 4.5.3, Table 26 :
252 bytes legal , 263 bytes possible */
if (sense_size > sizeof(sense))
sense_size = sizeof(sense);
memcpy((void *) p_env->gen.scsi_mmc_sense, &sense, sense_size);
p_env->gen.scsi_mmc_sense_valid = sense_size;
}
if (0 == i_rc) return DRIVER_OP_SUCCESS; if (0 == i_rc) return DRIVER_OP_SUCCESS;
if (-1 == i_rc) { if (-1 == i_rc) {
cdio_info ("ioctl CDROM_SEND_PACKET failed: %s", strerror(errno)); cdio_info ("ioctl CDROM_SEND_PACKET failed: %s", strerror(errno));
@@ -1648,9 +1677,13 @@ cdio_open_am_linux (const char *psz_orig_source, const char *access_mode)
ret->driver_id = DRIVER_LINUX; ret->driver_id = DRIVER_LINUX;
open_access_mode = (_AM_MMC_RDWR == _data->access_mode) open_access_mode = O_NONBLOCK;
? (O_RDWR|O_EXCL|O_NONBLOCK) : (O_RDONLY|O_NONBLOCK); if (_AM_MMC_RDWR == _data->access_mode)
open_access_mode |= O_RDWR;
else if (_AM_MMC_RDWR_EXCL == _data->access_mode)
open_access_mode |= O_RDWR | O_EXCL;
else
open_access_mode |= O_RDONLY;
if (cdio_generic_init(_data, open_access_mode)) { if (cdio_generic_init(_data, open_access_mode)) {
return ret; return ret;
} else { } else {

View File

@@ -1,7 +1,6 @@
/* /*
$Id: solaris.c,v 1.12 2008/04/22 15:29:12 karl Exp $ Copyright (C) 2002, 2003, 2004, 2005, 2006, 2009
Rocky Bernstein <rocky@gnu.org>
Copyright (C) 2002, 2003, 2004, 2005, 2006 Rocky Bernstein <rocky@gnu.org>
Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org> Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org>
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
@@ -277,10 +276,10 @@ init_solaris (_img_private_t *p_env)
p_buf Buffer for data, both sending and receiving p_buf Buffer for data, both sending and receiving
*/ */
static driver_return_code_t static driver_return_code_t
run_mmc_cmd_solaris( void *p_user_data, unsigned int i_timeout_ms, run_mmc_cmd_solaris(void *p_user_data, unsigned int i_timeout_ms,
unsigned int i_cdb, const mmc_cdb_t *p_cdb, unsigned int i_cdb, const mmc_cdb_t *p_cdb,
cdio_mmc_direction_t e_direction, cdio_mmc_direction_t e_direction,
unsigned int i_buf, /*in/out*/ void *p_buf ) unsigned int i_buf, /*in/out*/ void *p_buf)
{ {
const _img_private_t *p_env = p_user_data; const _img_private_t *p_env = p_user_data;
struct uscsi_cmd cgc; struct uscsi_cmd cgc;