|
@@ -19,6 +19,7 @@
|
19
|
19
|
FILE_LICENCE ( GPL2_OR_LATER );
|
20
|
20
|
|
21
|
21
|
#include <stdint.h>
|
|
22
|
+#include <strings.h>
|
22
|
23
|
#include <errno.h>
|
23
|
24
|
#include <ipxe/malloc.h>
|
24
|
25
|
#include <ipxe/iobuf.h>
|
|
@@ -40,18 +41,24 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
40
|
41
|
*/
|
41
|
42
|
struct io_buffer * alloc_iob ( size_t len ) {
|
42
|
43
|
struct io_buffer *iobuf = NULL;
|
|
44
|
+ size_t align;
|
43
|
45
|
void *data;
|
44
|
46
|
|
45
|
47
|
/* Pad to minimum length */
|
46
|
48
|
if ( len < IOB_ZLEN )
|
47
|
49
|
len = IOB_ZLEN;
|
48
|
50
|
|
49
|
|
- /* Align buffer length */
|
50
|
|
- len = ( len + __alignof__( *iobuf ) - 1 ) &
|
51
|
|
- ~( __alignof__( *iobuf ) - 1 );
|
52
|
|
-
|
|
51
|
+ /* Align buffer length to ensure that struct io_buffer is aligned */
|
|
52
|
+ len = ( len + __alignof__ ( *iobuf ) - 1 ) &
|
|
53
|
+ ~( __alignof__ ( *iobuf ) - 1 );
|
|
54
|
+
|
|
55
|
+ /* Align buffer on its own size to avoid potential problems
|
|
56
|
+ * with boundary-crossing DMA.
|
|
57
|
+ */
|
|
58
|
+ align = ( 1 << fls ( len - 1 ) );
|
|
59
|
+
|
53
|
60
|
/* Allocate memory for buffer plus descriptor */
|
54
|
|
- data = malloc_dma ( len + sizeof ( *iobuf ), IOB_ALIGN );
|
|
61
|
+ data = malloc_dma ( len + sizeof ( *iobuf ), align );
|
55
|
62
|
if ( ! data )
|
56
|
63
|
return NULL;
|
57
|
64
|
|
|
@@ -61,6 +68,7 @@ struct io_buffer * alloc_iob ( size_t len ) {
|
61
|
68
|
return iobuf;
|
62
|
69
|
}
|
63
|
70
|
|
|
71
|
+
|
64
|
72
|
/**
|
65
|
73
|
* Free I/O buffer
|
66
|
74
|
*
|