Search
lxdream.org :: lxdream/src/drivers/cd_osx.c
lxdream 0.9.1
released Jun 29
Download Now
filename src/drivers/cd_osx.c
changeset 736:a02d1475ccfd
prev720:b5594d1ac80a
next739:46fa527d9fef
author nkeynes
date Mon Jul 14 07:44:42 2008 +0000 (11 years ago)
permissions -rw-r--r--
last change Re-indent everything consistently
Fix include guards for consistency as well
file annotate diff log raw
nkeynes@709
     1
/**
nkeynes@709
     2
 * $Id$
nkeynes@709
     3
 *
nkeynes@709
     4
 * OSX native cd-rom driver.
nkeynes@709
     5
 *
nkeynes@709
     6
 * Copyright (c) 2005 Nathan Keynes.
nkeynes@709
     7
 *
nkeynes@709
     8
 * This program is free software; you can redistribute it and/or modify
nkeynes@709
     9
 * it under the terms of the GNU General Public License as published by
nkeynes@709
    10
 * the Free Software Foundation; either version 2 of the License, or
nkeynes@709
    11
 * (at your option) any later version.
nkeynes@709
    12
 *
nkeynes@709
    13
 * This program is distributed in the hope that it will be useful,
nkeynes@709
    14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
nkeynes@709
    15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
nkeynes@709
    16
 * GNU General Public License for more details.
nkeynes@709
    17
 */
nkeynes@709
    18
nkeynes@709
    19
#include <IOKit/IOKitLib.h>
nkeynes@720
    20
#include <IOKit/IOBSD.h>
nkeynes@709
    21
#include <IOKit/storage/IOStorageDeviceCharacteristics.h>
nkeynes@720
    22
#include <IOKit/storage/IOCDMediaBSDClient.h>
nkeynes@720
    23
#include <IOKit/storage/IOCDTypes.h>
nkeynes@720
    24
#include <sys/param.h>
nkeynes@720
    25
#include <errno.h>
nkeynes@709
    26
#include <stdio.h>
nkeynes@720
    27
#include <string.h>
nkeynes@720
    28
#include <paths.h>
nkeynes@709
    29
#include "gdrom/gddriver.h"
nkeynes@720
    30
#include "gdrom/packet.h"
nkeynes@720
    31
#include "drivers/osx_iokit.h"
nkeynes@709
    32
nkeynes@720
    33
#define MAXTOCENTRIES 600  /* This is a fairly generous overestimate really */
nkeynes@720
    34
#define MAXTOCSIZE 4 + (MAXTOCENTRIES*11)
nkeynes@720
    35
nkeynes@720
    36
static gboolean cdrom_osx_image_is_valid( FILE *f );
nkeynes@720
    37
static gdrom_disc_t cdrom_osx_open_device( const gchar *filename, FILE *f );
nkeynes@720
    38
static gdrom_error_t cdrom_osx_read_toc( gdrom_image_t disc );
nkeynes@720
    39
static gdrom_error_t cdrom_osx_read_sector( gdrom_disc_t disc, uint32_t sector,
nkeynes@736
    40
                                            int mode, unsigned char *buf, uint32_t *length );
nkeynes@709
    41
nkeynes@709
    42
struct gdrom_image_class cdrom_device_class = { "osx", NULL,
nkeynes@736
    43
        cdrom_osx_image_is_valid, cdrom_osx_open_device };
nkeynes@709
    44
nkeynes@720
    45
#define OSX_DRIVE(disc) ( (osx_cdrom_drive_t)(((gdrom_image_t)disc)->private) )
nkeynes@709
    46
nkeynes@720
    47
static void cdrom_osx_destroy( gdrom_disc_t disc )
nkeynes@709
    48
{
nkeynes@720
    49
    osx_cdrom_close_drive( OSX_DRIVE(disc) );
nkeynes@720
    50
    gdrom_image_destroy_no_close( disc );
nkeynes@709
    51
}
nkeynes@709
    52
nkeynes@720
    53
static void cdrom_osx_media_changed( osx_cdrom_drive_t drive, gboolean present,
nkeynes@720
    54
                                     void *user_data )
nkeynes@709
    55
{
nkeynes@720
    56
    gdrom_image_t image = (gdrom_image_t)user_data;
nkeynes@720
    57
    if( present ) {
nkeynes@720
    58
        cdrom_osx_read_toc( image );
nkeynes@720
    59
    } else {
nkeynes@720
    60
        image->disc_type = IDE_DISC_NONE;
nkeynes@720
    61
        image->track_count = 0;        
nkeynes@709
    62
    }
nkeynes@709
    63
}
nkeynes@709
    64
