@@ -330,18 +330,40 @@ static int flash_nios2_qspi_read(struct device *dev, off_t offset,
330330 u32_t word_to_read , bytes_to_copy ;
331331 s32_t rc = 0 ;
332332
333- k_sem_take (& flash_cfg -> sem_lock , K_FOREVER );
334333 /*
335- * check if offset is word aligned and
336- * length is with in the range
334+ * check if offset and length are within the range
337335 */
338- if ((data == NULL ) || (( offset + len ) > qspi_dev -> data_end ) ||
339- ( 0 != ( read_offset & ( NIOS2_WRITE_BLOCK_SIZE - 1 )) )) {
336+ if ((data == NULL ) || (offset < qspi_dev -> data_base ) ||
337+ (( offset + len ) > qspi_dev -> data_end )) {
340338 LOG_ERR ("read failed at offset 0x%lx" , (long )offset );
341- rc = - EINVAL ;
342- goto qspi_read_err ;
339+ return - EINVAL ;
343340 }
344341
342+ if (!len ) {
343+ return 0 ;
344+ }
345+
346+ k_sem_take (& flash_cfg -> sem_lock , K_FOREVER );
347+
348+ /* first unaligned start */
349+ read_offset &= ~(NIOS2_WRITE_BLOCK_SIZE - 1U );
350+ if (offset > read_offset ) {
351+ /* number of bytes from source to copy */
352+ bytes_to_copy = NIOS2_WRITE_BLOCK_SIZE - (offset - read_offset );
353+ if (bytes_to_copy > remaining_length ) {
354+ bytes_to_copy = remaining_length ;
355+ }
356+ /* read from flash 32 bits at a time */
357+ word_to_read = IORD_32DIRECT (qspi_dev -> data_base , read_offset );
358+ memcpy ((u8_t * )data , (u8_t * )& word_to_read + offset -
359+ read_offset , bytes_to_copy );
360+ /* update offset and length variables */
361+ read_offset += NIOS2_WRITE_BLOCK_SIZE ;
362+ buffer_offset += bytes_to_copy ;
363+ remaining_length -= bytes_to_copy ;
364+ }
365+
366+ /* aligned part, including unaligned end */
345367 while (remaining_length > 0 ) {
346368 /* number of bytes from source to copy */
347369 bytes_to_copy = NIOS2_WRITE_BLOCK_SIZE ;
@@ -354,14 +376,12 @@ static int flash_nios2_qspi_read(struct device *dev, off_t offset,
354376 word_to_read = IORD_32DIRECT (qspi_dev -> data_base , read_offset );
355377 memcpy ((u8_t * )data + buffer_offset , & word_to_read ,
356378 bytes_to_copy );
357-
358379 /* update offset and length variables */
359380 read_offset += bytes_to_copy ;
360381 buffer_offset += bytes_to_copy ;
361382 remaining_length -= bytes_to_copy ;
362383 }
363384
364- qspi_read_err :
365385 k_sem_give (& flash_cfg -> sem_lock );
366386 return rc ;
367387}
0 commit comments