IB/uverbs: Export ib_umem_get()/ib_umem_release() to modules
[safe/jmp/linux-2.6] / include / rdma / ib_verbs.h
index 61eed39..47cefca 100644 (file)
@@ -5,7 +5,7 @@
  * Copyright (c) 2004 Topspin Corporation.  All rights reserved.
  * Copyright (c) 2004 Voltaire Corporation.  All rights reserved.
  * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
- * Copyright (c) 2005, 2006 Cisco Systems.  All rights reserved.
+ * Copyright (c) 2005, 2006, 2007 Cisco Systems.  All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -43,6 +43,9 @@
 
 #include <linux/types.h>
 #include <linux/device.h>
+#include <linux/mm.h>
+#include <linux/dma-mapping.h>
+#include <linux/kref.h>
 
 #include <asm/atomic.h>
 #include <asm/scatterlist.h>
@@ -56,12 +59,22 @@ union ib_gid {
        } global;
 };
 
-enum ib_node_type {
-       IB_NODE_CA      = 1,
-       IB_NODE_SWITCH,
-       IB_NODE_ROUTER
+enum rdma_node_type {
+       /* IB values map to NodeInfo:NodeType. */
+       RDMA_NODE_IB_CA         = 1,
+       RDMA_NODE_IB_SWITCH,
+       RDMA_NODE_IB_ROUTER,
+       RDMA_NODE_RNIC
 };
 
+enum rdma_transport_type {
+       RDMA_TRANSPORT_IB,
+       RDMA_TRANSPORT_IWARP
+};
+
+enum rdma_transport_type
+rdma_node_get_transport(enum rdma_node_type node_type) __attribute_const__;
+
 enum ib_device_cap_flags {
        IB_DEVICE_RESIZE_MAX_WR         = 1,
        IB_DEVICE_BAD_PKEY_CNTR         = (1<<1),
@@ -78,6 +91,9 @@ enum ib_device_cap_flags {
        IB_DEVICE_RC_RNR_NAK_GEN        = (1<<12),
        IB_DEVICE_SRQ_RESIZE            = (1<<13),
        IB_DEVICE_N_NOTIFY_CQ           = (1<<14),
+       IB_DEVICE_ZERO_STAG             = (1<<15),
+       IB_DEVICE_SEND_W_INV            = (1<<16),
+       IB_DEVICE_MEM_WINDOW            = (1<<17)
 };
 
 enum ib_atomic_cap {
@@ -404,8 +420,8 @@ struct ib_wc {
        enum ib_wc_opcode       opcode;
        u32                     vendor_err;
        u32                     byte_len;
+       struct ib_qp           *qp;
        __be32                  imm_data;
-       u32                     qp_num;
        u32                     src_qp;
        int                     wc_flags;
        u16                     pkey_index;
@@ -415,9 +431,11 @@ struct ib_wc {
        u8                      port_num;       /* valid only for DR SMPs on switches */
 };
 
-enum ib_cq_notify {
-       IB_CQ_SOLICITED,
-       IB_CQ_NEXT_COMP
+enum ib_cq_notify_flags {
+       IB_CQ_SOLICITED                 = 1 << 0,
+       IB_CQ_NEXT_COMP                 = 1 << 1,
+       IB_CQ_SOLICITED_MASK            = IB_CQ_SOLICITED | IB_CQ_NEXT_COMP,
+       IB_CQ_REPORT_MISSED_EVENTS      = 1 << 2,
 };
 
 enum ib_srq_attr_mask {
@@ -692,6 +710,7 @@ struct ib_ucontext {
        struct list_head        qp_list;
        struct list_head        srq_list;
        struct list_head        ah_list;
+       int                     closing;
 };
 
 struct ib_uobject {
@@ -705,23 +724,6 @@ struct ib_uobject {
        int                     live;
 };
 
-struct ib_umem {
-       unsigned long           user_base;
-       unsigned long           virt_base;
-       size_t                  length;
-       int                     offset;
-       int                     page_size;
-       int                     writable;
-       struct list_head        chunk_list;
-};
-
-struct ib_umem_chunk {
-       struct list_head        list;
-       int                     nents;
-       int                     nmap;
-       struct scatterlist      page_list[0];
-};
-
 struct ib_udata {
        void __user *inbuf;
        void __user *outbuf;
@@ -734,11 +736,6 @@ struct ib_udata {
         ((void *) &((struct ib_umem_chunk *) 0)->page_list[1] -        \
          (void *) &((struct ib_umem_chunk *) 0)->page_list[0]))
 
-struct ib_umem_object {
-       struct ib_uobject       uobject;
-       struct ib_umem          umem;
-};
-
 struct ib_pd {
        struct ib_device       *device;
        struct ib_uobject      *uobject;
@@ -835,6 +832,51 @@ struct ib_cache {
        u8                     *lmc_cache;
 };
 
+struct ib_dma_mapping_ops {
+       int             (*mapping_error)(struct ib_device *dev,
+                                        u64 dma_addr);
+       u64             (*map_single)(struct ib_device *dev,
+                                     void *ptr, size_t size,
+                                     enum dma_data_direction direction);
+       void            (*unmap_single)(struct ib_device *dev,
+                                       u64 addr, size_t size,
+                                       enum dma_data_direction direction);
+       u64             (*map_page)(struct ib_device *dev,
+                                   struct page *page, unsigned long offset,
+                                   size_t size,
+                                   enum dma_data_direction direction);
+       void            (*unmap_page)(struct ib_device *dev,
+                                     u64 addr, size_t size,
+                                     enum dma_data_direction direction);
+       int             (*map_sg)(struct ib_device *dev,
+                                 struct scatterlist *sg, int nents,
+                                 enum dma_data_direction direction);
+       void            (*unmap_sg)(struct ib_device *dev,
+                                   struct scatterlist *sg, int nents,
+                                   enum dma_data_direction direction);
+       u64             (*dma_address)(struct ib_device *dev,
+                                      struct scatterlist *sg);
+       unsigned int    (*dma_len)(struct ib_device *dev,
+                                  struct scatterlist *sg);
+       void            (*sync_single_for_cpu)(struct ib_device *dev,
+                                              u64 dma_handle,
+                                              size_t size,
+                                              enum dma_data_direction dir);
+       void            (*sync_single_for_device)(struct ib_device *dev,
+                                                 u64 dma_handle,
+                                                 size_t size,
+                                                 enum dma_data_direction dir);
+       void            *(*alloc_coherent)(struct ib_device *dev,
+                                          size_t size,
+                                          u64 *dma_handle,
+                                          gfp_t flag);
+       void            (*free_coherent)(struct ib_device *dev,
+                                        size_t size, void *cpu_addr,
+                                        u64 dma_handle);
+};
+
+struct iw_cm_verbs;
+
 struct ib_device {
        struct device                *dma_device;
 
@@ -851,6 +893,10 @@ struct ib_device {
 
        u32                           flags;
 
+       int                           num_comp_vectors;
+
+       struct iw_cm_verbs           *iwcm;
+
        int                        (*query_device)(struct ib_device *device,
                                                   struct ib_device_attr *device_attr);
        int                        (*query_port)(struct ib_device *device,
@@ -915,6 +961,7 @@ struct ib_device {
                                                struct ib_recv_wr *recv_wr,
                                                struct ib_recv_wr **bad_recv_wr);
        struct ib_cq *             (*create_cq)(struct ib_device *device, int cqe,
+                                               int comp_vector,
                                                struct ib_ucontext *context,
                                                struct ib_udata *udata);
        int                        (*destroy_cq)(struct ib_cq *cq);
@@ -924,7 +971,7 @@ struct ib_device {
                                              struct ib_wc *wc);
        int                        (*peek_cq)(struct ib_cq *cq, int wc_cnt);
        int                        (*req_notify_cq)(struct ib_cq *cq,
-                                                   enum ib_cq_notify cq_notify);
+                                                   enum ib_cq_notify_flags flags);
        int                        (*req_ncomp_notif)(struct ib_cq *cq,
                                                      int wc_cnt);
        struct ib_mr *             (*get_dma_mr)(struct ib_pd *pd,
@@ -935,7 +982,8 @@ struct ib_device {
                                                  int mr_access_flags,
                                                  u64 *iova_start);
        struct ib_mr *             (*reg_user_mr)(struct ib_pd *pd,
-                                                 struct ib_umem *region,
+                                                 u64 start, u64 length,
+                                                 u64 virt_addr,
                                                  int mr_access_flags,
                                                  struct ib_udata *udata);
        int                        (*query_mr)(struct ib_mr *mr,
@@ -975,6 +1023,8 @@ struct ib_device {
                                                  struct ib_mad *in_mad,
                                                  struct ib_mad *out_mad);
 
+       struct ib_dma_mapping_ops   *dma_ops;
+
        struct module               *owner;
        struct class_device          class_dev;
        struct kobject               ports_parent;
@@ -1293,13 +1343,15 @@ static inline int ib_post_recv(struct ib_qp *qp,
  * @cq_context: Context associated with the CQ returned to the user via
  *   the associated completion and event handlers.
  * @cqe: The minimum size of the CQ.
+ * @comp_vector - Completion vector used to signal completion events.
+ *     Must be >= 0 and < context->num_comp_vectors.
  *
  * Users can examine the cq structure to determine the actual CQ size.
  */
 struct ib_cq *ib_create_cq(struct ib_device *device,
                           ib_comp_handler comp_handler,
                           void (*event_handler)(struct ib_event *, void *),
-                          void *cq_context, int cqe);
+                          void *cq_context, int cqe, int comp_vector);
 
 /**
  * ib_resize_cq - Modifies the capacity of the CQ.
@@ -1349,14 +1401,34 @@ int ib_peek_cq(struct ib_cq *cq, int wc_cnt);
 /**
  * ib_req_notify_cq - Request completion notification on a CQ.
  * @cq: The CQ to generate an event for.
- * @cq_notify: If set to %IB_CQ_SOLICITED, completion notification will
- *   occur on the next solicited event. If set to %IB_CQ_NEXT_COMP,
- *   notification will occur on the next completion.
+ * @flags:
+ *   Must contain exactly one of %IB_CQ_SOLICITED or %IB_CQ_NEXT_COMP
+ *   to request an event on the next solicited event or next work
+ *   completion at any type, respectively. %IB_CQ_REPORT_MISSED_EVENTS
+ *   may also be |ed in to request a hint about missed events, as
+ *   described below.
+ *
+ * Return Value:
+ *    < 0 means an error occurred while requesting notification
+ *   == 0 means notification was requested successfully, and if
+ *        IB_CQ_REPORT_MISSED_EVENTS was passed in, then no events
+ *        were missed and it is safe to wait for another event.  In
+ *        this case is it guaranteed that any work completions added
+ *        to the CQ since the last CQ poll will trigger a completion
+ *        notification event.
+ *    > 0 is only returned if IB_CQ_REPORT_MISSED_EVENTS was passed
+ *        in.  It means that the consumer must poll the CQ again to
+ *        make sure it is empty to avoid missing an event because of a
+ *        race between requesting notification and an entry being
+ *        added to the CQ.  This return value means it is possible
+ *        (but not guaranteed) that a work completion has been added
+ *        to the CQ since the last poll without triggering a
+ *        completion notification event.
  */
 static inline int ib_req_notify_cq(struct ib_cq *cq,
-                                  enum ib_cq_notify cq_notify)
+                                  enum ib_cq_notify_flags flags)
 {
-       return cq->device->req_notify_cq(cq, cq_notify);
+       return cq->device->req_notify_cq(cq, flags);
 }
 
 /**
@@ -1378,10 +1450,231 @@ static inline int ib_req_ncomp_notif(struct ib_cq *cq, int wc_cnt)
  *   usable for DMA.
  * @pd: The protection domain associated with the memory region.
  * @mr_access_flags: Specifies the memory access rights.
+ *
+ * Note that the ib_dma_*() functions defined below must be used
+ * to create/destroy addresses used with the Lkey or Rkey returned
+ * by ib_get_dma_mr().
  */
 struct ib_mr *ib_get_dma_mr(struct ib_pd *pd, int mr_access_flags);
 
 /**
+ * ib_dma_mapping_error - check a DMA addr for error
+ * @dev: The device for which the dma_addr was created
+ * @dma_addr: The DMA address to check
+ */
+static inline int ib_dma_mapping_error(struct ib_device *dev, u64 dma_addr)
+{
+       if (dev->dma_ops)
+               return dev->dma_ops->mapping_error(dev, dma_addr);
+       return dma_mapping_error(dma_addr);
+}
+
+/**
+ * ib_dma_map_single - Map a kernel virtual address to DMA address
+ * @dev: The device for which the dma_addr is to be created
+ * @cpu_addr: The kernel virtual address
+ * @size: The size of the region in bytes
+ * @direction: The direction of the DMA
+ */
+static inline u64 ib_dma_map_single(struct ib_device *dev,
+                                   void *cpu_addr, size_t size,
+                                   enum dma_data_direction direction)
+{
+       if (dev->dma_ops)
+               return dev->dma_ops->map_single(dev, cpu_addr, size, direction);
+       return dma_map_single(dev->dma_device, cpu_addr, size, direction);
+}
+
+/**
+ * ib_dma_unmap_single - Destroy a mapping created by ib_dma_map_single()
+ * @dev: The device for which the DMA address was created
+ * @addr: The DMA address
+ * @size: The size of the region in bytes
+ * @direction: The direction of the DMA
+ */
+static inline void ib_dma_unmap_single(struct ib_device *dev,
+                                      u64 addr, size_t size,
+                                      enum dma_data_direction direction)
+{
+       if (dev->dma_ops)
+               dev->dma_ops->unmap_single(dev, addr, size, direction);
+       else
+               dma_unmap_single(dev->dma_device, addr, size, direction);
+}
+
+/**
+ * ib_dma_map_page - Map a physical page to DMA address
+ * @dev: The device for which the dma_addr is to be created
+ * @page: The page to be mapped
+ * @offset: The offset within the page
+ * @size: The size of the region in bytes
+ * @direction: The direction of the DMA
+ */
+static inline u64 ib_dma_map_page(struct ib_device *dev,
+                                 struct page *page,
+                                 unsigned long offset,
+                                 size_t size,
+                                        enum dma_data_direction direction)
+{
+       if (dev->dma_ops)
+               return dev->dma_ops->map_page(dev, page, offset, size, direction);
+       return dma_map_page(dev->dma_device, page, offset, size, direction);
+}
+
+/**
+ * ib_dma_unmap_page - Destroy a mapping created by ib_dma_map_page()
+ * @dev: The device for which the DMA address was created
+ * @addr: The DMA address
+ * @size: The size of the region in bytes
+ * @direction: The direction of the DMA
+ */
+static inline void ib_dma_unmap_page(struct ib_device *dev,
+                                    u64 addr, size_t size,
+                                    enum dma_data_direction direction)
+{
+       if (dev->dma_ops)
+               dev->dma_ops->unmap_page(dev, addr, size, direction);
+       else
+               dma_unmap_page(dev->dma_device, addr, size, direction);
+}
+
+/**
+ * ib_dma_map_sg - Map a scatter/gather list to DMA addresses
+ * @dev: The device for which the DMA addresses are to be created
+ * @sg: The array of scatter/gather entries
+ * @nents: The number of scatter/gather entries
+ * @direction: The direction of the DMA
+ */
+static inline int ib_dma_map_sg(struct ib_device *dev,
+                               struct scatterlist *sg, int nents,
+                               enum dma_data_direction direction)
+{
+       if (dev->dma_ops)
+               return dev->dma_ops->map_sg(dev, sg, nents, direction);
+       return dma_map_sg(dev->dma_device, sg, nents, direction);
+}
+
+/**
+ * ib_dma_unmap_sg - Unmap a scatter/gather list of DMA addresses
+ * @dev: The device for which the DMA addresses were created
+ * @sg: The array of scatter/gather entries
+ * @nents: The number of scatter/gather entries
+ * @direction: The direction of the DMA
+ */
+static inline void ib_dma_unmap_sg(struct ib_device *dev,
+                                  struct scatterlist *sg, int nents,
+                                  enum dma_data_direction direction)
+{
+       if (dev->dma_ops)
+               dev->dma_ops->unmap_sg(dev, sg, nents, direction);
+       else
+               dma_unmap_sg(dev->dma_device, sg, nents, direction);
+}
+
+/**
+ * ib_sg_dma_address - Return the DMA address from a scatter/gather entry
+ * @dev: The device for which the DMA addresses were created
+ * @sg: The scatter/gather entry
+ */
+static inline u64 ib_sg_dma_address(struct ib_device *dev,
+                                   struct scatterlist *sg)
+{
+       if (dev->dma_ops)
+               return dev->dma_ops->dma_address(dev, sg);
+       return sg_dma_address(sg);
+}
+
+/**
+ * ib_sg_dma_len - Return the DMA length from a scatter/gather entry
+ * @dev: The device for which the DMA addresses were created
+ * @sg: The scatter/gather entry
+ */
+static inline unsigned int ib_sg_dma_len(struct ib_device *dev,
+                                        struct scatterlist *sg)
+{
+       if (dev->dma_ops)
+               return dev->dma_ops->dma_len(dev, sg);
+       return sg_dma_len(sg);
+}
+
+/**
+ * ib_dma_sync_single_for_cpu - Prepare DMA region to be accessed by CPU
+ * @dev: The device for which the DMA address was created
+ * @addr: The DMA address
+ * @size: The size of the region in bytes
+ * @dir: The direction of the DMA
+ */
+static inline void ib_dma_sync_single_for_cpu(struct ib_device *dev,
+                                             u64 addr,
+                                             size_t size,
+                                             enum dma_data_direction dir)
+{
+       if (dev->dma_ops)
+               dev->dma_ops->sync_single_for_cpu(dev, addr, size, dir);
+       else
+               dma_sync_single_for_cpu(dev->dma_device, addr, size, dir);
+}
+
+/**
+ * ib_dma_sync_single_for_device - Prepare DMA region to be accessed by device
+ * @dev: The device for which the DMA address was created
+ * @addr: The DMA address
+ * @size: The size of the region in bytes
+ * @dir: The direction of the DMA
+ */
+static inline void ib_dma_sync_single_for_device(struct ib_device *dev,
+                                                u64 addr,
+                                                size_t size,
+                                                enum dma_data_direction dir)
+{
+       if (dev->dma_ops)
+               dev->dma_ops->sync_single_for_device(dev, addr, size, dir);
+       else
+               dma_sync_single_for_device(dev->dma_device, addr, size, dir);
+}
+
+/**
+ * ib_dma_alloc_coherent - Allocate memory and map it for DMA
+ * @dev: The device for which the DMA address is requested
+ * @size: The size of the region to allocate in bytes
+ * @dma_handle: A pointer for returning the DMA address of the region
+ * @flag: memory allocator flags
+ */
+static inline void *ib_dma_alloc_coherent(struct ib_device *dev,
+                                          size_t size,
+                                          u64 *dma_handle,
+                                          gfp_t flag)
+{
+       if (dev->dma_ops)
+               return dev->dma_ops->alloc_coherent(dev, size, dma_handle, flag);
+       else {
+               dma_addr_t handle;
+               void *ret;
+
+               ret = dma_alloc_coherent(dev->dma_device, size, &handle, flag);
+               *dma_handle = handle;
+               return ret;
+       }
+}
+
+/**
+ * ib_dma_free_coherent - Free memory allocated by ib_dma_alloc_coherent()
+ * @dev: The device for which the DMA addresses were allocated
+ * @size: The size of the region
+ * @cpu_addr: the address returned by ib_dma_alloc_coherent()
+ * @dma_handle: the DMA address returned by ib_dma_alloc_coherent()
+ */
+static inline void ib_dma_free_coherent(struct ib_device *dev,
+                                       size_t size, void *cpu_addr,
+                                       u64 dma_handle)
+{
+       if (dev->dma_ops)
+               dev->dma_ops->free_coherent(dev, size, cpu_addr, dma_handle);
+       else
+               dma_free_coherent(dev->dma_device, size, cpu_addr, dma_handle);
+}
+
+/**
  * ib_reg_phys_mr - Prepares a virtually addressed memory region for use
  *   by an HCA.
  * @pd: The protection domain associated assigned to the registered region.