diff --git a/ChangeLog b/ChangeLog
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+Changes in 0.1.0.4
+
+* No need to explicitly pass #. of samples to bladeRFSyncTx
+  since we already have length encoded in the ByteString.
+* Ensure we close the device resource on exception within
+  the bracket of 'withBladeRF'.
+* Generalise bladerf_open() error handling.
+* Wrap C return error codes such that they are translated
+  into typed values of BladeRFError.
+* Provide a primitives to wrap C rets.
+* Map C err values to BladeRFError type.
+* Docs - Make a note about the pre-conditions of
+  bladeRFSynx{R,T}x action calls.
+* Bind bladerf_log_set_verbosity().
+* Use 'BLADERF_SERIAL_LENGTH' const over hard-coded const '33'.
+
 Changes in 0.1.0.3
 
 * HLint clean project.
diff --git a/hlibBladeRF.cabal b/hlibBladeRF.cabal
--- a/hlibBladeRF.cabal
+++ b/hlibBladeRF.cabal
@@ -2,7 +2,7 @@
 -- documentation, see http://haskell.org/cabal/users-guide/
 
 name:                hlibBladeRF
-version:             0.1.0.3
+version:             0.1.0.4
 synopsis:            Haskell binding to libBladeRF SDR library
 description:         IO Monadic binding for libbladeRF software defined radio.
 homepage:            https://victoredwardocallaghan.github.io/hlibBladeRF
@@ -77,4 +77,4 @@
   type:                git
   location:            git://github.com/victoredwardocallaghan/hlibBladeRF
   branch:              master
-  tag:                 v0.1.0.3
+  tag:                 v0.1.0.4
diff --git a/src/LibBladeRF/Flash.hs b/src/LibBladeRF/Flash.hs
--- a/src/LibBladeRF/Flash.hs
+++ b/src/LibBladeRF/Flash.hs
@@ -31,8 +31,10 @@
 bladeRFEraseFlash :: DeviceHandle  -- ^ Device handle
                   -> Word32        -- ^ Erase block to start erasing at
                   -> Word32        -- ^ Number of blocks to erase.
-                  -> IO CInt
-bladeRFEraseFlash dev = c'bladerf_erase_flash (unDeviceHandle dev)
+                  -> IO (Either BladeRFError ())
+bladeRFEraseFlash dev b n = do
+  ret <- c'bladerf_erase_flash (unDeviceHandle dev) b n
+  return $ bladeRFErrorTy ret
 
 -- | Read data from the bladeRF's SPI flash.
 --
@@ -51,9 +53,9 @@
                   -> BS.ByteString    -- ^ Data to write to flash
                   -> Word32           -- ^ page  Page to begin writing at
                   -> Word32           -- ^ count
