_cdio_osx.c: first attempt at issuing general SCSI-MMC passthrough command.

others: small changes.
This commit is contained in:
rocky
2004-08-16 00:52:53 +00:00
parent ff65f7133f
commit c8000d60e9
3 changed files with 177 additions and 30 deletions

View File

@@ -1,5 +1,5 @@
/*
$Id: _cdio_linux.c,v 1.91 2004/08/10 11:58:15 rocky Exp $
$Id: _cdio_linux.c,v 1.92 2004/08/16 00:52:53 rocky Exp $
Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org>
Copyright (C) 2002, 2003, 2004 Rocky Bernstein <rocky@panix.com>
@@ -27,7 +27,7 @@
# include "config.h"
#endif
static const char _rcsid[] = "$Id: _cdio_linux.c,v 1.91 2004/08/10 11:58:15 rocky Exp $";
static const char _rcsid[] = "$Id: _cdio_linux.c,v 1.92 2004/08/16 00:52:53 rocky Exp $";
#include <string.h>
@@ -227,14 +227,14 @@ get_arg_linux (void *env, const char key[])
*/
static void
get_drive_cap_linux (const void *p_user_data,
cdio_drive_read_cap_t *p_read_cap,
cdio_drive_write_cap_t *p_write_cap,
cdio_drive_misc_cap_t *p_misc_cap)
/*out*/ cdio_drive_read_cap_t *p_read_cap,
/*out*/ cdio_drive_write_cap_t *p_write_cap,
/*out*/ cdio_drive_misc_cap_t *p_misc_cap)
{
const _img_private_t *_obj = p_user_data;
const _img_private_t *p_env = p_user_data;
int32_t i_drivetype;
i_drivetype = ioctl (_obj->gen.fd, CDROM_GET_CAPABILITY, CDSL_CURRENT);
i_drivetype = ioctl (p_env->gen.fd, CDROM_GET_CAPABILITY, CDSL_CURRENT);
if (i_drivetype < 0) {
*p_read_cap = CDIO_DRIVE_CAP_ERROR;
@@ -295,9 +295,9 @@ static char *
_get_mcn_linux (const void *env) {
struct cdrom_mcn mcn;
const _img_private_t *_obj = env;
const _img_private_t *p_env = env;
memset(&mcn, 0, sizeof(mcn));
if (ioctl(_obj->gen.fd, CDROM_GET_MCN, &mcn) != 0)
if (ioctl(p_env->gen.fd, CDROM_GET_MCN, &mcn) != 0)
return NULL;
return strdup(mcn.medium_catalog_number);
}
@@ -632,7 +632,7 @@ _read_mode1_sector_linux (void *p_user_data, void *p_data, lsn_t lsn,
msf->cdmsf_frame0 = from_bcd8(_msf.f);
retry:
switch (_obj->access_mode)
switch (p_env->access_mode)
{
case _AM_NONE:
cdio_warn ("no way to read mode1");
@@ -1123,7 +1123,7 @@ cdio_open_am_linux (const char *psz_orig_source, const char *access_mode)
.read_mode2_sector = _read_mode2_sector_linux,
.read_mode2_sectors = _read_mode2_sectors_linux,
.read_toc = read_toc_linux,
.run_scsi_mmc_cmd = &run_scsi_cmd_linux,
.run_scsi_mmc_cmd = run_scsi_cmd_linux,
.set_arg = set_arg_linux,
.stat_size = stat_size_linux
};

View File

@@ -1,5 +1,5 @@
/*
$Id: _cdio_osx.c,v 1.51 2004/08/15 16:15:40 rocky Exp $
$Id: _cdio_osx.c,v 1.52 2004/08/16 00:52:53 rocky Exp $
Copyright (C) 2003, 2004 Rocky Bernstein <rocky@panix.com>
from vcdimager code:
@@ -34,7 +34,7 @@
#include "config.h"
#endif
static const char _rcsid[] = "$Id: _cdio_osx.c,v 1.51 2004/08/15 16:15:40 rocky Exp $";
static const char _rcsid[] = "$Id: _cdio_osx.c,v 1.52 2004/08/16 00:52:53 rocky Exp $";
#include <cdio/sector.h>
#include <cdio/util.h>
@@ -44,6 +44,14 @@ static const char _rcsid[] = "$Id: _cdio_osx.c,v 1.51 2004/08/15 16:15:40 rocky
#include <string.h>
#ifdef HAVE_DARWIN_CDROM
#undef VERSION
#include <mach/mach.h>
#include <Carbon/Carbon.h>
#include <IOKit/scsi-commands/SCSITaskLib.h>
#include <IOKit/IOKitLib.h>
#include <IOKit/IOCFPlugIn.h>
#include <mach/mach_error.h>
#include <stdio.h>
#include <stdlib.h>
@@ -55,6 +63,7 @@ static const char _rcsid[] = "$Id: _cdio_osx.c,v 1.51 2004/08/15 16:15:40 rocky
#include <sys/types.h>
#include <sys/ioctl.h>
#include <paths.h>
#include <CoreFoundation/CoreFoundation.h>
#include <CoreFoundation/CFBase.h>
@@ -102,9 +111,96 @@ typedef struct {
track_t i_first_session; /* first session number */
lsn_t *pp_lba;
CFMutableDictionaryRef dict;
SCSITaskDeviceInterface **pp_scsiTaskDeviceInterface;
} _img_private_t;
/*!
Run a SCSI MMC command.
cdio CD structure set by cdio_open().
i_timeout time in milliseconds we will wait for the command
to complete. If this value is -1, use the default
time-out value.
p_buf Buffer for data, both sending and receiving
i_buf Size of buffer
e_direction direction the transfer is to go.
cdb CDB bytes. All values that are needed should be set on
input. We'll figure out what the right CDB length should be.
We return true if command completed successfully and false if not.
*/
static int
run_scsi_cmd_osx( const void *p_user_data,
unsigned int i_timeout_ms,
unsigned int i_cdb, const scsi_mmc_cdb_t *p_cdb,
scsi_mmc_direction_t e_direction,
unsigned int i_buf, /*in/out*/ void *p_buf )
{
const _img_private_t *p_env = p_user_data;
SCSITaskDeviceInterface **sc;
SCSITaskInterface **cmd = NULL;
IOVirtualRange iov;
SCSI_Sense_Data senseData;
SCSITaskStatus status;
UInt64 bytesTransferred;
IOReturn ioReturnValue;
int ret = 0;
if (NULL == p_user_data) return 2;
sc = p_env->pp_scsiTaskDeviceInterface;
cmd = (*sc)->CreateSCSITask(sc);
if (cmd == NULL) {
cdio_warn("Failed to create SCSI task");
return -1;
}
iov.address = (IOVirtualAddress) p_buf;
iov.length = i_buf;
ioReturnValue = (*cmd)->SetCommandDescriptorBlock(cmd, (UInt8 *) p_cdb,
i_cdb);
if (ioReturnValue != kIOReturnSuccess) {
cdio_warn("SetCommandDescriptorBlock failed with status %x",
ioReturnValue);
return -1;
}
ioReturnValue = (*cmd)->SetScatterGatherEntries(cmd, &iov, 1, i_buf,
(SCSI_MMC_DATA_READ == e_direction ) ?
kSCSIDataTransfer_FromTargetToInitiator :
kSCSIDataTransfer_FromInitiatorToTarget);
if (ioReturnValue != kIOReturnSuccess) {
cdio_warn("SetScatterGatherEntries failed with status %x", ioReturnValue);
return -1;
}
ioReturnValue = (*cmd)->SetTimeoutDuration(cmd, i_timeout_ms );
if (ioReturnValue != kIOReturnSuccess) {
cdio_warn("SetTimeoutDuration failed with status %x", ioReturnValue);
return -1;
}
memset(&senseData, 0, sizeof(senseData));
ioReturnValue = (*cmd)->ExecuteTaskSync(cmd,
&senseData, &status, &bytesTransferred);
if (ioReturnValue != kIOReturnSuccess) {
cdio_warn("Command execution failed with status %x", ioReturnValue);
return -1;
}
if (cmd != NULL) {
(*cmd)->Release(cmd);
}
return (ret);
}
#if 0
/***************************************************************************
* GetFeaturesFlagsForDrive -Gets the bitfield which represents the
* features flags.
@@ -145,8 +241,6 @@ GetFeaturesFlagsForDrive ( CFMutableDictionaryRef dict,
return true;
}
/*!
*/
static void
get_drive_cap_osx(const void *p_user_data,
/*out*/ cdio_drive_read_cap_t *p_read_cap,
@@ -186,15 +280,16 @@ get_drive_cap_osx(const void *p_user_data,
if ( 0 != (i_dvdFlags & kDVDFeaturesReWriteableMask) )
*p_write_cap |= CDIO_DRIVE_CAP_WRITE_DVD_RW;
#if 0
/***
if ( 0 != (i_dvdFlags & kDVDFeaturesPlusRMask) )
*p_write_cap |= CDIO_DRIVE_CAP_WRITE_DVD_PR;
if ( 0 != (i_dvdFlags & kDVDFeaturesPlusRWMask )
*p_write_cap |= CDIO_DRIVE_CAP_WRITE_DVD_PRW;
#endif
***/
}
#endif
#if 0
/****************************************************************************
@@ -249,6 +344,10 @@ _free_osx (void *p_user_data) {
if (NULL != p_env->pp_lba) free((void *) p_env->pp_lba);
if (NULL != p_env->pTOC) free((void *) p_env->pTOC);
if (NULL != p_env->dict) CFRelease( p_env->dict );
if (NULL != p_env->pp_scsiTaskDeviceInterface)
( *(p_env->pp_scsiTaskDeviceInterface) )->
Release ( (p_env->pp_scsiTaskDeviceInterface) );
}
/*!
@@ -402,18 +501,62 @@ _set_arg_osx (void *user_data, const char key[], const char value[])
return 0;
}
static void TestDevice(_img_private_t *p_env, io_service_t service)
{
SInt32 score;
HRESULT herr;
kern_return_t err;
IOCFPlugInInterface **plugInInterface = NULL;
MMCDeviceInterface **mmcInterface = NULL;
/* Create the IOCFPlugIn interface so we can query it. */
err = IOCreatePlugInInterfaceForService ( service,
kIOMMCDeviceUserClientTypeID,
kIOCFPlugInInterfaceID,
&plugInInterface,
&score );
if ( err != noErr ) {
printf("IOCreatePlugInInterfaceForService returned %d\n", err);
return;
}
/* Query the interface for the MMCDeviceInterface. */
herr = ( *plugInInterface )->QueryInterface ( plugInInterface,
CFUUIDGetUUIDBytes ( kIOMMCDeviceInterfaceID ),
( LPVOID ) &mmcInterface );
if ( herr != S_OK ) {
printf("QueryInterface returned %ld\n", herr);
return;
}
p_env->pp_scsiTaskDeviceInterface =
( *mmcInterface )->GetSCSITaskDeviceInterface ( mmcInterface );
if ( NULL == p_env->pp_scsiTaskDeviceInterface ) {
printf("GetSCSITaskDeviceInterface returned NULL\n");
return;
}
( *mmcInterface )->Release ( mmcInterface );
IODestroyPlugInInterface ( plugInInterface );
}
/*!
Read and cache the CD's Track Table of Contents and track info.
Return false if successful or true if an error.
*/
static bool
_cdio_read_toc (_img_private_t *p_env)
read_toc_osx (void *p_user_data)
{
_img_private_t *p_env = p_user_data;
mach_port_t port;
char *psz_devname;
kern_return_t ret;
io_iterator_t iterator;
io_registry_entry_t service;
io_service_t service;
CFDataRef data;
p_env->gen.fd = open( p_env->gen.source_name, O_RDONLY | O_NONBLOCK );
@@ -512,6 +655,7 @@ _cdio_read_toc (_img_private_t *p_env)
return false;
}
TestDevice(p_env, service);
IOObjectRelease( service );
p_env->i_descriptors = CDTOCGetDescriptorCount ( p_env->pTOC );
@@ -631,7 +775,7 @@ _get_track_lba_osx(void *user_data, track_t i_track)
{
_img_private_t *p_env = user_data;
if (!p_env->toc_init) _cdio_read_toc (p_env) ;
if (!p_env->toc_init) read_toc_osx (p_env) ;
if (i_track == CDIO_CDROM_LEADOUT_TRACK) i_track = p_env->i_last_track+1;
@@ -732,7 +876,7 @@ _get_first_track_num_osx(void *user_data)
{
_img_private_t *p_env = user_data;
if (!p_env->toc_init) _cdio_read_toc (p_env) ;
if (!p_env->toc_init) read_toc_osx (p_env) ;
return p_env->i_first_track;
}
@@ -766,7 +910,7 @@ _get_num_tracks_osx(void *user_data)
{
_img_private_t *p_env = user_data;
if (!p_env->toc_init) _cdio_read_toc (p_env) ;
if (!p_env->toc_init) read_toc_osx (p_env) ;
return( TOTAL_TRACKS );
}
@@ -828,7 +972,7 @@ _get_track_green_osx(void *user_data, track_t i_track)
_img_private_t *p_env = user_data;
CDTrackInfo a_track;
if (!p_env->toc_init) _cdio_read_toc (p_env) ;
if (!p_env->toc_init) read_toc_osx (p_env) ;
if ( i_track > p_env->i_last_track || i_track < p_env->i_first_track )
return false;
@@ -1054,10 +1198,11 @@ cdio_open_osx (const char *psz_orig_source)
.eject_media = _eject_media_osx,
.free = _free_osx,
.get_arg = _get_arg_osx,
.get_cdtext = get_cdtext_generic,
.get_default_device = cdio_get_default_device_osx,
.get_devices = cdio_get_devices_osx,
.get_discmode = NULL,
.get_drive_cap = get_drive_cap_osx,
.get_discmode = get_discmode_generic,
.get_drive_cap = scsi_mmc_get_drive_cap_generic,
.get_first_track_num= _get_first_track_num_osx,
.get_mcn = _get_mcn_osx,
.get_num_tracks = _get_num_tracks_osx,
@@ -1072,6 +1217,8 @@ cdio_open_osx (const char *psz_orig_source)
.read_mode1_sectors = _get_read_mode1_sectors_osx,
.read_mode2_sector = _get_read_mode2_sector_osx,
.read_mode2_sectors = _get_read_mode2_sectors_osx,
.read_toc = read_toc_osx,
.run_scsi_mmc_cmd = run_scsi_cmd_osx,
.set_arg = _set_arg_osx,
.stat_size = _stat_size_osx
};

View File

@@ -1,5 +1,5 @@
/*
$Id: _cdio_sunos.c,v 1.72 2004/08/10 11:58:15 rocky Exp $
$Id: _cdio_sunos.c,v 1.73 2004/08/16 00:52:53 rocky Exp $
Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org>
Copyright (C) 2002, 2003, 2004 Rocky Bernstein <rocky@panix.com>
@@ -38,7 +38,7 @@
#ifdef HAVE_SOLARIS_CDROM
static const char _rcsid[] = "$Id: _cdio_sunos.c,v 1.72 2004/08/10 11:58:15 rocky Exp $";
static const char _rcsid[] = "$Id: _cdio_sunos.c,v 1.73 2004/08/16 00:52:53 rocky Exp $";
#ifdef HAVE_GLOB_H
#include <glob.h>
@@ -851,8 +851,8 @@ cdio_open_am_solaris (const char *psz_orig_source, const char *access_mode)
.read_mode1_sectors = _read_mode1_sectors_solaris,
.read_mode2_sector = _read_mode2_sector_solaris,
.read_mode2_sectors = _read_mode2_sectors_solaris,
.read_toc = &read_toc_solaris,
.run_scsi_mmc_cmd = &run_scsi_cmd_solaris,
.read_toc = read_toc_solaris,
.run_scsi_mmc_cmd = run_scsi_cmd_solaris,
.stat_size = _cdio_stat_size,
.set_arg = _set_arg_solaris
};