nkeynes@720
    65
nkeynes@720
    66
static gdrom_disc_t cdrom_osx_new( const char *name, osx_cdrom_drive_t drive )
nkeynes@709
    67
{
nkeynes@720
    68
    char tmp[strlen(name)+7];
nkeynes@720
    69
    sprintf( tmp, "dvd://%s", name );
nkeynes@720
    70
    gdrom_image_t image = (gdrom_image_t)gdrom_image_new(tmp, NULL);
nkeynes@720
    71
    image->private = drive;
nkeynes@736
    72
nkeynes@720
    73
    image->disc.read_sector = cdrom_osx_read_sector;
nkeynes@720
    74
    image->disc.close = cdrom_osx_destroy;
nkeynes@720
    75
    cdrom_osx_read_toc(image);
nkeynes@720
    76
    osx_cdrom_set_media_changed_callback( drive, cdrom_osx_media_changed, image );
nkeynes@720
    77
    return (gdrom_disc_t)image;
nkeynes@709
    78
}
nkeynes@709
    79
nkeynes@720
    80
gdrom_disc_t cdrom_open_device( const gchar *method, const gchar *path )
nkeynes@709
    81
{
nkeynes@720
    82
    gdrom_disc_t result = NULL;
nkeynes@736
    83
nkeynes@720
    84
    osx_cdrom_drive_t drive = osx_cdrom_open_drive(path);
nkeynes@720
    85
    if( drive == NULL ) {
nkeynes@709
    86
        return NULL;
nkeynes@720
    87
    } else {
nkeynes@720
    88
        return cdrom_osx_new( path, drive );
nkeynes@709
    89
    }
nkeynes@709
    90
}
nkeynes@709
    91
nkeynes@720
    92
nkeynes@720
    93
nkeynes@720
    94
static gboolean cdrom_enum_callback( io_object_t object, char *vendor, char *product, char *iopath, void *ptr )
nkeynes@709
    95
{
nkeynes@709
    96
    GList **list = (GList **)ptr;
nkeynes@720
    97
    char tmp1[sizeof(io_string_t) + 6];
nkeynes@709
    98
    char tmp2[512];
nkeynes@720
    99
    snprintf( tmp1, sizeof(tmp1), "dvd://%s", iopath );
nkeynes@709
   100
    snprintf( tmp2, sizeof(tmp2), "%s %s", vendor, product );
nkeynes@709
   101
    *list = g_list_append( *list, gdrom_device_new( tmp1, tmp2 ) );
nkeynes@709
   102
    return FALSE;
nkeynes@709
   103
}
nkeynes@709
   104
nkeynes@709
   105
GList *cdrom_get_native_devices(void)
nkeynes@709
   106
{
nkeynes@709
   107
    GList *list = NULL;
nkeynes@720
   108
    find_cdrom_drive(cdrom_enum_callback, &list);
nkeynes@736
   109
nkeynes@720
   110
    osx_register_iokit_notifications();
nkeynes@709
   111
    return list;
nkeynes@709
   112
}
nkeynes@709
   113
nkeynes@709
   114
nkeynes@709
   115
nkeynes@720
   116
static gboolean cdrom_osx_image_is_valid( FILE *f )
nkeynes@709
   117
{
nkeynes@709
   118
    return FALSE;
nkeynes@709
   119
}
nkeynes@709
   120
nkeynes@720
   121
static gdrom_disc_t cdrom_osx_open_device( const gchar *filename, FILE *f )
nkeynes@709
   122
{
nkeynes@709
   123
    return NULL;
nkeynes@709
   124
}
nkeynes@720
   125
nkeynes@720
   126
