diff options
author | Adrian Bradianu <adrian.bradianu@windriver.com> | 2016-06-28 17:36:00 +0300 |
---|---|---|
committer | Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com> | 2016-07-08 18:22:19 +0000 |
commit | 273c87b33e5c669e0df911e5d0fdfe57c684a110 (patch) | |
tree | 08f937d955ec90b4d861a91010333f5b35daffec /usb | |
parent | 6840ee35a4b54529fc2f29ff289a6f394a0f75b6 (diff) |
usb: cdc acm: Change Bulk Out handler to read data per 32-bit words
Quark SE USB controller is always storing data in the FIFOs per
32-bit words. Change Bulk Out handler to read data per 32-bit words.
Change-Id: I871278a754895edc5c7a395797b6dab0904bcdf6
Signed-off-by: Adrian Bradianu <adrian.bradianu@windriver.com>
Diffstat (limited to 'usb')
-rw-r--r-- | usb/class/cdc_acm.c | 43 |
1 files changed, 31 insertions, 12 deletions
diff --git a/usb/class/cdc_acm.c b/usb/class/cdc_acm.c index 859ae1f46..3497086b8 100644 --- a/usb/class/cdc_acm.c +++ b/usb/class/cdc_acm.c @@ -330,19 +330,38 @@ static void cdc_acm_bulk_out(uint8_t ep, enum usb_dc_ep_cb_status_code ep_status) { struct cdc_acm_dev_data_t * const dev_data = DEV_DATA(cdc_acm_dev); - uint32_t bytes_to_read, i, buf_tail; + uint32_t bytes_to_read, i, j, buf_head; + uint8_t tmp_buf[4]; /* Check how many bytes were received */ usb_read(ep, NULL, 0, &bytes_to_read); - for (i = 0; i < bytes_to_read; i++) { - buf_tail = (dev_data->rx_buf_tail + i) % CDC_ACM_BUFFER_SIZE; - usb_read(ep, &dev_data->rx_buf[buf_tail], 1, NULL); - } + buf_head = dev_data->rx_buf_head; - dev_data->rx_buf_tail = (dev_data->rx_buf_tail + bytes_to_read) % - CDC_ACM_BUFFER_SIZE; + /* + * Quark SE USB controller is always storing data + * in the FIFOs per 32-bit words. + */ + for (i = 0; i < bytes_to_read; i += 4) { + usb_read(ep, tmp_buf, 4, NULL); + for (j = 0; j < 4; j++) { + if (i + j == bytes_to_read) { + /* We read all the data */ + break; + } + + if (((buf_head + 1) % CDC_ACM_BUFFER_SIZE) == + dev_data->rx_buf_tail) { + /* FIFO full, discard data */ + DBG("CDC buffer full!\n"); + } else { + dev_data->rx_buf[buf_head] = tmp_buf[j]; + buf_head = (buf_head + 1) % CDC_ACM_BUFFER_SIZE; + } + } + } + dev_data->rx_buf_head = buf_head; dev_data->rx_ready = 1; /* Call callback only if rx irq ena */ if (dev_data->cb && dev_data->rx_irq_ena) @@ -531,21 +550,21 @@ static int cdc_acm_fifo_read(struct device *dev, uint8_t *rx_data, uint32_t avail_data, bytes_read, i; struct cdc_acm_dev_data_t * const dev_data = DEV_DATA(dev); - avail_data = (CDC_ACM_BUFFER_SIZE + dev_data->rx_buf_tail - - dev_data->rx_buf_head) % CDC_ACM_BUFFER_SIZE; + avail_data = (CDC_ACM_BUFFER_SIZE + dev_data->rx_buf_head - + dev_data->rx_buf_tail) % CDC_ACM_BUFFER_SIZE; if (avail_data > size) bytes_read = size; else bytes_read = avail_data; for (i = 0; i < bytes_read; i++) - rx_data[i] = dev_data->rx_buf[(dev_data->rx_buf_head + i) % + rx_data[i] = dev_data->rx_buf[(dev_data->rx_buf_tail + i) % CDC_ACM_BUFFER_SIZE]; - dev_data->rx_buf_head = (dev_data->rx_buf_head + bytes_read) % + dev_data->rx_buf_tail = (dev_data->rx_buf_tail + bytes_read) % CDC_ACM_BUFFER_SIZE; - if (dev_data->rx_buf_head == dev_data->rx_buf_tail) { + if (dev_data->rx_buf_tail == dev_data->rx_buf_head) { /* Buffer empty */ dev_data->rx_ready = 0; } |