OSDN Git Service

drm/i915/uc: Move uC fw helper code into dedicated files
authorMichal Wajdeczko <michal.wajdeczko@intel.com>
Wed, 4 Oct 2017 15:33:25 +0000 (15:33 +0000)
committerJoonas Lahtinen <joonas.lahtinen@linux.intel.com>
Wed, 4 Oct 2017 16:45:29 +0000 (19:45 +0300)
This is a prerequisite to unblock next steps.

v2: correct include order (Joonas)
v3: use common function prefix (Joonas)
    add kerneldoc (Michal)

Signed-off-by: Michal Wajdeczko <michal.wajdeczko@intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Sagar Arun Kamble <sagar.a.kamble@intel.com>
Reviewed-by: Sagar Arun Kamble <sagar.a.kamble@intel.com>
Reviewed-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20171004153327.32608-5-michal.wajdeczko@intel.com
drivers/gpu/drm/i915/Makefile
drivers/gpu/drm/i915/intel_uc.c
drivers/gpu/drm/i915/intel_uc.h
drivers/gpu/drm/i915/intel_uc_fw.c [new file with mode: 0644]
drivers/gpu/drm/i915/intel_uc_fw.h [new file with mode: 0644]

index 5182e3d..4850f26 100644 (file)
@@ -59,6 +59,7 @@ i915-y += i915_cmd_parser.o \
 
 # general-purpose microcontroller (GuC) support
 i915-y += intel_uc.o \
+         intel_uc_fw.o \
          intel_guc_ct.o \
          intel_guc_log.o \
          intel_guc_loader.o \
index 8151a9d..25694dd 100644 (file)
 #include "intel_uc.h"
 #include <linux/firmware.h>
 
-/* Cleans up uC firmware by releasing the firmware GEM obj.
- */
-static void __intel_uc_fw_fini(struct intel_uc_fw *uc_fw)
-{
-       struct drm_i915_gem_object *obj;
-
-       obj = fetch_and_zero(&uc_fw->obj);
-       if (obj)
-               i915_gem_object_put(obj);
-
-       uc_fw->fetch_status = INTEL_UC_FIRMWARE_NONE;
-}
-
 /* Reset GuC providing us with fresh state for both GuC and HuC.
  */
 static int __intel_uc_reset_hw(struct drm_i915_private *dev_priv)
@@ -112,154 +99,16 @@ void intel_uc_init_early(struct drm_i915_private *dev_priv)
        guc->notify = gen8_guc_raise_irq;
 }
 
