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