Commit 3b0d4f61c917c4612b561d75b33a11f4da00738b
1 parent
87f48e6a
OS X: support for the built in CD-ROM drive (Mike Kronenberg)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1583 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
107 additions
and
1 deletions
block.c
... | ... | @@ -32,9 +32,79 @@ |
32 | 32 | #include <sys/disk.h> |
33 | 33 | #endif |
34 | 34 | |
35 | +#ifdef CONFIG_COCOA | |
36 | +#include <paths.h> | |
37 | +#include <sys/param.h> | |
38 | +#include <IOKit/IOKitLib.h> | |
39 | +#include <IOKit/IOBSD.h> | |
40 | +#include <IOKit/storage/IOMediaBSDClient.h> | |
41 | +#include <IOKit/storage/IOMedia.h> | |
42 | +#include <IOKit/storage/IOCDMedia.h> | |
43 | +//#include <IOKit/storage/IOCDTypes.h> | |
44 | +#include <CoreFoundation/CoreFoundation.h> | |
45 | +#endif | |
46 | + | |
35 | 47 | static BlockDriverState *bdrv_first; |
36 | 48 | static BlockDriver *first_drv; |
37 | 49 | |
50 | +#ifdef CONFIG_COCOA | |
51 | +static kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator ); | |
52 | +static kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize ); | |
53 | + | |
54 | +kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator ) | |
55 | +{ | |
56 | + kern_return_t kernResult; | |
57 | + mach_port_t masterPort; | |
58 | + CFMutableDictionaryRef classesToMatch; | |
59 | + | |
60 | + kernResult = IOMasterPort( MACH_PORT_NULL, &masterPort ); | |
61 | + if ( KERN_SUCCESS != kernResult ) { | |
62 | + printf( "IOMasterPort returned %d\n", kernResult ); | |
63 | + } | |
64 | + | |
65 | + classesToMatch = IOServiceMatching( kIOCDMediaClass ); | |
66 | + if ( classesToMatch == NULL ) { | |
67 | + printf( "IOServiceMatching returned a NULL dictionary.\n" ); | |
68 | + } else { | |
69 | + CFDictionarySetValue( classesToMatch, CFSTR( kIOMediaEjectableKey ), kCFBooleanTrue ); | |
70 | + } | |
71 | + kernResult = IOServiceGetMatchingServices( masterPort, classesToMatch, mediaIterator ); | |
72 | + if ( KERN_SUCCESS != kernResult ) | |
73 | + { | |
74 | + printf( "IOServiceGetMatchingServices returned %d\n", kernResult ); | |
75 | + } | |
76 | + | |
77 | + return kernResult; | |
78 | +} | |
79 | + | |
80 | +kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize ) | |
81 | +{ | |
82 | + io_object_t nextMedia; | |
83 | + kern_return_t kernResult = KERN_FAILURE; | |
84 | + *bsdPath = '\0'; | |
85 | + nextMedia = IOIteratorNext( mediaIterator ); | |
86 | + if ( nextMedia ) | |
87 | + { | |
88 | + CFTypeRef bsdPathAsCFString; | |
89 | + bsdPathAsCFString = IORegistryEntryCreateCFProperty( nextMedia, CFSTR( kIOBSDNameKey ), kCFAllocatorDefault, 0 ); | |
90 | + if ( bsdPathAsCFString ) { | |
91 | + size_t devPathLength; | |
92 | + strcpy( bsdPath, _PATH_DEV ); | |
93 | + strcat( bsdPath, "r" ); | |
94 | + devPathLength = strlen( bsdPath ); | |
95 | + if ( CFStringGetCString( bsdPathAsCFString, bsdPath + devPathLength, maxPathSize - devPathLength, kCFStringEncodingASCII ) ) { | |
96 | + kernResult = KERN_SUCCESS; | |
97 | + } | |
98 | + CFRelease( bsdPathAsCFString ); | |
99 | + } | |
100 | + IOObjectRelease( nextMedia ); | |
101 | + } | |
102 | + | |
103 | + return kernResult; | |
104 | +} | |
105 | + | |
106 | +#endif | |
107 | + | |
38 | 108 | void bdrv_register(BlockDriver *bdrv) |
39 | 109 | { |
40 | 110 | bdrv->next = first_drv; |
... | ... | @@ -118,6 +188,12 @@ static BlockDriver *find_image_format(const char *filename) |
118 | 188 | bufsize = sectorsize; |
119 | 189 | } |
120 | 190 | #endif |
191 | +#ifdef CONFIG_COCOA | |
192 | + u_int32_t blockSize = 512; | |
193 | + if ( !ioctl( fd, DKIOCGETBLOCKSIZE, &blockSize ) && blockSize > bufsize) { | |
194 | + bufsize = blockSize; | |
195 | + } | |
196 | +#endif | |
121 | 197 | buf = qemu_malloc(bufsize); |
122 | 198 | if (!buf) |
123 | 199 | return NULL; |
... | ... | @@ -145,6 +221,32 @@ static BlockDriver *find_image_format(const char *filename) |
145 | 221 | |
146 | 222 | int bdrv_open(BlockDriverState *bs, const char *filename, int snapshot) |
147 | 223 | { |
224 | +#ifdef CONFIG_COCOA | |
225 | + if ( strncmp( filename, "/dev/cdrom", 10 ) == 0 ) { | |
226 | + kern_return_t kernResult; | |
227 | + io_iterator_t mediaIterator; | |
228 | + char bsdPath[ MAXPATHLEN ]; | |
229 | + int fd; | |
230 | + | |
231 | + kernResult = FindEjectableCDMedia( &mediaIterator ); | |
232 | + kernResult = GetBSDPath( mediaIterator, bsdPath, sizeof( bsdPath ) ); | |
233 | + | |
234 | + if ( bsdPath[ 0 ] != '\0' ) { | |
235 | + strcat(bsdPath,"s0"); | |
236 | + /* some CDs don't have a partition 0 */ | |
237 | + fd = open(bsdPath, O_RDONLY | O_BINARY | O_LARGEFILE); | |
238 | + if (fd < 0) { | |
239 | + bsdPath[strlen(bsdPath)-1] = '1'; | |
240 | + } else { | |
241 | + close(fd); | |
242 | + } | |
243 | + filename = bsdPath; | |
244 | + } | |
245 | + | |
246 | + if ( mediaIterator ) | |
247 | + IOObjectRelease( mediaIterator ); | |
248 | + } | |
249 | +#endif | |
148 | 250 | return bdrv_open2(bs, filename, snapshot, NULL); |
149 | 251 | } |
150 | 252 | |
... | ... | @@ -567,7 +669,11 @@ static int raw_open(BlockDriverState *bs, const char *filename) |
567 | 669 | #ifdef DIOCGMEDIASIZE |
568 | 670 | if (ioctl(fd, DIOCGMEDIASIZE, (off_t *)&size)) |
569 | 671 | #endif |
570 | - size = lseek(fd, 0LL, SEEK_END); | |
672 | +#ifdef CONFIG_COCOA | |
673 | + size = LONG_LONG_MAX; | |
674 | +#else | |
675 | + size = lseek(fd, 0LL, SEEK_END); | |
676 | +#endif | |
571 | 677 | } else |
572 | 678 | #endif |
573 | 679 | { | ... | ... |