diff --git a/block/raw-posix.c b/block/raw-posix.c
index ccfec1c..a11a9e7 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -42,9 +42,9 @@
 #include <IOKit/storage/IOMediaBSDClient.h>
 #include <IOKit/storage/IOMedia.h>
 #include <IOKit/storage/IOCDMedia.h>
-//#include <IOKit/storage/IOCDTypes.h>
+#include <IOKit/storage/IODVDMedia.h>
 #include <CoreFoundation/CoreFoundation.h>
-#endif
+#endif /* (__APPLE__) && (__MACH__) */
 
 #ifdef __sun__
 #define _POSIX_PTHREAD_SEMANTICS 1
@@ -1975,32 +1975,44 @@ BlockDriver bdrv_file = {
 /* host device */
 
 #if defined(__APPLE__) && defined(__MACH__)
-static kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator );
 static kern_return_t GetBSDPath(io_iterator_t mediaIterator, char *bsdPath,
                                 CFIndex maxPathSize, int flags);
-kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator )
+static kern_return_t FindEjectableOpticalMedia(io_iterator_t *mediaIterator,
+                                                                char *mediaType)
 {
     kern_return_t       kernResult;
     mach_port_t     masterPort;
     CFMutableDictionaryRef  classesToMatch;
+    const char *matching_array[] = {kIODVDMediaClass, kIOCDMediaClass};
 
     kernResult = IOMasterPort( MACH_PORT_NULL, &masterPort );
     if ( KERN_SUCCESS != kernResult ) {
         printf( "IOMasterPort returned %d\n", kernResult );
     }
 
-    classesToMatch = IOServiceMatching( kIOCDMediaClass );
-    if ( classesToMatch == NULL ) {
-        printf( "IOServiceMatching returned a NULL dictionary.\n" );
-    } else {
-    CFDictionarySetValue( classesToMatch, CFSTR( kIOMediaEjectableKey ), kCFBooleanTrue );
-    }
-    kernResult = IOServiceGetMatchingServices( masterPort, classesToMatch, mediaIterator );
-    if ( KERN_SUCCESS != kernResult )
-    {
-        printf( "IOServiceGetMatchingServices returned %d\n", kernResult );
-    }
+    int index;
+    for (index = 0; index < ARRAY_SIZE(matching_array); index++) {
+        classesToMatch = IOServiceMatching(matching_array[index]);
+        if (classesToMatch == NULL) {
+            printf("IOServiceMatching returned a NULL dictionary.\n");
+        } else {
+        CFDictionarySetValue(classesToMatch, CFSTR(kIOMediaEjectableKey),
+                                                                kCFBooleanTrue);
+        }
+        kernResult = IOServiceGetMatchingServices(masterPort, classesToMatch,
+                                                                 mediaIterator);
+        if (KERN_SUCCESS != kernResult) {
+            printf("IOServiceGetMatchingServices returned %d\n", kernResult);
+        }
 
+        /* If you found a match, leave the loop */
+        if (*mediaIterator != 0) {
+            DPRINTF("Matching using %s\n", matching_array[index]);
+            snprintf(mediaType, strlen(matching_array[index])+1, "%s",
+                                                         matching_array[index]);
+            break;
+        }
+    }
     return kernResult;
 }
 
@@ -2033,7 +2045,36 @@ kern_return_t GetBSDPath(io_iterator_t mediaIterator, char *bsdPath,
     return kernResult;
 }
 
-#endif
+/* Sets up a real cdrom for use in QEMU */
+static bool setup_cdrom(char *bsd_path, Error **errp)
+{
+    int index, num_of_test_partitions = 2, fd;
+    char test_partition[MAXPATHLEN];
+    bool partition_found = false;
+
+    /* look for a working partition */
+    for (index = 0; index < num_of_test_partitions; index++) {
+        snprintf(test_partition, sizeof(test_partition), "%ss%d", bsd_path,
+                                                                         index);
+        fd = qemu_open(test_partition, O_RDONLY | O_BINARY | O_LARGEFILE);
+        if (fd >= 0) {
+            partition_found = true;
+            qemu_close(fd);
+            break;
+        }
+    }
+
+    /* if a working partition on the device was not found */
+    if (partition_found == false) {
+        error_setg(errp, "Error: Failed to find a working partition on "
+                                                                     "disc!\n");
+    } else {
+        DPRINTF("Using %s as optical disc\n", test_partition);
+        pstrcpy(bsd_path, MAXPATHLEN, test_partition);
+    }
+    return partition_found;
+}
+#endif /* defined(__APPLE__) && defined(__MACH__) */
 
 static int hdev_probe_device(const char *filename)
 {
@@ -2115,6 +2156,17 @@ static bool hdev_is_sg(BlockDriverState *bs)
     return false;
 }
 
