Merge to Fedora kernel-2.6.18-1.2224_FC5 patched with stable patch-2.6.18.1-vs2.0...
[linux-2.6.git] / drivers / pci / msi.h
index 4ac52d4..56951c3 100644 (file)
@@ -6,6 +6,68 @@
 #ifndef MSI_H
 #define MSI_H
 
+/*
+ * MSI operation vector.  Used by the msi core code (drivers/pci/msi.c)
+ * to abstract platform-specific tasks relating to MSI address generation
+ * and resource management.
+ */
+struct msi_ops {
+       /**
+        * setup - generate an MSI bus address and data for a given vector
+        * @pdev: PCI device context (in)
+        * @vector: vector allocated by the msi core (in)
+        * @addr_hi: upper 32 bits of PCI bus MSI address (out)
+        * @addr_lo: lower 32 bits of PCI bus MSI address (out)
+        * @data: MSI data payload (out)
+        *
+        * Description: The setup op is used to generate a PCI bus addres and
+        * data which the msi core will program into the card MSI capability
+        * registers.  The setup routine is responsible for picking an initial
+        * cpu to target the MSI at.  The setup routine is responsible for
+        * examining pdev to determine the MSI capabilities of the card and
+        * generating a suitable address/data.  The setup routine is
+        * responsible for allocating and tracking any system resources it
+        * needs to route the MSI to the cpu it picks, and for associating
+        * those resources with the passed in vector.
+        *
+        * Returns 0 if the MSI address/data was successfully setup.
+        **/
+
+       int     (*setup)    (struct pci_dev *pdev, unsigned int vector,
+                            u32 *addr_hi, u32 *addr_lo, u32 *data);
+
+       /**
+        * teardown - release resources allocated by setup
+        * @vector: vector context for resources (in)
+        *
+        * Description:  The teardown op is used to release any resources
+        * that were allocated in the setup routine associated with the passed
+        * in vector.
+        **/
+
+       void    (*teardown) (unsigned int vector);
+
+       /**
+        * target - retarget an MSI at a different cpu
+        * @vector: vector context for resources (in)
+        * @cpu:  new cpu to direct vector at (in)
+        * @addr_hi: new value of PCI bus upper 32 bits (in/out)
+        * @addr_lo: new value of PCI bus lower 32 bits (in/out)
+        *
+        * Description:  The target op is used to redirect an MSI vector
+        * at a different cpu.  addr_hi/addr_lo coming in are the existing
+        * values that the MSI core has programmed into the card.  The
+        * target code is responsible for freeing any resources (if any)
+        * associated with the old address, and generating a new PCI bus
+        * addr_hi/addr_lo that will redirect the vector at the indicated cpu.
+        **/
+
+       void    (*target)   (unsigned int vector, unsigned int cpu,
+                            u32 *addr_hi, u32 *addr_lo);
+};
+
+extern int msi_register(struct msi_ops *ops);
+
 #include <asm/msi.h>
 
 /*
@@ -63,67 +125,6 @@ extern int pci_vector_resources(int last, int nr_released);
 #define msix_mask(address)             (address | PCI_MSIX_FLAGS_BITMASK)
 #define msix_is_pending(address)       (address & PCI_MSIX_FLAGS_PENDMASK)
 
-/*
- * MSI Defined Data Structures
- */
-#define MSI_ADDRESS_HEADER             0xfee
-#define MSI_ADDRESS_HEADER_SHIFT       12
-#define MSI_ADDRESS_HEADER_MASK                0xfff000
-#define MSI_ADDRESS_DEST_ID_MASK       0xfff0000f
-#define MSI_TARGET_CPU_MASK            0xff
-#define MSI_DELIVERY_MODE              0
-#define MSI_LEVEL_MODE                 1       /* Edge always assert */
-#define MSI_TRIGGER_MODE               0       /* MSI is edge sensitive */
-#define MSI_PHYSICAL_MODE              0
-#define MSI_LOGICAL_MODE               1
-#define MSI_REDIRECTION_HINT_MODE      0
-
-struct msg_data {
-#if defined(__LITTLE_ENDIAN_BITFIELD)
-       __u32   vector          :  8;
-       __u32   delivery_mode   :  3;   /* 000b: FIXED | 001b: lowest prior */
-       __u32   reserved_1      :  3;
-       __u32   level           :  1;   /* 0: deassert | 1: assert */
-       __u32   trigger         :  1;   /* 0: edge | 1: level */
-       __u32   reserved_2      : 16;
-#elif defined(__BIG_ENDIAN_BITFIELD)
-       __u32   reserved_2      : 16;
-       __u32   trigger         :  1;   /* 0: edge | 1: level */
-       __u32   level           :  1;   /* 0: deassert | 1: assert */
-       __u32   reserved_1      :  3;
-       __u32   delivery_mode   :  3;   /* 000b: FIXED | 001b: lowest prior */
-       __u32   vector          :  8;
-#else
-#error "Bitfield endianness not defined! Check your byteorder.h"
-#endif
-} __attribute__ ((packed));
-
-struct msg_address {
-       union {
-               struct {
-#if defined(__LITTLE_ENDIAN_BITFIELD)
-                       __u32   reserved_1      :  2;
-                       __u32   dest_mode       :  1;   /*0:physic | 1:logic */
-                       __u32   redirection_hint:  1;   /*0: dedicated CPU
-                                                         1: lowest priority */
-                       __u32   reserved_2      :  4;
-                       __u32   dest_id         : 24;   /* Destination ID */
-#elif defined(__BIG_ENDIAN_BITFIELD)
-                       __u32   dest_id         : 24;   /* Destination ID */
-                       __u32   reserved_2      :  4;
-                       __u32   redirection_hint:  1;   /*0: dedicated CPU
-                                                         1: lowest priority */
-                       __u32   dest_mode       :  1;   /*0:physic | 1:logic */
-                       __u32   reserved_1      :  2;
-#else
-#error "Bitfield endianness not defined! Check your byteorder.h"
-#endif
-               }u;
-                       __u32  value;
-       }lo_address;
-       __u32   hi_address;
-} __attribute__ ((packed));
-
 struct msi_desc {
        struct {
                __u8    type    : 5;    /* {0: unused, 5h:MSI, 11h:MSI-X} */
@@ -132,7 +133,7 @@ struct msi_desc {
                __u8    reserved: 1;    /* reserved                       */
                __u8    entry_nr;       /* specific enabled entry         */
                __u8    default_vector; /* default pre-assigned vector    */
-               __u8    current_cpu;    /* current destination cpu        */
+               __u8    unused;         /* formerly unused destination cpu*/
        }msi_attrib;
 
        struct {
@@ -142,6 +143,14 @@ struct msi_desc {
 
        void __iomem *mask_base;
        struct pci_dev *dev;
+
+#ifdef CONFIG_PM
+       /* PM save area for MSIX address/data */
+
+       u32     address_hi_save;
+       u32     address_lo_save;
+       u32     data_save;
+#endif
 };
 
 #endif /* MSI_H */