Skip to contentSkip to conversation

char/moxa.c: fix endianess and multiple-card issues

PATCH In review Dirk Eibach 3 participants 3 messages Aug 18, 2006 – Aug 20, 2006 Char and misc drivers

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 char/moxa.c: fix endianess and multiple-card issues

From: Dirk Eibach <[email protected]>

While testing Moxa C218T/PCI on PowerPC 405EP I found that loading firmware using the linux kernel driver fails because calculation of the checksum is not endianess independent in the original code.

After I fixed this I found that uploading firmware in a system with multiple cards causes a kernel oops. I had a look in the recent moxa sources and found that they do some kind of locking there. Applying this lock fixed the problem.

This patch applies to kernel 2.6.16.

---

drivers/char/moxa.c +6 -2
@@ -143,6 +143,7 @@ typedef struct _moxa_board_conf {
 
 static moxa_board_conf moxa_boards[MAX_BOARDS];
 static void __iomem *moxaBaseAddr[MAX_BOARDS];
+static int loadstat[MAX_BOARDS]={0,0,0,0};
 
 struct moxa_str {
 	int type;
@@ -1690,6 +1691,8 @@ int MoxaDriverPoll(void)
 	if (moxaCard == 0)
 		return (-1);
 	for (card = 0; card < MAX_BOARDS; card++) {
+	        if(loadstat[card]==0)
+			continue;
 		if ((ports = moxa_boards[card].numPorts) == 0)
 			continue;
 		if (readb(moxaIntPend[card]) == 0xff) {
@@ -2905,6 +2908,7 @@ static int moxaloadcode(int cardno, unsi
 		}
 		break;
 	}
+	loadstat[cardno] = 1;
 	return (0);
 }
 
@@ -2922,7 +2926,7 @@ static int moxaloadc218(int cardno, void
 	len1 = len >> 1;
 	ptr = (ushort *) moxaBuff;
 	for (i = 0; i < len1; i++)
-		usum += *(ptr + i);
+		usum += le16_to_cpu(*(ptr + i));
 	retry = 0;
 	do {
 		len1 = len >> 1;
@@ -2994,7 +2998,7 @@ static int moxaloadc320(int cardno, void
 	wlen = len >> 1;
 	uptr = (ushort *) moxaBuff;
 	for (i = 0; i < wlen; i++)
-		usum += uptr[i];
+		usum += le16_to_cpu(uptr[i]);
 	retry = 0;
 	j = 0;
 	do {
#1 lore raw
Quoted 10 lines · Dirk Eibach

From: Dirk Eibach <[email protected]>

While testing Moxa C218T/PCI on PowerPC 405EP I found that loading firmware using the linux kernel driver fails because calculation of the checksum is not endianess independent in the original code.

After I fixed this I found that uploading firmware in a system with multiple cards causes a kernel oops. I had a look in the recent moxa sources and found that they do some kind of locking there. Applying this lock fixed the problem.

Patch for endian bug needs sparse endian annotations as well.
--------------------------------------
[PATCH] moxa: fix checksum endianness

From: Dirk Eibach <[email protected]>

While testing Moxa C218T/PCI on PowerPC 405EP I found that loading firmware using the linux kernel driver fails because calculation of the checksum is not endianess independent in the original code.

---

 drivers/char/moxa.c |   13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)
drivers/char/moxa.c +7 -6
@@ -2910,7 +2910,8 @@ static int moxaloadc218(int cardno, void
 {
 	char retry;
 	int i, j, len1, len2;
-	ushort usum, *ptr, keycode;
+	ushort usum, keycode;
+	__le16 *ptr;
 
 	if (moxa_boards[cardno].boardType == MOXA_BOARD_CP204J)
 		keycode = CP204J_KeyCode;
@@ -2918,9 +2919,9 @@ static int moxaloadc218(int cardno, void
 		keycode = C218_KeyCode;
 	usum = 0;
 	len1 = len >> 1;
-	ptr = (ushort *) moxaBuff;
+	ptr = (__le16 *) moxaBuff;
 	for (i = 0; i < len1; i++)
-		usum += *(ptr + i);
+		usum += le16_to_cpu(*(ptr + i));
 	retry = 0;
 	do {
 		len1 = len >> 1;
@@ -2986,13 +2987,13 @@ static int moxaloadc320(int cardno, void
 {
 	ushort usum;
 	int i, j, wlen, len2, retry;
-	ushort *uptr;
+	__le16 *uptr;
 
 	usum = 0;
 	wlen = len >> 1;
-	uptr = (ushort *) moxaBuff;
+	uptr = (__le16 *) moxaBuff;
 	for (i = 0; i < wlen; i++)
-		usum += uptr[i];
+		usum += le16_to_cpu(uptr[i]);
 	retry = 0;
 	j = 0;
 	do {
Acked-by on v1 1/1
#2 lore raw
In reply to Dirk Eibach

Ar Gwe, 2006-08-18 am 13:39 +0200, ysgrifennodd Dirk Eibach:

Quoted 7 lines

From: Dirk Eibach <[email protected]>

While testing Moxa C218T/PCI on PowerPC 405EP I found that loading firmware using the linux kernel driver fails because calculation of the checksum is not endianess independent in the original code.

Checksum changes are clearly correct. Other changes is an improvement but not I think enough to handle malicious firmware attacks. That said such an attacker has CAP_SYS_RAWIO anyway so that part is irrelevant except for neatness