+/* Prints directions on mounting and unmounting a device */
+static void print_unmounting_directions(const char *file_name)
+{
+    error_report("Error: If device %s is mounted on the desktop, unmount"
+                             " it first before using it in QEMU.\n", file_name);
+    error_report("Command to unmount device: diskutil unmountDisk %s\n",
+                                                                     file_name);
+    error_report("Command to mount device: diskutil mountDisk %s\n",
+                                                                     file_name);
+}
+
 static int hdev_open(BlockDriverState *bs, QDict *options, int flags,
                      Error **errp)
 {
@@ -2125,30 +2177,33 @@ static int hdev_open(BlockDriverState *bs, QDict *options, int flags,
 #if defined(__APPLE__) && defined(__MACH__)
     const char *filename = qdict_get_str(options, "filename");
 
-    if (strstart(filename, "/dev/cdrom", NULL)) {
-        kern_return_t kernResult;
+    /* If using a real cdrom */
+    if (strcmp(filename, "/dev/cdrom") == 0) {
+        char bsd_path[MAXPATHLEN];
+        char mediaType[11]; /* IODVDMedia is the longest value */
         io_iterator_t mediaIterator;
-        char bsdPath[ MAXPATHLEN ];
-        int fd;
-
-        kernResult = FindEjectableCDMedia( &mediaIterator );
-        kernResult = GetBSDPath(mediaIterator, bsdPath, sizeof(bsdPath),
-                                                                        flags);
-        if ( bsdPath[ 0 ] != '\0' ) {
-            strcat(bsdPath,"s0");
-            /* some CDs don't have a partition 0 */
-            fd = qemu_open(bsdPath, O_RDONLY | O_BINARY | O_LARGEFILE);
-            if (fd < 0) {
-                bsdPath[strlen(bsdPath)-1] = '1';
-            } else {
-                qemu_close(fd);
-            }
-            filename = bsdPath;
-            qdict_put(options, "filename", qstring_from_str(filename));
+        FindEjectableOpticalMedia(&mediaIterator, mediaType);
+        GetBSDPath(mediaIterator, bsd_path, sizeof(bsd_path), flags);
+        if (mediaIterator) {
+            IOObjectRelease(mediaIterator);
         }
 
-        if ( mediaIterator )
-            IOObjectRelease( mediaIterator );
+        /* If a real optical drive was not found */
+        if (bsd_path[0] == '\0') {
+            error_setg(errp, "Error: failed to obtain bsd path for optical"
+                                                                   " drive!\n");
+            return -1;
+        }
+
+        /* If using a cdrom disc and finding a partition on the disc failed */
+        if (strncmp(mediaType, "IOCDMedia", 9) == 0 &&
+                                         setup_cdrom(bsd_path, errp) == false) {
+            print_unmounting_directions(bsd_path);
+            return -1;
+        }
+
+        filename = bsd_path;
+        qdict_put(options, "filename", qstring_from_str(filename));
     }
 #endif
 
@@ -2159,9 +2214,16 @@ static int hdev_open(BlockDriverState *bs, QDict *options, int flags,
         if (local_err) {
             error_propagate(errp, local_err);
         }
-        return ret;
     }
 
+#if defined(__APPLE__) && defined(__MACH__)
+    /* if a physical device experienced an error while being opened */
+    if (strncmp(filename, "/dev/", 5) == 0 && ret != 0) {
+        print_unmounting_directions(filename);
+        return -1;
+    }
+#endif /* defined(__APPLE__) && defined(__MACH__) */
+
     /* Since this does ioctl the device must be already opened */
     bs->sg = hdev_is_sg(bs);
 
