Re: [hatari-devel] Re: Hatari SCSI Driver patch

[ Thread Index | Date Index | More lists.tuxfamily.org/hatari-devel Archives ]


Hi Eero,

The attached diffs add libudev support to the SCSI Driver, on systems
where libudev is available.

Take care

Uwe
diff -r fc78b727e8da CMakeLists.txt
--- a/CMakeLists.txt	Sun Oct 18 13:37:26 2015 +0300
+++ b/CMakeLists.txt	Thu Oct 22 12:20:01 2015 +0200
@@ -135,6 +135,8 @@
 	set(HAVE_CAPSIMAGE 1)
 endif(CAPSIMAGE_FOUND)
 
+find_library(UDEV_LIBRARY udev libudev)
+
 # ################
 # CPP Definitions:
 # ################
@@ -183,6 +185,7 @@
 check_include_files(${SDL_INCLUDE_DIR}/SDL_config.h HAVE_SDL_CONFIG_H)
 check_include_files(sys/times.h HAVE_SYS_TIMES_H)
 check_include_files("sys/socket.h;sys/un.h" HAVE_UNIX_DOMAIN_SOCKETS)
+check_include_files("libudev.h" HAVE_UDEV)
 
 # #############################
 # Check for optional functions:
diff -r fc78b727e8da cmake/config-cmake.h
--- a/cmake/config-cmake.h	Sun Oct 18 13:37:26 2015 +0300
+++ b/cmake/config-cmake.h	Thu Oct 22 12:20:01 2015 +0200
@@ -99,3 +99,6 @@
 
 /* Define to 1 to enable trace logs - undefine to slightly increase speed */
 #cmakedefine ENABLE_TRACING 1
+
+/* Define to 1 if udev support is available */
+#cmakedefine HAVE_UDEV 1
diff -r fc78b727e8da src/CMakeLists.txt
--- a/src/CMakeLists.txt	Sun Oct 18 13:37:26 2015 +0300
+++ b/src/CMakeLists.txt	Thu Oct 22 12:20:01 2015 +0200
@@ -147,6 +147,10 @@
 	target_link_libraries(hatari ${CAPSIMAGE_LIBRARY})
 endif(CAPSIMAGE_FOUND)
 
+if(UDEV_LIBRARY)
+	target_link_libraries(hatari ${UDEV_LIBRARY})
+endif(UDEV_LIBRARY)
+
 if(WIN32)
 	# Needed for socket() on Windows
 	target_link_libraries(hatari ws2_32)
diff -r fc78b727e8da src/nf_scsidrv.c
--- a/src/nf_scsidrv.c	Sun Oct 18 13:37:26 2015 +0300
+++ b/src/nf_scsidrv.c	Thu Oct 22 12:20:01 2015 +0200
@@ -16,9 +16,13 @@
 
 #if defined(__linux__)
 
+#include "config.h"
 #include <stdlib.h>
 #include <unistd.h>
 #include <fcntl.h>
+#ifdef HAVE_UDEV
+#include <libudev.h>
+#endif
 #include <sys/ioctl.h>
 #include <scsi/sg.h>
 #include "stMemory.h"
@@ -47,6 +51,13 @@
 
 static HANDLE_META_DATA handle_meta_data[SCSI_MAX_HANDLES];
 
+#ifdef HAVE_UDEV
+static struct udev *udev;
+static struct udev_monitor *mon;
+static int fd;
+static fd_set udevFds;
+static struct timeval tv;
+#endif
 
 static Uint32 read_stack_long(Uint32 *stack)
 {
@@ -73,19 +84,54 @@
     STMemory_WriteWord(addr, value);
 }
 
-static void set_error(Uint32 handle, Uint32 errnum)
+static void set_error(Uint32 handle, int errbit)
 {
     Uint32 i;
     for(i = 0; i < SCSI_MAX_HANDLES; i++)
     {
         if(handle != i && handle_meta_data[i].fd &&
-           handle_meta_data[i].id_lo == handle_meta_data[handle].id_lo)
+            handle_meta_data[i].id_lo == handle_meta_data[handle].id_lo)
         {
-            handle_meta_data[i].error = errnum;
+            handle_meta_data[i].error |= errbit;
         }
     }
 }
 
+#ifdef HAVE_UDEV
+// udev-based check for media change
+static void check_mchg_udev(void)
+{
+    FD_ZERO(&udevFds);
+    FD_SET(fd, &udevFds);
+
+    int ret = select(fd + 1, &udevFds, 0, 0, &tv);
+    if(ret > 0 && FD_ISSET(fd, &udevFds))
+    {
+        struct udev_device *dev = udev_monitor_receive_device(mon);
+        const char *dev_type = udev_device_get_devtype(dev);
+        const char *action = udev_device_get_action(dev);
+        if(!strcmp("disk",  dev_type) && !strcmp("change", action))
+        {
+            LOG_TRACE(TRACE_SCSIDRV, ": %s was changed",
+                      udev_device_get_devnode(dev));
+
+            // TODO Determine sg device name from block device name
+            // and only report media change for the actually affected device
+            
+            // cErrMediach for all open handles
+            Uint32 i;
+            for(i = 0; i < SCSI_MAX_HANDLES; i++)
+            {
+                if(handle_meta_data[i].fd)
+                {
+                    handle_meta_data[i].error |= 1;
+                }
+            }
+        }
+    }
+}
+#endif
+
 static int check_device_file(Uint32 id)
 {
     char device_file[16];
@@ -149,6 +195,24 @@
 
 static int scsidrv_open(Uint32 stack)
 {
+#ifdef HAVE_UDEV
+    if(!udev)
+    {
+        udev = udev_new();
+        if(!udev) {
+            return -1;
+        }
+
+        mon = udev_monitor_new_from_netlink(udev, "udev");
+        udev_monitor_filter_add_match_subsystem_devtype(mon, "block", NULL);
+        udev_monitor_enable_receiving(mon);
+        fd = udev_monitor_get_fd(mon);
+
+        tv.tv_sec = 0;
+        tv.tv_usec = 0;
+    }
+#endif
+
     Uint32 handle = read_stack_long(&stack);
     Uint32 id = read_stack_long(&stack);
 
@@ -316,16 +380,22 @@
         return GEMDOS_ENHNDL;
     }
 
+    int errbit = 1 << errnum;
+
     if(rwflag)
     {
-        set_error(handle, errnum);
+        set_error(handle, errbit);
 
-        return errnum;
+        return 0;
     }
     else
     {
-        int status = handle_meta_data[handle].error;
-        handle_meta_data[handle].error = 0;
+#ifdef HAVE_UDEV
+        check_mchg_udev();
+#endif
+
+        int status = handle_meta_data[handle].error & errbit;
+        handle_meta_data[handle].error &= ~errbit;
 
         return status;
     }


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/