[PATCH] cistpl: Use get_unaligned when accessing possibly-unaligned data
Haavard Skinnemoen
hskinnemoen at atmel.com
Mon Jul 9 11:37:07 EDT 2007
When trying to use the PCMCIA layer on AVR32, it crashed when parsing
the CIS data because of an unaligned halfword access. So I went
through cistpl.c and converted all the cases I could find of accessing
data through something different than a u8 * and converted them to use
get_unaligned() instead.
Signed-off-by: Haavard Skinnemoen <hskinnemoen at atmel.com>
---
drivers/pcmcia/cistpl.c | 32 +++++++++++++++++---------------
1 files changed, 17 insertions(+), 15 deletions(-)
diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c
index d154dee..2ddacd4 100644
--- a/drivers/pcmcia/cistpl.c
+++ b/drivers/pcmcia/cistpl.c
@@ -25,6 +25,7 @@
#include <linux/ioport.h>
#include <asm/io.h>
#include <asm/byteorder.h>
+#include <asm/unaligned.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/ss.h>
@@ -461,7 +462,7 @@ static int follow_link(struct pcmcia_socket *s, tuple_t *tuple)
/* Get indirect link from the MFC tuple */
read_cis_cache(s, LINK_SPACE(tuple->Flags),
tuple->LinkOffset, 5, link);
- ofs = le32_to_cpu(*(__le32 *)(link+1));
+ ofs = le32_to_cpu(get_unaligned((__le32 *)(link+1)));
SPACE(tuple->Flags) = (link[0] == CISTPL_MFC_ATTR);
/* Move to the next indirect link */
tuple->LinkOffset += 5;
@@ -669,8 +670,9 @@ static int parse_checksum(tuple_t *tuple, cistpl_checksum_t *csum)
if (tuple->TupleDataLen < 5)
return CS_BAD_TUPLE;
p = (u_char *)tuple->TupleData;
- csum->addr = tuple->CISOffset+(short)le16_to_cpu(*(__le16 *)p)-2;
- csum->len = le16_to_cpu(*(__le16 *)(p + 2));
+ csum->addr = tuple->CISOffset
+ + (short)le16_to_cpu(get_unaligned((__le16 *)p)) -2;
+ csum->len = le16_to_cpu(get_unaligned((__le16 *)(p + 2)));
csum->sum = *(p+4);
return CS_SUCCESS;
}
@@ -681,7 +683,7 @@ static int parse_longlink(tuple_t *tuple, cistpl_longlink_t *link)
{
if (tuple->TupleDataLen < 4)
return CS_BAD_TUPLE;
- link->addr = le32_to_cpu(*(__le32 *)tuple->TupleData);
+ link->addr = le32_to_cpu(get_unaligned((__le32 *)tuple->TupleData));
return CS_SUCCESS;
}
@@ -700,7 +702,7 @@ static int parse_longlink_mfc(tuple_t *tuple,
return CS_BAD_TUPLE;
for (i = 0; i < link->nfn; i++) {
link->fn[i].space = *p; p++;
- link->fn[i].addr = le32_to_cpu(*(__le32 *)p); p += 4;
+ link->fn[i].addr = le32_to_cpu(get_unaligned((__le32 *)p)); p += 4;
}
return CS_SUCCESS;
}
@@ -791,8 +793,8 @@ static int parse_manfid(tuple_t *tuple, cistpl_manfid_t *m)
if (tuple->TupleDataLen < 4)
return CS_BAD_TUPLE;
p = (__le16 *)tuple->TupleData;
- m->manf = le16_to_cpu(p[0]);
- m->card = le16_to_cpu(p[1]);
+ m->manf = le16_to_cpu(get_unaligned(&p[0]));
+ m->card = le16_to_cpu(get_unaligned(&p[1]));
return CS_SUCCESS;
}
@@ -1091,7 +1093,7 @@ static int parse_cftable_entry(tuple_t *tuple,
break;
case 0x20:
entry->mem.nwin = 1;
- entry->mem.win[0].len = le16_to_cpu(*(__le16 *)p) << 8;
+ entry->mem.win[0].len = le16_to_cpu(get_unaligned((__le16 *)p)) << 8;
entry->mem.win[0].card_addr = 0;
entry->mem.win[0].host_addr = 0;
p += 2;
@@ -1099,9 +1101,9 @@ static int parse_cftable_entry(tuple_t *tuple,
break;
case 0x40:
entry->mem.nwin = 1;
- entry->mem.win[0].len = le16_to_cpu(*(__le16 *)p) << 8;
+ entry->mem.win[0].len = le16_to_cpu(get_unaligned((__le16 *)p)) << 8;
entry->mem.win[0].card_addr =
- le16_to_cpu(*(__le16 *)(p+2)) << 8;
+ le16_to_cpu(get_unaligned((__le16 *)(p+2))) << 8;
entry->mem.win[0].host_addr = 0;
p += 4;
if (p > q) return CS_BAD_TUPLE;
@@ -1138,7 +1140,7 @@ static int parse_bar(tuple_t *tuple, cistpl_bar_t *bar)
p = (u_char *)tuple->TupleData;
bar->attr = *p;
p += 2;
- bar->size = le32_to_cpu(*(__le32 *)p);
+ bar->size = le32_to_cpu(get_unaligned((__le32 *)p));
return CS_SUCCESS;
}
@@ -1151,7 +1153,7 @@ static int parse_config_cb(tuple_t *tuple, cistpl_config_t *config)
return CS_BAD_TUPLE;
config->last_idx = *(++p);
p++;
- config->base = le32_to_cpu(*(__le32 *)p);
+ config->base = le32_to_cpu(get_unaligned((__le32 *)p));
config->subtuples = tuple->TupleDataLen - 6;
return CS_SUCCESS;
}
@@ -1267,7 +1269,7 @@ static int parse_vers_2(tuple_t *tuple, cistpl_vers_2_t *v2)
v2->vers = p[0];
v2->comply = p[1];
- v2->dindex = le16_to_cpu(*(__le16 *)(p+2));
+ v2->dindex = le16_to_cpu(get_unaligned((__le16 *)(p+2)));
v2->vspec8 = p[6];
v2->vspec9 = p[7];
v2->nhdr = p[8];
@@ -1308,8 +1310,8 @@ static int parse_format(tuple_t *tuple, cistpl_format_t *fmt)
fmt->type = p[0];
fmt->edc = p[1];
- fmt->offset = le32_to_cpu(*(__le32 *)(p+2));
- fmt->length = le32_to_cpu(*(__le32 *)(p+6));
+ fmt->offset = le32_to_cpu(get_unaligned((__le32 *)(p+2)));
+ fmt->length = le32_to_cpu(get_unaligned((__le32 *)(p+6)));
return CS_SUCCESS;
}
--
1.5.2.3
More information about the linux-pcmcia
mailing list