diff options
-rw-r--r-- | apps/debug_menu.c | 4 | ||||
-rw-r--r-- | firmware/drivers/ata.c | 35 | ||||
-rw-r--r-- | firmware/export/usb.h | 40 | ||||
-rw-r--r-- | firmware/export/usb_core.h | 2 | ||||
-rw-r--r-- | firmware/usb.c | 357 | ||||
-rw-r--r-- | firmware/usbstack/usb_charging_only.h | 2 | ||||
-rw-r--r-- | firmware/usbstack/usb_class_driver.h | 2 | ||||
-rw-r--r-- | firmware/usbstack/usb_core.c | 39 | ||||
-rw-r--r-- | firmware/usbstack/usb_storage.c | 9 |
9 files changed, 245 insertions, 245 deletions
diff --git a/apps/debug_menu.c b/apps/debug_menu.c index 7477bb001c..d3022df78e 100644 --- a/apps/debug_menu.c +++ b/apps/debug_menu.c | |||
@@ -2575,7 +2575,7 @@ static bool logf_usb_serial(void) | |||
2575 | } | 2575 | } |
2576 | #endif | 2576 | #endif |
2577 | 2577 | ||
2578 | #if defined(HAVE_USBSTACK) && defined(USB_STORAGE) | 2578 | #if 0 && defined(HAVE_USBSTACK) && defined(USB_STORAGE) |
2579 | static bool usb_reconnect(void) | 2579 | static bool usb_reconnect(void) |
2580 | { | 2580 | { |
2581 | splash(HZ, "Reconnect mass storage"); | 2581 | splash(HZ, "Reconnect mass storage"); |
@@ -2720,7 +2720,7 @@ static const struct the_menu_item menuitems[] = { | |||
2720 | #if defined(HAVE_USBSTACK) && defined(ROCKBOX_HAS_LOGF) && defined(USB_SERIAL) | 2720 | #if defined(HAVE_USBSTACK) && defined(ROCKBOX_HAS_LOGF) && defined(USB_SERIAL) |
2721 | {"logf over usb",logf_usb_serial }, | 2721 | {"logf over usb",logf_usb_serial }, |
2722 | #endif | 2722 | #endif |
2723 | #if defined(HAVE_USBSTACK) && defined(USB_STORAGE) | 2723 | #if 0 && defined(HAVE_USBSTACK) && defined(USB_STORAGE) |
2724 | {"reconnect usb storage",usb_reconnect}, | 2724 | {"reconnect usb storage",usb_reconnect}, |
2725 | #endif | 2725 | #endif |
2726 | #ifdef CPU_BOOST_LOGGING | 2726 | #ifdef CPU_BOOST_LOGGING |
diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c index edef507e0d..5f5829736f 100644 --- a/firmware/drivers/ata.c +++ b/firmware/drivers/ata.c | |||
@@ -61,8 +61,9 @@ | |||
61 | #define CMD_SET_FEATURES 0xEF | 61 | #define CMD_SET_FEATURES 0xEF |
62 | #define CMD_SECURITY_FREEZE_LOCK 0xF5 | 62 | #define CMD_SECURITY_FREEZE_LOCK 0xF5 |
63 | 63 | ||
64 | #define Q_SLEEP 0 | 64 | /* Should all be < 0x100 (which are reserved for control messages) */ |
65 | #define Q_CLOSE 1 | 65 | #define Q_SLEEP 0 |
66 | #define Q_CLOSE 1 | ||
66 | 67 | ||
67 | #define READ_TIMEOUT 5*HZ | 68 | #define READ_TIMEOUT 5*HZ |
68 | 69 | ||
@@ -143,7 +144,7 @@ static void ata_lock_unlock(struct ata_lock *l) | |||
143 | #define mutex_unlock ata_lock_unlock | 144 | #define mutex_unlock ata_lock_unlock |
144 | #endif /* MAX_PHYS_SECTOR_SIZE */ | 145 | #endif /* MAX_PHYS_SECTOR_SIZE */ |
145 | 146 | ||
146 | #if defined(HAVE_USBSTACK) && defined(USE_ROCKBOX_USB) && !defined(BOOTLOADER) | 147 | #if defined(HAVE_USBSTACK) && defined(USE_ROCKBOX_USB) |
147 | #define ALLOW_USB_SPINDOWN | 148 | #define ALLOW_USB_SPINDOWN |
148 | #endif | 149 | #endif |
149 | 150 | ||
@@ -164,7 +165,7 @@ static bool lba48 = false; /* set for 48 bit addressing */ | |||
164 | #endif | 165 | #endif |
165 | static long ata_stack[(DEFAULT_STACK_SIZE*3)/sizeof(long)]; | 166 | static long ata_stack[(DEFAULT_STACK_SIZE*3)/sizeof(long)]; |
166 | static const char ata_thread_name[] = "ata"; | 167 | static const char ata_thread_name[] = "ata"; |
167 | static struct event_queue ata_queue; | 168 | static struct event_queue ata_queue SHAREDBSS_ATTR; |
168 | static bool initialized = false; | 169 | static bool initialized = false; |
169 | 170 | ||
170 | static long last_user_activity = -1; | 171 | static long last_user_activity = -1; |
@@ -910,7 +911,9 @@ static void ata_thread(void) | |||
910 | #ifdef ALLOW_USB_SPINDOWN | 911 | #ifdef ALLOW_USB_SPINDOWN |
911 | if(!usb_mode) | 912 | if(!usb_mode) |
912 | #endif | 913 | #endif |
914 | { | ||
913 | call_storage_idle_notifys(false); | 915 | call_storage_idle_notifys(false); |
916 | } | ||
914 | last_seen_mtx_unlock = 0; | 917 | last_seen_mtx_unlock = 0; |
915 | } | 918 | } |
916 | } | 919 | } |
@@ -923,7 +926,9 @@ static void ata_thread(void) | |||
923 | #ifdef ALLOW_USB_SPINDOWN | 926 | #ifdef ALLOW_USB_SPINDOWN |
924 | if(!usb_mode) | 927 | if(!usb_mode) |
925 | #endif | 928 | #endif |
929 | { | ||
926 | call_storage_idle_notifys(true); | 930 | call_storage_idle_notifys(true); |
931 | } | ||
927 | ata_perform_sleep(); | 932 | ata_perform_sleep(); |
928 | last_sleep = current_tick; | 933 | last_sleep = current_tick; |
929 | } | 934 | } |
@@ -935,14 +940,21 @@ static void ata_thread(void) | |||
935 | { | 940 | { |
936 | mutex_lock(&ata_mtx); | 941 | mutex_lock(&ata_mtx); |
937 | ide_power_enable(false); | 942 | ide_power_enable(false); |
938 | mutex_unlock(&ata_mtx); | ||
939 | poweroff = true; | 943 | poweroff = true; |
944 | mutex_unlock(&ata_mtx); | ||
940 | } | 945 | } |
941 | #endif | 946 | #endif |
942 | break; | 947 | break; |
943 | 948 | ||
944 | #ifndef USB_NONE | 949 | #ifndef USB_NONE |
945 | case SYS_USB_CONNECTED: | 950 | case SYS_USB_CONNECTED: |
951 | /* Tell the USB thread that we are safe */ | ||
952 | DEBUGF("ata_thread got SYS_USB_CONNECTED\n"); | ||
953 | #ifdef ALLOW_USB_SPINDOWN | ||
954 | usb_mode = true; | ||
955 | usb_acknowledge(SYS_USB_CONNECTED_ACK); | ||
956 | /* There is no need to force ATA power on */ | ||
957 | #else | ||
946 | if (poweroff) { | 958 | if (poweroff) { |
947 | mutex_lock(&ata_mtx); | 959 | mutex_lock(&ata_mtx); |
948 | ata_led(true); | 960 | ata_led(true); |
@@ -951,14 +963,8 @@ static void ata_thread(void) | |||
951 | mutex_unlock(&ata_mtx); | 963 | mutex_unlock(&ata_mtx); |
952 | } | 964 | } |
953 | 965 | ||
954 | /* Tell the USB thread that we are safe */ | ||
955 | DEBUGF("ata_thread got SYS_USB_CONNECTED\n"); | ||
956 | usb_acknowledge(SYS_USB_CONNECTED_ACK); | ||
957 | |||
958 | #ifdef ALLOW_USB_SPINDOWN | ||
959 | usb_mode = true; | ||
960 | #else | ||
961 | /* Wait until the USB cable is extracted again */ | 966 | /* Wait until the USB cable is extracted again */ |
967 | usb_acknowledge(SYS_USB_CONNECTED_ACK); | ||
962 | usb_wait_for_disconnect(&ata_queue); | 968 | usb_wait_for_disconnect(&ata_queue); |
963 | #endif | 969 | #endif |
964 | break; | 970 | break; |
@@ -971,12 +977,15 @@ static void ata_thread(void) | |||
971 | usb_mode = false; | 977 | usb_mode = false; |
972 | break; | 978 | break; |
973 | #endif | 979 | #endif |
974 | #endif | 980 | #endif /* USB_NONE */ |
981 | |||
975 | case Q_SLEEP: | 982 | case Q_SLEEP: |
976 | #ifdef ALLOW_USB_SPINDOWN | 983 | #ifdef ALLOW_USB_SPINDOWN |
977 | if(!usb_mode) | 984 | if(!usb_mode) |
978 | #endif | 985 | #endif |
986 | { | ||
979 | call_storage_idle_notifys(false); | 987 | call_storage_idle_notifys(false); |
988 | } | ||
980 | last_disk_activity = current_tick - sleep_timeout + (HZ/2); | 989 | last_disk_activity = current_tick - sleep_timeout + (HZ/2); |
981 | break; | 990 | break; |
982 | 991 | ||
diff --git a/firmware/export/usb.h b/firmware/export/usb.h index c8bbf28267..49b70f659a 100644 --- a/firmware/export/usb.h +++ b/firmware/export/usb.h | |||
@@ -24,20 +24,33 @@ | |||
24 | #include "kernel.h" | 24 | #include "kernel.h" |
25 | #include "button.h" | 25 | #include "button.h" |
26 | 26 | ||
27 | #if defined(IPOD_COLOR) || defined(IPOD_4G) \ | ||
28 | || defined(IPOD_MINI) || defined(IPOD_MINI2G) | ||
29 | #define USB_FIREWIRE_HANDLING | ||
30 | #endif | ||
31 | |||
27 | /* Messages from usb_tick and thread states */ | 32 | /* Messages from usb_tick and thread states */ |
28 | enum { | 33 | enum { |
29 | USB_INSERTED, | 34 | USB_INSERTED, /* Event+State */ |
30 | USB_EXTRACTED, | 35 | USB_EXTRACTED, /* Event+State */ |
31 | USB_REENABLE, | 36 | #ifdef HAVE_USB_POWER |
32 | USB_POWERED, | 37 | USB_POWERED, /* State */ |
33 | USB_TRANSFER_COMPLETION, | 38 | #endif |
34 | USB_REQUEST_DISK, | 39 | #ifdef HAVE_LCD_BITMAP |
35 | USB_RELEASE_DISK, | 40 | USB_SCREENDUMP, /* State */ |
36 | USB_REQUEST_REBOOT, | 41 | #endif |
37 | USB_QUIT, | 42 | #if (CONFIG_STORAGE & STORAGE_MMC) |
43 | USB_REENABLE, /* Event */ | ||
44 | #endif | ||
45 | #ifdef HAVE_USBSTACK | ||
46 | USB_TRANSFER_COMPLETION, /* Event */ | ||
47 | #endif | ||
48 | #ifdef USB_FIREWIRE_HANDLING | ||
49 | USB_REQUEST_REBOOT, /* Event */ | ||
50 | #endif | ||
51 | USB_QUIT, /* Event */ | ||
38 | }; | 52 | }; |
39 | 53 | ||
40 | |||
41 | #ifdef HAVE_USB_POWER | 54 | #ifdef HAVE_USB_POWER |
42 | #if CONFIG_KEYPAD == RECORDER_PAD | 55 | #if CONFIG_KEYPAD == RECORDER_PAD |
43 | #define USBPOWER_BUTTON BUTTON_F1 | 56 | #define USBPOWER_BUTTON BUTTON_F1 |
@@ -111,13 +124,10 @@ bool usb_charging_enabled(void); | |||
111 | #ifdef HAVE_USBSTACK | 124 | #ifdef HAVE_USBSTACK |
112 | void usb_signal_transfer_completion(struct usb_transfer_completion_event_data* event_data); | 125 | void usb_signal_transfer_completion(struct usb_transfer_completion_event_data* event_data); |
113 | bool usb_driver_enabled(int driver); | 126 | bool usb_driver_enabled(int driver); |
114 | bool usb_exclusive_ata(void); /* ata is available for usb */ | 127 | bool usb_exclusive_storage(void); /* storage is available for usb */ |
115 | void usb_request_exclusive_ata(void); | ||
116 | void usb_release_exclusive_ata(void); | ||
117 | #endif | 128 | #endif |
118 | 129 | ||
119 | #if defined(IPOD_COLOR) || defined(IPOD_4G) \ | 130 | #ifdef USB_FIREWIRE_HANDLING |
120 | || defined(IPOD_MINI) || defined(IPOD_MINI2G) | ||
121 | bool firewire_detect(void); | 131 | bool firewire_detect(void); |
122 | #endif | 132 | #endif |
123 | 133 | ||
diff --git a/firmware/export/usb_core.h b/firmware/export/usb_core.h index 9d9e327bb3..7af8e43c8d 100644 --- a/firmware/export/usb_core.h +++ b/firmware/export/usb_core.h | |||
@@ -52,7 +52,7 @@ void usb_core_exit(void); | |||
52 | void usb_core_control_request(struct usb_ctrlrequest* req); | 52 | void usb_core_control_request(struct usb_ctrlrequest* req); |
53 | void usb_core_transfer_complete(int endpoint, int dir, int status, int length); | 53 | void usb_core_transfer_complete(int endpoint, int dir, int status, int length); |
54 | void usb_core_bus_reset(void); | 54 | void usb_core_bus_reset(void); |
55 | bool usb_core_exclusive_connection(void); | 55 | bool usb_core_any_exclusive_storage(void); |
56 | void usb_core_enable_driver(int driver,bool enabled); | 56 | void usb_core_enable_driver(int driver,bool enabled); |
57 | bool usb_core_driver_enabled (int driver); | 57 | bool usb_core_driver_enabled (int driver); |
58 | void usb_core_handle_transfer_completion( | 58 | void usb_core_handle_transfer_completion( |
diff --git a/firmware/usb.c b/firmware/usb.c index ec47e0653c..b52a255c0a 100644 --- a/firmware/usb.c +++ b/firmware/usb.c | |||
@@ -79,7 +79,7 @@ static int usb_mmc_countdown = 0; | |||
79 | static long usb_stack[(DEFAULT_STACK_SIZE + 0x800)/sizeof(long)]; | 79 | static long usb_stack[(DEFAULT_STACK_SIZE + 0x800)/sizeof(long)]; |
80 | static const char usb_thread_name[] = "usb"; | 80 | static const char usb_thread_name[] = "usb"; |
81 | static unsigned int usb_thread_entry = 0; | 81 | static unsigned int usb_thread_entry = 0; |
82 | #endif | 82 | #endif /* USB_FULL_INIT */ |
83 | static struct event_queue usb_queue; | 83 | static struct event_queue usb_queue; |
84 | static int last_usb_status; | 84 | static int last_usb_status; |
85 | static bool usb_monitor_enabled; | 85 | static bool usb_monitor_enabled; |
@@ -87,16 +87,80 @@ static bool usb_monitor_enabled; | |||
87 | static bool exclusive_storage_access; | 87 | static bool exclusive_storage_access; |
88 | #endif | 88 | #endif |
89 | 89 | ||
90 | 90 | #ifdef USB_FIREWIRE_HANDLING | |
91 | #if defined(IPOD_COLOR) || defined(IPOD_4G) \ | ||
92 | || defined(IPOD_MINI) || defined(IPOD_MINI2G) | ||
93 | static int firewire_countdown; | 91 | static int firewire_countdown; |
94 | static bool last_firewire_status; | 92 | static bool last_firewire_status; |
95 | #endif | 93 | #endif |
96 | 94 | ||
97 | #ifdef USB_FULL_INIT | 95 | #ifdef USB_FULL_INIT |
98 | #ifndef HAVE_USBSTACK | 96 | |
99 | static void usb_slave_mode(bool on) | 97 | #if defined(USB_FIREWIRE_HANDLING) \ |
98 | || (defined(HAVE_USBSTACK) && !defined(USE_ROCKBOX_USB)) | ||
99 | static void try_reboot(void) | ||
100 | { | ||
101 | #ifdef HAVE_DISK_STORAGE | ||
102 | storage_sleepnow(); /* Immediately spindown the disk. */ | ||
103 | sleep(HZ*2); | ||
104 | #endif | ||
105 | |||
106 | #ifdef IPOD_ARCH /* The following code is based on ipodlinux */ | ||
107 | #if CONFIG_CPU == PP5020 | ||
108 | memcpy((void *)0x40017f00, "diskmode\0\0hotstuff\0\0\1", 21); | ||
109 | #elif CONFIG_CPU == PP5022 | ||
110 | memcpy((void *)0x4001ff00, "diskmode\0\0hotstuff\0\0\1", 21); | ||
111 | #endif /* CONFIG_CPU */ | ||
112 | #endif /* IPOD_ARCH */ | ||
113 | |||
114 | system_reboot(); /* Reboot */ | ||
115 | } | ||
116 | #endif /* USB_FIRWIRE_HANDLING || (HAVE_USBSTACK && !USE_ROCKBOX_USB) */ | ||
117 | |||
118 | #ifdef HAVE_USBSTACK | ||
119 | /* inline since branch is chosen at compile time */ | ||
120 | static inline void usb_slave_mode(bool on) | ||
121 | { | ||
122 | #ifdef USE_ROCKBOX_USB | ||
123 | int rc; | ||
124 | |||
125 | if (on) | ||
126 | { | ||
127 | trigger_cpu_boost(); | ||
128 | #ifdef HAVE_PRIORITY_SCHEDULING | ||
129 | thread_set_priority(THREAD_ID_CURRENT, PRIORITY_REALTIME); | ||
130 | #endif | ||
131 | usb_enable(true); | ||
132 | } | ||
133 | else /* usb_state == USB_INSERTED (only!) */ | ||
134 | { | ||
135 | usb_enable(false); | ||
136 | #ifdef HAVE_PRIORITY_SCHEDULING | ||
137 | thread_set_priority(THREAD_ID_CURRENT, PRIORITY_SYSTEM); | ||
138 | #endif | ||
139 | /* Entered exclusive mode */ | ||
140 | rc = disk_mount_all(); | ||
141 | if (rc <= 0) /* no partition */ | ||
142 | panicf("mount: %d",rc); | ||
143 | |||
144 | cancel_cpu_boost(); | ||
145 | } | ||
146 | #else /* !USB_ROCKBOX_USB */ | ||
147 | if (on) | ||
148 | { | ||
149 | /* until we have native mass-storage mode, we want to reboot on | ||
150 | usb host connect */ | ||
151 | try_reboot(); | ||
152 | } | ||
153 | #endif /* USE_ROCKBOX_USB */ | ||
154 | } | ||
155 | |||
156 | void usb_signal_transfer_completion( | ||
157 | struct usb_transfer_completion_event_data* event_data) | ||
158 | { | ||
159 | queue_post(&usb_queue, USB_TRANSFER_COMPLETION, (intptr_t)event_data); | ||
160 | } | ||
161 | #else /* !HAVE_USBSTACK */ | ||
162 | /* inline since branch is chosen at compile time */ | ||
163 | static inline void usb_slave_mode(bool on) | ||
100 | { | 164 | { |
101 | int rc; | 165 | int rc; |
102 | 166 | ||
@@ -107,11 +171,14 @@ static void usb_slave_mode(bool on) | |||
107 | storage_init(); | 171 | storage_init(); |
108 | storage_enable(false); | 172 | storage_enable(false); |
109 | usb_enable(true); | 173 | usb_enable(true); |
174 | cpu_idle_mode(true); | ||
110 | } | 175 | } |
111 | else | 176 | else |
112 | { | 177 | { |
113 | DEBUGF("Leaving USB slave mode\n"); | 178 | DEBUGF("Leaving USB slave mode\n"); |
114 | 179 | ||
180 | cpu_idle_mode(false); | ||
181 | |||
115 | /* Let the ISDx00 settle */ | 182 | /* Let the ISDx00 settle */ |
116 | sleep(HZ*1); | 183 | sleep(HZ*1); |
117 | 184 | ||
@@ -126,34 +193,31 @@ static void usb_slave_mode(bool on) | |||
126 | panicf("mount: %d",rc); | 193 | panicf("mount: %d",rc); |
127 | } | 194 | } |
128 | } | 195 | } |
129 | #endif | 196 | #endif /* HAVE_USBSTACK */ |
130 | 197 | ||
131 | static void try_reboot(void) | 198 | #ifdef HAVE_USB_POWER |
199 | static inline bool usb_power_button(void) | ||
132 | { | 200 | { |
133 | #ifdef HAVE_DISK_STORAGE | 201 | #if defined(IRIVER_H10) || defined (IRIVER_H10_5GB) |
134 | storage_sleepnow(); /* Immediately spindown the disk. */ | 202 | return (button_status() & ~USBPOWER_BTN_IGNORE) != USBPOWER_BUTTON; |
135 | sleep(HZ*2); | 203 | #else |
204 | return (button_status() & ~USBPOWER_BTN_IGNORE) == USBPOWER_BUTTON; | ||
136 | #endif | 205 | #endif |
206 | } | ||
137 | 207 | ||
138 | #ifdef IPOD_ARCH /* The following code is based on ipodlinux */ | 208 | #ifdef USB_FIREWIRE_HANDLING |
139 | #if CONFIG_CPU == PP5020 | 209 | static inline bool usb_reboot_button(void) |
140 | memcpy((void *)0x40017f00, "diskmode\0\0hotstuff\0\0\1", 21); | 210 | { |
141 | #elif CONFIG_CPU == PP5022 | 211 | return (button_status() & ~USBPOWER_BTN_IGNORE) != USBPOWER_BUTTON; |
142 | memcpy((void *)0x4001ff00, "diskmode\0\0hotstuff\0\0\1", 21); | ||
143 | #endif /* CONFIG_CPU */ | ||
144 | #endif /* IPOD_ARCH */ | ||
145 | |||
146 | system_reboot(); /* Reboot */ | ||
147 | } | 212 | } |
213 | #endif | ||
214 | #endif /* HAVE_USB_POWER */ | ||
148 | 215 | ||
149 | static void usb_thread(void) | 216 | static void usb_thread(void) |
150 | { | 217 | { |
151 | int num_acks_to_expect = -1; | 218 | int num_acks_to_expect = 0; |
152 | bool waiting_for_ack; | ||
153 | struct queue_event ev; | 219 | struct queue_event ev; |
154 | 220 | ||
155 | waiting_for_ack = false; | ||
156 | |||
157 | while(1) | 221 | while(1) |
158 | { | 222 | { |
159 | queue_wait(&usb_queue, &ev); | 223 | queue_wait(&usb_queue, &ev); |
@@ -165,180 +229,116 @@ static void usb_thread(void) | |||
165 | #endif | 229 | #endif |
166 | #ifdef HAVE_USBSTACK | 230 | #ifdef HAVE_USBSTACK |
167 | case USB_TRANSFER_COMPLETION: | 231 | case USB_TRANSFER_COMPLETION: |
168 | usb_core_handle_transfer_completion((struct usb_transfer_completion_event_data*)ev.data); | 232 | usb_core_handle_transfer_completion( |
169 | break; | 233 | (struct usb_transfer_completion_event_data*)ev.data); |
170 | #endif | ||
171 | #ifdef HAVE_USB_POWER | ||
172 | case USB_POWERED: | ||
173 | usb_state = USB_POWERED; | ||
174 | break; | 234 | break; |
175 | #endif | 235 | #endif |
176 | case USB_INSERTED: | 236 | case USB_INSERTED: |
177 | #ifdef HAVE_LCD_BITMAP | 237 | #ifdef HAVE_LCD_BITMAP |
178 | if(do_screendump_instead_of_usb) | 238 | if(do_screendump_instead_of_usb) |
179 | { | 239 | { |
240 | usb_state = USB_SCREENDUMP; | ||
180 | screen_dump(); | 241 | screen_dump(); |
242 | break; | ||
181 | } | 243 | } |
182 | else | ||
183 | #endif | 244 | #endif |
184 | #ifdef HAVE_USB_POWER | 245 | #ifdef HAVE_USB_POWER |
185 | #if defined(IRIVER_H10) || defined (IRIVER_H10_5GB) | 246 | if (usb_power_button()) |
186 | if((button_status() & ~USBPOWER_BTN_IGNORE) != USBPOWER_BUTTON) | ||
187 | #else | ||
188 | if((button_status() & ~USBPOWER_BTN_IGNORE) == USBPOWER_BUTTON) | ||
189 | #endif | ||
190 | { | 247 | { |
248 | /* Only charging is desired */ | ||
191 | usb_state = USB_POWERED; | 249 | usb_state = USB_POWERED; |
192 | #ifdef HAVE_USBSTACK | 250 | #ifdef HAVE_USBSTACK |
193 | usb_core_enable_driver(USB_DRIVER_MASS_STORAGE,false); | 251 | usb_core_enable_driver(USB_DRIVER_MASS_STORAGE, false); |
194 | usb_core_enable_driver(USB_DRIVER_CHARGING_ONLY,true); | 252 | usb_core_enable_driver(USB_DRIVER_CHARGING_ONLY, true); |
195 | usb_enable(true); | ||
196 | #endif | ||
197 | } | ||
198 | else | ||
199 | #endif | ||
200 | { | ||
201 | #ifdef HAVE_USBSTACK | ||
202 | /* Set the state to USB_POWERED for now. if a real | ||
203 | connection is detected it will switch to USB_INSERTED */ | ||
204 | usb_state = USB_POWERED; | ||
205 | usb_core_enable_driver(USB_DRIVER_MASS_STORAGE,true); | ||
206 | usb_core_enable_driver(USB_DRIVER_CHARGING_ONLY,false); | ||
207 | usb_enable(true); | 253 | usb_enable(true); |
208 | #else | ||
209 | /* Tell all threads that they have to back off the ATA. | ||
210 | We subtract one for our own thread. */ | ||
211 | num_acks_to_expect = | ||
212 | queue_broadcast(SYS_USB_CONNECTED, 0) - 1; | ||
213 | waiting_for_ack = true; | ||
214 | DEBUGF("USB inserted. Waiting for ack from %d threads...\n", | ||
215 | num_acks_to_expect); | ||
216 | #endif | 254 | #endif |
255 | break; | ||
217 | } | 256 | } |
218 | break; | 257 | #endif /* HAVE_USB_POWER */ |
219 | #ifdef HAVE_USBSTACK | 258 | #ifdef HAVE_USBSTACK |
220 | case USB_REQUEST_DISK: | 259 | /* Set the state to USB_POWERED for now. If permission to connect |
221 | if(!waiting_for_ack) | 260 | * by threads and storage is granted it will be changed to |
261 | * USB_CONNECTED. */ | ||
262 | usb_state = USB_POWERED; | ||
263 | usb_core_enable_driver(USB_DRIVER_MASS_STORAGE, true); | ||
264 | usb_core_enable_driver(USB_DRIVER_CHARGING_ONLY, false); | ||
265 | |||
266 | /* Check any drivers enabled at this point for exclusive storage | ||
267 | * access requirements. */ | ||
268 | exclusive_storage_access = usb_core_any_exclusive_storage(); | ||
269 | |||
270 | if (exclusive_storage_access) | ||
271 | #endif /* HAVE_USBSTACK */ | ||
222 | { | 272 | { |
223 | /* Tell all threads that they have to back off the ATA. | 273 | /* Tell all threads that they have to back off the storage. |
224 | We subtract one for our own thread. */ | 274 | We subtract one for our own thread. */ |
225 | num_acks_to_expect = | 275 | num_acks_to_expect = queue_broadcast(SYS_USB_CONNECTED, 0) - 1; |
226 | queue_broadcast(SYS_USB_CONNECTED, 0) - 1; | ||
227 | waiting_for_ack = true; | ||
228 | DEBUGF("USB inserted. Waiting for ack from %d threads...\n", | 276 | DEBUGF("USB inserted. Waiting for ack from %d threads...\n", |
229 | num_acks_to_expect); | 277 | num_acks_for_connect); |
230 | } | 278 | } |
231 | break; | 279 | break; |
232 | case USB_RELEASE_DISK: | 280 | |
233 | if(!waiting_for_ack) | 281 | case SYS_USB_CONNECTED_ACK: |
282 | if(num_acks_to_expect > 0 && --num_acks_to_expect == 0) | ||
234 | { | 283 | { |
235 | /* Tell all threads that they have to back off the ATA. | 284 | DEBUGF("All threads have acknowledged the connect.\n"); |
236 | We subtract one for our own thread. */ | 285 | usb_slave_mode(true); |
237 | num_acks_to_expect = | 286 | usb_state = USB_INSERTED; |
238 | queue_broadcast(SYS_USB_DISCONNECTED, 0) - 1; | ||
239 | waiting_for_ack = true; | ||
240 | DEBUGF("USB inserted. Waiting for ack from %d threads...\n", | ||
241 | num_acks_to_expect); | ||
242 | } | 287 | } |
243 | break; | 288 | else |
244 | #endif | ||
245 | case SYS_USB_CONNECTED_ACK: | ||
246 | if(waiting_for_ack) | ||
247 | { | 289 | { |
248 | num_acks_to_expect--; | 290 | DEBUGF("usb: got ack, %d to go...\n", |
249 | if(num_acks_to_expect == 0) | 291 | num_acks_to_expect); |
250 | { | ||
251 | DEBUGF("All threads have acknowledged the connect.\n"); | ||
252 | #ifdef HAVE_USBSTACK | ||
253 | #ifndef USE_ROCKBOX_USB | ||
254 | /* until we have native mass-storage mode, we want to reboot on | ||
255 | usb host connect */ | ||
256 | try_reboot(); | ||
257 | #endif /* USE_ROCKBOX_USB */ | ||
258 | #ifdef HAVE_PRIORITY_SCHEDULING | ||
259 | thread_set_priority(usb_thread_entry,PRIORITY_REALTIME); | ||
260 | #endif | ||
261 | exclusive_storage_access = true; | ||
262 | |||
263 | #else | ||
264 | usb_slave_mode(true); | ||
265 | cpu_idle_mode(true); | ||
266 | #endif | ||
267 | usb_state = USB_INSERTED; | ||
268 | waiting_for_ack = false; | ||
269 | } | ||
270 | else | ||
271 | { | ||
272 | DEBUGF("usb: got ack, %d to go...\n", | ||
273 | num_acks_to_expect); | ||
274 | } | ||
275 | } | 292 | } |
276 | break; | 293 | break; |
277 | 294 | ||
278 | case USB_EXTRACTED: | 295 | case USB_EXTRACTED: |
279 | #ifdef HAVE_USBSTACK | ||
280 | usb_enable(false); | ||
281 | #ifdef HAVE_PRIORITY_SCHEDULING | ||
282 | thread_set_priority(usb_thread_entry,PRIORITY_SYSTEM); | ||
283 | #endif | ||
284 | #endif | ||
285 | #ifdef HAVE_LCD_BITMAP | 296 | #ifdef HAVE_LCD_BITMAP |
286 | if(do_screendump_instead_of_usb) | 297 | if(usb_state == USB_SCREENDUMP) |
287 | break; | 298 | { |
288 | #endif | 299 | usb_state = USB_EXTRACTED; |
289 | #ifdef HAVE_USB_POWER | 300 | break; /* Connected for screendump only */ |
301 | } | ||
302 | #endif /* HAVE_LCD_BITMAP */ | ||
303 | #ifndef HAVE_USBSTACK /* Stack must undo this if POWERED state was transitional */ | ||
290 | if(usb_state == USB_POWERED) | 304 | if(usb_state == USB_POWERED) |
291 | { | 305 | { |
292 | usb_state = USB_EXTRACTED; | 306 | usb_state = USB_EXTRACTED; |
293 | break; | 307 | break; |
294 | } | 308 | } |
295 | #endif | 309 | #endif /* HAVE_USBSTACK */ |
296 | #ifndef HAVE_USBSTACK | ||
297 | if(usb_state == USB_INSERTED) | 310 | if(usb_state == USB_INSERTED) |
298 | { | 311 | { |
299 | /* Only disable the USB mode if we really have enabled it | 312 | /* Only disable the USB mode if we really have enabled it |
300 | some threads might not have acknowledged the | 313 | some threads might not have acknowledged the |
301 | insertion */ | 314 | insertion */ |
302 | usb_slave_mode(false); | 315 | usb_slave_mode(false); |
303 | cpu_idle_mode(false); | ||
304 | } | 316 | } |
305 | #endif | ||
306 | 317 | ||
307 | usb_state = USB_EXTRACTED; | 318 | usb_state = USB_EXTRACTED; |
308 | #ifdef HAVE_USBSTACK | 319 | #ifdef HAVE_USBSTACK |
309 | if(exclusive_storage_access) | 320 | if (!exclusive_storage_access) |
310 | { | 321 | break; |
311 | int rc = disk_mount_all(); | 322 | |
312 | if (rc <= 0) /* no partition */ | 323 | exclusive_storage_access = false; |
313 | panicf("mount: %d",rc); | 324 | #endif /* HAVE_USBSTACK */ |
314 | exclusive_storage_access = false; | 325 | /* Tell all threads that we are back in business */ |
315 | #endif | 326 | num_acks_to_expect = |
316 | /* Tell all threads that we are back in business */ | 327 | queue_broadcast(SYS_USB_DISCONNECTED, 0) - 1; |
317 | num_acks_to_expect = | 328 | DEBUGF("USB extracted. Waiting for ack from %d threads...\n", |
318 | queue_broadcast(SYS_USB_DISCONNECTED, 0) - 1; | 329 | num_acks_to_expect); |
319 | waiting_for_ack = true; | ||
320 | DEBUGF("USB extracted. Waiting for ack from %d threads...\n", | ||
321 | num_acks_to_expect); | ||
322 | #ifdef HAVE_USBSTACK | ||
323 | } | ||
324 | #endif | ||
325 | break; | 330 | break; |
326 | 331 | ||
327 | case SYS_USB_DISCONNECTED_ACK: | 332 | case SYS_USB_DISCONNECTED_ACK: |
328 | if(waiting_for_ack) | 333 | if(num_acks_to_expect > 0 && --num_acks_to_expect == 0) |
329 | { | 334 | { |
330 | num_acks_to_expect--; | 335 | DEBUGF("All threads have acknowledged. " |
331 | if(num_acks_to_expect == 0) | 336 | "We're in business.\n"); |
332 | { | 337 | } |
333 | DEBUGF("All threads have acknowledged. " | 338 | else |
334 | "We're in business.\n"); | 339 | { |
335 | waiting_for_ack = false; | 340 | DEBUGF("usb: got ack, %d to go...\n", |
336 | } | 341 | num_acks_to_expect); |
337 | else | ||
338 | { | ||
339 | DEBUGF("usb: got ack, %d to go...\n", | ||
340 | num_acks_to_expect); | ||
341 | } | ||
342 | } | 342 | } |
343 | break; | 343 | break; |
344 | 344 | ||
@@ -347,49 +347,44 @@ static void usb_thread(void) | |||
347 | case SYS_HOTSWAP_EXTRACTED: | 347 | case SYS_HOTSWAP_EXTRACTED: |
348 | #ifdef HAVE_USBSTACK | 348 | #ifdef HAVE_USBSTACK |
349 | usb_core_hotswap_event(1,ev.id == SYS_HOTSWAP_INSERTED); | 349 | usb_core_hotswap_event(1,ev.id == SYS_HOTSWAP_INSERTED); |
350 | #else | 350 | #else /* !HAVE_USBSTACK */ |
351 | if(usb_state == USB_INSERTED) | 351 | if(usb_state == USB_INSERTED) |
352 | { | 352 | { |
353 | usb_enable(false); | 353 | usb_enable(false); |
354 | #if (CONFIG_STORAGE & STORAGE_MMC) | 354 | #if (CONFIG_STORAGE & STORAGE_MMC) |
355 | usb_mmc_countdown = HZ/2; /* re-enable after 0.5 sec */ | 355 | usb_mmc_countdown = HZ/2; /* re-enable after 0.5 sec */ |
356 | #endif | 356 | #endif /* STORAGE_MMC */ |
357 | } | 357 | } |
358 | #endif | 358 | #endif /* HAVE_USBSTACK */ |
359 | break; | 359 | break; |
360 | 360 | ||
361 | #if (CONFIG_STORAGE & STORAGE_MMC) | ||
361 | case USB_REENABLE: | 362 | case USB_REENABLE: |
362 | if(usb_state == USB_INSERTED) | 363 | if(usb_state == USB_INSERTED) |
363 | usb_enable(true); /* reenable only if still inserted */ | 364 | usb_enable(true); /* reenable only if still inserted */ |
364 | break; | 365 | break; |
366 | #endif /* STORAGE_MMC */ | ||
365 | #endif /* HAVE_HOTSWAP */ | 367 | #endif /* HAVE_HOTSWAP */ |
368 | |||
369 | #ifdef USB_FIREWIRE_HANDLING | ||
366 | case USB_REQUEST_REBOOT: | 370 | case USB_REQUEST_REBOOT: |
367 | #ifdef HAVE_USB_POWER | 371 | #ifdef HAVE_USB_POWER |
368 | if((button_status() & ~USBPOWER_BTN_IGNORE) != USBPOWER_BUTTON) | 372 | if (usb_reboot_button()) |
369 | #endif | 373 | #endif |
370 | try_reboot(); | 374 | try_reboot(); |
371 | break; | 375 | break; |
376 | #endif /* USB_FIREWIRE_HANDLING */ | ||
372 | } | 377 | } |
373 | } | 378 | } |
374 | } | 379 | } |
375 | #endif | ||
376 | 380 | ||
377 | #ifdef HAVE_USBSTACK | ||
378 | void usb_signal_transfer_completion(struct usb_transfer_completion_event_data* event_data) | ||
379 | { | ||
380 | queue_post(&usb_queue, USB_TRANSFER_COMPLETION, (intptr_t)event_data); | ||
381 | } | ||
382 | #endif | ||
383 | |||
384 | #ifdef USB_FULL_INIT | ||
385 | static void usb_tick(void) | 381 | static void usb_tick(void) |
386 | { | 382 | { |
387 | int current_status; | 383 | int current_status; |
388 | 384 | ||
389 | if(usb_monitor_enabled) | 385 | if(usb_monitor_enabled) |
390 | { | 386 | { |
391 | #if defined(IPOD_COLOR) || defined(IPOD_4G) \ | 387 | #ifdef USB_FIREWIRE_HANDLING |
392 | || defined(IPOD_MINI) || defined(IPOD_MINI2G) | ||
393 | int current_firewire_status = firewire_detect(); | 388 | int current_firewire_status = firewire_detect(); |
394 | if(current_firewire_status != last_firewire_status) | 389 | if(current_firewire_status != last_firewire_status) |
395 | { | 390 | { |
@@ -409,7 +404,7 @@ static void usb_tick(void) | |||
409 | queue_post(&usb_queue, USB_REQUEST_REBOOT, 0); | 404 | queue_post(&usb_queue, USB_REQUEST_REBOOT, 0); |
410 | } | 405 | } |
411 | } | 406 | } |
412 | #endif | 407 | #endif /* USB_FIREWIRE_HANDLING */ |
413 | 408 | ||
414 | current_status = usb_detect(); | 409 | current_status = usb_detect(); |
415 | 410 | ||
@@ -442,7 +437,7 @@ static void usb_tick(void) | |||
442 | } | 437 | } |
443 | #endif | 438 | #endif |
444 | } | 439 | } |
445 | #endif | 440 | #endif /* USB_FULL_INIT */ |
446 | 441 | ||
447 | void usb_acknowledge(long id) | 442 | void usb_acknowledge(long id) |
448 | { | 443 | { |
@@ -458,8 +453,7 @@ void usb_init(void) | |||
458 | usb_monitor_enabled = false; | 453 | usb_monitor_enabled = false; |
459 | countdown = -1; | 454 | countdown = -1; |
460 | 455 | ||
461 | #if defined(IPOD_COLOR) || defined(IPOD_4G) \ | 456 | #ifdef USB_FIREWIRE_HANDLING |
462 | || defined(IPOD_MINI) || defined(IPOD_MINI2G) | ||
463 | firewire_countdown = -1; | 457 | firewire_countdown = -1; |
464 | last_firewire_status = false; | 458 | last_firewire_status = false; |
465 | #endif | 459 | #endif |
@@ -480,8 +474,7 @@ void usb_init(void) | |||
480 | IF_PRIO(, PRIORITY_SYSTEM) IF_COP(, CPU)); | 474 | IF_PRIO(, PRIORITY_SYSTEM) IF_COP(, CPU)); |
481 | 475 | ||
482 | tick_add_task(usb_tick); | 476 | tick_add_task(usb_tick); |
483 | #endif | 477 | #endif /* USB_FULL_INIT */ |
484 | |||
485 | } | 478 | } |
486 | 479 | ||
487 | void usb_wait_for_disconnect(struct event_queue *q) | 480 | void usb_wait_for_disconnect(struct event_queue *q) |
@@ -518,10 +511,8 @@ int usb_wait_for_disconnect_w_tmo(struct event_queue *q, int ticks) | |||
518 | case SYS_USB_DISCONNECTED: | 511 | case SYS_USB_DISCONNECTED: |
519 | usb_acknowledge(SYS_USB_DISCONNECTED_ACK); | 512 | usb_acknowledge(SYS_USB_DISCONNECTED_ACK); |
520 | return 0; | 513 | return 0; |
521 | break; | ||
522 | case SYS_TIMEOUT: | 514 | case SYS_TIMEOUT: |
523 | return 1; | 515 | return 1; |
524 | break; | ||
525 | } | 516 | } |
526 | } | 517 | } |
527 | #else | 518 | #else |
@@ -562,27 +553,7 @@ bool usb_inserted(void) | |||
562 | } | 553 | } |
563 | 554 | ||
564 | #ifdef HAVE_USBSTACK | 555 | #ifdef HAVE_USBSTACK |
565 | void usb_request_exclusive_ata(void) | 556 | bool usb_exclusive_storage(void) |
566 | { | ||
567 | /* This is not really a clean place to start boosting the cpu. but it's | ||
568 | * currently the best one. We want to get rid of having to boost the cpu | ||
569 | * for usb anyway */ | ||
570 | trigger_cpu_boost(); | ||
571 | if(!exclusive_storage_access) { | ||
572 | queue_post(&usb_queue, USB_REQUEST_DISK, 0); | ||
573 | } | ||
574 | } | ||
575 | |||
576 | void usb_release_exclusive_ata(void) | ||
577 | { | ||
578 | cancel_cpu_boost(); | ||
579 | if(exclusive_storage_access) { | ||
580 | queue_post(&usb_queue, USB_RELEASE_DISK, 0); | ||
581 | exclusive_storage_access = false; | ||
582 | } | ||
583 | } | ||
584 | |||
585 | bool usb_exclusive_ata(void) | ||
586 | { | 557 | { |
587 | return exclusive_storage_access; | 558 | return exclusive_storage_access; |
588 | } | 559 | } |
diff --git a/firmware/usbstack/usb_charging_only.h b/firmware/usbstack/usb_charging_only.h index 8bdf58ff1d..839e07dae4 100644 --- a/firmware/usbstack/usb_charging_only.h +++ b/firmware/usbstack/usb_charging_only.h | |||
@@ -5,7 +5,7 @@ | |||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | 5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < |
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | 6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ |
7 | * \/ \/ \/ \/ \/ | 7 | * \/ \/ \/ \/ \/ |
8 | * $Id: $ | 8 | * $Id$ |
9 | * | 9 | * |
10 | * Copyright (C) 2008 by Frank Gevaerts | 10 | * Copyright (C) 2008 by Frank Gevaerts |
11 | * | 11 | * |
diff --git a/firmware/usbstack/usb_class_driver.h b/firmware/usbstack/usb_class_driver.h index e089c488a8..b037e1dec2 100644 --- a/firmware/usbstack/usb_class_driver.h +++ b/firmware/usbstack/usb_class_driver.h | |||
@@ -33,7 +33,7 @@ struct usb_class_driver { | |||
33 | /* Driver api starts here */ | 33 | /* Driver api starts here */ |
34 | 34 | ||
35 | /* Set this to true if the driver needs exclusive disk access (e.g. usb storage) */ | 35 | /* Set this to true if the driver needs exclusive disk access (e.g. usb storage) */ |
36 | bool needs_exclusive_ata; | 36 | bool needs_exclusive_storage; |
37 | 37 | ||
38 | /* Let the driver request endpoints it need. Returns zero on success */ | 38 | /* Let the driver request endpoints it need. Returns zero on success */ |
39 | int (*request_endpoints)(struct usb_class_driver *); | 39 | int (*request_endpoints)(struct usb_class_driver *); |
diff --git a/firmware/usbstack/usb_core.c b/firmware/usbstack/usb_core.c index ea5d6590f6..50c9d8589c 100644 --- a/firmware/usbstack/usb_core.c +++ b/firmware/usbstack/usb_core.c | |||
@@ -54,6 +54,9 @@ | |||
54 | #include "ata.h" | 54 | #include "ata.h" |
55 | #endif | 55 | #endif |
56 | 56 | ||
57 | #ifndef USB_MAX_CURRENT | ||
58 | #define USB_MAX_CURRENT 500 | ||
59 | #endif | ||
57 | 60 | ||
58 | /*-------------------------------------------------------------------------*/ | 61 | /*-------------------------------------------------------------------------*/ |
59 | /* USB protocol descriptors: */ | 62 | /* USB protocol descriptors: */ |
@@ -94,7 +97,7 @@ static struct usb_config_descriptor __attribute__((aligned(2))) | |||
94 | .bConfigurationValue = 1, | 97 | .bConfigurationValue = 1, |
95 | .iConfiguration = 0, | 98 | .iConfiguration = 0, |
96 | .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, | 99 | .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, |
97 | .bMaxPower = 250, /* 500mA in 2mA units */ | 100 | .bMaxPower = (USB_MAX_CURRENT+1) / 2, /* In 2mA units */ |
98 | }; | 101 | }; |
99 | 102 | ||
100 | 103 | ||
@@ -179,7 +182,7 @@ static struct usb_class_driver drivers[USB_NUM_DRIVERS] = | |||
179 | #ifdef USB_STORAGE | 182 | #ifdef USB_STORAGE |
180 | [USB_DRIVER_MASS_STORAGE] = { | 183 | [USB_DRIVER_MASS_STORAGE] = { |
181 | .enabled = false, | 184 | .enabled = false, |
182 | .needs_exclusive_ata = true, | 185 | .needs_exclusive_storage = true, |
183 | .first_interface = 0, | 186 | .first_interface = 0, |
184 | .last_interface = 0, | 187 | .last_interface = 0, |
185 | .request_endpoints = usb_storage_request_endpoints, | 188 | .request_endpoints = usb_storage_request_endpoints, |
@@ -198,7 +201,7 @@ static struct usb_class_driver drivers[USB_NUM_DRIVERS] = | |||
198 | #ifdef USB_SERIAL | 201 | #ifdef USB_SERIAL |
199 | [USB_DRIVER_SERIAL] = { | 202 | [USB_DRIVER_SERIAL] = { |
200 | .enabled = false, | 203 | .enabled = false, |
201 | .needs_exclusive_ata = false, | 204 | .needs_exclusive_storage = false, |
202 | .first_interface = 0, | 205 | .first_interface = 0, |
203 | .last_interface = 0, | 206 | .last_interface = 0, |
204 | .request_endpoints = usb_serial_request_endpoints, | 207 | .request_endpoints = usb_serial_request_endpoints, |
@@ -217,7 +220,7 @@ static struct usb_class_driver drivers[USB_NUM_DRIVERS] = | |||
217 | #ifdef USB_CHARGING_ONLY | 220 | #ifdef USB_CHARGING_ONLY |
218 | [USB_DRIVER_CHARGING_ONLY] = { | 221 | [USB_DRIVER_CHARGING_ONLY] = { |
219 | .enabled = false, | 222 | .enabled = false, |
220 | .needs_exclusive_ata = false, | 223 | .needs_exclusive_storage = false, |
221 | .first_interface = 0, | 224 | .first_interface = 0, |
222 | .last_interface = 0, | 225 | .last_interface = 0, |
223 | .request_endpoints = usb_charging_only_request_endpoints, | 226 | .request_endpoints = usb_charging_only_request_endpoints, |
@@ -353,13 +356,17 @@ void usb_core_exit(void) | |||
353 | int i; | 356 | int i; |
354 | for(i=0;i<USB_NUM_DRIVERS;i++) { | 357 | for(i=0;i<USB_NUM_DRIVERS;i++) { |
355 | if(drivers[i].enabled && drivers[i].disconnect != NULL) | 358 | if(drivers[i].enabled && drivers[i].disconnect != NULL) |
359 | { | ||
356 | drivers[i].disconnect (); | 360 | drivers[i].disconnect (); |
361 | drivers[i].enabled = false; | ||
362 | } | ||
357 | } | 363 | } |
358 | 364 | ||
359 | if (initialized) { | 365 | if (initialized) { |
360 | usb_drv_exit(); | 366 | usb_drv_exit(); |
361 | } | 367 | } |
362 | initialized = false; | 368 | initialized = false; |
369 | usb_state = DEFAULT; | ||
363 | logf("usb_core_exit() finished"); | 370 | logf("usb_core_exit() finished"); |
364 | } | 371 | } |
365 | 372 | ||
@@ -392,6 +399,20 @@ bool usb_core_driver_enabled(int driver) | |||
392 | return drivers[driver].enabled; | 399 | return drivers[driver].enabled; |
393 | } | 400 | } |
394 | 401 | ||
402 | bool usb_core_any_exclusive_storage(void) | ||
403 | { | ||
404 | int i; | ||
405 | for(i=0;i<USB_NUM_DRIVERS;i++) { | ||
406 | if(drivers[i].enabled && | ||
407 | drivers[i].needs_exclusive_storage) | ||
408 | { | ||
409 | return true; | ||
410 | } | ||
411 | } | ||
412 | |||
413 | return false; | ||
414 | } | ||
415 | |||
395 | #ifdef HAVE_HOTSWAP | 416 | #ifdef HAVE_HOTSWAP |
396 | void usb_core_hotswap_event(int volume,bool inserted) | 417 | void usb_core_hotswap_event(int volume,bool inserted) |
397 | { | 418 | { |
@@ -484,14 +505,6 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req) | |||
484 | usb_core_set_serial_function_id(); | 505 | usb_core_set_serial_function_id(); |
485 | 506 | ||
486 | allocate_interfaces_and_endpoints(); | 507 | allocate_interfaces_and_endpoints(); |
487 | |||
488 | for(i=0;i<USB_NUM_DRIVERS;i++) { | ||
489 | if(drivers[i].enabled && | ||
490 | drivers[i].needs_exclusive_ata) { | ||
491 | usb_request_exclusive_ata(); | ||
492 | break; | ||
493 | } | ||
494 | } | ||
495 | } | 508 | } |
496 | 509 | ||
497 | switch(req->bRequestType & 0x1f) { | 510 | switch(req->bRequestType & 0x1f) { |
@@ -788,7 +801,7 @@ unsigned short usb_allowed_current() | |||
788 | { | 801 | { |
789 | if (usb_state == CONFIGURED) | 802 | if (usb_state == CONFIGURED) |
790 | { | 803 | { |
791 | return 500; | 804 | return MAX(USB_MAX_CURRENT, 100); |
792 | } | 805 | } |
793 | else | 806 | else |
794 | { | 807 | { |
diff --git a/firmware/usbstack/usb_storage.c b/firmware/usbstack/usb_storage.c index 8a4915123c..a70681d3e0 100644 --- a/firmware/usbstack/usb_storage.c +++ b/firmware/usbstack/usb_storage.c | |||
@@ -293,6 +293,7 @@ static bool check_disk_present(IF_MV_NONVOID(int volume)) | |||
293 | #endif | 293 | #endif |
294 | } | 294 | } |
295 | 295 | ||
296 | #if 0 | ||
296 | static void try_release_ata(void) | 297 | static void try_release_ata(void) |
297 | { | 298 | { |
298 | /* Check if there is a connected drive left. If not, | 299 | /* Check if there is a connected drive left. If not, |
@@ -310,6 +311,7 @@ static void try_release_ata(void) | |||
310 | usb_release_exclusive_ata(); | 311 | usb_release_exclusive_ata(); |
311 | } | 312 | } |
312 | } | 313 | } |
314 | #endif | ||
313 | 315 | ||
314 | #ifdef HAVE_HOTSWAP | 316 | #ifdef HAVE_HOTSWAP |
315 | void usb_storage_notify_hotswap(int volume,bool inserted) | 317 | void usb_storage_notify_hotswap(int volume,bool inserted) |
@@ -320,9 +322,7 @@ void usb_storage_notify_hotswap(int volume,bool inserted) | |||
320 | } | 322 | } |
321 | else { | 323 | else { |
322 | ejected[volume] = true; | 324 | ejected[volume] = true; |
323 | try_release_ata(); | ||
324 | } | 325 | } |
325 | |||
326 | } | 326 | } |
327 | #endif | 327 | #endif |
328 | 328 | ||
@@ -334,7 +334,6 @@ void usb_storage_reconnect(void) | |||
334 | for(i=0;i<NUM_VOLUMES;i++) | 334 | for(i=0;i<NUM_VOLUMES;i++) |
335 | ejected[i] = !check_disk_present(IF_MV(i)); | 335 | ejected[i] = !check_disk_present(IF_MV(i)); |
336 | logf("%s", __func__); | 336 | logf("%s", __func__); |
337 | usb_request_exclusive_ata(); | ||
338 | } | 337 | } |
339 | } | 338 | } |
340 | 339 | ||
@@ -682,7 +681,6 @@ static void handle_scsi(struct command_block_wrapper* cbw) | |||
682 | #ifdef HAVE_HOTSWAP | 681 | #ifdef HAVE_HOTSWAP |
683 | if(storage_removable(lun) && !storage_present(lun)) { | 682 | if(storage_removable(lun) && !storage_present(lun)) { |
684 | ejected[lun] = true; | 683 | ejected[lun] = true; |
685 | try_release_ata(); | ||
686 | } | 684 | } |
687 | #endif | 685 | #endif |
688 | 686 | ||
@@ -699,7 +697,7 @@ static void handle_scsi(struct command_block_wrapper* cbw) | |||
699 | switch (cbw->command_block[0]) { | 697 | switch (cbw->command_block[0]) { |
700 | case SCSI_TEST_UNIT_READY: | 698 | case SCSI_TEST_UNIT_READY: |
701 | logf("scsi test_unit_ready %d",lun); | 699 | logf("scsi test_unit_ready %d",lun); |
702 | if(!usb_exclusive_ata()) { | 700 | if(!usb_exclusive_storage()) { |
703 | send_csw(UMS_STATUS_FAIL); | 701 | send_csw(UMS_STATUS_FAIL); |
704 | cur_sense_data.sense_key=SENSE_NOT_READY; | 702 | cur_sense_data.sense_key=SENSE_NOT_READY; |
705 | cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT; | 703 | cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT; |
@@ -885,7 +883,6 @@ static void handle_scsi(struct command_block_wrapper* cbw) | |||
885 | { | 883 | { |
886 | logf("scsi eject"); | 884 | logf("scsi eject"); |
887 | ejected[lun]=true; | 885 | ejected[lun]=true; |
888 | try_release_ata(); | ||
889 | } | 886 | } |
890 | } | 887 | } |
891 | } | 888 | } |