|
12 | 12 | #include "cortexm/task.h" |
13 | 13 |
|
14 | 14 | int drive_sdio_open(const devfs_handle_t *handle) { |
15 | | - const drive_sdio_config_t *config = handle->config; |
| 15 | + DEVFS_DRIVER_DECLARE_CONFIG(drive_sdio); |
16 | 16 | return config->device.driver.open(&config->device.handle); |
17 | 17 | } |
18 | 18 |
|
| 19 | +static int handle_misaligned_read_complete(void *context, const mcu_event_t *event) { |
| 20 | + MCU_UNUSED_ARGUMENT(event); |
| 21 | + const devfs_handle_t *handle = context; |
| 22 | + DEVFS_DRIVER_DECLARE_CONFIG_STATE(drive_sdio); |
| 23 | + |
| 24 | + // copy the data to the original buffer |
| 25 | + memcpy( |
| 26 | + (u8 *)state->async_buffer + state->bytes_read, config->dma_read_buffer, |
| 27 | + state->async->nbyte); |
| 28 | + |
| 29 | + state->bytes_read += state->async->nbyte; |
| 30 | + |
| 31 | + int result = 0; |
| 32 | + |
| 33 | + if (state->bytes_read < state->async_nbyte) { |
| 34 | + // read another block |
| 35 | + result = config->device.driver.read(&config->device.handle, state->async); |
| 36 | + } else { |
| 37 | + // finalize the transaction |
| 38 | + result = state->async_nbyte; |
| 39 | + } |
| 40 | + |
| 41 | + if (result != 0) { |
| 42 | + // restore the async object |
| 43 | + state->async->buf = state->async_buffer; |
| 44 | + state->async->nbyte = state->async_nbyte; |
| 45 | + state->async->handler = state->async_handler; |
| 46 | + |
| 47 | + // mark as not busy |
| 48 | + state->async_handler.callback = 0; |
| 49 | + state->async->result = result; |
| 50 | + |
| 51 | + if (result < 0) { |
| 52 | + devfs_execute_event_handler( |
| 53 | + &state->async->handler, MCU_EVENT_FLAG_ERROR | MCU_EVENT_FLAG_CANCELED, 0); |
| 54 | + } else { |
| 55 | + devfs_execute_event_handler(&state->async->handler, MCU_EVENT_FLAG_DATA_READY, 0); |
| 56 | + } |
| 57 | + |
| 58 | + return 0; |
| 59 | + } |
| 60 | +} |
| 61 | + |
19 | 62 | int drive_sdio_read(const devfs_handle_t *handle, devfs_async_t *async) { |
20 | | - const drive_sdio_config_t *config = handle->config; |
| 63 | + DEVFS_DRIVER_DECLARE_CONFIG_STATE(drive_sdio); |
| 64 | + if (config->dma_read_buffer) { |
| 65 | + if (state->async_handler.callback != 0) { |
| 66 | + return SYSFS_SET_RETURN(EBUSY); |
| 67 | + } |
| 68 | + |
| 69 | + if ((u32)async->buf % 32) { |
| 70 | + // can't have misaligned reads -- need to use the dedicated buffer |
| 71 | + // save the originals |
| 72 | + state->async_buffer = async->buf; |
| 73 | + state->async_handler = async->handler; |
| 74 | + state->async_nbyte = async->nbyte; |
| 75 | + state->bytes_read = 0; |
| 76 | + state->async = async; |
| 77 | + |
| 78 | + // re-route the async object to use the aligned DMA buffer |
| 79 | + async->buf = config->dma_read_buffer; |
| 80 | + async->handler.callback = handle_misaligned_read_complete; |
| 81 | + async->handler.context = (void *)handle; |
| 82 | + |
| 83 | + // adjust the size accordingly |
| 84 | + if (async->nbyte > config->dma_read_buffer_size) { |
| 85 | + async->nbyte = config->dma_read_buffer_size; |
| 86 | + } |
| 87 | + } |
| 88 | + } |
21 | 89 | return config->device.driver.read(&config->device.handle, async); |
22 | 90 | } |
23 | 91 |
|
24 | 92 | int drive_sdio_write(const devfs_handle_t *handle, devfs_async_t *async) { |
25 | | - const drive_sdio_config_t *config = handle->config; |
| 93 | + DEVFS_DRIVER_DECLARE_CONFIG(drive_sdio); |
26 | 94 | return config->device.driver.write(&config->device.handle, async); |
27 | 95 | } |
28 | 96 |
|
29 | 97 | int drive_sdio_ioctl(const devfs_handle_t *handle, int request, void *ctl) { |
30 | | - const drive_sdio_config_t *config = handle->config; |
| 98 | + DEVFS_DRIVER_DECLARE_CONFIG(drive_sdio); |
31 | 99 | drive_info_t *info = ctl; |
32 | 100 | drive_attr_t *attr = ctl; |
33 | 101 | u32 o_flags; |
@@ -103,7 +171,7 @@ int drive_sdio_ioctl(const devfs_handle_t *handle, int request, void *ctl) { |
103 | 171 | } |
104 | 172 |
|
105 | 173 | int drive_sdio_close(const devfs_handle_t *handle) { |
106 | | - const drive_sdio_config_t *config = handle->config; |
| 174 | + DEVFS_DRIVER_DECLARE_CONFIG(drive_sdio); |
107 | 175 | return config->device.driver.close(&config->device.handle); |
108 | 176 | } |
109 | 177 |
|
|
0 commit comments