summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2013-05-30 11:24:16 +0200
committerThomas Martitz <kugel@rockbox.org>2013-12-23 12:17:38 +0100
commit22e802e80048defd401462e062afcb10093ac793 (patch)
tree09d24f7eb2a3b18e6563e838398b2715394f7c4c /firmware
parent64b9e1fa7b645daa36ca0018dc168d4f871fd538 (diff)
downloadrockbox-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.h4
-rw-r--r--firmware/target/arm/pp/usb-fw-pp502x.c15
-rw-r--r--firmware/usbstack/usb_storage.c17
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);
75int audio_get_file_pos(void); 75int audio_get_file_pos(void);
76void audio_beep(int duration); 76void 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(!) */
80unsigned char *audio_get_buffer(bool talk_buf, size_t *buffer_size);
81
82#if CONFIG_CODEC == SWCODEC 78#if CONFIG_CODEC == SWCODEC
83void audio_next_dir(void); 79void audio_next_dir(void);
84void audio_prev_dir(void); 80void 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 */
236extern unsigned char freebuffer[];
237extern unsigned char freebufferend[];
238unsigned 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
248void usb_drv_int_enable(bool enable) 233void 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
434static int usb_handle;
433void usb_storage_init_connection(void) 435void 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
479void usb_storage_disconnect(void) 485void 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() */