-                  -> IO ()
+                  -> IO (Either BladeRFError ())
 bladeRFWriteFlash dev b p c = allocaBytes (fromIntegral $ p * c'BLADERF_FLASH_PAGE_SIZE) $ \bptr -> do
   -- XXX - Buffer allocation size must be `page` * BLADERF_FLASH_PAGE_SIZE bytes or larger.
   pokeArray bptr (BS.unpack b) -- XXX can we overflow here??
-  _ <- c'bladerf_write_flash (unDeviceHandle dev) bptr p c
-  return () -- ignore ret
+  ret <- c'bladerf_write_flash (unDeviceHandle dev) bptr p c
+  return $ bladeRFErrorTy ret
diff --git a/src/LibBladeRF/Frequency.hs b/src/LibBladeRF/Frequency.hs
--- a/src/LibBladeRF/Frequency.hs
+++ b/src/LibBladeRF/Frequency.hs
@@ -28,10 +28,10 @@
 -- | Write value to VCTCXO DAC.
 bladeRFDACWrite :: DeviceHandle -- ^ Device handle
                 -> Word16       -- ^ Data to write to DAC register
-                -> IO ()
+                -> IO (Either BladeRFError ())
 bladeRFDACWrite dev v = do
-  c'bladerf_dac_write (unDeviceHandle dev) v
-  return () -- ignores ret
+  ret <- c'bladerf_dac_write (unDeviceHandle dev) v
+  return $ bladeRFErrorTy ret
 
 -- | Get module's current frequency in Hz.
 bladeRFGetFrequency :: DeviceHandle  -- ^ Device handle
@@ -47,10 +47,10 @@
 bladeRFSetFrequency :: DeviceHandle  -- ^ Device handle
                     -> BladeRFModule -- ^ Module to configure
                     -> Int           -- ^ Desired frequency
-                    -> IO ()
+                    -> IO (Either BladeRFError ())
 bladeRFSetFrequency dev m f = do
-  c'bladerf_set_frequency (unDeviceHandle dev) ((fromIntegral . fromEnum) m) (fromIntegral f)
-  return () -- ignores ret
+  ret <- c'bladerf_set_frequency (unDeviceHandle dev) ((fromIntegral . fromEnum) m) (fromIntegral f)
+  return $ bladeRFErrorTy ret
 
 -- | Obtain the current value of the specified configuration parameter.
 bladeRFGetCorrection :: DeviceHandle       -- ^ Device handle
@@ -66,7 +66,7 @@
                      -> BladeRFModule     -- ^ Module to apply correction to
                      -> BladeRFCorrection -- ^ Correction type
                      -> Word16            -- ^ Value to apply
-                     -> IO ()
+                     -> IO (Either BladeRFError ())
 bladeRFSetCorrection dev m c v = do
-  c'bladerf_set_correction (unDeviceHandle dev) ((fromIntegral . fromEnum) m) ((fromIntegral . fromEnum) c) v
-  return () -- ignores ret
+  ret <- c'bladerf_set_correction (unDeviceHandle dev) ((fromIntegral . fromEnum) m) ((fromIntegral . fromEnum) c) v
+  return $ bladeRFErrorTy ret
diff --git a/src/LibBladeRF/Gain.hs b/src/LibBladeRF/Gain.hs
--- a/src/LibBladeRF/Gain.hs
+++ b/src/LibBladeRF/Gain.hs
@@ -40,10 +40,10 @@
 -- | Set the PA gain in dB.
 bladeRFSetTXVGA2 :: DeviceHandle -- ^ Device handle
                  -> Int          -- ^ Desired gain
-                 -> IO ()
+                 -> IO (Either BladeRFError ())
 bladeRFSetTXVGA2 dev g = do
-  c'bladerf_set_txvga2 (unDeviceHandle dev) (fromIntegral g)
-  return () -- ignores ret
+  ret <- c'bladerf_set_txvga2 (unDeviceHandle dev) (fromIntegral g)
+  return $ bladeRFErrorTy ret
 
 -- | Get the PA gain in dB.
 bladeRFGetTXVGA2 :: DeviceHandle -- ^ Device handle
@@ -57,10 +57,10 @@
 -- | Set the post-LPF gain in dB.
 bladeRFSetTXVGA1 :: DeviceHandle         -- ^ Device handle
                  -> BladeRFVGAGainBounds -- ^ Desired gain
-                 -> IO ()
+                 -> IO (Either BladeRFError ())
 bladeRFSetTXVGA1 dev g = do
-  c'bladerf_set_txvga1 (unDeviceHandle dev) ((fromIntegral . fromEnum) g)
-  return () -- ignores ret
+  ret <- c'bladerf_set_txvga1 (unDeviceHandle dev) ((fromIntegral . fromEnum) g)
+  return $ bladeRFErrorTy ret
 
 -- | Get the post-LPF gain in dB.
 bladeRFGetTXVGA1 :: DeviceHandle -- ^ Device handle
@@ -74,10 +74,10 @@
 -- | Set the post-LPF VGA gain.
 bladeRFSetRXVGA2 :: DeviceHandle         -- ^ Device handle
                  -> BladeRFVGAGainBounds -- ^ Desired gain
-                 -> IO ()
+                 -> IO (Either BladeRFError ())
 bladeRFSetRXVGA2 dev g = do
-  c'bladerf_set_rxvga2 (unDeviceHandle dev) ((fromIntegral . fromEnum) g)
-  return () -- ignores ret
+  ret <- c'bladerf_set_rxvga2 (unDeviceHandle dev) ((fromIntegral . fromEnum) g)
+  return $ bladeRFErrorTy ret
 
 -- | Get the post-LPF VGA gain.
 bladeRFGetRXVGA2 :: DeviceHandle -- ^ Device handle
@@ -91,10 +91,10 @@
 -- | Set the pre-LPF VGA gain.
 bladeRFSetRXVGA1 :: DeviceHandle         -- ^ Device handle
                  -> BladeRFVGAGainBounds -- ^ Desired gain
-                 -> IO ()
+                 -> IO (Either BladeRFError ())
 bladeRFSetRXVGA1 dev g = do
-  c'bladerf_set_rxvga1 (unDeviceHandle dev) ((fromIntegral . fromEnum) g)
-  return () -- ignores ret
+  ret <- c'bladerf_set_rxvga1 (unDeviceHandle dev) ((fromIntegral . fromEnum) g)
+  return $ bladeRFErrorTy ret
 
 -- | Get the pre-LPF VGA gain.
 bladeRFGetRXVGA1 :: DeviceHandle -- ^ Device handle
@@ -108,10 +108,10 @@
 -- | Set LNA Gain.
 bladeRFSetLNAGain :: DeviceHandle   -- ^ Device handle
                   -> BladeRFLNAGain -- ^ Desired gain level
-                  -> IO ()
+                  -> IO (Either BladeRFError ())
 bladeRFSetLNAGain dev g = do
-  c'bladerf_set_lna_gain (unDeviceHandle dev) ((fromIntegral . fromEnum) g)
-  return () -- ignores ret
+  ret <- c'bladerf_set_lna_gain (unDeviceHandle dev) ((fromIntegral . fromEnum) g)
+  return $ bladeRFErrorTy ret
 
 -- | Get LNA Gain.
 bladeRFGetLNAGain :: DeviceHandle      -- ^ Device handle
@@ -130,7 +130,7 @@
 bladeRFSetGain :: DeviceHandle  -- ^ Device handle
                -> BladeRFModule -- ^ Module
                -> Int           -- ^ Desired gain
-               -> IO ()
+               -> IO (Either BladeRFError ())
 bladeRFSetGain dev m g = do
-  c'bladerf_set_gain (unDeviceHandle dev) ((fromIntegral . fromEnum) m) (fromIntegral g)
-  return () -- ignores ret
+  ret <- c'bladerf_set_gain (unDeviceHandle dev) ((fromIntegral . fromEnum) m) (fromIntegral g)
+  return $ bladeRFErrorTy ret
diff --git a/src/LibBladeRF/Gpio.hs b/src/LibBladeRF/Gpio.hs
--- a/src/LibBladeRF/Gpio.hs
+++ b/src/LibBladeRF/Gpio.hs
@@ -35,7 +35,7 @@
 -- accidentally clearing other GPIO bits that may be set by the library internally.
 bladeRFConfigGPIOWrite :: DeviceHandle -- ^ Device handle
                        -> Word32       -- ^ Data to write to GPIO register
-                       -> IO ()
+                       -> IO (Either BladeRFError ())
 bladeRFConfigGPIOWrite dev v = do
-  c'bladerf_config_gpio_write (unDeviceHandle dev) v
-  return () -- ignores ret
+  ret <- c'bladerf_config_gpio_write (unDeviceHandle dev) v
+  return $ bladeRFErrorTy ret
diff --git a/src/LibBladeRF/LibBladeRF.hs b/src/LibBladeRF/LibBladeRF.hs
--- a/src/LibBladeRF/LibBladeRF.hs
+++ b/src/LibBladeRF/LibBladeRF.hs
@@ -18,6 +18,8 @@
 module LibBladeRF.LibBladeRF ( withBladeRF
                              , DeviceHandle(..)
                              , BladeRFError(..)
+                             , bladeRFErrorValue
+                             , bladeRFErrorTy
                              ) where
 
 import Foreign
@@ -27,6 +29,8 @@
 
 import Control.Exception
 import Data.Typeable (Typeable, cast)
+import Data.Maybe
+import Data.Tuple
 
 import Bindings.LibBladeRF
 
@@ -46,7 +50,7 @@
                   | BLADERF_ERR_UPDATE_FPGA -- ^ An FPGA update is required
                   | BLADERF_ERR_UPDATE_FW   -- ^ A firmware update is requied
                   | BLADERF_ERR_TIME_PAST   -- ^ Requested timestamp is in the past
-                   deriving (Typeable)
+                   deriving (Eq, Typeable)
 
 instance Show BladeRFError where
   show BLADERF_ERR_UNEXPECTED  = "An unexpected failure occurred"
@@ -66,15 +70,46 @@
 
 instance Exception BladeRFError
 
+-- | Returned C Error codes
+--
+-- bladeRF library routines return negative values to indicate errors.
+-- Values >= 0 are used to indicate success.
+instance Enum BladeRFError where
+  fromEnum = fromJust . flip lookup errors
+  toEnum   = fromJust . flip lookup (map swap errors)
+
+errors = [ (BLADERF_ERR_UNEXPECTED, c'BLADERF_ERR_UNEXPECTED)
+         , (BLADERF_ERR_RANGE, c'BLADERF_ERR_RANGE)
+         , (BLADERF_ERR_INVAL, c'BLADERF_ERR_INVAL)
+         , (BLADERF_ERR_MEM, c'BLADERF_ERR_MEM)
+         , (BLADERF_ERR_IO, c'BLADERF_ERR_IO)
+         , (BLADERF_ERR_TIMEOUT, c'BLADERF_ERR_TIMEOUT)
+         , (BLADERF_ERR_NODEV, c'BLADERF_ERR_NODEV)
+         , (BLADERF_ERR_UNSUPPORTED, c'BLADERF_ERR_UNSUPPORTED)
+         , (BLADERF_ERR_MISALIGNED, c'BLADERF_ERR_MISALIGNED)
+         , (BLADERF_ERR_CHECKSUM, c'BLADERF_ERR_CHECKSUM)
+         , (BLADERF_ERR_NO_FILE, c'BLADERF_ERR_NO_FILE)
+         , (BLADERF_ERR_UPDATE_FPGA, c'BLADERF_ERR_UPDATE_FPGA)
+         , (BLADERF_ERR_UPDATE_FW, c'BLADERF_ERR_UPDATE_FW)
+         , (BLADERF_ERR_TIME_PAST, c'BLADERF_ERR_TIME_PAST)
+         ]
+
+-- | (For internal use) Obtain a 'BladeRFError' type of a C value from the Error codes list.
+bladeRFErrorValue :: CInt -> Either BladeRFError Int
+bladeRFErrorValue c | c >= 0 = (Right . fromIntegral) c         -- Success (on ret == 0)
+                    | c <  0 = (Left . toEnum . fromIntegral) c -- C ret code to typed error
+
+-- | (For internal use) Obtain a 'BladeRFError' type of a C value from the Error codes list.
+bladeRFErrorTy :: CInt -> Either BladeRFError ()
+bladeRFErrorTy c | c >= 0 = return ()                        -- Success (on ret == 0)
+                 | c <  0 = (Left . toEnum . fromIntegral) c -- C ret code to typed error
+
 -- | DeviceHandle wrapper around C device descriptor pointer
 newtype DeviceHandle = DeviceHandle { unDeviceHandle :: Ptr C'bladerf }
 
 -- | Essential wrapper
-withBladeRF :: (DeviceHandle -> IO a) -> IO ()
-withBladeRF body = do
-  dev <- openBladeRF
-  body dev
-  closeBladeRF dev
+withBladeRF :: (DeviceHandle -> IO c) -> IO c
+withBladeRF  = bracket openBladeRF closeBladeRF
 
 -- | Handy helper to wrap around Either results
 openBladeRF :: IO DeviceHandle
@@ -91,7 +126,7 @@
 openBladeRF'  = alloca $ \ptr -> do
   ret <- c'bladerf_open ptr nullPtr
   if ret /= 0 then
-    return (Left BLADERF_ERR_NODEV) -- is this the right error in every case?
+    return $ (Left . toEnum . fromIntegral) ret
   else do
     pdev <- peek ptr
     return (Right (DeviceHandle pdev))
diff --git a/src/LibBladeRF/Sync.hs b/src/LibBladeRF/Sync.hs
--- a/src/LibBladeRF/Sync.hs
+++ b/src/LibBladeRF/Sync.hs
@@ -44,11 +44,11 @@
                   -> Int           -- ^ The size of the underlying stream buffers, in samples. This value must be a multiple of 1024.
                   -> Int           -- ^ The number of active USB transfers that may be in-flight at any given time.
                   -> Int           -- ^ Timeout (milliseconds) for transfers in the underlying data stream.
-                  -> IO ()
+                  -> IO (Either BladeRFError ())
 
 bladeRFSyncConfig dev m f nb sz tr to = do
-  c'bladerf_sync_config (unDeviceHandle dev) ((fromIntegral . fromEnum) m) ((fromIntegral . fromEnum) f) (fromIntegral nb) (fromIntegral sz) (fromIntegral tr) (fromIntegral to)
-  return () -- ignores ret
+  ret <- c'bladerf_sync_config (unDeviceHandle dev) ((fromIntegral . fromEnum) m) ((fromIntegral . fromEnum) f) (fromIntegral nb) (fromIntegral sz) (fromIntegral tr) (fromIntegral to)
+  return $ bladeRFErrorTy ret
 
 -- | Transmit IQ samples.
 --
@@ -59,20 +59,29 @@
 -- Samples will only be sent to the FPGA when a buffer have been filled. The
 -- number of samples required to fill a buffer corresponds to the `buffer_size`
 -- parameter passed to 'bladeRFSyncConfig'.
+--
+-- Precondition:
+--
+--   1. A 'bladeRFSyncConfig' call has been to configure the device
+--      for synchronous data transfer.
+--
+--   2. A call to 'LibBladeRF.Utils.bladeRFEnableModule' should be
+--      made before attempting to transmit samples. Failing to do
+--      this may result in timeouts and other errors.
 bladeRFSyncTx :: DeviceHandle          -- ^ Device handle
               -> BS.ByteString         -- ^ Array of samples
-              -> Int                   -- ^ Number of samples to write
               -> Maybe BladeRFMetadata -- ^ Sample metadata. This must be provided when using
                                        --   the 'FORMAT_SC16_Q11_META' format, but may
                                        --   be 'Nothing' when the interface is configured for
                                        --   the 'FORMAT_SC16_Q11' format.
               -> Int                   -- ^ Timeout (milliseconds) for this call to complete. Zero implies infinite.
               -> IO ()
-bladeRFSyncTx dev s n md t = do
+bladeRFSyncTx dev s md t = do
+  -- The number of samples to write is the length of the bytestring `div` by (|IQ|=2 * |int16_t|=2)=4
   alloca $ \pmd ->
     case md of
       Nothing -> BS.useAsCStringLen s $
-                   \(p, _len) -> c'bladerf_sync_tx (unDeviceHandle dev) p (fromIntegral n) nullPtr (fromIntegral t)
+                   \(p, len) -> c'bladerf_sync_tx (unDeviceHandle dev) p (fromIntegral $ len `div` 4) nullPtr (fromIntegral t)
       Just md -> do
                  -- Use the following instead when switching to ghc7.8 later..
                  -- bladeRFMetadataToCBladeRFMetadata :: BladeRFMetadata -> C'bladerf_metadata
@@ -84,7 +93,7 @@
                                                }
                  poke pmd meta
                  BS.useAsCStringLen s $
-                   \(p, _len) -> c'bladerf_sync_tx (unDeviceHandle dev) p (fromIntegral n) pmd (fromIntegral t)
+                   \(p, len) -> c'bladerf_sync_tx (unDeviceHandle dev) p (fromIntegral $ len `div` 4) pmd (fromIntegral t)
   return () -- XXX ignores ret
 
 -- | Receive IQ samples.
@@ -92,6 +101,15 @@
 -- Underthe hood, this call starts up an underlying asynchronous stream as
 -- needed. This stream can be stopped by disabling the RX module. (See
 -- 'LibBladeRF.Utils.bladeRFEnableModule' for more details.)
+--
+-- Precondition:
+--
+--   1. A 'bladeRFSyncConfig' call has been to configure the device
+--      for synchronous data transfer.
+--
+--   2. A call to 'LibBladeRF.Utils.bladeRFEnableModule' should be
+--      made before attempting to transmit samples. Failing to do
+--      this may result in timeouts and other errors.
 bladeRFSyncRx :: DeviceHandle    -- ^ Device handle
               -> Int             -- ^ Number of samples to read
               -> Int             -- ^ Timeout (milliseconds) for this call to complete. Zero implies infinite.
diff --git a/src/LibBladeRF/Types.hs b/src/LibBladeRF/Types.hs
--- a/src/LibBladeRF/Types.hs
+++ b/src/LibBladeRF/Types.hs
@@ -12,7 +12,8 @@
 -- {-# LANGUAGE Trustworthy, DeriveGeneric #-}
 {-# LANGUAGE Trustworthy #-}
 
-module LibBladeRF.Types ( BladeRFVersion(..)
+module LibBladeRF.Types ( BladeRFLogLevel(..)
+                        , BladeRFVersion(..)
                         , BladeRFDeviceInfo(..)
                         , BladeRFFPGASize(..)
                         , BladeRFBackend(..)
@@ -40,6 +41,29 @@
 --import Data.Coerce
 --import GHC.Generics
 
+-- | Severity levels for logging actions
+data BladeRFLogLevel = LOG_LEVEL_VERBOSE  -- ^ Verbose level logging
+                     | LOG_LEVEL_DEBUG    -- ^ Debug level logging
+                     | LOG_LEVEL_INFO     -- ^ Information level logging
+                     | LOG_LEVEL_WARNING  -- ^ Warning level logging
+                     | LOG_LEVEL_ERROR    -- ^ Error level logging
+                     | LOG_LEVEL_CRITICAL -- ^ Fatal error level logging
+                     | LOG_LEVEL_SILENT   -- ^ No output
+                     deriving (Eq)
+
+instance Enum BladeRFLogLevel where
+  fromEnum = fromJust . flip lookup loglevels
+  toEnum   = fromJust . flip lookup (map swap loglevels)
+
+loglevels = [ (LOG_LEVEL_VERBOSE, c'BLADERF_LOG_LEVEL_VERBOSE)
+            , (LOG_LEVEL_DEBUG, c'BLADERF_LOG_LEVEL_DEBUG)
+            , (LOG_LEVEL_INFO, c'BLADERF_LOG_LEVEL_INFO)
+            , (LOG_LEVEL_WARNING, c'BLADERF_LOG_LEVEL_WARNING)
+            , (LOG_LEVEL_ERROR, c'BLADERF_LOG_LEVEL_ERROR)
+            , (LOG_LEVEL_CRITICAL, c'BLADERF_LOG_LEVEL_CRITICAL)
+            , (LOG_LEVEL_SILENT, c'BLADERF_LOG_LEVEL_SILENT)
+            ]
+
 -- | Version structure for FPGA, firmware, libbladeRF, and associated utilities.
 data BladeRFVersion = BladeRFVersion { major :: Word16 -- ^ Major version
                                      , minor :: Word16 -- ^ Minor version
@@ -145,7 +169,7 @@
 
       Samples consist of interleaved IQ value pairs, with I being the first
       value in the pair. Each value in the pair is a right-aligned,
-      little-endian int16_t. The FPGA ensures that these values are
+      little-endian 'Int16'. The FPGA ensures that these values are
       sign-extended.
 
       When using this format the minimum required buffer size, in bytes, is:
diff --git a/src/LibBladeRF/Utils.hs b/src/LibBladeRF/Utils.hs
--- a/src/LibBladeRF/Utils.hs
+++ b/src/LibBladeRF/Utils.hs
@@ -9,7 +9,8 @@
   This module encapsulates misc libbladeRF library functions.
 -}
 
-module LibBladeRF.Utils ( bladeRFLibVersion
+module LibBladeRF.Utils ( bladeRFLogSetVerbosity
+                        , bladeRFLibVersion
                         , bladeRFFwVersion
                         , bladeRFFPGAVersion
                         , bladeRFDeviceSpeed
@@ -30,6 +31,13 @@
 import LibBladeRF.LibBladeRF
 import LibBladeRF.Types
 
+-- | Sets the filter level for displayed log messages.
+--
+-- Messages that are at or above the specified log level will be printed, while
+-- messages with a lower log level will be suppressed.
+bladeRFLogSetVerbosity :: BladeRFLogLevel -- ^ The new log level filter value
+                       -> IO ()
+bladeRFLogSetVerbosity l = c'bladerf_log_set_verbosity $ (fromIntegral . fromEnum) l
 
 -- internal use only
 toBladeRFVer :: C'bladerf_version -> String -> BladeRFVersion
@@ -83,11 +91,11 @@
 -- power cycle. Pass Full path to FPGA bitstream.
 bladeRFLoadFPGA :: DeviceHandle -- ^ Device handle
                 -> String       -- ^ Full path to FPGA bitstream
-                -> IO ()
+                -> IO (Either BladeRFError ())
 bladeRFLoadFPGA dev s = do
   p <- newCString s
-  _ <- c'bladerf_load_fpga (unDeviceHandle dev) p
-  return ()
+  ret <- c'bladerf_load_fpga (unDeviceHandle dev) p
+  return $ bladeRFErrorTy ret
 
 -- | Obtain the bus speed at which the device is operating.
 bladeRFDeviceSpeed :: DeviceHandle    -- ^ Device handle
@@ -115,7 +123,7 @@
 -- | Query a device's serial number.
 bladeRFGetSerial :: DeviceHandle -- ^ Device handle
                  -> IO String    -- ^ Returned serial number.
-bladeRFGetSerial dev = allocaBytes 34 $ \cstring -> do
+bladeRFGetSerial dev = allocaBytes (c'BLADERF_SERIAL_LENGTH + 1) $ \cstring -> do
   -- API bug bladerf_get_serial() should be allocating the buffer itself, not the call site!
   -- See upstream report: https://github.com/Nuand/bladeRF/issues/382
   -- device serial is 33 bytes long + null terminating byte.
@@ -138,10 +146,10 @@
 bladeRFEnableModule :: DeviceHandle  -- ^ Device handle
                     -> BladeRFModule -- ^ Device module
                     -> Bool          -- ^ 'True' to enable, 'False' to disable
-                    -> IO ()
+                    -> IO (Either BladeRFError ())
 bladeRFEnableModule dev m t = do
-  c'bladerf_enable_module (unDeviceHandle dev) ((fromIntegral . fromEnum) m) t
-  return () -- XXX ignore ret
+  ret <- c'bladerf_enable_module (unDeviceHandle dev) ((fromIntegral . fromEnum) m) t
+  return $ bladeRFErrorTy ret
 
 -- | Apply specified loopback mode.
 --
@@ -151,10 +159,10 @@
 bladeRFSetLoopback :: DeviceHandle    -- ^ Device handle
                    -> BladeRFLoopback -- ^ Loopback mode. Note that 'LB_NONE'
                                       --   disables the use of loopback functionality.
-                   -> IO ()
+                   -> IO (Either BladeRFError ())
 bladeRFSetLoopback dev l = do
-  c'bladerf_set_loopback (unDeviceHandle dev) ((fromIntegral . fromEnum) l)
-  return () -- XXX ignore ret
+  ret <- c'bladerf_set_loopback (unDeviceHandle dev) ((fromIntegral . fromEnum) l)
+  return $ bladeRFErrorTy ret
 
 -- | Get current loopback mode.
 bladeRFGetLoopback :: DeviceHandle       -- ^ Device handle