-static void fetch_uc_fw(struct drm_i915_private *dev_priv,
-                       struct intel_uc_fw *uc_fw)
-{
-       struct pci_dev *pdev = dev_priv->drm.pdev;
-       struct drm_i915_gem_object *obj;
-       const struct firmware *fw = NULL;
-       struct uc_css_header *css;
-       size_t size;
-       int err;
-
-       if (!uc_fw->path)
-               return;
-
-       uc_fw->fetch_status = INTEL_UC_FIRMWARE_PENDING;
-
-       DRM_DEBUG_DRIVER("before requesting firmware: uC fw fetch status %s\n",
-                        intel_uc_fw_status_repr(uc_fw->fetch_status));
-
-       err = request_firmware(&fw, uc_fw->path, &pdev->dev);
-       if (err)
-               goto fail;
-       if (!fw)
-               goto fail;
-
-       DRM_DEBUG_DRIVER("fetch uC fw from %s succeeded, fw %p\n",
-                        uc_fw->path, fw);
-
-       /* Check the size of the blob before examining buffer contents */
-       if (fw->size < sizeof(struct uc_css_header)) {
-               DRM_NOTE("Firmware header is missing\n");
-               goto fail;
-       }
-
-       css = (struct uc_css_header *)fw->data;
-
-       /* Firmware bits always start from header */
-       uc_fw->header_offset = 0;
-       uc_fw->header_size = (css->header_size_dw - css->modulus_size_dw -
-                             css->key_size_dw - css->exponent_size_dw) * sizeof(u32);
-
-       if (uc_fw->header_size != sizeof(struct uc_css_header)) {
-               DRM_NOTE("CSS header definition mismatch\n");
-               goto fail;
-       }
-
-       /* then, uCode */
-       uc_fw->ucode_offset = uc_fw->header_offset + uc_fw->header_size;
-       uc_fw->ucode_size = (css->size_dw - css->header_size_dw) * sizeof(u32);
-
-       /* now RSA */
-       if (css->key_size_dw != UOS_RSA_SCRATCH_MAX_COUNT) {
-               DRM_NOTE("RSA key size is bad\n");
-               goto fail;
-       }
-       uc_fw->rsa_offset = uc_fw->ucode_offset + uc_fw->ucode_size;
-       uc_fw->rsa_size = css->key_size_dw * sizeof(u32);
-
-       /* At least, it should have header, uCode and RSA. Size of all three. */
-       size = uc_fw->header_size + uc_fw->ucode_size + uc_fw->rsa_size;
-       if (fw->size < size) {
-               DRM_NOTE("Missing firmware components\n");
-               goto fail;
-       }
-
-       /*
-        * The GuC firmware image has the version number embedded at a
-        * well-known offset within the firmware blob; note that major / minor
-        * version are TWO bytes each (i.e. u16), although all pointers and
-        * offsets are defined in terms of bytes (u8).
-        */
-       switch (uc_fw->type) {
-       case INTEL_UC_FW_TYPE_GUC:
-               /* Header and uCode will be loaded to WOPCM. Size of the two. */
-               size = uc_fw->header_size + uc_fw->ucode_size;
-
-               /* Top 32k of WOPCM is reserved (8K stack + 24k RC6 context). */
-               if (size > intel_guc_wopcm_size(dev_priv)) {
-                       DRM_ERROR("Firmware is too large to fit in WOPCM\n");
-                       goto fail;
-               }
-               uc_fw->major_ver_found = css->guc.sw_version >> 16;
-               uc_fw->minor_ver_found = css->guc.sw_version & 0xFFFF;
-               break;
-
-       case INTEL_UC_FW_TYPE_HUC:
-               uc_fw->major_ver_found = css->huc.sw_version >> 16;
-               uc_fw->minor_ver_found = css->huc.sw_version & 0xFFFF;
-               break;
-
-       default:
-               DRM_ERROR("Unknown firmware type %d\n", uc_fw->type);
-               err = -ENOEXEC;
-               goto fail;
-       }
-
-       if (uc_fw->major_ver_wanted == 0 && uc_fw->minor_ver_wanted == 0) {
-               DRM_NOTE("Skipping %s firmware version check\n",
-                        intel_uc_fw_type_repr(uc_fw->type));
-       } else if (uc_fw->major_ver_found != uc_fw->major_ver_wanted ||
-                  uc_fw->minor_ver_found < uc_fw->minor_ver_wanted) {
-               DRM_NOTE("%s firmware version %d.%d, required %d.%d\n",
-                        intel_uc_fw_type_repr(uc_fw->type),
-                        uc_fw->major_ver_found, uc_fw->minor_ver_found,
-                        uc_fw->major_ver_wanted, uc_fw->minor_ver_wanted);
-               err = -ENOEXEC;
-               goto fail;
-       }
-
-       DRM_DEBUG_DRIVER("firmware version %d.%d OK (minimum %d.%d)\n",
-                        uc_fw->major_ver_found, uc_fw->minor_ver_found,
-                        uc_fw->major_ver_wanted, uc_fw->minor_ver_wanted);
-
-       obj = i915_gem_object_create_from_data(dev_priv, fw->data, fw->size);
-       if (IS_ERR(obj)) {
-               err = PTR_ERR(obj);
-               goto fail;
-       }
-
-       uc_fw->obj = obj;
-       uc_fw->size = fw->size;
-
-       DRM_DEBUG_DRIVER("uC fw fetch status SUCCESS, obj %p\n",
-                        uc_fw->obj);
-
-       release_firmware(fw);
-       uc_fw->fetch_status = INTEL_UC_FIRMWARE_SUCCESS;
-       return;
-
-fail:
-       DRM_WARN("Failed to fetch valid uC firmware from %s (error %d)\n",
-                uc_fw->path, err);
-       DRM_DEBUG_DRIVER("uC fw fetch status FAIL; err %d, fw %p, obj %p\n",
-                        err, fw, uc_fw->obj);
-
-       release_firmware(fw);           /* OK even if fw is NULL */
-       uc_fw->fetch_status = INTEL_UC_FIRMWARE_FAIL;
-}
-
 void intel_uc_init_fw(struct drm_i915_private *dev_priv)
 {
-       fetch_uc_fw(dev_priv, &dev_priv->huc.fw);
-       fetch_uc_fw(dev_priv, &dev_priv->guc.fw);
+       intel_uc_fw_fetch(dev_priv, &dev_priv->huc.fw);
+       intel_uc_fw_fetch(dev_priv, &dev_priv->guc.fw);
 }
 
 void intel_uc_fini_fw(struct drm_i915_private *dev_priv)
 {
-       __intel_uc_fw_fini(&dev_priv->guc.fw);
-       __intel_uc_fw_fini(&dev_priv->huc.fw);
+       intel_uc_fw_fini(&dev_priv->guc.fw);
+       intel_uc_fw_fini(&dev_priv->huc.fw);
 }
 
 static inline i915_reg_t guc_send_reg(struct intel_guc *guc, u32 i)
