diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2011-01-05 19:35:51 +0000 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2011-01-05 19:35:51 +0000 |
commit | 89a7a8138ec97a038200ab3080710bd101a9ff0e (patch) | |
tree | 0d407ed964975d8eb3f13eafd85a3abe18918184 /firmware/target | |
parent | f97b9f11e4f95cf87b09f5184e2016d247f72d09 (diff) | |
download | rockbox-89a7a8138ec97a038200ab3080710bd101a9ff0e.tar.gz rockbox-89a7a8138ec97a038200ab3080710bd101a9ff0e.zip |
Gigabeat S: Make it a removable mass-storage device. Windows will assign a drive to only the main data partition by default. To access the bootloader partition instead, press 'Vol -' while it connects (in bootloader and firmware). Hopefully doesn't break anything for anyone.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@28972 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target')
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/usb-gigabeat-s.c | 44 | ||||
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/usb-target.h | 13 |
2 files changed, 56 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 | ||
35 | static int usb_status = USB_EXTRACTED; | 35 | static int usb_status = USB_EXTRACTED; |
36 | static bool bootloader_install_mode = false; | ||
36 | 37 | ||
37 | static void enable_transceiver(bool enable) | 38 | static void enable_transceiver(bool enable) |
38 | { | 39 | { |
@@ -106,6 +107,16 @@ void usb_enable(bool on) | |||
106 | 107 | ||
107 | void usb_attach(void) | 108 | void 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 */ | ||
149 | void 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 | } | ||
diff --git a/firmware/target/arm/imx31/gigabeat-s/usb-target.h b/firmware/target/arm/imx31/gigabeat-s/usb-target.h index c93400ca0b..7931058241 100644 --- a/firmware/target/arm/imx31/gigabeat-s/usb-target.h +++ b/firmware/target/arm/imx31/gigabeat-s/usb-target.h | |||
@@ -30,4 +30,17 @@ void usb_init_device(void); | |||
30 | /* Read the immediate state of the cable from the PMIC */ | 30 | /* Read the immediate state of the cable from the PMIC */ |
31 | bool usb_plugged(void); | 31 | bool usb_plugged(void); |
32 | 32 | ||
33 | /** Sector read/write filters **/ | ||
34 | |||
35 | /* Filter some things in the MBR - see usb-gigabeat-s.c */ | ||
36 | void usb_fix_mbr(unsigned char *mbr); | ||
37 | #define USBSTOR_READ_SECTORS_FILTER() \ | ||
38 | ({ if (cur_cmd.sector == 0) \ | ||
39 | usb_fix_mbr(cur_cmd.data[cur_cmd.data_select]); \ | ||
40 | 0; }) | ||
41 | |||
42 | /* Disallow MBR writes entirely since it was "fixed" in usb_fix_mbr */ | ||
43 | #define USBSTOR_WRITE_SECTORS_FILTER() \ | ||
44 | ({ cur_cmd.sector != 0 ? 0 : -1; }) | ||
45 | |||
33 | #endif /* USB_TARGET */ | 46 | #endif /* USB_TARGET */ |