Search Linux Wireless

Re: [2.6.23.9] hostap_plx locks up PC when reading PCI I/O memory

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sun, 9 Dec 2007 19:41:58 +0000 (GMT)
Chris Rankin <rankincj@xxxxxxxxx> wrote:

> Hi,
> 
> I've recently been having trouble loading the hostap_plx 802.11b wireless networking driver, and
> this evening I managed to narrow the problem down to these lines of code by copying code from
> hostap_plx into a "test driver" until the test driver also locked the PC up:
> 
>         /* read CIS; it is in even offsets in the beginning of attr_mem */
>         for (i = 0; i < CIS_MAX_LEN; i++)
>                 cis[i] = readb(attr_mem + 2 * i);
> 
> If I comment these lines out then my test driver just complains about the garbage CIS information
> and fails gracefully. Leave these lines in and my PC freezes instantly.
> 
> These lines are part of the prism2_plx_check_cis() function, which is called when the module first
> loads. CIX_MAX_LEN is a #define for 256, and cis is a u8* pointer previously allocated as:
> 
> cis = kmalloc(CIS_MAX_LEN, GFP_KERNEL);
> 
> attr_mem is one of the function's paramters, and is defined as void __iomem *attr_mem.
> 
> As far as I can tell, the PCI I/O memory information is correct, and matches what lspci tells me:
> 
> 00:0e.0 Network controller: Netgear MA301 802.11b Wireless PCI Adapter (rev 02)
>         Subsystem: Netgear MA301 802.11b Wireless PCI Adapter
>         Control: I/O+ Mem+ BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+
> FastB2B-
>         Status: Cap- 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR-
> <PERR-
>         Interrupt: pin A routed to IRQ 5
>         Region 1: I/O ports at 1000 [size=128]
>         Region 2: Memory at e8002000 (32-bit, non-prefetchable) [size=4K]
>         Region 3: I/O ports at 1080 [size=64]
> 
> so there is apparently 4K of I/O memory at 0xe8002000.
> 
> Can anyone help me understand why my PC is locking up when it executes this code, please?
> 

I guess something like this:


--- a/drivers/net/wireless/hostap/hostap_plx.c~a
+++ a/drivers/net/wireless/hostap/hostap_plx.c
@@ -343,13 +343,14 @@ static int prism2_plx_check_cis(void __i
 	int i, pos;
 	unsigned int rmsz, rasz, manfid1, manfid2;
 	struct prism2_plx_manfid *manfid;
+	int len = min(CIS_MAX_LEN, attr_len);
 
-	cis = kmalloc(CIS_MAX_LEN, GFP_KERNEL);
+	cis = kmalloc(len, GFP_KERNEL);
 	if (cis == NULL)
 		return -ENOMEM;
 
 	/* read CIS; it is in even offsets in the beginning of attr_mem */
-	for (i = 0; i < CIS_MAX_LEN; i++)
+	for (i = 0; i < len; i++)
 		cis[i] = readb(attr_mem + 2 * i);
 	printk(KERN_DEBUG "%s: CIS: %02x %02x %02x %02x %02x %02x ...\n",
 	       dev_info, cis[0], cis[1], cis[2], cis[3], cis[4], cis[5]);
@@ -361,8 +362,8 @@ static int prism2_plx_check_cis(void __i
 	manfid1 = manfid2 = 0;
 
 	pos = 0;
-	while (pos < CIS_MAX_LEN - 1 && cis[pos] != CISTPL_END) {
-		if (pos + 2 + cis[pos + 1] > CIS_MAX_LEN)
+	while (pos < len - 1 && cis[pos] != CISTPL_END) {
+		if (pos + 2 + cis[pos + 1] > len)
 			goto cis_error;
 
 		switch (cis[pos]) {
@@ -401,7 +402,7 @@ static int prism2_plx_check_cis(void __i
 		pos += cis[pos + 1] + 2;
 	}
 
-	if (pos >= CIS_MAX_LEN || cis[pos] != CISTPL_END)
+	if (pos >= len || cis[pos] != CISTPL_END)
 		goto cis_error;
 
 	for (manfid = prism2_plx_known_manfids; manfid->manfid1 != 0; manfid++)
_

would be a bit safer, but looking at your /proc/iomem I doubt if it will
fix anything.

It might be interesting to see what value of `i' is causing it to fall
over.

Did any earlier version of the 2.6 kernel work OK?
-
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux