summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
authorFrank Gevaerts <frank@gevaerts.be>2009-03-08 18:45:19 +0000
committerFrank Gevaerts <frank@gevaerts.be>2009-03-08 18:45:19 +0000
commit871db6f5d997e9fffe4fe951e708e42ac77cc181 (patch)
tree4daacd7068637d12c4c43726a235567f96104bda /firmware
parent30a2713b6eef28194d9feb4e9758624f821936ff (diff)
downloadrockbox-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.h1
-rw-r--r--firmware/usbstack/usb_storage.c21
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);
131void usb_signal_transfer_completion(struct usb_transfer_completion_event_data* event_data); 131void usb_signal_transfer_completion(struct usb_transfer_completion_event_data* event_data);
132bool usb_driver_enabled(int driver); 132bool usb_driver_enabled(int driver);
133bool usb_exclusive_storage(void); /* storage is available for usb */ 133bool usb_exclusive_storage(void); /* storage is available for usb */
134void usb_storage_try_release_storage(void);
134#endif 135#endif
135int usb_release_exclusive_storage(void); 136int 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);
260static void fill_inquiry(IF_MV_NONVOID(int lun)); 260static void fill_inquiry(IF_MV_NONVOID(int lun));
261static void send_and_read_next(void); 261static void send_and_read_next(void);
262static bool ejected[NUM_VOLUMES]; 262static bool ejected[NUM_VOLUMES];
263static bool locked[NUM_VOLUMES];
263 264
264static int usb_interface; 265static int usb_interface;
265static int ep_in, ep_out; 266static 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
307static void try_release_ata(void) 308void 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);