IODVDMediaBSDClient.cpp [plain text]
#include <sys/errno.h>
#include <IOKit/storage/IODVDMediaBSDClient.h>
#define super IOMediaBSDClient
OSDefineMetaClassAndStructors(IODVDMediaBSDClient, IOMediaBSDClient)
static bool DKIOC_IS_RESERVED(caddr_t data, u_int16_t reserved)
{
UInt32 index;
for ( index = 0; index < sizeof(reserved) * 8; index++, reserved >>= 1 )
{
if ( (reserved & 1) )
{
if ( data[index] ) return true;
}
}
return false;
}
static IOMemoryDescriptor * DKIOC_PREPARE_BUFFER( void * address,
UInt32 length,
IODirection direction )
{
IOMemoryDescriptor * buffer = 0;
if ( address && length )
{
buffer = IOMemoryDescriptor::withAddress( (vm_address_t) address,
length,
direction,
current_task() );
}
if ( buffer )
{
if ( buffer->prepare() != kIOReturnSuccess ) {
buffer->release();
buffer = 0;
}
}
return buffer;
}
static void DKIOC_COMPLETE_BUFFER(IOMemoryDescriptor * buffer)
{
if ( buffer )
{
buffer->complete(); buffer->release(); }
}
IODVDMedia * IODVDMediaBSDClient::getProvider() const
{
return (IODVDMedia *) IOService::getProvider();
}
int IODVDMediaBSDClient::ioctl( dev_t dev,
u_long cmd,
caddr_t data,
int flags,
proc_t proc )
{
IOMemoryDescriptor * buffer = 0;
int error = 0;
IOReturn status = kIOReturnSuccess;
switch ( cmd )
{
case DKIOCDVDREADSTRUCTURE: {
dk_dvd_read_structure_t * request;
request = (dk_dvd_read_structure_t *) data;
if ( DKIOC_IS_RESERVED(data, 0x000E) ) { error = EINVAL; break; }
buffer = DKIOC_PREPARE_BUFFER(
request->buffer,
request->bufferLength,
kIODirectionIn );
status = getProvider()->readStructure(
buffer,
(DVDStructureFormat) request->format,
request->address,
request->layer,
request->grantID );
status = (status == kIOReturnUnderrun) ? kIOReturnSuccess : status;
DKIOC_COMPLETE_BUFFER(buffer);
} break;
case DKIOCDVDREPORTKEY: {
dk_dvd_report_key_t * request = (dk_dvd_report_key_t *) data;
if ( DKIOC_IS_RESERVED(data, 0x020C) ) { error = EINVAL; break; }
buffer = DKIOC_PREPARE_BUFFER(
request->buffer,
request->bufferLength,
kIODirectionIn );
status = getProvider()->reportKey(
buffer,
(DVDKeyClass) request->keyClass,
request->address,
request->grantID,
(DVDKeyFormat) request->format );
status = (status == kIOReturnUnderrun) ? kIOReturnSuccess : status;
DKIOC_COMPLETE_BUFFER(buffer);
} break;
case DKIOCDVDSENDKEY: {
dk_dvd_send_key_t * request = (dk_dvd_send_key_t *) data;
if ( DKIOC_IS_RESERVED(data, 0x02FC) ) { error = EINVAL; break; }
buffer = DKIOC_PREPARE_BUFFER(
request->buffer,
request->bufferLength,
kIODirectionOut );
status = getProvider()->sendKey(
buffer,
(DVDKeyClass) request->keyClass,
request->grantID,
(DVDKeyFormat) request->format );
status = (status == kIOReturnUnderrun) ? kIOReturnSuccess : status;
DKIOC_COMPLETE_BUFFER(buffer);
} break;
case DKIOCDVDGETSPEED: {
status = getProvider()->getSpeed((u_int16_t *)data);
} break;
case DKIOCDVDSETSPEED: {
status = getProvider()->setSpeed(*(u_int16_t *)data);
} break;
case DKIOCDVDREADDISCINFO: {
dk_dvd_read_disc_info_t * request;
request = (dk_dvd_read_disc_info_t *) data;
if ( DKIOC_IS_RESERVED(data, 0x03FF) ) { error = EINVAL; break; }
buffer = DKIOC_PREPARE_BUFFER(
request->buffer,
request->bufferLength,
kIODirectionIn );
status = getProvider()->readDiscInfo(
buffer,
&request->bufferLength );
status = (status == kIOReturnUnderrun) ? kIOReturnSuccess : status;
DKIOC_COMPLETE_BUFFER(buffer);
} break;
case DKIOCDVDREADRZONEINFO: {
dk_dvd_read_rzone_info_t * request;
request = (dk_dvd_read_rzone_info_t *) data;
if ( DKIOC_IS_RESERVED(data, 0x020F) ) { error = EINVAL; break; }
buffer = DKIOC_PREPARE_BUFFER(
request->buffer,
request->bufferLength,
kIODirectionIn );
status = getProvider()->readRZoneInfo(
buffer,
request->address,
request->addressType,
&request->bufferLength );
status = (status == kIOReturnUnderrun) ? kIOReturnSuccess : status;
DKIOC_COMPLETE_BUFFER(buffer);
} break;
default:
{
error = super::ioctl(dev, cmd, data, flags, proc);
} break;
}
return error ? error : getProvider()->errnoFromReturn(status);
}
OSMetaClassDefineReservedUnused(IODVDMediaBSDClient, 0);
OSMetaClassDefineReservedUnused(IODVDMediaBSDClient, 1);
OSMetaClassDefineReservedUnused(IODVDMediaBSDClient, 2);
OSMetaClassDefineReservedUnused(IODVDMediaBSDClient, 3);
OSMetaClassDefineReservedUnused(IODVDMediaBSDClient, 4);
OSMetaClassDefineReservedUnused(IODVDMediaBSDClient, 5);
OSMetaClassDefineReservedUnused(IODVDMediaBSDClient, 6);
OSMetaClassDefineReservedUnused(IODVDMediaBSDClient, 7);