>From fd50b614793fc1b73fb9632d303fd71df1ff577a Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Fri, 26 Sep 2014 11:02:12 -0700 Subject: [PATCH 4/4] Enable multipage support for the A300CS This optimizes the algorithm for page aligned reads of big pages. With the previous commit the oceanic common layer gives us such reads which makes the code slightly faster. Thanks to the caching this doesn't actually reduce the total number of reads from the device, but it still seems like the right thing to do. Signed-off-by: Dirk Hohndel --- src/oceanic_atom2.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/oceanic_atom2.c b/src/oceanic_atom2.c index 0fa1996d1b4c..27b4e5c010fa 100644 --- a/src/oceanic_atom2.c +++ b/src/oceanic_atom2.c @@ -561,6 +561,7 @@ oceanic_atom2_device_open (dc_device_t **out, dc_context_t *context, const char } else if (OCEANIC_COMMON_MATCH (device->base.version, aeris_a300cs_version)) { device->base.layout = &aeris_a300cs_layout; device->bigpage = 16; + device->base.multipage = 16; } else { device->base.layout = &oceanic_default_layout; } @@ -680,13 +681,22 @@ oceanic_atom2_generic_device_read (dc_device_t *abstract, unsigned int address, return DC_STATUS_SUCCESS; } -/* instead of reading randomly in 16 byte (PAGESIZE) chunks, we read in 256 byte (16 * PAGESIZE = BIGPAGESIZE) - * pages and just track what has and has not been read, yet */ + static dc_status_t oceanic_atom2_bigpage_device_read (dc_device_t *abstract, unsigned int address, unsigned char data[], unsigned int size) { + /* if we have an aligned read of exactly the device's page size (which the multipage algorithm in + * oceanic_common should give us most of the time) just read that, otherwise read the enclosing + * larger page(s) and copy what is needed into data */ oceanic_atom2_device_t *device = (oceanic_atom2_device_t*) abstract; unsigned int pagesize = PAGESIZE * device->bigpage; + + if (size == pagesize && address % pagesize == 0) { + // excellent, multipage did its job + return oceanic_atom2_generic_device_read(abstract, address, data, pagesize); + } + + /* for the smaller reads we want to cache things */ if (!device->bitmap) { device->bitmap = malloc(device->base.layout->memsize / pagesize / 8); device->cache = malloc(device->base.layout->memsize); @@ -694,6 +704,7 @@ oceanic_atom2_bigpage_device_read (dc_device_t *abstract, unsigned int address, return DC_STATUS_NOMEMORY; memset(device->bitmap, 0, device->base.layout->memsize / pagesize / 8); } + if ((address % PAGESIZE != 0) || (size % PAGESIZE != 0)) return DC_STATUS_INVALIDARGS; -- 1.8.0.rc0.18.gf84667d