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