*****************************************************************************
* Copyright (C) 1998-2000 Apple Computer, Inc. All rights reserved.
* Copyright (C) 2001 VideoLAN
- * $Id: DVDioctl.cpp,v 1.2 2001/04/04 02:49:18 sam Exp $
+ * $Id: DVDioctl.cpp,v 1.7 2001/06/25 11:34:08 sam Exp $
*
* Authors: Samuel Hocevar <sam@zoy.org>
+ * Eugenio Jarosiewicz <ej0@cise.ufl.edu>
*
* The contents of this file constitute Original Code as defined in and
* are subject to the Apple Public Source License Version 1.1 (the
* it is still in use
*****************************************************************************/
-//XXX: uncomment to activate the key exchange ioctls - may hang the machine
-//#define ACTIVATE_DANGEROUS_IOCTL 1
-
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <IOKit/storage/IODVDMedia.h>
#include <IOKit/storage/IODVDBlockStorageDriver.h>
+#undef CONTROL //some include above #defines this and breaks the next include...grr.
+#include <IOKit/scsi-commands/IOSCSIMultimediaCommandsDevice.h>
+#include <IOKit/scsi-commands/IODVDServices.h>
+
#include "DVDioctl.h"
/*****************************************************************************
/*****************************************************************************
* Variable typedefs
*****************************************************************************/
-typedef void * dkr_t;
-typedef enum { DKRTYPE_BUF, DKRTYPE_DIO } dkrtype_t;
-typedef struct dio { dev_t dev; struct uio * uio; } dio_t;
-typedef struct buf buf_t;
+typedef enum { DKRTYPE_BUF, DKRTYPE_DIO } dkrtype_t;
+typedef struct dio { dev_t dev; struct uio * uio; } dio_t;
+typedef struct buf buf_t;
+typedef void * dkr_t;
/*****************************************************************************
* Local prototypes
static void *p_node;
static IODVDMedia *p_dvd;
static IODVDBlockStorageDriver *p_drive;
+static IODVDServices *p_services;
+static IOSCSIMultimediaCommandsDevice *p_scsi_mcd;
/*****************************************************************************
* DKR_GET_DEV: borrowed from IOMediaBSDClient.cpp
p_node = NULL;
p_dvd = NULL;
p_drive = NULL;
+ p_services = NULL;
+ p_scsi_mcd = NULL;
i_major = -1;
b_inuse = false;
p_drive = p_dvd->getProvider();
+ p_services = OSDynamicCast( IODVDServices, p_drive->getProvider() );
+
+ p_scsi_mcd = OSDynamicCast( IOSCSIMultimediaCommandsDevice, p_services->getProvider() );
+
log( LOG_INFO, "DVD ioctl: IODVDMedia->open()\n" );
return 0;
p_dvd = NULL;
p_drive = NULL;
+ p_services = NULL;
+ p_scsi_mcd = NULL;
b_inuse = false;
log( LOG_INFO, "DVD ioctl: IODVDMedia->close()\n" );
static int DVDBlockIoctl( dev_t dev, u_long cmd, caddr_t addr, int flags,
struct proc *p )
{
- dvdioctl_data_t * p_data = (dvdioctl_data_t *)addr;
+#define p_data (((dvdioctl_data_t *)addr))
+ IOReturn i_ret = EINVAL;
+
+ /* Only needed for IODVD_READ_STRUCTURE */
+ SCSITask *p_request;
+ SCSIServiceResponse response;
+
+ IOMemoryDescriptor *p_mem;
+
+ p_mem = IOMemoryDescriptor::withAddress( p_data->p_buffer,
+ p_data->i_size,
+ kIODirectionOutIn );
switch( cmd )
{
log( LOG_INFO, "DVD ioctl: IODVD_READ_STRUCTURE\n" );
- return 0;
+ i_ret = kIOReturnUnsupported;
+ response = kSCSIServiceResponse_SERVICE_DELIVERY_OR_TARGET_FAILURE;
+
+/* HACK! - Make GetSCSITask and friends in /System/Library/Frameworks/Kernel.framework/Versions/A/Headers/IOKit/scsi-commands/IOSCSIPrimaryCommandsDevice.h public by moving public: from line 96 to line 79 (as root). It's only a compile time check - not a link time thing, so it should be ok. */
+ p_request = p_scsi_mcd->GetSCSITask( );
+
+ if ( p_scsi_mcd->READ_DVD_STRUCTURE ( p_request,
+ p_mem,
+ p_data->i_lba,
+ 0,//?LAYER_NUMBER
+ p_data->i_keyformat,
+ p_mem->getLength(),//p_data->i_size ?
+ p_data->i_agid,
+ 0x00 //?CONTROL
+ ) == true )
+ {
+ /* The command was successfully built, now send it */
+ response = p_scsi_mcd->SendCommand( p_request );
+ }
+ else
+ {
+#if 0
+ exit -1;
+ PANIC_NOW(( "IOSCSIMultimediaCommandsDevice:: "
+ "readDVDstruct malformed command" ));
+#endif
+ }
+
+ if( ( response == kSCSIServiceResponse_TASK_COMPLETE ) &&
+ ( p_request->GetTaskStatus ( ) == kSCSITaskStatus_GOOD ) )
+ {
+ i_ret = kIOReturnSuccess;
+ }
+ else
+ {
+ i_ret = kIOReturnError;
+ }
+
+ p_scsi_mcd->ReleaseSCSITask( p_request );
+
+ }
+
+ break;
case IODVD_SEND_KEY:
log( LOG_INFO, "DVD ioctl: send key to `%s', "
- "buf %d, format %d, class %d, agid %d\n",
+ "buf %d, class %d, lba N/A, agid %d, format %d\n",
p_drive->getDeviceTypeName(),
- (int)p_data->p_buffer, p_data->i_keyformat,
- p_data->i_keyclass, p_data->i_agid );
-
-#ifdef ACTIVATE_DANGEROUS_IOCTL
- return p_drive->sendKey( (IOMemoryDescriptor *)p_data->p_buffer,
- (DVDKeyClass)p_data->i_keyclass,
- p_data->i_agid,
- (DVDKeyFormat)p_data->i_keyformat );
-#else
- return -1;
-#endif
+ (int)p_data->p_buffer, p_data->i_keyclass,
+ p_data->i_agid, p_data->i_keyformat );
+
+ i_ret = p_drive->sendKey( p_mem, (DVDKeyClass)p_data->i_keyclass,
+ p_data->i_agid,
+ (DVDKeyFormat)p_data->i_keyformat );
+
+ break;
case IODVD_REPORT_KEY:
log( LOG_INFO, "DVD ioctl: report key from `%s', "
- p_drive->getDeviceTypeName(),
"buf %d, class %d, lba %d, agid %d, format %d\n",
+ p_drive->getDeviceTypeName(),
(int)p_data->p_buffer, p_data->i_keyclass, p_data->i_lba,
p_data->i_agid, p_data->i_keyformat );
-#ifdef ACTIVATE_DANGEROUS_IOCTL
- return p_drive->reportKey( (IOMemoryDescriptor *)p_data->p_buffer,
- (DVDKeyClass)p_data->i_keyclass,
- p_data->i_lba, p_data->i_agid,
- (DVDKeyFormat)p_data->i_keyformat );
-#else
- return -1;
-#endif
+ i_ret = p_drive->reportKey( p_mem, (DVDKeyClass)p_data->i_keyclass,
+ p_data->i_lba, p_data->i_agid,
+ (DVDKeyFormat)p_data->i_keyformat );
+
+ break;
default:
log( LOG_INFO, "DVD ioctl: unknown ioctl\n" );
- return EINVAL;
+ i_ret = EINVAL;
+
+ break;
}
+
+ return i_ret;
+#undef p_data
}
/*****************************************************************************