[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[tyndur-devel] [PATCH 04/22] cdi/misc: Add CDI_UPCAST and endianness functions



+ Type inheritance is a common pattern seen in CDI. The new CDI_UPCAST()
  macro makes conversion to superclasses safer and allows for multiple
  inheritance if the need arises.
+ Add some endianness conversion functions. Even though support for big
  endian platforms is nowhere in sight, endianness conversion is still a
  common operation which should not be implemented in the driver itself
  but provided by the CDI implementation.

Signed-off-by: Max Reitz <max@xxxxxxxxxx>
Signed-off-by: Kevin Wolf <kevin@xxxxxxxxxx>
---
 src/modules/cdi/include/cdi/misc.h | 141 +++++++++++++++++++++++++++++++++++++
 1 file changed, 141 insertions(+)

diff --git a/src/modules/cdi/include/cdi/misc.h b/src/modules/cdi/include/cdi/misc.h
index 07967ec..b0973e6 100644
--- a/src/modules/cdi/include/cdi/misc.h
+++ b/src/modules/cdi/include/cdi/misc.h
@@ -85,6 +85,147 @@ int cdi_ioports_free(uint16_t start, uint16_t count);
  */
 void cdi_sleep_ms(uint32_t ms);
 
+/**
+ * \german
+ * Castet @object (muss ein Pointer sein) zu einem Pointer auf ein Objekt des
+ * Typs @to, welcher eine Unterklasse vom Typ von @object sein muss. @field ist
+ * das Feld von @to, das @object enthält.
+ *
+ * Beispiel:
+ * struct cdi_driver* driver;
+ * struct cdi_storage_driver* storage_driver =
+ *     CDI_UPCAST(driver, struct cdi_storage_driver, drv);
+ * \endgerman
+ * \english
+ * Casts @object (must be a pointer) to a pointer to an object of type @to which
+ * must be a subclass of @object's type. @field is the entry in @to which
+ * contains @object.
+ *
+ * Example:
+ * struct cdi_driver* driver;
+ * struct cdi_storage_driver* storage_driver =
+ *     CDI_UPCAST(driver, struct cdi_storage_driver, drv);
+ * \endenglish
+ * \thuringiansaxonian
+ * Dud @object (mussä Boindr sein) zuä Boindr uffn Objekt vondn Dühp @to
+ * umwürschn, der dannoo ähne Undrglasse vondn Dühp von @object sein muss.
+ * @field is das Feld von @to, dasdawelsches @object enthaldn dud.
+ *
+ * Baispiel:
+ * struct cdi_driver* driver;
+ * struct cdi_storage_driver* storage_driver =
+ *     CDI_UPCAST(driver, struct cdi_storage_driver, drv);
+ * \endthuringiansaxonian
+ * \french
+ * Convertit @object (qui doit être un pointeur) en un pointeur à un objet du
+ * type @to, qui doit être une sous-classe du type d'@objet. @field est
+ * l'inscription de @to qui est @object.
+ *
+ * Exemple:
+ * struct cdi_driver* driver;
+ * struct cdi_storage_driver* storage_driver =
+ *     CDI_UPCAST(driver, struct cdi_storage_driver, drv);
+ * \endfrench
+ * \japanese
+ * ポインター@objectはタイプ@toに指すポインターになられる。@toは@objectの
+ * タイプのサブクラスではないだめ。@fieldは@toの@objectを容れるフィールド。
+ *
+ * 例:
+ * struct cdi_driver* driver;
+ * struct cdi_storage_driver* storage_driver =
+ *     CDI_UPCAST(driver, struct cdi_storage_driver, drv);
+ * \endjapanese
+ */
+#define CDI_UPCAST(object, to, field) \
+    /* Type compatibility check */ \
+    ((void)((object) - &((to*)0)->field), \
+    /* The cast itself */ \
+     (to*)((char*)(object) - (char*)&((to*)0)->field))
+
+/**
+ * \german
+ * Funktionen zur Endiannesskonvertierung. Es sei darauf hingewiesen, dass die
+ * meisten (wenn nicht alle) CDI-Treiber nur Little-Endian-Plattformen als Host
+ * unterstützen.
+ * \endgerman
+ * \english
+ * Functions for endianness conversion. Be aware that most if not all CDI
+ * drivers only support little endian machines as a host.
+ * \endenglish
+ * \thuringiansaxonian
+ * Fungzschjounen fürde Endschjannessumwandlung. Passe uff, fast wenn ni gar
+ * wirklisch alle CDI-Draibr gönnn nur uff Liddl-Endschjan-Blattform loofn.
+ * \endthuringiansaxonian
+ * \french
+ * Fonctions pour la conversion boutisme. Au fait, la plupart si pas tous des
+ * pilotes CDI ne peuvent que fonctionner sur une plateforme petit-boutiste.
+ * \endfrench
+ * \japanese
+ * エンディアンネスを変わるファンクション。因みに、全部(無ければ大部)の
+ * CDIドライバーはリトルエンディアンのプラットフォームだけに働ける。
+ * \endjapanese
+ */
+
+static inline uint16_t cdi_be16_to_cpu(uint16_t x)
+{
+    return (x >> 8) | (x << 8);
+}
+
+static inline uint32_t cdi_be32_to_cpu(uint32_t x)
+{
+    return ((uint32_t)cdi_be16_to_cpu(x) << 16) | (uint32_t)cdi_be16_to_cpu(x >> 16);
+}
+
+static inline uint64_t cdi_be64_to_cpu(uint64_t x)
+{
+    return ((uint64_t)cdi_be32_to_cpu(x) << 32) | (uint64_t)cdi_be32_to_cpu(x >> 32);
+}
+
+static inline uint16_t cdi_cpu_to_be16(uint16_t x)
+{
+    return cdi_be16_to_cpu(x);
+}
+
+static inline uint32_t cdi_cpu_to_be32(uint32_t x)
+{
+    return cdi_be32_to_cpu(x);
+}
+
+static inline uint64_t cdi_cpu_to_be64(uint64_t x)
+{
+    return cdi_be64_to_cpu(x);
+}
+
+static inline uint16_t cdi_le16_to_cpu(uint16_t x)
+{
+    return x;
+}
+
+static inline uint32_t cdi_le32_to_cpu(uint32_t x)
+{
+    return x;
+}
+
+static inline uint64_t cdi_le64_to_cpu(uint64_t x)
+{
+    return x;
+}
+
+static inline uint16_t cdi_cpu_to_le16(uint16_t x)
+{
+    return cdi_le16_to_cpu(x);
+}
+
+static inline uint32_t cdi_cpu_to_le32(uint32_t x)
+{
+    return cdi_le32_to_cpu(x);
+}
+
+static inline uint64_t cdi_cpu_to_le64(uint64_t x)
+{
+    return cdi_le64_to_cpu(x);
+}
+
 #ifdef __cplusplus
 }; // extern "C"
 #endif
-- 
2.6.3