raw-posix: split hdev drivers

Instead of declaring one BlockDriver for all host devices declared one
for each type:  a generic one for normal disk devices, a Linux floppy
driver and a CDROM driver for Linux and FreeBSD.  This gets rid of a lot
of messy ifdefs and switching based on the type in the various removal
device methods.

block.c grows a new method to find the correct host device driver based
on OS-sepcific criteria, which will later into the actual drivers in a
later patch in this series.

Signed-off-by: Christoph Hellwig <hch@lst.de>
diff --git a/block.c b/block.c
index e6b91c6..2e20593 100644
--- a/block.c
+++ b/block.c
@@ -249,8 +249,48 @@
     return NULL;
 }
 
-/* XXX: force raw format if block or character device ? It would
-   simplify the BSD case */
+/*
+ * Detect host devices. By convention, /dev/cdrom[N] is always
+ * recognized as a host CDROM.
+ */
+#ifdef _WIN32
+static BlockDriver *find_hdev_driver(const char *filename)
+{
+    if (strstart(filename, "/dev/cdrom", NULL))
+        return bdrv_find_format("host_device");
+    if (is_windows_drive(filename))
+        return bdrv_find_format("host_device");
+    return NULL;
+}
+#else
+static BlockDriver *find_hdev_driver(const char *filename)
+{
+    struct stat st;
+
+#ifdef __linux__
+    if (strstart(filename, "/dev/fd", NULL))
+        return bdrv_find_format("host_floppy");
+    if (strstart(filename, "/dev/cd", NULL))
+        return bdrv_find_format("host_cdrom");
+#elif defined(__FreeBSD__)
+    if (strstart(filename, "/dev/cd", NULL) ||
+        strstart(filename, "/dev/acd", NULL)) {
+        return bdrv_find_format("host_cdrom");
+    }
+#else
+    if (strstart(filename, "/dev/cdrom", NULL))
+        return bdrv_find_format("host_device");
+#endif
+
+    if (stat(filename, &st) >= 0 &&
+            (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode))) {
+        return bdrv_find_format("host_device");
+    }
+
+    return NULL;
+}
+#endif
+
 static BlockDriver *find_image_format(const char *filename)
 {
     int ret, score, score_max;
@@ -258,23 +298,6 @@
     uint8_t buf[2048];
     BlockDriverState *bs;
 
-    /* detect host devices. By convention, /dev/cdrom[N] is always
-       recognized as a host CDROM */
-    if (strstart(filename, "/dev/cdrom", NULL))
-        return bdrv_find_format("host_device");
-#ifdef _WIN32
-    if (is_windows_drive(filename))
-        return bdrv_find_format("host_device");
-#else
-    {
-        struct stat st;
-        if (stat(filename, &st) >= 0 &&
-            (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode))) {
-            return bdrv_find_format("host_device");
-        }
-    }
-#endif
-
     drv = find_protocol(filename);
     /* no need to test disk image formats for vvfat */
     if (drv && strcmp(drv->format_name, "vvfat") == 0)
@@ -394,7 +417,10 @@
     if (flags & BDRV_O_FILE) {
         drv = find_protocol(filename);
     } else if (!drv) {
-        drv = find_image_format(filename);
+        drv = find_hdev_driver(filename);
+        if (!drv) {
+            drv = find_image_format(filename);
+        }
     }
     if (!drv) {
         ret = -ENOENT;