Just to clarify things: If you have a struct like this: struct { unsigned int a; unsigned char p1; unsigned int b; unsigned char p2; unsigned char p3; unsigned char p4; unsigned int c; } __packed;
without __attribute__((aligned(4))), gcc will generate alignment-safe code when accessing fields a, b and c. with __attribute__((aligned(4))), gcc will do direct access for fields a and c, and alignment-safe access for field b. In the specific case of athn(4), all fields in descriptors are 32-bit, so __packed is probably not necessary, but I like my hardware structs to be __packed. Damien | Add __attribute__((aligned(4))) to __packed Tx/Rx descriptors. | This makes gcc generate much more efficient code on architectures | with strong alignment constraints (like sparc64). | We use __packed to tell the compiler to not insert padding between | fields but the start of the descriptors is always 32-bit aligned. | When __packed is used, gcc assumes worst case scenario and generates | complicated code to prevent unaligned accesses. | | Inspired by a similar change to ath9k. | Tested on sparc64. | | For the record, example to set a field to 1 on a sparc64: | without __attribute__((aligned(4))): | ldub [%g2], %g1 | and %g1, 0, %g1 | stb %g1, [%g2] | ldub [%g2+1], %g1 | and %g1, 0, %g1 | stb %g1, [%g2+1] | ldub [%g2+2], %g1 | and %g1, 0, %g1 | stb %g1, [%g2+2] | ldub [%g2+3], %g1 | and %g1, 0, %g1 | or %g1, 1, %g1 | stb %g1, [%g2+3] | | with __attribute__((aligned(4))): | mov 1, %g1 | st %g1, [%g2]