diff --git a/Foreign/CUDA/Driver/Context.chs b/Foreign/CUDA/Driver/Context.chs
--- a/Foreign/CUDA/Driver/Context.chs
+++ b/Foreign/CUDA/Driver/Context.chs
@@ -10,6 +10,7 @@
 --------------------------------------------------------------------------------
 
 #include <cuda.h>
+#include "cbits/stubs.h"
 {# context lib="cuda" #}
 
 module Foreign.CUDA.Driver.Context
@@ -18,10 +19,16 @@
 #if CUDA_VERSION >= 3010
     Limit(..),
 #endif
+#if CUDA_VERSION >= 3020
+    Cache(..),
+#endif
     create, attach, detach, destroy, current, pop, push, sync,
 #if CUDA_VERSION >= 3010
     getLimit, setLimit
 #endif
+#if CUDA_VERSION >= 3020
+    , setCacheConfig
+#endif
   )
   where
 
@@ -62,6 +69,14 @@
     { underscoreToCase }
     with prefix="CU_LIMIT" deriving (Eq, Show) #}
 #endif
+#if CUDA_VERSION >= 3020
+-- |
+-- Device cache configuration flags
+--
+{# enum CUfunc_cache_enum as Cache
+    { underscoreToCase }
+    with prefix="CU_FUNC_CACHE" deriving (Eq, Show) #}
+#endif
 
 --------------------------------------------------------------------------------
 -- Context management
@@ -159,6 +174,10 @@
   { } -> `Status' cToEnum #}
 
 
+--------------------------------------------------------------------------------
+-- Cache configuration
+--------------------------------------------------------------------------------
+
 #if CUDA_VERSION >= 3010
 -- |
 -- Query compute 2.0 call stack limits
@@ -179,5 +198,17 @@
 {# fun unsafe cuCtxSetLimit
   { cFromEnum `Limit'
   , cIntConv  `Int'   } -> `Status' cToEnum #}
+#endif
+#if CUDA_VERSION >= 3020
+-- |
+-- On devices where the L1 cache and shared memory use the same hardware
+-- resources, this sets the preferred cache configuration for the current
+-- context. This is only a preference.
+--
+setCacheConfig :: Cache -> IO ()
+setCacheConfig c = nothingIfOk =<< cuCtxSetCacheConfig c
+
+{# fun unsafe cuCtxSetCacheConfig
+  { cFromEnum `Cache' } -> `Status' cToEnum #}
 #endif
 
diff --git a/Foreign/CUDA/Driver/Device.chs b/Foreign/CUDA/Driver/Device.chs
--- a/Foreign/CUDA/Driver/Device.chs
+++ b/Foreign/CUDA/Driver/Device.chs
@@ -19,6 +19,7 @@
   where
 
 #include <cuda.h>
+#include "cbits/stubs.h"
 {# context lib="cuda" #}
 
 -- Friends
diff --git a/Foreign/CUDA/Driver/Error.chs b/Foreign/CUDA/Driver/Error.chs
--- a/Foreign/CUDA/Driver/Error.chs
+++ b/Foreign/CUDA/Driver/Error.chs
@@ -69,6 +69,8 @@
 describe NotMappedAsArray            = "mapped resource not available for access as an array"
 describe NotMappedAsPointer          = "mapped resource not available for access as a pointer"
 describe EccUncorrectable            = "uncorrectable ECC error detected"
+#endif
+#if CUDA_VERSION >= 3000 && CUDA_VERSION < 3020
 describe PointerIs64bit              = "attempt to retrieve a 64-bit pointer via a 32-bit API function"
 describe SizeIs64bit                 = "attempt to retrieve 64-bit size via a 32-bit API function"
 #endif
@@ -76,6 +78,9 @@
 describe UnsupportedLimit            = "limits not supported by device"
 describe SharedObjectSymbolNotFound  = "link to a shared object failed to resolve"
 describe SharedObjectInitFailed      = "shared object initialisation failed"
+#endif
+#if CUDA_VERSION >= 3020
+describe OperatingSystem             = "operating system call failed"
 #endif
 describe Unknown                     = "unknown error"
 
diff --git a/Foreign/CUDA/Driver/Event.chs b/Foreign/CUDA/Driver/Event.chs
--- a/Foreign/CUDA/Driver/Event.chs
+++ b/Foreign/CUDA/Driver/Event.chs
@@ -1,4 +1,4 @@
-{-# LANGUAGE ForeignFunctionInterface #-}
+{-# LANGUAGE ForeignFunctionInterface, EmptyDataDecls #-}
 --------------------------------------------------------------------------------
 -- |
 -- Module    : Foreign.CUDA.Driver.Event
@@ -9,16 +9,22 @@
 --
 --------------------------------------------------------------------------------
 
+#include <cuda.h>
+{# context lib="cuda" #}
+
 module Foreign.CUDA.Driver.Event
   (
     Event, EventFlag(..),
+#if CUDA_VERSION >= 3020
+    WaitFlag,
+#endif
     create, destroy, elapsedTime, query, record, block
+#if CUDA_VERSION >= 3020
+    , wait
+#endif
   )
   where
 
-#include <cuda.h>
-{# context lib="cuda" #}
-
 -- Friends
 import Foreign.CUDA.Internal.C2HS
 import Foreign.CUDA.Driver.Error
@@ -48,6 +54,13 @@
     with prefix="CU_EVENT" deriving (Eq, Show) #}
 
 
+-- |
+-- Possible option flags for waiting for events
+--
+data WaitFlag
+instance Enum WaitFlag where
+
+
 --------------------------------------------------------------------------------
 -- Event management
 --------------------------------------------------------------------------------
@@ -115,6 +128,23 @@
   { useEvent  `Event'
   , useStream `Stream' } -> `Status' cToEnum #}
 
+
+#if CUDA_VERSION >= 3020
+-- |
+-- Marks all future work submitted to the (optional) stream wait until the given
+-- event reports completion before beginning execution.
+--
+wait :: Event -> Maybe Stream -> [WaitFlag] -> IO ()
+wait ev mst flags =
+  nothingIfOk =<< case mst of
+    Just st -> cuStreamWaitEvent st ev flags
+    Nothing -> cuStreamWaitEvent (Stream nullPtr) ev flags
+
+{# fun unsafe cuStreamWaitEvent
+  { useStream       `Stream'
+  , useEvent        `Event'
+  , combineBitMasks `[WaitFlag]' } -> `Status' cToEnum #}
+#endif
 
 -- |
 -- Wait until the event has been recorded
diff --git a/Foreign/CUDA/Driver/Exec.chs b/Foreign/CUDA/Driver/Exec.chs
--- a/Foreign/CUDA/Driver/Exec.chs
+++ b/Foreign/CUDA/Driver/Exec.chs
@@ -20,7 +20,7 @@
 #endif
     requires, setBlockShape, setSharedSize, setParams,
 #if CUDA_VERSION >= 3000
-    setCacheConfig,
+    setCacheConfigFun,
 #endif
     launch
   )
@@ -71,7 +71,7 @@
 data FunParam where
   IArg :: Int     -> FunParam
   FArg :: Float   -> FunParam
-  TArg :: Texture -> FunParam
+  TArg :: Texture -> FunParam           -- deprecated
   VArg :: Storable a => a -> FunParam
 
 
@@ -126,8 +126,8 @@
 -- Switching between configuration modes may insert a device-side
 -- synchronisation point for streamed kernel launches.
 --
-setCacheConfig :: Fun -> CacheConfig -> IO ()
-setCacheConfig fn pref = nothingIfOk =<< cuFuncSetCacheConfig fn pref
+setCacheConfigFun :: Fun -> CacheConfig -> IO ()
+setCacheConfigFun fn pref = nothingIfOk =<< cuFuncSetCacheConfig fn pref
 
 {# fun unsafe cuFuncSetCacheConfig
   { useFun    `Fun'
@@ -173,7 +173,11 @@
 
     set f o (IArg v) = nothingIfOk =<< cuParamSeti f o v
     set f o (FArg v) = nothingIfOk =<< cuParamSetf f o v
+#if CUDA_VERSION < 3020
     set f _ (TArg v) = nothingIfOk =<< cuParamSetTexRef f (-1) v
+#else
+    set _ _ (TArg _) = return ()
+#endif
     set f o (VArg v) = with v $ \p -> (nothingIfOk =<< cuParamSetv f o p (sizeOf v))
 
 
@@ -198,8 +202,10 @@
   , castPtr `Ptr a'
   ,         `Int'   } -> `Status' cToEnum #}
 
+#if CUDA_VERSION < 3020
 {# fun unsafe cuParamSetTexRef
   { useFun     `Fun'
   ,            `Int'    -- must be CU_PARAM_TR_DEFAULT (-1)
   , useTexture `Texture' } -> `Status' cToEnum #}
+#endif
 
diff --git a/Foreign/CUDA/Driver/Marshal.chs b/Foreign/CUDA/Driver/Marshal.chs
--- a/Foreign/CUDA/Driver/Marshal.chs
+++ b/Foreign/CUDA/Driver/Marshal.chs
@@ -27,7 +27,7 @@
     withListArray, withListArrayLen,
 
     -- * Utility
-    memset, getDevicePtr,
+    memset, getDevicePtr, getBasePtr, getMemInfo,
 
     -- Internal
     useDeviceHandle, peekDeviceHandle
@@ -35,6 +35,7 @@
   where
 
 #include <cuda.h>
+#include "cbits/stubs.h"
 {# context lib="cuda" #}
 
 -- Friends
@@ -44,6 +45,7 @@
 import Foreign.CUDA.Internal.C2HS
 
 -- System
+import Data.Int
 import Unsafe.Coerce
 import Control.Applicative
 import Control.Exception.Extensible
@@ -377,32 +379,54 @@
     alloca'  = F.alloca
     useHP    = castPtr . useHostPtr
 
+-- |
+-- Return the base address and allocation size of the given device pointer
+--
+getBasePtr :: DevicePtr a -> IO (DevicePtr a, Int64)
+getBasePtr dptr = do
+  (status,base,size) <- cuMemGetAddressRange dptr
+  resultIfOk (status, (base,size))
 
+{# fun unsafe cuMemGetAddressRange
+  { alloca'-        `DevicePtr a' peekDeviceHandle*
+  , alloca'-        `Int64'       peekIntConv*
+  , useDeviceHandle `DevicePtr a'                   } -> `Status' cToEnum #}
+  where
+    alloca' :: Storable a => (Ptr a -> IO b) -> IO b
+    alloca' = F.alloca
+
+
+-- |
+-- Return the amount of free and total memory respectively available to the
+-- current context (bytes)
+--
+getMemInfo :: IO (Int64, Int64)
+getMemInfo = do
+  (status,f,t) <- cuMemGetInfo
+  resultIfOk (status,(f,t))
+
+{# fun unsafe cuMemGetInfo
+  { alloca'- `Int64' peekIntConv*
+  , alloca'- `Int64' peekIntConv* } -> `Status' cToEnum #}
+  where
+    alloca' = F.alloca
+
+
 --------------------------------------------------------------------------------
 -- Internal
 --------------------------------------------------------------------------------
 
--- Lift an opaque handle to a typed DevicePtr representation. The driver
--- interface requires this special type for 'mallocArray' and the like, which is
--- a 32-bit value on all platforms.
---
--- Tesla architecture products (compute 1.x) support only a 32-bit address space
--- and expect pointers passed to kernels of this width, while the Fermi
--- architecture (compute 2.x) supports 64-bit wide pointers.
---
--- When interface with the driver functions, we require this special 32-bit
--- opaque type. When passing pointers to kernel functions, we must use the
--- native host pointer type. On 32-bit platforms, this distinction is
--- irrelevant. For Tesla devices executing on 64-bit host platforms, the runtime
--- will automatically squash pointers to 32-bits. Fermi architectures however
--- may use the entire bitwidth, so the 32-bit CUdeviceptr must be converted to
--- a 64-bit pointer by the application before passing to the kernel.
+type DeviceHandle = {# type CUdeviceptr #}
+
+-- Lift an opaque handle to a typed DevicePtr representation. This occasions
+-- arcane distinctions for the different driver versions and Tesla (compute 1.x)
+-- and Fermi (compute 2.x) class architectures on 32- and 64-bit hosts.
 --
-peekDeviceHandle :: Ptr {# type CUdeviceptr #} -> IO (DevicePtr a)
+peekDeviceHandle :: Ptr DeviceHandle -> IO (DevicePtr a)
 peekDeviceHandle p = DevicePtr . intPtrToPtr . fromIntegral <$> peek p
 
 -- Use a device pointer as an opaque handle type
 --
-useDeviceHandle :: DevicePtr a -> {# type CUdeviceptr #}
+useDeviceHandle :: DevicePtr a -> DeviceHandle
 useDeviceHandle = fromIntegral . ptrToIntPtr . useDevicePtr
 
diff --git a/Foreign/CUDA/Driver/Module.chs b/Foreign/CUDA/Driver/Module.chs
--- a/Foreign/CUDA/Driver/Module.chs
+++ b/Foreign/CUDA/Driver/Module.chs
@@ -19,6 +19,7 @@
   where
 
 #include <cuda.h>
+#include "cbits/stubs.h"
 {# context lib="cuda" #}
 
 -- Friends
@@ -35,6 +36,7 @@
 import Unsafe.Coerce
 
 import Control.Monad                            (liftM)
+import Control.Exception.Extensible             (throwIO)
 import Data.ByteString.Char8                    (ByteString)
 import qualified Data.ByteString.Char8 as B
 
@@ -93,7 +95,7 @@
 -- Returns a function handle
 --
 getFun :: Module -> String -> IO Fun
-getFun mdl fn = resultIfOk =<< cuModuleGetFunction mdl fn
+getFun mdl fn = resultIfFound "function" fn =<< cuModuleGetFunction mdl fn
 
 {# fun unsafe cuModuleGetFunction
   { alloca-      `Fun'    peekFun*
@@ -108,7 +110,7 @@
 getPtr :: Module -> String -> IO (DevicePtr a, Int)
 getPtr mdl name = do
   (status,dptr,bytes) <- cuModuleGetGlobal mdl name
-  resultIfOk (status,(dptr,bytes))
+  resultIfFound "global" name (status,(dptr,bytes))
 
 {# fun unsafe cuModuleGetGlobal
   { alloca-      `DevicePtr a' peekDeviceHandle*
@@ -121,7 +123,7 @@
 -- Return a handle to a texture reference
 --
 getTex :: Module -> String -> IO Texture
-getTex mdl name = resultIfOk =<< cuModuleGetTexRef mdl name
+getTex mdl name = resultIfFound "texture" name =<< cuModuleGetTexRef mdl name
 
 {# fun unsafe cuModuleGetTexRef
   { alloca-      `Texture' peekTex*
@@ -208,6 +210,13 @@
 --------------------------------------------------------------------------------
 -- Internal
 --------------------------------------------------------------------------------
+
+resultIfFound :: String -> String -> (Status, a) -> IO a
+resultIfFound kind name (status,result) =
+  case status of
+       Success  -> return result
+       NotFound -> cudaError (kind ++ ' ' : describe status ++ ": " ++ name)
+       _        -> throwIO (ExitCode status)
 
 peekMod :: Ptr {# type CUmodule #} -> IO Module
 peekMod = liftM Module . peek
diff --git a/Foreign/CUDA/Driver/Texture.chs b/Foreign/CUDA/Driver/Texture.chs
--- a/Foreign/CUDA/Driver/Texture.chs
+++ b/Foreign/CUDA/Driver/Texture.chs
@@ -9,10 +9,17 @@
 --
 --------------------------------------------------------------------------------
 
+#include <cuda.h>
+#include "cbits/stubs.h"
+{# context lib="cuda" #}
+
 module Foreign.CUDA.Driver.Texture
   (
     Texture(..), Format(..), AddressMode(..), FilterMode(..), ReadMode(..),
-    create, destroy, bind, bind2D,
+#if CUDA_VERSION < 3020
+    create, destroy,
+#endif
+    bind, bind2D,
     getAddressMode, getFilterMode, getFormat,
     setAddressMode, setFilterMode, setFormat, setReadMode,
 
@@ -21,10 +28,6 @@
   )
   where
 
-#include <cuda.h>
-#include "cbits/stubs.h"
-{# context lib="cuda" #}
-
 -- Friends
 import Foreign.CUDA.Ptr
 import Foreign.CUDA.Driver.Error
@@ -93,6 +96,7 @@
 -- Texture management
 --------------------------------------------------------------------------------
 
+#if CUDA_VERSION < 3020
 -- |Create a new texture reference. Once created, the application must call
 -- 'setPtr' to associate the reference with allocated memory. Other texture
 -- reference functions are used to specify the format and interpretation to be
@@ -112,7 +116,7 @@
 
 {# fun unsafe cuTexRefDestroy
   { useTexture `Texture' } -> `Status' cToEnum #}
-
+#endif
 
 -- |Bind a linear array address of the given size (bytes) as a texture
 -- reference. Any previously bound references are unbound.
diff --git a/Setup.hs b/Setup.hs
--- a/Setup.hs
+++ b/Setup.hs
@@ -23,20 +23,16 @@
 ppC2hs bi lbi
     = PreProcessor {
         platformIndependent = False,
-        runPreProcessor = \(inBaseDir, inRelativeFile)
-                           (outBaseDir, outRelativeFile) verbosity ->
+        runPreProcessor     = \(inBaseDir, inRelativeFile)
+                               (outBaseDir, outRelativeFile) verbosity ->
           rawSystemProgramConf verbosity c2hsProgram (withPrograms lbi) . filter (not . null) $
-            extra_flags
+            maybe [] words (lookup "x-extra-c2hs-options" (customFieldsBI bi))
             ++ ["--include=" ++ outBaseDir]
             ++ ["--cppopts=" ++ opt | opt <- getCppOptions bi lbi]
             ++ ["--output-dir=" ++ outBaseDir,
                 "--output=" ++ outRelativeFile,
                 inBaseDir </> inRelativeFile]
       }
-  where
-    extra_flags = case lookup "x-extra-c2hs-options" (customFieldsBI bi) of
-                       Nothing -> []
-                       Just s  -> [s]
 
 getCppOptions :: BuildInfo -> LocalBuildInfo -> [String]
 getCppOptions bi lbi
diff --git a/cbits/stubs.c b/cbits/stubs.c
--- a/cbits/stubs.c
+++ b/cbits/stubs.c
@@ -32,3 +32,94 @@
     return cuTexRefSetAddress2D(tex, &desc, dptr, pitch);
 }
 
+#if CUDA_VERSION >= 3020
+/*
+ * Extra exports for CUDA-3.2
+ */
+CUresult CUDAAPI cuDeviceTotalMem(size_t *bytes, CUdevice dev)
+{
+    return cuDeviceTotalMem_v2(bytes, dev);
+}
+
+CUresult CUDAAPI cuCtxCreate(CUcontext *pctx, unsigned int flags, CUdevice dev)
+{
+    return cuCtxCreate_v2(pctx, flags, dev);
+}
+
+CUresult CUDAAPI cuModuleGetGlobal(CUdeviceptr *dptr, size_t *bytes, CUmodule hmod, const char *name)
+{
+    return cuModuleGetGlobal_v2(dptr, bytes, hmod, name);
+}
+
+CUresult CUDAAPI cuMemAlloc(CUdeviceptr *dptr, size_t bytesize)
+{
+    return cuMemAlloc_v2(dptr, bytesize);
+}
+
+CUresult CUDAAPI cuMemFree(CUdeviceptr dptr)
+{
+    return cuMemFree_v2(dptr);
+}
+
+CUresult CUDAAPI cuMemGetInfo(size_t *free, size_t *total)
+{
+    return cuMemGetInfo_v2(free, total);
+}
+
+CUresult CUDAAPI cuMemGetAddressRange(CUdeviceptr *pbase, size_t *psize, CUdeviceptr dptr)
+{
+    return cuMemGetAddressRange_v2(pbase, psize, dptr);
+}
+
+CUresult CUDAAPI cuMemHostGetDevicePointer(CUdeviceptr *pdptr, void *p, unsigned int Flags)
+{
+    return cuMemHostGetDevicePointer_v2(pdptr, p, Flags);
+}
+
+CUresult CUDAAPI cuMemcpyHtoD(CUdeviceptr dstDevice, const void *srcHost, size_t ByteCount)
+{
+    return cuMemcpyHtoD_v2(dstDevice, srcHost, ByteCount);
+}
+
+CUresult CUDAAPI cuMemcpyDtoH(void *dstHost, CUdeviceptr srcDevice, size_t ByteCount)
+{
+    return cuMemcpyDtoH_v2(dstHost, srcDevice, ByteCount);
+}
+
+CUresult CUDAAPI cuMemcpyDtoD(CUdeviceptr dstDevice, CUdeviceptr srcDevice, size_t ByteCount)
+{
+    return cuMemcpyDtoD_v2(dstDevice, srcDevice, ByteCount);
+}
+
+CUresult CUDAAPI cuMemcpyHtoDAsync(CUdeviceptr dstDevice, const void *srcHost, size_t ByteCount, CUstream hStream)
+{
+    return cuMemcpyHtoDAsync_v2(dstDevice, srcHost, ByteCount, hStream);
+}
+
+CUresult CUDAAPI cuMemcpyDtoHAsync(void *dstHost, CUdeviceptr srcDevice, size_t ByteCount, CUstream hStream)
+{
+    return cuMemcpyDtoHAsync_v2(dstHost, srcDevice, ByteCount, hStream);
+}
+
+CUresult CUDAAPI cuMemsetD8(CUdeviceptr dstDevice, unsigned char uc, size_t N)
+{
+    return cuMemsetD8_v2(dstDevice, uc, N);
+}
+
+CUresult CUDAAPI cuMemsetD16(CUdeviceptr dstDevice, unsigned short us, size_t N)
+{
+    return cuMemsetD16_v2(dstDevice, us, N);
+}
+
+CUresult CUDAAPI cuMemsetD32(CUdeviceptr dstDevice, unsigned int ui, size_t N)
+{
+    return cuMemsetD32_v2(dstDevice, ui, N);
+}
+
+CUresult CUDAAPI cuTexRefSetAddress(size_t *ByteOffset, CUtexref hTexRef, CUdeviceptr dptr, size_t bytes)
+{
+    return cuTexRefSetAddress_v2(ByteOffset, hTexRef, dptr, bytes);
+}
+
+#endif
+
diff --git a/cbits/stubs.h b/cbits/stubs.h
--- a/cbits/stubs.h
+++ b/cbits/stubs.h
@@ -21,6 +21,98 @@
 CUresult
 cuTexRefSetAddress2DSimple(CUtexref tex, CUarray_format fmt, int chn, CUdeviceptr dptr, int width, int height, int pitch);
 
+/*
+ * Need to re-export some symbols as they are now generated by #defines, which
+ * c2hs does not like in the function binding hooks.
+ */
+#if CUDA_VERSION >= 3020
+#undef cuDeviceTotalMem
+#undef cuCtxCreate
+#undef cuModuleGetGlobal
+#undef cuMemGetInfo
+#undef cuMemAlloc
+#undef cuMemAllocPitch
+#undef cuMemFree
+#undef cuMemGetAddressRange
+#undef cuMemAllocHost
+#undef cuMemHostGetDevicePointer
+#undef cuMemcpyHtoD
+#undef cuMemcpyDtoH
+#undef cuMemcpyDtoD
+#undef cuMemcpyDtoA
+#undef cuMemcpyAtoD
+#undef cuMemcpyHtoA
+#undef cuMemcpyAtoH
+#undef cuMemcpyAtoA
+#undef cuMemcpyHtoAAsync
+#undef cuMemcpyAtoHAsync
+#undef cuMemcpy2D
+#undef cuMemcpy2DUnaligned
+#undef cuMemcpy3D
+#undef cuMemcpyHtoDAsync
+#undef cuMemcpyDtoHAsync
+#undef cuMemcpyDtoDAsync
+#undef cuMemcpy2DAsync
+#undef cuMemcpy3DAsync
+#undef cuMemsetD8
+#undef cuMemsetD16
+#undef cuMemsetD32
+#undef cuMemsetD2D8
+#undef cuMemsetD2D16
+#undef cuMemsetD2D32
+#undef cuArrayCreate
+#undef cuArrayGetDescriptor
+#undef cuArray3DCreate
+#undef cuArray3DGetDescriptor
+#undef cuTexRefSetAddress
+// #undef cuTexRefSetAddress2D
+#undef cuTexRefGetAddress
+#undef cuGraphicsResourceGetMappedPointer
+
+CUresult CUDAAPI cuDeviceTotalMem(size_t *bytes, CUdevice dev);
+CUresult CUDAAPI cuCtxCreate(CUcontext *pctx, unsigned int flags, CUdevice dev);
+CUresult CUDAAPI cuModuleGetGlobal(CUdeviceptr *dptr, size_t *bytes, CUmodule hmod, const char *name);
+CUresult CUDAAPI cuMemGetInfo(size_t *free, size_t *total);
+CUresult CUDAAPI cuMemAlloc(CUdeviceptr *dptr, size_t bytesize);
+// CUresult CUDAAPI cuMemAllocPitch(CUdeviceptr *dptr, unsigned int *pPitch, unsigned int WidthInBytes, unsigned int Height, unsigned int ElementSizeBytes);
+CUresult CUDAAPI cuMemFree(CUdeviceptr dptr);
+CUresult CUDAAPI cuMemGetAddressRange(CUdeviceptr *pbase, size_t *psize, CUdeviceptr dptr);
+// CUresult CUDAAPI cuMemAllocHost(void **pp, unsigned int bytesize);
+CUresult CUDAAPI cuMemHostGetDevicePointer(CUdeviceptr *pdptr, void *p, unsigned int Flags);
+CUresult CUDAAPI cuMemcpyHtoD(CUdeviceptr dstDevice, const void *srcHost, size_t ByteCount);
+CUresult CUDAAPI cuMemcpyDtoH(void *dstHost, CUdeviceptr srcDevice, size_t ByteCount);
+CUresult CUDAAPI cuMemcpyDtoD(CUdeviceptr dstDevice, CUdeviceptr srcDevice, size_t ByteCount);
+// CUresult CUDAAPI cuMemcpyDtoA(CUarray dstArray, unsigned int dstOffset, CUdeviceptr srcDevice, unsigned int ByteCount);
+// CUresult CUDAAPI cuMemcpyAtoD(CUdeviceptr dstDevice, CUarray srcArray, unsigned int srcOffset, unsigned int ByteCount);
+// CUresult CUDAAPI cuMemcpyHtoA(CUarray dstArray, unsigned int dstOffset, const void *srcHost, unsigned int ByteCount);
+// CUresult CUDAAPI cuMemcpyAtoH(void *dstHost, CUarray srcArray, unsigned int srcOffset, unsigned int ByteCount);
+// CUresult CUDAAPI cuMemcpyAtoA(CUarray dstArray, unsigned int dstOffset, CUarray srcArray, unsigned int srcOffset, unsigned int ByteCount);
+// CUresult CUDAAPI cuMemcpyHtoAAsync(CUarray dstArray, unsigned int dstOffset, const void *srcHost, unsigned int ByteCount, CUstream hStream);
+// CUresult CUDAAPI cuMemcpyAtoHAsync(void *dstHost, CUarray srcArray, unsigned int srcOffset, unsigned int ByteCount, CUstream hStream);
+// CUresult CUDAAPI cuMemcpy2D(const CUDA_MEMCPY2D *pCopy);
+// CUresult CUDAAPI cuMemcpy2DUnaligned(const CUDA_MEMCPY2D *pCopy);
+// CUresult CUDAAPI cuMemcpy3D(const CUDA_MEMCPY3D *pCopy);
+CUresult CUDAAPI cuMemcpyHtoDAsync(CUdeviceptr dstDevice, const void *srcHost, size_t ByteCount, CUstream hStream);
+CUresult CUDAAPI cuMemcpyDtoHAsync(void *dstHost, CUdeviceptr srcDevice, size_t ByteCount, CUstream hStream);
+// CUresult CUDAAPI cuMemcpyDtoDAsync(CUdeviceptr dstDevice, CUdeviceptr srcDevice, unsigned int ByteCount, CUstream hStream);
+// CUresult CUDAAPI cuMemcpy2DAsync(const CUDA_MEMCPY2D *pCopy, CUstream hStream);
+// CUresult CUDAAPI cuMemcpy3DAsync(const CUDA_MEMCPY3D *pCopy, CUstream hStream);
+CUresult CUDAAPI cuMemsetD8(CUdeviceptr dstDevice, unsigned char uc, size_t N);
+CUresult CUDAAPI cuMemsetD16(CUdeviceptr dstDevice, unsigned short us, size_t N);
+CUresult CUDAAPI cuMemsetD32(CUdeviceptr dstDevice, unsigned int ui, size_t N);
+// CUresult CUDAAPI cuMemsetD2D8(CUdeviceptr dstDevice, unsigned int dstPitch, unsigned char uc, unsigned int Width, unsigned int Height);
+// CUresult CUDAAPI cuMemsetD2D16(CUdeviceptr dstDevice, unsigned int dstPitch, unsigned short us, unsigned int Width, unsigned int Height);
+// CUresult CUDAAPI cuMemsetD2D32(CUdeviceptr dstDevice, unsigned int dstPitch, unsigned int ui, unsigned int Width, unsigned int Height);
+// CUresult CUDAAPI cuArrayCreate(CUarray *pHandle, const CUDA_ARRAY_DESCRIPTOR *pAllocateArray);
+// CUresult CUDAAPI cuArrayGetDescriptor(CUDA_ARRAY_DESCRIPTOR *pArrayDescriptor, CUarray hArray);
+// CUresult CUDAAPI cuArray3DCreate(CUarray *pHandle, const CUDA_ARRAY3D_DESCRIPTOR *pAllocateArray);
+// CUresult CUDAAPI cuArray3DGetDescriptor(CUDA_ARRAY3D_DESCRIPTOR *pArrayDescriptor, CUarray hArray);
+CUresult CUDAAPI cuTexRefSetAddress(size_t *ByteOffset, CUtexref hTexRef, CUdeviceptr dptr, size_t bytes);
+// CUresult CUDAAPI cuTexRefSetAddress2D(CUtexref hTexRef, const CUDA_ARRAY_DESCRIPTOR *desc, CUdeviceptr dptr, unsigned int Pitch);
+// CUresult CUDAAPI cuTexRefGetAddress(CUdeviceptr *pdptr, CUtexref hTexRef);
+// CUresult CUDAAPI cuGraphicsResourceGetMappedPointer(CUdeviceptr *pDevPtr, unsigned int *pSize, CUgraphicsResource resource);
+#endif
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/configure b/configure
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.61 for Haskell CUDA bindings 0.2.1.
+# Generated by GNU Autoconf 2.61 for Haskell CUDA bindings 0.3.2.
 #
 # Report bugs to <tmcdonell@cse.unsw.edu.au>.
 #
@@ -574,8 +574,8 @@
 # Identity of this package.
 PACKAGE_NAME='Haskell CUDA bindings'
 PACKAGE_TARNAME='cuda'
-PACKAGE_VERSION='0.2.1'
-PACKAGE_STRING='Haskell CUDA bindings 0.2.1'
+PACKAGE_VERSION='0.3.2'
+PACKAGE_STRING='Haskell CUDA bindings 0.3.2'
 PACKAGE_BUGREPORT='tmcdonell@cse.unsw.edu.au'
 
 ac_unique_file="Foreign/CUDA.hs"
@@ -1198,7 +1198,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures Haskell CUDA bindings 0.2.1 to adapt to many kinds of systems.
+\`configure' configures Haskell CUDA bindings 0.3.2 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1264,7 +1264,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of Haskell CUDA bindings 0.2.1:";;
+     short | recursive ) echo "Configuration of Haskell CUDA bindings 0.3.2:";;
    esac
   cat <<\_ACEOF
 
@@ -1344,7 +1344,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-Haskell CUDA bindings configure 0.2.1
+Haskell CUDA bindings configure 0.3.2
 generated by GNU Autoconf 2.61
 
 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1358,7 +1358,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by Haskell CUDA bindings $as_me 0.2.1, which was
+It was created by Haskell CUDA bindings $as_me 0.3.2, which was
 generated by GNU Autoconf 2.61.  Invocation command line was
 
   $ $0 $@
@@ -2483,7 +2483,8 @@
   program_prefix=${target_alias}-
 
 # Search the user's PATH for the 'nvcc' compiler. If it is found, add this
-# prefix to the include and library search directories.
+# prefix to the include and library search directories. Additionally, set nvcc
+# as the C preprocessor for c2hs (only, or it won't try to link cudart)
 #
 # Extract the first word of "nvcc", so it can be a program name with args.
 set dummy nvcc; ac_word=$2
@@ -2527,11 +2528,13 @@
 
 if test "$NVCC" != ""; then
     cuda_prefix="$(dirname $(dirname $NVCC))"
-    CPPFLAGS+="-I${cuda_prefix}/include"
+    cuda_c2hsflags+="--cpp=$NVCC --cppopts=-E "
+    CPPFLAGS+="-I${cuda_prefix}/include "
+#    CC=${NVCC}
 
     case $target in
-    x86_64*) LDFLAGS+="-L${cuda_prefix}/lib64" ;;
-    *)       LDFLAGS+="-L${cuda_prefix}/lib"   ;;
+    x86_64*) LDFLAGS+="-L${cuda_prefix}/lib64 " ;;
+    *)       LDFLAGS+="-L${cuda_prefix}/lib "   ;;
     esac
 fi
 
@@ -2545,7 +2548,7 @@
     SNOWLEOPARD=`grep '<string>10.6' /System/Library/CoreServices/SystemVersion.plist`
 fi
 if test "$SNOWLEOPARD" != ""; then
-    cuda_c2hsflags+="-C-U__BLOCKS__"
+    cuda_c2hsflags+="--cppopts=-U__BLOCKS__ "
     { echo "$as_me:$LINENO: result: yes" >&5
 echo "${ECHO_T}yes" >&6; }
 else
@@ -4627,7 +4630,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by Haskell CUDA bindings $as_me 0.2.1, which was
+This file was extended by Haskell CUDA bindings $as_me 0.3.2, which was
 generated by GNU Autoconf 2.61.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -4670,7 +4673,7 @@
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
 ac_cs_version="\\
-Haskell CUDA bindings config.status 0.2.1
+Haskell CUDA bindings config.status 0.3.2
 configured by $0, generated by GNU Autoconf 2.61,
   with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
 
diff --git a/configure.ac b/configure.ac
--- a/configure.ac
+++ b/configure.ac
@@ -1,4 +1,4 @@
-AC_INIT([Haskell CUDA bindings], [0.2.1], [tmcdonell@cse.unsw.edu.au], [cuda])
+AC_INIT([Haskell CUDA bindings], [0.3.2], [tmcdonell@cse.unsw.edu.au], [cuda])
 AC_CONFIG_SRCDIR([Foreign/CUDA.hs])
 AC_CONFIG_FILES([cuda.buildinfo])
 AC_PROG_CXX
@@ -8,16 +8,19 @@
 AC_CANONICAL_TARGET
 
 # Search the user's PATH for the 'nvcc' compiler. If it is found, add this
-# prefix to the include and library search directories.
+# prefix to the include and library search directories. Additionally, set nvcc
+# as the C preprocessor for c2hs (only, or it won't try to link cudart)
 #
 AC_PATH_PROG(NVCC, nvcc)
 if test "$NVCC" != ""; then
     cuda_prefix="$(dirname $(dirname $NVCC))"
-    CPPFLAGS+="-I${cuda_prefix}/include"
+    cuda_c2hsflags+="--cpp=$NVCC --cppopts=-E "
+    CPPFLAGS+="-I${cuda_prefix}/include "
+#    CC=${NVCC}
 
     case $target in
-    x86_64*) LDFLAGS+="-L${cuda_prefix}/lib64" ;;
-    *)       LDFLAGS+="-L${cuda_prefix}/lib"   ;;
+    x86_64*) LDFLAGS+="-L${cuda_prefix}/lib64 " ;;
+    *)       LDFLAGS+="-L${cuda_prefix}/lib "   ;;
     esac
 fi
 
@@ -30,7 +33,7 @@
     SNOWLEOPARD=`grep '<string>10.6' /System/Library/CoreServices/SystemVersion.plist`
 fi
 if test "$SNOWLEOPARD" != ""; then
-    cuda_c2hsflags+="-C-U__BLOCKS__"
+    cuda_c2hsflags+="--cppopts=-U__BLOCKS__ "
     AC_MSG_RESULT(yes)
 else
     AC_MSG_RESULT(no)
diff --git a/cuda.cabal b/cuda.cabal
--- a/cuda.cabal
+++ b/cuda.cabal
@@ -1,5 +1,5 @@
 Name:                   cuda
-Version:                0.2.2
+Version:                0.3.2
 Synopsis:               FFI binding to the CUDA interface for programming NVIDIA GPUs
 Description:
     The CUDA library provides a direct, general purpose C-like SPMD programming
@@ -10,30 +10,28 @@
     .
     <http://developer.nvidia.com/object/cuda.html>
     .
-    /New in 0.2.2:/
-    .
-    * Foreign.CUDA.Analysis.optimalBlockSizeBy
-    .
-    /New in 0.2.1:/
-    .
-    * Improved cabal configuration phase
-    .
-    * Fixes for SDK 3.1 release changes
-    .
-    * Additional CUDA 3.1 bindings
-    .
-    /New in 0.2:/
-    .
-    * Occupancy calculator
-    .
-    * Textures
-    .
-    * Additional CUDA 3.0 bindings
-    .
-    /New in 0.1:/
-    .
-    * Initial release
+    The configure script will look for your CUDA installation in the standard
+    places, and if the nvcc compiler is found in your PATH, relative to that.
     .
+    > CHANGE LOG
+    >   0.3.2
+    >    - Initial support for CUDA 3.2
+    >
+    >   0.2.2
+    >    - Foreign.CUDA.Analysis.optimalBlockSizeBy
+    >
+    >   0.2.1
+    >    - Improved cabal configuration phase
+    >    - Fixes for SDK 3.1 release changes
+    >    - Additional CUDA 3.1 bindings
+    >
+    >   0.2
+    >    - Occupancy calculator
+    >    - Textures
+    >    - Additional CUDA 3.0 bindings
+    >
+    >   0.1
+    >    - Initial release
 
 License:                BSD3
 License-file:           LICENSE
