Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[cascardo/linux.git] / include / rdma / ib_verbs.h
index fd2353f..5342ac6 100644 (file)
@@ -45,6 +45,7 @@
 #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>
@@ -419,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;
@@ -430,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 {
@@ -911,6 +914,8 @@ struct ib_device {
 
        u32                           flags;
 
+       int                           num_comp_vectors;
+
        struct iw_cm_verbs           *iwcm;
 
        int                        (*query_device)(struct ib_device *device,
@@ -977,6 +982,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);
@@ -986,7 +992,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,
@@ -1357,13 +1363,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.
@@ -1413,14 +1421,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);
 }
 
 /**
@@ -1456,9 +1484,9 @@ struct ib_mr *ib_get_dma_mr(struct ib_pd *pd, int mr_access_flags);
  */
 static inline int ib_dma_mapping_error(struct ib_device *dev, u64 dma_addr)
 {
-       return dev->dma_ops ?
-               dev->dma_ops->mapping_error(dev, dma_addr) :
-               dma_mapping_error(dma_addr);
+       if (dev->dma_ops)
+               return dev->dma_ops->mapping_error(dev, dma_addr);
+       return dma_mapping_error(dma_addr);
 }
 
 /**
@@ -1472,9 +1500,9 @@ static inline u64 ib_dma_map_single(struct ib_device *dev,
                                    void *cpu_addr, size_t size,
                                    enum dma_data_direction direction)
 {
-       return dev->dma_ops ?
-               dev->dma_ops->map_single(dev, cpu_addr, size, direction) :
-               dma_map_single(dev->dma_device, cpu_addr, size, 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);
 }
 
 /**
@@ -1488,8 +1516,9 @@ static inline void ib_dma_unmap_single(struct ib_device *dev,
                                       u64 addr, size_t size,
                                       enum dma_data_direction direction)
 {
-       dev->dma_ops ?
-               dev->dma_ops->unmap_single(dev, addr, size, direction) :
+       if (dev->dma_ops)
+               dev->dma_ops->unmap_single(dev, addr, size, direction);
+       else
                dma_unmap_single(dev->dma_device, addr, size, direction);
 }
 
@@ -1507,9 +1536,9 @@ static inline u64 ib_dma_map_page(struct ib_device *dev,
                                  size_t size,
                                         enum dma_data_direction direction)
 {
-       return dev->dma_ops ?
-               dev->dma_ops->map_page(dev, page, offset, size, direction) :
-               dma_map_page(dev->dma_device, page, offset, size, 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);
 }
 
 /**
@@ -1523,8 +1552,9 @@ static inline void ib_dma_unmap_page(struct ib_device *dev,
                                     u64 addr, size_t size,
                                     enum dma_data_direction direction)
 {
-       dev->dma_ops ?
-               dev->dma_ops->unmap_page(dev, addr, size, direction) :
+       if (dev->dma_ops)
+               dev->dma_ops->unmap_page(dev, addr, size, direction);
+       else
                dma_unmap_page(dev->dma_device, addr, size, direction);
 }
 
@@ -1539,9 +1569,9 @@ static inline int ib_dma_map_sg(struct ib_device *dev,
                                struct scatterlist *sg, int nents,
                                enum dma_data_direction direction)
 {
-       return dev->dma_ops ?
-               dev->dma_ops->map_sg(dev, sg, nents, direction) :
-               dma_map_sg(dev->dma_device, sg, nents, 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);
 }
 
 /**
@@ -1555,8 +1585,9 @@ static inline void ib_dma_unmap_sg(struct ib_device *dev,
                                   struct scatterlist *sg, int nents,
                                   enum dma_data_direction direction)
 {
-       dev->dma_ops ?
-               dev->dma_ops->unmap_sg(dev, sg, nents, direction) :
+       if (dev->dma_ops)
+               dev->dma_ops->unmap_sg(dev, sg, nents, direction);
+       else
                dma_unmap_sg(dev->dma_device, sg, nents, direction);
 }
 
@@ -1568,8 +1599,9 @@ static inline void ib_dma_unmap_sg(struct ib_device *dev,
 static inline u64 ib_sg_dma_address(struct ib_device *dev,
                                    struct scatterlist *sg)
 {
-       return dev->dma_ops ?
-               dev->dma_ops->dma_address(dev, sg) : sg_dma_address(sg);
+       if (dev->dma_ops)
+               return dev->dma_ops->dma_address(dev, sg);
+       return sg_dma_address(sg);
 }
 
 /**
@@ -1580,8 +1612,9 @@ static inline u64 ib_sg_dma_address(struct ib_device *dev,
 static inline unsigned int ib_sg_dma_len(struct ib_device *dev,
                                         struct scatterlist *sg)
 {
-       return dev->dma_ops ?
-               dev->dma_ops->dma_len(dev, sg) : sg_dma_len(sg);
+       if (dev->dma_ops)
+               return dev->dma_ops->dma_len(dev, sg);
+       return sg_dma_len(sg);
 }
 
 /**
@@ -1596,8 +1629,9 @@ static inline void ib_dma_sync_single_for_cpu(struct ib_device *dev,
                                              size_t size,
                                              enum dma_data_direction dir)
 {
-       dev->dma_ops ?
-               dev->dma_ops->sync_single_for_cpu(dev, addr, size, 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);
 }
 
@@ -1613,8 +1647,9 @@ static inline void ib_dma_sync_single_for_device(struct ib_device *dev,
                                                 size_t size,
                                                 enum dma_data_direction dir)
 {
-       dev->dma_ops ?
-               dev->dma_ops->sync_single_for_device(dev, addr, size, 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);
 }
 
@@ -1630,9 +1665,16 @@ static inline void *ib_dma_alloc_coherent(struct ib_device *dev,
                                           u64 *dma_handle,
                                           gfp_t flag)
 {
-       return dev->dma_ops ?
-               dev->dma_ops->alloc_coherent(dev, size, dma_handle, flag) :
-               dma_alloc_coherent(dev->dma_device, size, dma_handle, 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;
+       }
 }
 
 /**
@@ -1646,8 +1688,9 @@ static inline void ib_dma_free_coherent(struct ib_device *dev,
                                        size_t size, void *cpu_addr,
                                        u64 dma_handle)
 {
-       dev->dma_ops ?
-               dev->dma_ops->free_coherent(dev, size, cpu_addr, 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);
 }