static gdrom_error_t cdrom_osx_read_toc( gdrom_image_t image )
nkeynes@720
   127
{
nkeynes@720
   128
    osx_cdrom_drive_t drive = OSX_DRIVE(image);
nkeynes@736
   129
nkeynes@720
   130
    int fh = osx_cdrom_get_media_handle(drive);
nkeynes@720
   131
    if( fh == -1 ) {
nkeynes@720
   132
        image->disc_type = IDE_DISC_NONE;
nkeynes@720
   133
        image->track_count = 0;
nkeynes@720
   134
        return -1;
nkeynes@720
   135
    } else {
nkeynes@720
   136
        unsigned char buf[MAXTOCSIZE];
nkeynes@720
   137
        dk_cd_read_toc_t readtoc;
nkeynes@720
   138
        memset( &readtoc, 0, sizeof(readtoc) );
nkeynes@720
   139
        readtoc.format = 2;
nkeynes@720
   140
        readtoc.formatAsTime = 0;
nkeynes@720
   141
        readtoc.address.session = 0;
nkeynes@720
   142
        readtoc.bufferLength = sizeof(buf);
nkeynes@720
   143
        readtoc.buffer = buf;
nkeynes@736
   144
nkeynes@720
   145
        if( ioctl(fh, DKIOCCDREADTOC, &readtoc ) == -1 ) {
nkeynes@720
   146
            ERROR( "Failed to read TOC: %s", strerror(errno) );
nkeynes@720
   147
            image->disc_type = IDE_DISC_NONE;
nkeynes@720
   148
            image->track_count = 0;
nkeynes@720
   149
            return -1;
nkeynes@720
   150
        } else {
nkeynes@720
   151
            mmc_parse_toc2( image, buf );
nkeynes@720
   152
        }
nkeynes@720
   153
    }
nkeynes@720
   154
    return 0;
nkeynes@720
   155
}
nkeynes@720
   156
nkeynes@720
   157
static gdrom_error_t cdrom_osx_read_sector( gdrom_disc_t disc, uint32_t sector,
nkeynes@736
   158
                                            int mode, unsigned char *buf, uint32_t *length ) 
nkeynes@720
   159
{
nkeynes@720
   160
    osx_cdrom_drive_t drive = OSX_DRIVE(disc);
nkeynes@720
   161
    int fh = osx_cdrom_get_media_handle(drive);
nkeynes@720
   162
    if( fh == -1 ) {
nkeynes@720
   163
        return PKT_ERR_NODISC;
nkeynes@720
   164
    } else {
nkeynes@720
   165
        dk_cd_read_t readcd;
nkeynes@720
   166
nkeynes@720
   167
        memset( &readcd, 0, sizeof(readcd) );
nkeynes@720
   168
        // This is complicated by needing to know the exact read size. Gah.
nkeynes@720
   169
        if( READ_CD_RAW(mode) ) {
nkeynes@720
   170
            *length = 2352;
nkeynes@720
   171
            readcd.sectorArea = 0xF8; 
nkeynes@720
   172
        } else {
nkeynes@720
   173
            // This is incomplete...
nkeynes@720
   174
            if( READ_CD_DATA(mode) ) {
nkeynes@720
   175
                readcd.sectorArea = kCDSectorAreaUser;
nkeynes@720
   176
                switch( READ_CD_MODE(mode) ) {
nkeynes@720
   177
                case READ_CD_MODE_CDDA:
nkeynes@720
   178
                    *length = 2352;
nkeynes@720
   179
                    break;
nkeynes@720
   180
                case READ_CD_MODE_1:
nkeynes@720
   181
                case READ_CD_MODE_2_FORM_1:
nkeynes@720
   182
                    *length = 2048;
nkeynes@720
   183
                    break;
nkeynes@720
   184
                case READ_CD_MODE_2:
nkeynes@720
   185
                    *length = 2336;
nkeynes@720
   186
                    break;
nkeynes@720
   187
                case READ_CD_MODE_2_FORM_2:
nkeynes@720
   188
                    *length = 2324;
nkeynes@720
   189
                    break;
nkeynes@720
   190
                }
nkeynes@720
   191
            }
nkeynes@720
   192
        }
nkeynes@736
   193
nkeynes@720
   194
        readcd.offset = *length * (sector - 150);
nkeynes@720
   195
        readcd.sectorType = READ_CD_MODE(mode)>>1;
nkeynes@720
   196
        readcd.bufferLength = *length;
nkeynes@720
   197
        readcd.buffer = buf;
nkeynes@720
   198
        if( ioctl( fh, DKIOCCDREAD, &readcd ) == -1 ) {
nkeynes@720
   199
            ERROR( "Failed to read CD: %s", strerror(errno) );
nkeynes@720
   200
            return -1;
nkeynes@720
   201
        } else {
nkeynes@720
   202
            return 0;
nkeynes@720
   203
        }
nkeynes@720
   204
    }
nkeynes@720
   205
}
nkeynes@720
   206
.