diff --git a/CHANGELOG b/CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,11 @@
+haskell-libmodbus (1.1.2) unstable; urgency=medium
+
+  * Change FFI calls to not be unsafe, to prevent a FFI call
+    that stalls for some reason (such as a broken device)
+    from blocking haskell threads.
+
+ -- Joey Hess <id@joeyh.name>  Wed, 23 Mar 2022 13:26:09 -0400
+
 haskell-libmodbus (1.1.1) unstable; urgency=medium
 
   * Use modbus_strerror for better messages in exceptions.
diff --git a/System/Modbus.hsc b/System/Modbus.hsc
--- a/System/Modbus.hsc
+++ b/System/Modbus.hsc
@@ -136,91 +136,91 @@
 import qualified Data.ByteString.Lazy as L
 import GHC.IO.Exception
 
-foreign import ccall unsafe "modbus.h &modbus_close" modbus_close
+foreign import ccall "modbus.h &modbus_close" modbus_close
 	:: FunPtr (Ptr () -> IO ())
 
-foreign import ccall unsafe "modbus.h &modbus_free" modbus_free
+foreign import ccall "modbus.h &modbus_free" modbus_free
 	:: FunPtr (Ptr () -> IO ())
 
-foreign import ccall unsafe "modbus.h modbus_new_rtu" modbus_new_rtu
+foreign import ccall "modbus.h modbus_new_rtu" modbus_new_rtu
 	:: CString -> Int -> CChar -> Int -> Int -> IO (Ptr ())
 
-foreign import ccall unsafe "modbus.h modbus_rtu_get_serial_mode" modbus_rtu_get_serial_mode
+foreign import ccall "modbus.h modbus_rtu_get_serial_mode" modbus_rtu_get_serial_mode
 	:: Ptr () -> IO Int
 
-foreign import ccall unsafe "modbus.h modbus_rtu_set_serial_mode" modbus_rtu_set_serial_mode
+foreign import ccall "modbus.h modbus_rtu_set_serial_mode" modbus_rtu_set_serial_mode
 	:: Ptr () -> Int -> IO Int
 
-foreign import ccall unsafe "modbus.h modbus_rtu_get_rts" modbus_rtu_get_rts
+foreign import ccall "modbus.h modbus_rtu_get_rts" modbus_rtu_get_rts
 	:: Ptr () -> IO Int
 
-foreign import ccall unsafe "modbus.h modbus_rtu_set_rts" modbus_rtu_set_rts
+foreign import ccall "modbus.h modbus_rtu_set_rts" modbus_rtu_set_rts
 	:: Ptr () -> Int -> IO Int
 
-foreign import ccall unsafe "modbus.h modbus_rtu_get_rts_delay" modbus_rtu_get_rts_delay
+foreign import ccall "modbus.h modbus_rtu_get_rts_delay" modbus_rtu_get_rts_delay
 	:: Ptr () -> IO Int
 
-foreign import ccall unsafe "modbus.h modbus_rtu_set_rts_delay" modbus_rtu_set_rts_delay
+foreign import ccall "modbus.h modbus_rtu_set_rts_delay" modbus_rtu_set_rts_delay
 	:: Ptr () -> Int -> IO Int
 
-foreign import ccall unsafe "modbus.h modbus_new_tcp" modbus_new_tcp
+foreign import ccall "modbus.h modbus_new_tcp" modbus_new_tcp
 	:: CString -> Int -> IO (Ptr ())
 
-foreign import ccall unsafe "modbus.h modbus_new_tcp" modbus_new_tcp_pi
+foreign import ccall "modbus.h modbus_new_tcp" modbus_new_tcp_pi
 	:: CString -> CString -> IO (Ptr ())
 
-foreign import ccall unsafe "modbus.h modbus_set_slave" modbus_set_slave
+foreign import ccall "modbus.h modbus_set_slave" modbus_set_slave
 	:: Ptr () -> Int -> IO Int
 
-foreign import ccall unsafe "modbus.h modbus_connect" modbus_connect
+foreign import ccall "modbus.h modbus_connect" modbus_connect
 	:: Ptr () -> IO Int
 
-foreign import ccall unsafe "modbus.h modbus_set_debug" modbus_set_debug
+foreign import ccall "modbus.h modbus_set_debug" modbus_set_debug
 	:: Ptr () -> Int -> IO Int
 
-foreign import ccall unsafe "modbus.h modbus_get_byte_timeout" modbus_get_byte_timeout
+foreign import ccall "modbus.h modbus_get_byte_timeout" modbus_get_byte_timeout
 	:: Ptr () -> Ptr Word32 -> Ptr Word32 -> IO Int
 
