diff options
author | Thomas Martitz <kugel@rockbox.org> | 2013-05-30 11:24:16 +0200 |
---|---|---|
committer | Thomas Martitz <kugel@rockbox.org> | 2013-12-23 12:17:38 +0100 |
commit | 22e802e80048defd401462e062afcb10093ac793 (patch) | |
tree | 09d24f7eb2a3b18e6563e838398b2715394f7c4c /firmware | |
parent | 64b9e1fa7b645daa36ca0018dc168d4f871fd538 (diff) | |
download | rockbox-22e802e80048defd401462e062afcb10093ac793.tar.gz rockbox-22e802e80048defd401462e062afcb10093ac793.zip |
playback,talk: Share audiobuffer via core_alloc_maximum().
This fixes the radioart crash that was the result of buffering.c working
on a freed buffer at the same time as buflib (radioart uses buffering.c for the
images). With this change the buffer is owned by buflib exclusively so this
cannot happen.
As a result, audio_get_buffer() doesn't exist anymore. Callers should call
core_alloc_maximum() directly. This buffer needs to be protected as usual
against movement if necessary (previously it was not protected at all which
cased the radioart crash), To get most of it they can adjust the willingness of
the talk engine to give its buffer away (at the expense of disabling voice
interface) with the new talk_buffer_set_policy() function.
Change-Id: I52123012208d04967876a304451d634e2bef3a33
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/export/audio.h | 4 | ||||
-rw-r--r-- | firmware/target/arm/pp/usb-fw-pp502x.c | 15 | ||||
-rw-r--r-- | firmware/usbstack/usb_storage.c | 17 |
3 files changed, 12 insertions, 24 deletions
diff --git a/firmware/export/audio.h b/firmware/export/audio.h index 8108f50939..57f7981b34 100644 --- a/firmware/export/audio.h +++ b/firmware/export/audio.h | |||
@@ -75,10 +75,6 @@ void audio_error_clear(void); | |||
75 | int audio_get_file_pos(void); | 75 | int audio_get_file_pos(void); |
76 | void audio_beep(int duration); | 76 | void audio_beep(int duration); |
77 | 77 | ||
78 | /* Required call when audio buffer is required for some other purpose */ | ||
79 | /* implemented in apps but called from firmware(!) */ | ||
80 | unsigned char *audio_get_buffer(bool talk_buf, size_t *buffer_size); | ||
81 | |||
82 | #if CONFIG_CODEC == SWCODEC | 78 | #if CONFIG_CODEC == SWCODEC |
83 | void audio_next_dir(void); | 79 | void audio_next_dir(void); |
84 | void audio_prev_dir(void); | 80 | void audio_prev_dir(void); |
diff --git a/firmware/target/arm/pp/usb-fw-pp502x.c b/firmware/target/arm/pp/usb-fw-pp502x.c index 44cce14389..acbb221cfd 100644 --- a/firmware/target/arm/pp/usb-fw-pp502x.c +++ b/firmware/target/arm/pp/usb-fw-pp502x.c | |||
@@ -230,21 +230,6 @@ void usb_insert_int(void) | |||
230 | } | 230 | } |
231 | #endif /* USB_STATUS_BY_EVENT */ | 231 | #endif /* USB_STATUS_BY_EVENT */ |
232 | 232 | ||
233 | #ifdef HAVE_BOOTLOADER_USB_MODE | ||
234 | /* Replacement function that returns all unused memory after the bootloader | ||
235 | * because the storage driver uses the audio buffer */ | ||
236 | extern unsigned char freebuffer[]; | ||
237 | extern unsigned char freebufferend[]; | ||
238 | unsigned char *audio_get_buffer(bool talk_buf, size_t *buffer_size) | ||
239 | { | ||
240 | if (buffer_size) | ||
241 | *buffer_size = freebufferend - freebuffer + 1; | ||
242 | |||
243 | return freebuffer; | ||
244 | (void)talk_buf; | ||
245 | } | ||
246 | #endif /* HAVE_BOOTLOADER_USB_MODE */ | ||
247 | |||
248 | void usb_drv_int_enable(bool enable) | 233 | void usb_drv_int_enable(bool enable) |
249 | { | 234 | { |
250 | /* enable/disable USB IRQ in CPU */ | 235 | /* enable/disable USB IRQ in CPU */ |
diff --git a/firmware/usbstack/usb_storage.c b/firmware/usbstack/usb_storage.c index d1279d0ee1..a3b867319d 100644 --- a/firmware/usbstack/usb_storage.c +++ b/firmware/usbstack/usb_storage.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #if CONFIG_RTC | 34 | #if CONFIG_RTC |
35 | #include "timefuncs.h" | 35 | #include "timefuncs.h" |
36 | #endif | 36 | #endif |
37 | #include "core_alloc.h" | ||
37 | 38 | ||
38 | #ifdef USB_USE_RAMDISK | 39 | #ifdef USB_USE_RAMDISK |
39 | #define RAMDISK_SIZE 2048 | 40 | #define RAMDISK_SIZE 2048 |
@@ -430,6 +431,7 @@ int usb_storage_get_config_descriptor(unsigned char *dest,int max_packet_size) | |||
430 | return (dest - orig_dest); | 431 | return (dest - orig_dest); |
431 | } | 432 | } |
432 | 433 | ||
434 | static int usb_handle; | ||
433 | void usb_storage_init_connection(void) | 435 | void usb_storage_init_connection(void) |
434 | { | 436 | { |
435 | logf("ums: set config"); | 437 | logf("ums: set config"); |
@@ -452,13 +454,17 @@ void usb_storage_init_connection(void) | |||
452 | #else | 454 | #else |
453 | /* TODO : check if bufsize is at least 32K ? */ | 455 | /* TODO : check if bufsize is at least 32K ? */ |
454 | size_t bufsize; | 456 | size_t bufsize; |
455 | unsigned char * audio_buffer; | 457 | unsigned char * buffer; |
458 | /* dummy ops with no callbacks, needed because by | ||
459 | * default buflib buffers can be moved around which must be avoided */ | ||
460 | static struct buflib_callbacks dummy_ops; | ||
456 | 461 | ||
457 | audio_buffer = audio_get_buffer(false,&bufsize); | 462 | usb_handle = core_alloc_maximum("usb storage", &bufsize, &dummy_ops); |
463 | buffer = core_get_data(usb_handle); | ||
458 | #if defined(UNCACHED_ADDR) && CONFIG_CPU != AS3525 | 464 | #if defined(UNCACHED_ADDR) && CONFIG_CPU != AS3525 |
459 | cbw_buffer = (void *)UNCACHED_ADDR((unsigned int)(audio_buffer+31) & 0xffffffe0); | 465 | cbw_buffer = (void *)UNCACHED_ADDR((unsigned int)(buffer+31) & 0xffffffe0); |
460 | #else | 466 | #else |
461 | cbw_buffer = (void *)((unsigned int)(audio_buffer+31) & 0xffffffe0); | 467 | cbw_buffer = (void *)((unsigned int)(buffer+31) & 0xffffffe0); |
462 | #endif | 468 | #endif |
463 | tb.transfer_buffer = cbw_buffer + MAX_CBW_SIZE; | 469 | tb.transfer_buffer = cbw_buffer + MAX_CBW_SIZE; |
464 | commit_discard_dcache(); | 470 | commit_discard_dcache(); |
@@ -478,7 +484,8 @@ void usb_storage_init_connection(void) | |||
478 | 484 | ||
479 | void usb_storage_disconnect(void) | 485 | void usb_storage_disconnect(void) |
480 | { | 486 | { |
481 | /* Empty for now */ | 487 | if (usb_handle > 0) |
488 | usb_handle = core_free(usb_handle); | ||
482 | } | 489 | } |
483 | 490 | ||
484 | /* called by usb_core_transfer_complete() */ | 491 | /* called by usb_core_transfer_complete() */ |