index 388528f..f0d5a3f 100644 (file)
@@ -24,6 +24,7 @@
 #ifndef _INTEL_UC_H_
 #define _INTEL_UC_H_
 
+#include "intel_uc_fw.h"
 #include "intel_guc_fwif.h"
 #include "i915_guc_reg.h"
 #include "intel_ringbuffer.h"
@@ -70,72 +71,6 @@ struct i915_guc_client {
        uint64_t submissions[I915_NUM_ENGINES];
 };
 
-enum intel_uc_fw_status {
-       INTEL_UC_FIRMWARE_FAIL = -1,
-       INTEL_UC_FIRMWARE_NONE = 0,
-       INTEL_UC_FIRMWARE_PENDING,
-       INTEL_UC_FIRMWARE_SUCCESS
-};
-
-/* User-friendly representation of an enum */
-static inline
-const char *intel_uc_fw_status_repr(enum intel_uc_fw_status status)
-{
-       switch (status) {
-       case INTEL_UC_FIRMWARE_FAIL:
-               return "FAIL";
-       case INTEL_UC_FIRMWARE_NONE:
-               return "NONE";
-       case INTEL_UC_FIRMWARE_PENDING:
-               return "PENDING";
-       case INTEL_UC_FIRMWARE_SUCCESS:
-               return "SUCCESS";
-       }
-       return "<invalid>";
-}
-
-enum intel_uc_fw_type {
-       INTEL_UC_FW_TYPE_GUC,
-       INTEL_UC_FW_TYPE_HUC
-};
-
-/* User-friendly representation of an enum */
-static inline const char *intel_uc_fw_type_repr(enum intel_uc_fw_type type)
-{
-       switch (type) {
-       case INTEL_UC_FW_TYPE_GUC:
-               return "GuC";
-       case INTEL_UC_FW_TYPE_HUC:
-               return "HuC";
-       }
-       return "uC";
-}
-
-/*
- * This structure encapsulates all the data needed during the process
- * of fetching, caching, and loading the firmware image into the GuC.
- */
-struct intel_uc_fw {
-       const char *path;
-       size_t size;
-       struct drm_i915_gem_object *obj;
-       enum intel_uc_fw_status fetch_status;
-       enum intel_uc_fw_status load_status;
-
-       uint16_t major_ver_wanted;
-       uint16_t minor_ver_wanted;
-       uint16_t major_ver_found;
-       uint16_t minor_ver_found;
-
-       enum intel_uc_fw_type type;
-       uint32_t header_size;
-       uint32_t header_offset;
-       uint32_t rsa_size;
-       uint32_t rsa_offset;
-       uint32_t ucode_size;
-       uint32_t ucode_offset;
-};
-
 struct intel_guc_log {
        uint32_t flags;
        struct i915_vma *vma;
diff --git a/drivers/gpu/drm/i915/intel_uc_fw.c b/drivers/gpu/drm/i915/intel_uc_fw.c
new file mode 100644 (file)
index 0000000..766b1cb
--- /dev/null
@@ -0,0 +1,193 @@
+/*
+ * Copyright © 2016-2017 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#include <linux/firmware.h>
+
+#include "intel_uc_fw.h"
+#include "i915_drv.h"
+
+/**
+ * intel_uc_fw_fetch - fetch uC firmware
+ *
+ * @dev_priv: device private
+ * @uc_fw: uC firmware
+ *
+ * Fetch uC firmware into GEM obj.
+ */
+void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
+                      struct intel_uc_fw *uc_fw)
+{
+       struct pci_dev *pdev = dev_priv->drm.pdev;
+       struct drm_i915_gem_object *obj;
+       const struct firmware *fw = NULL;
+       struct uc_css_header *css;
+       size_t size;
+       int err;
+
+       if (!uc_fw->path)
+               return;
+
+       uc_fw->fetch_status = INTEL_UC_FIRMWARE_PENDING;
+
+       DRM_DEBUG_DRIVER("before requesting firmware: uC fw fetch status %s\n",
+                        intel_uc_fw_status_repr(uc_fw->fetch_status));
+
+       err = request_firmware(&fw, uc_fw->path, &pdev->dev);
+       if (err)
+               goto fail;
+       if (!fw)
+               goto fail;
+
+       DRM_DEBUG_DRIVER("fetch uC fw from %s succeeded, fw %p\n",
+                        uc_fw->path, fw);
+
+       /* Check the size of the blob before examining buffer contents */
+       if (fw->size < sizeof(struct uc_css_header)) {
+               DRM_NOTE("Firmware header is missing\n");
+               goto fail;
+       }
+
+       css = (struct uc_css_header *)fw->data;
+
+       /* Firmware bits always start from header */
+       uc_fw->header_offset = 0;
+       uc_fw->header_size = (css->header_size_dw - css->modulus_size_dw -
+                             css->key_size_dw - css->exponent_size_dw) *
+                            sizeof(u32);
+
+       if (uc_fw->header_size != sizeof(struct uc_css_header)) {
+               DRM_NOTE("CSS header definition mismatch\n");
+               goto fail;
+       }
+
+       /* then, uCode */
+       uc_fw->ucode_offset = uc_fw->header_offset + uc_fw->header_size;
+       uc_fw->ucode_size = (css->size_dw - css->header_size_dw) * sizeof(u32);
+
+       /* now RSA */
+       if (css->key_size_dw != UOS_RSA_SCRATCH_MAX_COUNT) {
+               DRM_NOTE("RSA key size is bad\n");
+               goto fail;
+       }
+       uc_fw->rsa_offset = uc_fw->ucode_offset + uc_fw->ucode_size;
+       uc_fw->rsa_size = css->key_size_dw * sizeof(u32);
+
+       /* At least, it should have header, uCode and RSA. Size of all three. */
+       size = uc_fw->header_size + uc_fw->ucode_size + uc_fw->rsa_size;
+       if (fw->size < size) {
+               DRM_NOTE("Missing firmware components\n");
+               goto fail;
+       }
+
+       /*
+        * The GuC firmware image has the version number embedded at a
+        * well-known offset within the firmware blob; note that major / minor
+        * version are TWO bytes each (i.e. u16), although all pointers and
+        * offsets are defined in terms of bytes (u8).
+        */
+       switch (uc_fw->type) {
+       case INTEL_UC_FW_TYPE_GUC:
+               /* Header and uCode will be loaded to WOPCM. Size of the two. */
+               size = uc_fw->header_size + uc_fw->ucode_size;
+
+               /* Top 32k of WOPCM is reserved (8K stack + 24k RC6 context). */
+               if (size > intel_guc_wopcm_size(dev_priv)) {
+                       DRM_ERROR("Firmware is too large to fit in WOPCM\n");
+                       goto fail;
+               }
+               uc_fw->major_ver_found = css->guc.sw_version >> 16;
+               uc_fw->minor_ver_found = css->guc.sw_version & 0xFFFF;
+               break;
+
+       case INTEL_UC_FW_TYPE_HUC:
+               uc_fw->major_ver_found = css->huc.sw_version >> 16;
+               uc_fw->minor_ver_found = css->huc.sw_version & 0xFFFF;
+               break;
+
+       default:
+               DRM_ERROR("Unknown firmware type %d\n", uc_fw->type);
+               err = -ENOEXEC;
+               goto fail;
+       }
+
+       if (uc_fw->major_ver_wanted == 0 && uc_fw->minor_ver_wanted == 0) {
+               DRM_NOTE("Skipping %s firmware version check\n",
+                        intel_uc_fw_type_repr(uc_fw->type));
+       } else if (uc_fw->major_ver_found != uc_fw->major_ver_wanted ||
+                  uc_fw->minor_ver_found < uc_fw->minor_ver_wanted) {
+               DRM_NOTE("%s firmware version %d.%d, required %d.%d\n",
+                        intel_uc_fw_type_repr(uc_fw->type),
+                        uc_fw->major_ver_found, uc_fw->minor_ver_found,
+                        uc_fw->major_ver_wanted, uc_fw->minor_ver_wanted);
+               err = -ENOEXEC;
+               goto fail;
+       }
+
+       DRM_DEBUG_DRIVER("firmware version %d.%d OK (minimum %d.%d)\n",
+                        uc_fw->major_ver_found, uc_fw->minor_ver_found,
+                        uc_fw->major_ver_wanted, uc_fw->minor_ver_wanted);
+
+       obj = i915_gem_object_create_from_data(dev_priv, fw->data, fw->size);
+       if (IS_ERR(obj)) {
+               err = PTR_ERR(obj);
+               goto fail;
+       }
+
+       uc_fw->obj = obj;
+       uc_fw->size = fw->size;
+
+       DRM_DEBUG_DRIVER("uC fw fetch status SUCCESS, obj %p\n",
+                        uc_fw->obj);
+
+       release_firmware(fw);
+       uc_fw->fetch_status = INTEL_UC_FIRMWARE_SUCCESS;
+       return;
+
+fail:
+       DRM_WARN("Failed to fetch valid uC firmware from %s (error %d)\n",
+                uc_fw->path, err);
+       DRM_DEBUG_DRIVER("uC fw fetch status FAIL; err %d, fw %p, obj %p\n",
+                        err, fw, uc_fw->obj);
+
+       release_firmware(fw);           /* OK even if fw is NULL */
+       uc_fw->fetch_status = INTEL_UC_FIRMWARE_FAIL;
+}
+
+/**
+ * intel_uc_fw_fini - cleanup uC firmware
+ *
+ * @uc_fw: uC firmware
+ *
+ * Cleans up uC firmware by releasing the firmware GEM obj.
+ */
+void intel_uc_fw_fini(struct intel_uc_fw *uc_fw)
+{
+       struct drm_i915_gem_object *obj;
+
+       obj = fetch_and_zero(&uc_fw->obj);
+       if (obj)
+               i915_gem_object_put(obj);
+
+       uc_fw->fetch_status = INTEL_UC_FIRMWARE_NONE;
+}
diff --git a/drivers/gpu/drm/i915/intel_uc_fw.h b/drivers/gpu/drm/i915/intel_uc_fw.h
new file mode 100644 (file)
index 0000000..849b2ce
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ * Copyright © 2014-2017 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#ifndef _INTEL_UC_FW_H_
+#define _INTEL_UC_FW_H_
+
+struct drm_i915_private;
+
+enum intel_uc_fw_status {
+       INTEL_UC_FIRMWARE_FAIL = -1,
+       INTEL_UC_FIRMWARE_NONE = 0,
+       INTEL_UC_FIRMWARE_PENDING,
+       INTEL_UC_FIRMWARE_SUCCESS
+};
+
+enum intel_uc_fw_type {
+       INTEL_UC_FW_TYPE_GUC,
+       INTEL_UC_FW_TYPE_HUC
+};
+
+/*
+ * This structure encapsulates all the data needed during the process
+ * of fetching, caching, and loading the firmware image into the uC.
+ */
+struct intel_uc_fw {
+       const char *path;
+       size_t size;
+       struct drm_i915_gem_object *obj;
+       enum intel_uc_fw_status fetch_status;
+       enum intel_uc_fw_status load_status;
+
+       uint16_t major_ver_wanted;
+       uint16_t minor_ver_wanted;
+       uint16_t major_ver_found;
+       uint16_t minor_ver_found;
+
+       enum intel_uc_fw_type type;
+       uint32_t header_size;
+       uint32_t header_offset;
+       uint32_t rsa_size;
+       uint32_t rsa_offset;
+       uint32_t ucode_size;
+       uint32_t ucode_offset;
+};
+
+static inline
+const char *intel_uc_fw_status_repr(enum intel_uc_fw_status status)
+{
+       switch (status) {
+       case INTEL_UC_FIRMWARE_FAIL:
+               return "FAIL";
+       case INTEL_UC_FIRMWARE_NONE:
+               return "NONE";
+       case INTEL_UC_FIRMWARE_PENDING:
+               return "PENDING";
+       case INTEL_UC_FIRMWARE_SUCCESS:
+               return "SUCCESS";
+       }
+       return "<invalid>";
+}
+
+static inline const char *intel_uc_fw_type_repr(enum intel_uc_fw_type type)
+{
+       switch (type) {
+       case INTEL_UC_FW_TYPE_GUC:
+               return "GuC";
+       case INTEL_UC_FW_TYPE_HUC:
+               return "HuC";
+       }
+       return "uC";
+}
+
+void intel_uc_fw_fetch(struct drm_i915_private *dev_priv,
+                      struct intel_uc_fw *uc_fw);
+void intel_uc_fw_fini(struct intel_uc_fw *uc_fw);
+
+#endif