-foreign import ccall unsafe "modbus.h modbus_set_byte_timeout" modbus_set_byte_timeout
+foreign import ccall "modbus.h modbus_set_byte_timeout" modbus_set_byte_timeout
 	:: Ptr () -> Ptr Word32 -> Ptr Word32 -> IO Int
 
-foreign import ccall unsafe "modbus.h modbus_get_response_timeout" modbus_get_response_timeout
+foreign import ccall "modbus.h modbus_get_response_timeout" modbus_get_response_timeout
 	:: Ptr () -> Ptr Word32 -> Ptr Word32 -> IO Int
 
-foreign import ccall unsafe "modbus.h modbus_set_response_timeout" modbus_set_response_timeout
+foreign import ccall "modbus.h modbus_set_response_timeout" modbus_set_response_timeout
 	:: Ptr () -> Ptr Word32 -> Ptr Word32 -> IO Int
 
-foreign import ccall unsafe "modbus.h modbus_set_error_recovery" modbus_set_error_recovery
+foreign import ccall "modbus.h modbus_set_error_recovery" modbus_set_error_recovery
 	:: Ptr () -> Int -> IO Int
 
-foreign import ccall unsafe "modbus.h modbus_read_registers" modbus_read_registers
+foreign import ccall "modbus.h modbus_read_registers" modbus_read_registers
 	:: Ptr () -> Int -> Int -> Ptr Word16 -> IO Int
 
-foreign import ccall unsafe "modbus.h modbus_read_input_registers" modbus_read_input_registers
+foreign import ccall "modbus.h modbus_read_input_registers" modbus_read_input_registers
 	:: Ptr () -> Int -> Int -> Ptr Word16 -> IO Int
 
-foreign import ccall unsafe "modbus.h modbus_write_registers" modbus_write_registers
+foreign import ccall "modbus.h modbus_write_registers" modbus_write_registers
 	:: Ptr () -> Int -> Int -> Ptr Word16 -> IO Int
 
-foreign import ccall unsafe "modbus.h modbus_write_register" modbus_write_register
+foreign import ccall "modbus.h modbus_write_register" modbus_write_register
 	:: Ptr () -> Int -> Word16 -> IO Int
 
-foreign import ccall unsafe "modbus.h modbus_write_and_read_registers" modbus_write_and_read_registers
+foreign import ccall "modbus.h modbus_write_and_read_registers" modbus_write_and_read_registers
 	:: Ptr () -> Int -> Int -> Ptr Word16 -> Int -> Int -> Ptr Word16 -> IO Int
 
-foreign import ccall unsafe "modbus.h modbus_read_bits" modbus_read_bits
+foreign import ccall "modbus.h modbus_read_bits" modbus_read_bits
 	:: Ptr () -> Int -> Int -> Ptr Word8 -> IO Int
 
-foreign import ccall unsafe "modbus.h modbus_read_input_bits" modbus_read_input_bits
+foreign import ccall "modbus.h modbus_read_input_bits" modbus_read_input_bits
 	:: Ptr () -> Int -> Int -> Ptr Word8 -> IO Int
 
-foreign import ccall unsafe "modbus.h modbus_write_bits" modbus_write_bits
+foreign import ccall "modbus.h modbus_write_bits" modbus_write_bits
 	:: Ptr () -> Int -> Int -> Ptr Word8 -> IO Int
 
-foreign import ccall unsafe "modbus.h modbus_write_bit" modbus_write_bit
+foreign import ccall "modbus.h modbus_write_bit" modbus_write_bit
 	:: Ptr () -> Int -> Int -> IO Int
 
-foreign import ccall unsafe "modbus.h modbus_strerror" modbus_strerror
+foreign import ccall "modbus.h modbus_strerror" modbus_strerror
 	:: Errno -> IO (Ptr CChar)
 
 accessVector
diff --git a/libmodbus.cabal b/libmodbus.cabal
--- a/libmodbus.cabal
+++ b/libmodbus.cabal
@@ -1,6 +1,6 @@
 Name: libmodbus
-Version: 1.1.1
-Cabal-Version: >= 1.8
+Version: 1.1.2
+Cabal-Version: >= 1.10
 License: BSD2
 Maintainer: Joey Hess <id@joeyh.name>
 Author: Joey Hess
@@ -22,6 +22,7 @@
   GHC-Options: -Wall -fno-warn-tabs
   Extra-Libraries: modbus
   Exposed-Modules: System.Modbus
+  Default-Language: Haskell2010
   Build-Depends:
     base >= 4.5 && < 5,
     vector >= 0.12 && <= 0.13, 
