summaryrefslogtreecommitdiffstats
path: root/utils/hwstub/include/hwstub_usb.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/hwstub/include/hwstub_usb.hpp')
-rw-r--r--utils/hwstub/include/hwstub_usb.hpp194
1 files changed, 194 insertions, 0 deletions
diff --git a/utils/hwstub/include/hwstub_usb.hpp b/utils/hwstub/include/hwstub_usb.hpp
new file mode 100644
index 0000000000..6a9d4d8798
--- /dev/null
+++ b/utils/hwstub/include/hwstub_usb.hpp
@@ -0,0 +1,194 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2015 by Amaury Pouly
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+#ifndef __HWSTUB_USB_HPP__
+#define __HWSTUB_USB_HPP__
+
+#include "hwstub_usb.hpp"
+#include <libusb.h>
+
+namespace hwstub {
+namespace usb {
+
+/** USB context
+ *
+ * Context based on libusb. */
+class context : public hwstub::context
+{
+protected:
+ context(libusb_context *ctx, bool cleanup_ctx);
+public:
+ virtual ~context();
+ /** Return native libusb context */
+ libusb_context *native_context();
+ /** Create a USB context. If cleanup_ctx is true, libusb_exit() will be
+ * called on the context on deletion of this class. If ctx is NULL, libusb_init()
+ * will be called with NULL so there is no need to init the default context. */
+ static std::shared_ptr<context> create(libusb_context *ctx, bool cleanup_ctx = false,
+ std::string *error = nullptr);
+
+protected:
+ /* NOTE ctx_dev_t = libusb_device* */
+ libusb_device *from_ctx_dev(ctx_dev_t dev);
+ ctx_dev_t to_ctx_dev(libusb_device *dev);
+ virtual error fetch_device_list(std::vector<ctx_dev_t>& list, void*& ptr);
+ virtual void destroy_device_list(void *ptr);
+ virtual error create_device(ctx_dev_t dev, std::shared_ptr<hwstub::device>& hwdev);
+ virtual bool match_device(ctx_dev_t dev, std::shared_ptr<hwstub::device> hwdev);
+
+ libusb_context *m_usb_ctx; /* libusb context (might be NULL) */
+ bool m_cleanup_ctx; /* cleanup context on delete ? */
+};
+
+/** USB device
+ *
+ * Device based on libusb_device. */
+class device : public hwstub::device
+{
+ friend class context; /* for ctor */
+protected:
+ device(std::shared_ptr<hwstub::context> ctx, libusb_device *dev);
+public:
+ virtual ~device();
+ /** Return native libusb device */
+ libusb_device *native_device();
+ /** Get bus number */
+ uint8_t get_bus_number();
+ /** Get device address */
+ uint8_t get_address();
+ /** Get device VID */
+ uint16_t get_vid();
+ /** Get device PID */
+ uint16_t get_pid();
+
+protected:
+ /** Return true if this might be a hwstub device and should appear in the list */
+ static bool is_hwstub_dev(libusb_device *dev);
+
+ virtual error open_dev(std::shared_ptr<hwstub::handle>& handle);
+ virtual bool has_multiple_open() const;
+
+ libusb_device *m_dev; /* USB device */
+};
+
+/** USB handle
+ *
+ * Handle based on libusb_device_handle. */
+class handle : public hwstub::handle
+{
+protected:
+ handle(std::shared_ptr<hwstub::device> dev, libusb_device_handle *handle);
+public:
+ virtual ~handle();
+ /** set operation timeout */
+ void set_timeout(std::chrono::milliseconds ms);
+
+protected:
+ /* interpret libusb error: >=0 means SUCCESS, others are treated as errors,
+ * LIBUSB_ERROR_NO_DEVICE is treated as DISCONNECTED */
+ error interpret_libusb_error(int err);
+ /* interpret libusb error: <0 returns interpret_libusb_error(err), otherwise
+ * returns SUCCESS if err == expected_value */
+ error interpret_libusb_error(int err, size_t expected_value);
+ /* interpret libusb error: <0 returns interpret_libusb_error(err), otherwise
+ * returns SUCCESS and write size in out_size */
+ error interpret_libusb_size(int err, size_t& out_size);
+
+ libusb_device_handle *m_handle; /* USB handle */
+ unsigned int m_timeout; /* in milliseconds */
+};
+
+/** Rockbox USB handle
+ *
+ * HWSTUB/Rockbox protocol. */
+class rb_handle : public handle
+{
+ friend class device; /* for find_intf() */
+protected:
+ rb_handle(std::shared_ptr<hwstub::device> dev, libusb_device_handle *handle, int intf);
+public:
+ virtual ~rb_handle();
+
+protected:
+ virtual error read_dev(uint32_t addr, void *buf, size_t& sz, bool atomic);
+ virtual error write_dev(uint32_t addr, const void *buf, size_t& sz, bool atomic);
+ virtual error get_dev_desc(uint16_t desc, void *buf, size_t& buf_sz);
+ virtual error get_dev_log(void *buf, size_t& buf_sz);
+ virtual error exec_dev(uint32_t addr, uint16_t flags);
+ virtual error status() const;
+ virtual size_t get_buffer_size();
+ /* Probe a device to check if it is an hwstub device and return the interface
+ * number, or <0 on error. */
+ static bool find_intf(struct libusb_device_descriptor *dev,
+ struct libusb_config_descriptor *config, int& intf);
+
+ error m_probe_status; /* probing status */
+ int m_intf; /* interface number */
+ uint16_t m_transac_id; /* transaction ID */
+ size_t m_buf_size; /* Device buffer size */
+};
+
+/** JZ USB handle
+ *
+ * JZ boot protocol */
+class jz_handle : public handle
+{
+ friend class device; /* for is_boot_dev() */
+protected:
+ jz_handle(std::shared_ptr<hwstub::device> dev, libusb_device_handle *handle);
+public:
+ virtual ~jz_handle();
+
+protected:
+ virtual error read_dev(uint32_t addr, void *buf, size_t& sz, bool atomic);
+ virtual error write_dev(uint32_t addr, const void *buf, size_t& sz, bool atomic);
+ virtual error get_dev_desc(uint16_t desc, void *buf, size_t& buf_sz);
+ virtual error get_dev_log(void *buf, size_t& buf_sz);
+ virtual error exec_dev(uint32_t addr, uint16_t flags);
+ virtual error status() const;
+ virtual size_t get_buffer_size();
+ error probe();
+ error probe_jz4760b();
+ error read_reg32(uint32_t addr, uint32_t& value);
+ error write_reg32(uint32_t addr, uint32_t value);
+
+ error jz_cpuinfo(char cpuinfo[8]);
+ error jz_set_addr(uint32_t addr);
+ error jz_set_length(uint32_t size);
+ error jz_upload(void *data, size_t& length);
+ error jz_download(const void *data, size_t& length);
+ error jz_start1(uint32_t addr);
+ error jz_flush_caches();
+ error jz_start2(uint32_t addr);
+ /* Probe a device to check if it is a jz boot device */
+ static bool is_boot_dev(struct libusb_device_descriptor *dev,
+ struct libusb_config_descriptor *config);
+
+ error m_probe_status; /* probing status */
+ struct hwstub_version_desc_t m_desc_version;
+ struct hwstub_layout_desc_t m_desc_layout;
+ struct hwstub_target_desc_t m_desc_target;
+ struct hwstub_jz_desc_t m_desc_jz;
+};
+
+} // namespace usb
+} // namespace hwstub
+
+#endif /* __HWSTUB_USB_HPP__ */