diff options
author | Frank Gevaerts <frank@gevaerts.be> | 2009-03-08 18:45:19 +0000 |
---|---|---|
committer | Frank Gevaerts <frank@gevaerts.be> | 2009-03-08 18:45:19 +0000 |
commit | 871db6f5d997e9fffe4fe951e708e42ac77cc181 (patch) | |
tree | 4daacd7068637d12c4c43726a235567f96104bda /firmware | |
parent | 30a2713b6eef28194d9feb4e9758624f821936ff (diff) | |
download | rockbox-871db6f5d997e9fffe4fe951e708e42ac77cc181.tar.gz rockbox-871db6f5d997e9fffe4fe951e708e42ac77cc181.zip |
Allow the user to leave MSC mode by pressing the USB POWER button (the one that's used to go to usb power mode on plugin) when the host OS hasn't locked the device.
This only works for devices that expose a removable device, so for now the gigabeat S is out of luck.
(slightly modified from FS#9993)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@20244 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/export/usb.h | 1 | ||||
-rw-r--r-- | firmware/usbstack/usb_storage.c | 21 |
2 files changed, 17 insertions, 5 deletions
diff --git a/firmware/export/usb.h b/firmware/export/usb.h index ecbec3a914..be36ee0b31 100644 --- a/firmware/export/usb.h +++ b/firmware/export/usb.h | |||
@@ -131,6 +131,7 @@ bool usb_charging_enabled(void); | |||
131 | void usb_signal_transfer_completion(struct usb_transfer_completion_event_data* event_data); | 131 | void usb_signal_transfer_completion(struct usb_transfer_completion_event_data* event_data); |
132 | bool usb_driver_enabled(int driver); | 132 | bool usb_driver_enabled(int driver); |
133 | bool usb_exclusive_storage(void); /* storage is available for usb */ | 133 | bool usb_exclusive_storage(void); /* storage is available for usb */ |
134 | void usb_storage_try_release_storage(void); | ||
134 | #endif | 135 | #endif |
135 | int usb_release_exclusive_storage(void); | 136 | int usb_release_exclusive_storage(void); |
136 | 137 | ||
diff --git a/firmware/usbstack/usb_storage.c b/firmware/usbstack/usb_storage.c index 9b0625e4e2..aa8cb29da3 100644 --- a/firmware/usbstack/usb_storage.c +++ b/firmware/usbstack/usb_storage.c | |||
@@ -260,6 +260,7 @@ static void receive_block_data(void *data,int size); | |||
260 | static void fill_inquiry(IF_MV_NONVOID(int lun)); | 260 | static void fill_inquiry(IF_MV_NONVOID(int lun)); |
261 | static void send_and_read_next(void); | 261 | static void send_and_read_next(void); |
262 | static bool ejected[NUM_VOLUMES]; | 262 | static bool ejected[NUM_VOLUMES]; |
263 | static bool locked[NUM_VOLUMES]; | ||
263 | 264 | ||
264 | static int usb_interface; | 265 | static int usb_interface; |
265 | static int ep_in, ep_out; | 266 | static int ep_in, ep_out; |
@@ -304,14 +305,14 @@ static bool check_disk_present(IF_MV_NONVOID(int volume)) | |||
304 | #endif | 305 | #endif |
305 | } | 306 | } |
306 | 307 | ||
307 | static void try_release_ata(void) | 308 | void usb_storage_try_release_storage(void) |
308 | { | 309 | { |
309 | /* Check if there is a connected drive left. If not, | 310 | /* Check if there is a connected drive left. If not, |
310 | release excusive access */ | 311 | release excusive access */ |
311 | bool canrelease=true; | 312 | bool canrelease=true; |
312 | int i; | 313 | int i; |
313 | for(i=0;i<NUM_VOLUMES;i++) { | 314 | for(i=0;i<NUM_VOLUMES;i++) { |
314 | if(ejected[i]==false){ | 315 | if(ejected[i]==false && locked[i]==true){ |
315 | canrelease=false; | 316 | canrelease=false; |
316 | break; | 317 | break; |
317 | } | 318 | } |
@@ -331,7 +332,9 @@ void usb_storage_notify_hotswap(int volume,bool inserted) | |||
331 | } | 332 | } |
332 | else { | 333 | else { |
333 | ejected[volume] = true; | 334 | ejected[volume] = true; |
334 | try_release_ata(); | 335 | /* If this happens while the device is locked, weird things may happen. |
336 | At least try to keep our state consistent */ | ||
337 | locked[volume]=false; | ||
335 | } | 338 | } |
336 | } | 339 | } |
337 | #endif | 340 | #endif |
@@ -419,6 +422,14 @@ void usb_storage_init_connection(void) | |||
419 | 422 | ||
420 | int i; | 423 | int i; |
421 | for(i=0;i<NUM_VOLUMES;i++) { | 424 | for(i=0;i<NUM_VOLUMES;i++) { |
425 | #ifdef TOSHIBA_GIGABEAT_S | ||
426 | /* As long as the Gigabeat S is a non-removable device, we need | ||
427 | to mark the device as locked to avoid usb_storage_try_release_ata() | ||
428 | to leave MSC mode while the device is in use */ | ||
429 | locked[i] = true; | ||
430 | #else | ||
431 | locked[i] = false; | ||
432 | #endif | ||
422 | ejected[i] = !check_disk_present(IF_MV(i)); | 433 | ejected[i] = !check_disk_present(IF_MV(i)); |
423 | queue_broadcast(SYS_USB_LUN_LOCKED, (i<<16)+0); | 434 | queue_broadcast(SYS_USB_LUN_LOCKED, (i<<16)+0); |
424 | } | 435 | } |
@@ -685,7 +696,6 @@ static void handle_scsi(struct command_block_wrapper* cbw) | |||
685 | #ifdef HAVE_HOTSWAP | 696 | #ifdef HAVE_HOTSWAP |
686 | if(storage_removable(lun) && !storage_present(lun)) { | 697 | if(storage_removable(lun) && !storage_present(lun)) { |
687 | ejected[lun] = true; | 698 | ejected[lun] = true; |
688 | try_release_ata(); | ||
689 | } | 699 | } |
690 | #endif | 700 | #endif |
691 | 701 | ||
@@ -889,7 +899,6 @@ static void handle_scsi(struct command_block_wrapper* cbw) | |||
889 | { | 899 | { |
890 | logf("scsi eject"); | 900 | logf("scsi eject"); |
891 | ejected[lun]=true; | 901 | ejected[lun]=true; |
892 | try_release_ata(); | ||
893 | } | 902 | } |
894 | } | 903 | } |
895 | } | 904 | } |
@@ -900,10 +909,12 @@ static void handle_scsi(struct command_block_wrapper* cbw) | |||
900 | logf("scsi allow_medium_removal %d",lun); | 909 | logf("scsi allow_medium_removal %d",lun); |
901 | if((cbw->command_block[4] & 0x03) == 0) | 910 | if((cbw->command_block[4] & 0x03) == 0) |
902 | { | 911 | { |
912 | locked[lun]=false; | ||
903 | queue_broadcast(SYS_USB_LUN_LOCKED, (lun<<16)+0); | 913 | queue_broadcast(SYS_USB_LUN_LOCKED, (lun<<16)+0); |
904 | } | 914 | } |
905 | else | 915 | else |
906 | { | 916 | { |
917 | locked[lun]=true; | ||
907 | queue_broadcast(SYS_USB_LUN_LOCKED, (lun<<16)+1); | 918 | queue_broadcast(SYS_USB_LUN_LOCKED, (lun<<16)+1); |
908 | } | 919 | } |
909 | send_csw(UMS_STATUS_GOOD); | 920 | send_csw(UMS_STATUS_GOOD); |