summaryrefslogtreecommitdiff
path: root/firmware/target/arm/imx31/gigabeat-s/usb-gigabeat-s.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/imx31/gigabeat-s/usb-gigabeat-s.c')
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/usb-gigabeat-s.c44
1 files changed, 43 insertions, 1 deletions
diff --git a/firmware/target/arm/imx31/gigabeat-s/usb-gigabeat-s.c b/firmware/target/arm/imx31/gigabeat-s/usb-gigabeat-s.c
index 016f24fc48..c52a9a6dec 100644
--- a/firmware/target/arm/imx31/gigabeat-s/usb-gigabeat-s.c
+++ b/firmware/target/arm/imx31/gigabeat-s/usb-gigabeat-s.c
@@ -19,7 +19,6 @@
19 * 19 *
20 ****************************************************************************/ 20 ****************************************************************************/
21#include "config.h" 21#include "config.h"
22#include "cpu.h"
23#include "system.h" 22#include "system.h"
24#include "kernel.h" 23#include "kernel.h"
25#include "ata.h" 24#include "ata.h"
@@ -31,8 +30,10 @@
31#include "ccm-imx31.h" 30#include "ccm-imx31.h"
32#include "avic-imx31.h" 31#include "avic-imx31.h"
33#include "power-gigabeat-s.h" 32#include "power-gigabeat-s.h"
33#include <string.h>
34 34
35static int usb_status = USB_EXTRACTED; 35static int usb_status = USB_EXTRACTED;
36static bool bootloader_install_mode = false;
36 37
37static void enable_transceiver(bool enable) 38static void enable_transceiver(bool enable)
38{ 39{
@@ -106,6 +107,16 @@ void usb_enable(bool on)
106 107
107void usb_attach(void) 108void usb_attach(void)
108{ 109{
110 bootloader_install_mode = false;
111
112 if (usb_core_driver_enabled(USB_DRIVER_MASS_STORAGE))
113 {
114 /* Check if this will be bootloader install mode, exposing the
115 * boot partition instead of the data partition */
116 bootloader_install_mode =
117 (button_status() & USB_BL_INSTALL_MODE_BTN) != 0;
118 }
119
109 usb_drv_attach(); 120 usb_drv_attach();
110} 121}
111 122
@@ -133,3 +144,34 @@ void usb_drv_usb_detect_event(void)
133 if (usb_drv_powered()) 144 if (usb_drv_powered())
134 usb_status_event(USB_INSERTED); 145 usb_status_event(USB_INSERTED);
135} 146}
147
148/* Called when reading the MBR */
149void usb_fix_mbr(unsigned char *mbr)
150{
151 unsigned char* p = mbr + 0x1be;
152 char tmp[16];
153
154 /* The Gigabeat S factory partition table contains invalid values for the
155 "active" flag in the MBR. This prevents at least the Linux kernel
156 from accepting the partition table, so we fix it on-the-fly. */
157 p[0x00] &= 0x80;
158 p[0x10] &= 0x80;
159 p[0x20] &= 0x80;
160 p[0x30] &= 0x80;
161
162 if (bootloader_install_mode)
163 return;
164
165 /* Windows ignores the partition flags and mounts the first partition it
166 sees when the device reports itself as removable. Swap the partitions
167 so the data partition appears to be partition 0. Mark the boot
168 partition 0 as hidden and make it partition 1. */
169
170 /* Mark the first partition as hidden */
171 p[0x04] |= 0x10;
172
173 /* Swap first and second partitions */
174 memcpy(tmp, &p[0x00], 16);
175 memcpy(&p[0x00], &p[0x10], 16);
176 memcpy(&p[0x10], tmp, 16);
177}