b44 module in openSuSe 11.4 freezes laptop

ugh! 11.4 has been a bit of a pain. The broadcom driver, b44, for the
Broadcom 44xx/47xx, freezes my system. I cannot be the only victim of this faulty driver.

The driver is not for the WLAN, but rather for 10/100 ethernet on a Dell Insprion 1720 laptop.

Is there a workaround, or fix, for this issue?

On 04/10/2011 10:06 AM, revbee wrote:
>
> ugh! 11.4 has been a bit of a pain. The broadcom driver, b44, for the
> Broadcom 44xx/47xx, freezes my system. I cannot be the only victim of
> this faulty driver.
>
> The driver is not for the WLAN, but rather for 10/100 ethernet on a
> Dell Insprion 1720 laptop.
>
> Is there a workaround, or fix, for this issue?

What is the Bugzilla number for this?

There have been no changes in b44 for years. It is very surprising that it now
fails.

I performed a diff on the latest kernel source from 11.3 and 11.4 and there is a difference. I have posted the 2 files.


ldb@emily:~> diff b44-11.4.c b44-11.3.c 
138d137
< static int dma_desc_align_mask;
153,155c152,153
< 	ssb_dma_sync_single_range_for_device(sdev, dma_base,
< 					     offset & dma_desc_align_mask,
< 					     dma_desc_sync_size, dir);
---
> 	dma_sync_single_for_device(sdev->dma_dev, dma_base + offset,
> 				   dma_desc_sync_size, dir);
163,165c161,162
< 	ssb_dma_sync_single_range_for_cpu(sdev, dma_base,
< 					  offset & dma_desc_align_mask,
< 					  dma_desc_sync_size, dir);
---
> 	dma_sync_single_for_cpu(sdev->dma_dev, dma_base + offset,
> 				dma_desc_sync_size, dir);
387,388c384,385
< #ifdef SSB_DRIVER_MIPS
< extern char *nvram_get(char *name);
---
> #ifdef CONFIG_BCM47XX
> #include <asm/mach-bcm47xx/nvram.h>
391c388
< 	const char *str;
---
> 	char buf[20];
400,401c397
< 	str = nvram_get("boardnum");
< 	if (!str)
---
> 	if (nvram_getenv("boardnum", buf, sizeof(buf)) < 0)
403c399
< 	if (simple_strtoul(str, NULL, 0) == 2) {
---
> 	if (simple_strtoul(buf, NULL, 0) == 2) {
611,614c607,610
< 		ssb_dma_unmap_single(bp->sdev,
< 				     rp->mapping,
< 				     skb->len,
< 				     DMA_TO_DEVICE);
---
> 		dma_unmap_single(bp->sdev->dma_dev,
> 				 rp->mapping,
> 				 skb->len,
> 				 DMA_TO_DEVICE);
651,653c647,649
< 	mapping = ssb_dma_map_single(bp->sdev, skb->data,
< 				     RX_PKT_BUF_SZ,
< 				     DMA_FROM_DEVICE);
---
> 	mapping = dma_map_single(bp->sdev->dma_dev, skb->data,
> 				 RX_PKT_BUF_SZ,
> 				 DMA_FROM_DEVICE);
657c653
< 	if (ssb_dma_mapping_error(bp->sdev, mapping) ||
---
> 	if (dma_mapping_error(bp->sdev->dma_dev, mapping) ||
660,661c656,657
< 		if (!ssb_dma_mapping_error(bp->sdev, mapping))
< 			ssb_dma_unmap_single(bp->sdev, mapping,
---
> 		if (!dma_mapping_error(bp->sdev->dma_dev, mapping))
> 			dma_unmap_single(bp->sdev->dma_dev, mapping,
667,673c663,669
< 		mapping = ssb_dma_map_single(bp->sdev, skb->data,
< 					     RX_PKT_BUF_SZ,
< 					     DMA_FROM_DEVICE);
< 		if (ssb_dma_mapping_error(bp->sdev, mapping) ||
< 			mapping + RX_PKT_BUF_SZ > DMA_BIT_MASK(30)) {
< 			if (!ssb_dma_mapping_error(bp->sdev, mapping))
< 				ssb_dma_unmap_single(bp->sdev, mapping, RX_PKT_BUF_SZ,DMA_FROM_DEVICE);
---
> 		mapping = dma_map_single(bp->sdev->dma_dev, skb->data,
> 					 RX_PKT_BUF_SZ,
> 					 DMA_FROM_DEVICE);
> 		if (dma_mapping_error(bp->sdev->dma_dev, mapping) ||
> 		    mapping + RX_PKT_BUF_SZ > DMA_BIT_MASK(30)) {
> 			if (!dma_mapping_error(bp->sdev->dma_dev, mapping))
> 				dma_unmap_single(bp->sdev->dma_dev, mapping, RX_PKT_BUF_SZ,DMA_FROM_DEVICE);
748,750c744,746
< 	ssb_dma_sync_single_for_device(bp->sdev, dest_map->mapping,
< 				       RX_PKT_BUF_SZ,
< 				       DMA_FROM_DEVICE);
---
> 	dma_sync_single_for_device(bp->sdev->dma_dev, dest_map->mapping,
> 				   RX_PKT_BUF_SZ,
> 				   DMA_FROM_DEVICE);
770,772c766,768
< 		ssb_dma_sync_single_for_cpu(bp->sdev, map,
< 					    RX_PKT_BUF_SZ,
< 					    DMA_FROM_DEVICE);
---
> 		dma_sync_single_for_cpu(bp->sdev->dma_dev, map,
> 					RX_PKT_BUF_SZ,
> 					DMA_FROM_DEVICE);
804,805c800,801
< 			ssb_dma_unmap_single(bp->sdev, map,
< 					     skb_size, DMA_FROM_DEVICE);
---
> 			dma_unmap_single(bp->sdev->dma_dev, map,
> 					 skb_size, DMA_FROM_DEVICE);
824c820
< 		skb->ip_summed = CHECKSUM_NONE;
---
> 		skb_checksum_none_assert(skb);
853a850,858
> 	if (bp->istat & ISTAT_RFO) {	/* fast recovery, in ~20msec */
> 		bp->istat &= ~ISTAT_RFO;
> 		b44_disable_ints(bp);
> 		ssb_device_enable(bp->sdev, 0); /* resets ISTAT_RFO */
> 		b44_init_rings(bp);
> 		b44_init_hw(bp, B44_FULL_RESET_SKIP_PHY);
> 		netif_wake_queue(bp->dev);
> 	}
> 
957,958c962,963
< 	mapping = ssb_dma_map_single(bp->sdev, skb->data, len, DMA_TO_DEVICE);
< 	if (ssb_dma_mapping_error(bp->sdev, mapping) || mapping + len > DMA_BIT_MASK(30)) {
---
> 	mapping = dma_map_single(bp->sdev->dma_dev, skb->data, len, DMA_TO_DEVICE);
> 	if (dma_mapping_error(bp->sdev->dma_dev, mapping) || mapping + len > DMA_BIT_MASK(30)) {
962,963c967,968
< 		if (!ssb_dma_mapping_error(bp->sdev, mapping))
< 			ssb_dma_unmap_single(bp->sdev, mapping, len,
---
> 		if (!dma_mapping_error(bp->sdev->dma_dev, mapping))
> 			dma_unmap_single(bp->sdev->dma_dev, mapping, len,
970,974c975,979
< 		mapping = ssb_dma_map_single(bp->sdev, bounce_skb->data,
< 					     len, DMA_TO_DEVICE);
< 		if (ssb_dma_mapping_error(bp->sdev, mapping) || mapping + len > DMA_BIT_MASK(30)) {
< 			if (!ssb_dma_mapping_error(bp->sdev, mapping))
< 				ssb_dma_unmap_single(bp->sdev, mapping,
---
> 		mapping = dma_map_single(bp->sdev->dma_dev, bounce_skb->data,
> 					 len, DMA_TO_DEVICE);
> 		if (dma_mapping_error(bp->sdev->dma_dev, mapping) || mapping + len > DMA_BIT_MASK(30)) {
> 			if (!dma_mapping_error(bp->sdev->dma_dev, mapping))
> 				dma_unmap_single(bp->sdev->dma_dev, mapping,
1017,1018d1021
< 	dev->trans_start = jiffies;
< 
1073,1074c1076,1077
< 		ssb_dma_unmap_single(bp->sdev, rp->mapping, RX_PKT_BUF_SZ,
< 				     DMA_FROM_DEVICE);
---
> 		dma_unmap_single(bp->sdev->dma_dev, rp->mapping, RX_PKT_BUF_SZ,
> 				 DMA_FROM_DEVICE);
1085,1086c1088,1089
< 		ssb_dma_unmap_single(bp->sdev, rp->mapping, rp->skb->len,
< 				     DMA_TO_DEVICE);
---
> 		dma_unmap_single(bp->sdev->dma_dev, rp->mapping, rp->skb->len,
> 				 DMA_TO_DEVICE);
1108,1110c1111,1112
< 		ssb_dma_sync_single_for_device(bp->sdev, bp->rx_ring_dma,
< 					       DMA_TABLE_BYTES,
< 					       DMA_BIDIRECTIONAL);
---
> 		dma_sync_single_for_device(bp->sdev->dma_dev, bp->rx_ring_dma,
> 					   DMA_TABLE_BYTES, DMA_BIDIRECTIONAL);
1113,1115c1115,1116
< 		ssb_dma_sync_single_for_device(bp->sdev, bp->tx_ring_dma,
< 					       DMA_TABLE_BYTES,
< 					       DMA_TO_DEVICE);
---
> 		dma_sync_single_for_device(bp->sdev->dma_dev, bp->tx_ring_dma,
> 					   DMA_TABLE_BYTES, DMA_TO_DEVICE);
1135,1137c1136,1137
< 			ssb_dma_unmap_single(bp->sdev, bp->rx_ring_dma,
< 					     DMA_TABLE_BYTES,
< 					     DMA_BIDIRECTIONAL);
---
> 			dma_unmap_single(bp->sdev->dma_dev, bp->rx_ring_dma,
> 					 DMA_TABLE_BYTES, DMA_BIDIRECTIONAL);
1140,1142c1140,1141
< 			ssb_dma_free_consistent(bp->sdev, DMA_TABLE_BYTES,
< 						bp->rx_ring, bp->rx_ring_dma,
< 						GFP_KERNEL);
---
> 			dma_free_coherent(bp->sdev->dma_dev, DMA_TABLE_BYTES,
> 					  bp->rx_ring, bp->rx_ring_dma);
1148,1150c1147,1148
< 			ssb_dma_unmap_single(bp->sdev, bp->tx_ring_dma,
< 					     DMA_TABLE_BYTES,
< 					     DMA_TO_DEVICE);
---
> 			dma_unmap_single(bp->sdev->dma_dev, bp->tx_ring_dma,
> 					 DMA_TABLE_BYTES, DMA_TO_DEVICE);
1153,1155c1151,1152
< 			ssb_dma_free_consistent(bp->sdev, DMA_TABLE_BYTES,
< 						bp->tx_ring, bp->tx_ring_dma,
< 						GFP_KERNEL);
---
> 			dma_free_coherent(bp->sdev->dma_dev, DMA_TABLE_BYTES,
> 					  bp->tx_ring, bp->tx_ring_dma);
1180c1177,1178
< 	bp->rx_ring = ssb_dma_alloc_consistent(bp->sdev, size, &bp->rx_ring_dma, gfp);
---
> 	bp->rx_ring = dma_alloc_coherent(bp->sdev->dma_dev, size,
> 					 &bp->rx_ring_dma, gfp);
1192,1194c1190,1192
< 		rx_ring_dma = ssb_dma_map_single(bp->sdev, rx_ring,
< 						 DMA_TABLE_BYTES,
< 						 DMA_BIDIRECTIONAL);
---
> 		rx_ring_dma = dma_map_single(bp->sdev->dma_dev, rx_ring,
> 					     DMA_TABLE_BYTES,
> 					     DMA_BIDIRECTIONAL);
1196c1194
< 		if (ssb_dma_mapping_error(bp->sdev, rx_ring_dma) ||
---
> 		if (dma_mapping_error(bp->sdev->dma_dev, rx_ring_dma) ||
1207c1205,1206
< 	bp->tx_ring = ssb_dma_alloc_consistent(bp->sdev, size, &bp->tx_ring_dma, gfp);
---
> 	bp->tx_ring = dma_alloc_coherent(bp->sdev->dma_dev, size,
> 					 &bp->tx_ring_dma, gfp);
1219,1221c1218,1220
< 		tx_ring_dma = ssb_dma_map_single(bp->sdev, tx_ring,
< 			                    DMA_TABLE_BYTES,
< 			                    DMA_TO_DEVICE);
---
> 		tx_ring_dma = dma_map_single(bp->sdev->dma_dev, tx_ring,
> 					     DMA_TABLE_BYTES,
> 					     DMA_TO_DEVICE);
1223c1222
< 		if (ssb_dma_mapping_error(bp->sdev, tx_ring_dma) ||
---
> 		if (dma_mapping_error(bp->sdev->dma_dev, tx_ring_dma) ||
1684c1683
< 	struct dev_mc_list *mclist;
---
> 	struct netdev_hw_addr *ha;
1689c1688
< 	netdev_for_each_mc_addr(mclist, dev) {
---
> 	netdev_for_each_mc_addr(ha, dev) {
1692c1691
< 		__b44_cam_write(bp, mclist->dmi_addr, i++ + 1);
---
> 		__b44_cam_write(bp, ha->addr, i++ + 1);
2173,2174d2171
< 	netif_carrier_off(dev);
< 
2181,2182c2178,2180
< 	err = ssb_dma_set_mask(sdev, DMA_BIT_MASK(30));
< 	if (err) {
---
> 
> 	if (dma_set_mask(sdev->dma_dev, DMA_BIT_MASK(30)) ||
> 	    dma_set_coherent_mask(sdev->dma_dev, DMA_BIT_MASK(30))) {
2186a2185
> 
2213a2213,2214
> 	netif_carrier_off(dev);
> 
2296a2298,2307
> 	spin_lock_irq(&bp->lock);
> 	b44_init_rings(bp);
> 	b44_init_hw(bp, B44_FULL_RESET);
> 	spin_unlock_irq(&bp->lock);
> 
> 	/*
> 	 * As a shared interrupt, the handler can be called immediately. To be
> 	 * able to check the interrupt status the hardware must already be
> 	 * powered back on (b44_init_hw).
> 	 */
2299a2311,2314
> 		spin_lock_irq(&bp->lock);
> 		b44_halt(bp);
> 		b44_free_rings(bp);
> 		spin_unlock_irq(&bp->lock);
2303,2306d2317
< 	spin_lock_irq(&bp->lock);
< 
< 	b44_init_rings(bp);
< 	b44_init_hw(bp, B44_FULL_RESET);
2308d2318
< 	spin_unlock_irq(&bp->lock);
2349d2358
< 	dma_desc_align_mask = ~(dma_desc_align_size - 1);


I need to submit a bugzilla report.

Bug #686492](https://bugzilla.novell.com/show_bug.cgi?id=686492) has been created

On 04/10/2011 11:36 AM, revbee wrote:
>
> I performed a diff on the latest kernel source from 11.3 and 11.4 and
> there is a difference. I have posted the 2 files.

For future posting of differences, use the -u switch on the diff command. It is
easier to see the changes in context.

I will go over these changes below:

>
> Code:
> --------------------
>
> ldb@emily:~> diff b44-11.4.c b44-11.3.c
> 138d137
> < static int dma_desc_align_mask;

This lines removes a forward definition for a routine that is no longer used.

> 153,155c152,153
> < ssb_dma_sync_single_range_for_device(sdev, dma_base,
> < offset& dma_desc_align_mask,
> < dma_desc_sync_size, dir);
> —
> > dma_sync_single_for_device(sdev->dma_dev, dma_base + offset,
> > dma_desc_sync_size, dir);
> 163,165c161,162
> < ssb_dma_sync_single_range_for_cpu(sdev, dma_base,
> < offset& dma_desc_align_mask,
> < dma_desc_sync_size, dir);
> —
> > dma_sync_single_for_cpu(sdev->dma_dev, dma_base + offset,
> > dma_desc_sync_size, dir);

The 2 previous hunks switch DMA from an ssb-specific routine to a general one.
AFAICT, the change is correct.

> 387,388c384,385
> < #ifdef SSB_DRIVER_MIPS
> < extern char *nvram_get(char *name);
> —
> > #ifdef CONFIG_BCM47XX
> > #include<asm/mach-bcm47xx/nvram.h>

This hunk only applies to MIPS processors. As openSUSE does not run on those
processors, this cannot be a problem.

> 391c388
> < const char *str;
> —
> > char buf[20];
> 400,401c397
> < str = nvram_get(“boardnum”);
> < if (!str)
> —
> > if (nvram_getenv(“boardnum”, buf, sizeof(buf))< 0)
> 403c399
> < if (simple_strtoul(str, NULL, 0) == 2) {
> —
> > if (simple_strtoul(buf, NULL, 0) == 2) {

The previous three changes handles the way the driver gets the board number from
nvram. It looks fine.

> 611,614c607,610
> < ssb_dma_unmap_single(bp->sdev,
> < rp->mapping,
> < skb->len,
> < DMA_TO_DEVICE);
> —
> > dma_unmap_single(bp->sdev->dma_dev,
> > rp->mapping,
> > skb->len,
> > DMA_TO_DEVICE);
> 651,653c647,649
> < mapping = ssb_dma_map_single(bp->sdev, skb->data,
> < RX_PKT_BUF_SZ,
> < DMA_FROM_DEVICE);
> —
> > mapping = dma_map_single(bp->sdev->dma_dev, skb->data,
> > RX_PKT_BUF_SZ,
> > DMA_FROM_DEVICE);
> 657c653
> < if (ssb_dma_mapping_error(bp->sdev, mapping) ||
> —
> > if (dma_mapping_error(bp->sdev->dma_dev, mapping) ||
> 660,661c656,657
> < if (!ssb_dma_mapping_error(bp->sdev, mapping))
> < ssb_dma_unmap_single(bp->sdev, mapping,
> —
> > if (!dma_mapping_error(bp->sdev->dma_dev, mapping))
> > dma_unmap_single(bp->sdev->dma_dev, mapping,
> 667,673c663,669
> < mapping = ssb_dma_map_single(bp->sdev, skb->data,
> < RX_PKT_BUF_SZ,
> < DMA_FROM_DEVICE);
> < if (ssb_dma_mapping_error(bp->sdev, mapping) ||
> < mapping + RX_PKT_BUF_SZ> DMA_BIT_MASK(30)) {
> < if (!ssb_dma_mapping_error(bp->sdev, mapping))
> < ssb_dma_unmap_single(bp->sdev, mapping, RX_PKT_BUF_SZ,DMA_FROM_DEVICE);
> —
> > mapping = dma_map_single(bp->sdev->dma_dev, skb->data,
> > RX_PKT_BUF_SZ,
> > DMA_FROM_DEVICE);
> > if (dma_mapping_error(bp->sdev->dma_dev, mapping) ||
> > mapping + RX_PKT_BUF_SZ> DMA_BIT_MASK(30)) {
> > if (!dma_mapping_error(bp->sdev->dma_dev, mapping))
> > dma_unmap_single(bp->sdev->dma_dev, mapping, RX_PKT_BUF_SZ,DMA_FROM_DEVICE);
> 748,750c744,746
> < ssb_dma_sync_single_for_device(bp->sdev, dest_map->mapping,
> < RX_PKT_BUF_SZ,
> < DMA_FROM_DEVICE);
> —
> > dma_sync_single_for_device(bp->sdev->dma_dev, dest_map->mapping,
> > RX_PKT_BUF_SZ,
> > DMA_FROM_DEVICE);
> 770,772c766,768
> < ssb_dma_sync_single_for_cpu(bp->sdev, map,
> < RX_PKT_BUF_SZ,
> < DMA_FROM_DEVICE);
> —
> > dma_sync_single_for_cpu(bp->sdev->dma_dev, map,
> > RX_PKT_BUF_SZ,
> > DMA_FROM_DEVICE);
> 804,805c800,801
> < ssb_dma_unmap_single(bp->sdev, map,
> < skb_size, DMA_FROM_DEVICE);
> —
> > dma_unmap_single(bp->sdev->dma_dev, map,
> > skb_size, DMA_FROM_DEVICE);

The above hunks are part of the DMA changes. Again they look OK.

> 824c820
> < skb->ip_summed = CHECKSUM_NONE;
> —
> > skb_checksum_none_assert(skb);

This one I cannot evaluate.

> 853a850,858
> > if (bp->istat& ISTAT_RFO) { /* fast recovery, in ~20msec /
> > bp->istat&= ~ISTAT_RFO;
> > b44_disable_ints(bp);
> > ssb_device_enable(bp->sdev, 0); /
resets ISTAT_RFO */
> > b44_init_rings(bp);
> > b44_init_hw(bp, B44_FULL_RESET_SKIP_PHY);
> > netif_wake_queue(bp->dev);
> > }
> >

Again, I cannot evaluate.

> 957,958c962,963
> < mapping = ssb_dma_map_single(bp->sdev, skb->data, len, DMA_TO_DEVICE);
> < if (ssb_dma_mapping_error(bp->sdev, mapping) || mapping + len> DMA_BIT_MASK(30)) {
> —
> > mapping = dma_map_single(bp->sdev->dma_dev, skb->data, len, DMA_TO_DEVICE);
> > if (dma_mapping_error(bp->sdev->dma_dev, mapping) || mapping + len> DMA_BIT_MASK(30)) {
> 962,963c967,968
> < if (!ssb_dma_mapping_error(bp->sdev, mapping))
> < ssb_dma_unmap_single(bp->sdev, mapping, len,
> —
> > if (!dma_mapping_error(bp->sdev->dma_dev, mapping))
> > dma_unmap_single(bp->sdev->dma_dev, mapping, len,
> 970,974c975,979
> < mapping = ssb_dma_map_single(bp->sdev, bounce_skb->data,
> < len, DMA_TO_DEVICE);
> < if (ssb_dma_mapping_error(bp->sdev, mapping) || mapping + len> DMA_BIT_MASK(30)) {
> < if (!ssb_dma_mapping_error(bp->sdev, mapping))
> < ssb_dma_unmap_single(bp->sdev, mapping,
> —
> > mapping = dma_map_single(bp->sdev->dma_dev, bounce_skb->data,
> > len, DMA_TO_DEVICE);
> > if (dma_mapping_error(bp->sdev->dma_dev, mapping) || mapping + len> DMA_BIT_MASK(30)) {
> > if (!dma_mapping_error(bp->sdev->dma_dev, mapping))
> > dma_unmap_single(bp->sdev->dma_dev, mapping,

The above changes are part of the DMA changes and look OK.

> 1017,1018d1021
> < dev->trans_start = jiffies;
> <

I cannot evaluate this one.

> 1073,1074c1076,1077
> < ssb_dma_unmap_single(bp->sdev, rp->mapping, RX_PKT_BUF_SZ,
> < DMA_FROM_DEVICE);
> —
> > dma_unmap_single(bp->sdev->dma_dev, rp->mapping, RX_PKT_BUF_SZ,
> > DMA_FROM_DEVICE);
> 1085,1086c1088,1089
> < ssb_dma_unmap_single(bp->sdev, rp->mapping, rp->skb->len,
> < DMA_TO_DEVICE);
> —
> > dma_unmap_single(bp->sdev->dma_dev, rp->mapping, rp->skb->len,
> > DMA_TO_DEVICE);
> 1108,1110c1111,1112
> < ssb_dma_sync_single_for_device(bp->sdev, bp->rx_ring_dma,
> < DMA_TABLE_BYTES,
> < DMA_BIDIRECTIONAL);
> —
> > dma_sync_single_for_device(bp->sdev->dma_dev, bp->rx_ring_dma,
> > DMA_TABLE_BYTES, DMA_BIDIRECTIONAL);
> 1113,1115c1115,1116
> < ssb_dma_sync_single_for_device(bp->sdev, bp->tx_ring_dma,
> < DMA_TABLE_BYTES,
> < DMA_TO_DEVICE);
> —
> > dma_sync_single_for_device(bp->sdev->dma_dev, bp->tx_ring_dma,
> > DMA_TABLE_BYTES, DMA_TO_DEVICE);
> 1135,1137c1136,1137
> < ssb_dma_unmap_single(bp->sdev, bp->rx_ring_dma,
> < DMA_TABLE_BYTES,
> < DMA_BIDIRECTIONAL);
> —
> > dma_unmap_single(bp->sdev->dma_dev, bp->rx_ring_dma,
> > DMA_TABLE_BYTES, DMA_BIDIRECTIONAL);
> 1140,1142c1140,1141
> < ssb_dma_free_consistent(bp->sdev, DMA_TABLE_BYTES,
> < bp->rx_ring, bp->rx_ring_dma,
> < GFP_KERNEL);
> —
> > dma_free_coherent(bp->sdev->dma_dev, DMA_TABLE_BYTES,
> > bp->rx_ring, bp->rx_ring_dma);
> 1148,1150c1147,1148
> < ssb_dma_unmap_single(bp->sdev, bp->tx_ring_dma,
> < DMA_TABLE_BYTES,
> < DMA_TO_DEVICE);
> —
> > dma_unmap_single(bp->sdev->dma_dev, bp->tx_ring_dma,
> > DMA_TABLE_BYTES, DMA_TO_DEVICE);
> 1153,1155c1151,1152
> < ssb_dma_free_consistent(bp->sdev, DMA_TABLE_BYTES,
> < bp->tx_ring, bp->tx_ring_dma,
> < GFP_KERNEL);
> —
> > dma_free_coherent(bp->sdev->dma_dev, DMA_TABLE_BYTES,
> > bp->tx_ring, bp->tx_ring_dma);
> 1180c1177,1178
> < bp->rx_ring = ssb_dma_alloc_consistent(bp->sdev, size,&bp->rx_ring_dma, gfp);
> —
> > bp->rx_ring = dma_alloc_coherent(bp->sdev->dma_dev, size,
> > &bp->rx_ring_dma, gfp);
> 1192,1194c1190,1192
> < rx_ring_dma = ssb_dma_map_single(bp->sdev, rx_ring,
> < DMA_TABLE_BYTES,
> < DMA_BIDIRECTIONAL);
> —
> > rx_ring_dma = dma_map_single(bp->sdev->dma_dev, rx_ring,
> > DMA_TABLE_BYTES,
> > DMA_BIDIRECTIONAL);
> 1196c1194
> < if (ssb_dma_mapping_error(bp->sdev, rx_ring_dma) ||
> —
> > if (dma_mapping_error(bp->sdev->dma_dev, rx_ring_dma) ||
> 1207c1205,1206
> < bp->tx_ring = ssb_dma_alloc_consistent(bp->sdev, size,&bp->tx_ring_dma, gfp);
> —
> > bp->tx_ring = dma_alloc_coherent(bp->sdev->dma_dev, size,
> > &bp->tx_ring_dma, gfp);
> 1219,1221c1218,1220
> < tx_ring_dma = ssb_dma_map_single(bp->sdev, tx_ring,
> < DMA_TABLE_BYTES,
> < DMA_TO_DEVICE);
> —
> > tx_ring_dma = dma_map_single(bp->sdev->dma_dev, tx_ring,
> > DMA_TABLE_BYTES,
> > DMA_TO_DEVICE);
> 1223c1222
> < if (ssb_dma_mapping_error(bp->sdev, tx_ring_dma) ||
> —
> > if (dma_mapping_error(bp->sdev->dma_dev, tx_ring_dma) ||

Again, DMA changes that look OK.

> 1684c1683
> < struct dev_mc_list *mclist;
> —
> > struct netdev_hw_addr *ha;
> 1689c1688
> < netdev_for_each_mc_addr(mclist, dev) {
> —
> > netdev_for_each_mc_addr(ha, dev) {
> 1692c1691
> < __b44_cam_write(bp, mclist->dmi_addr, i++ + 1);
> —
> > __b44_cam_write(bp, ha->addr, i++ + 1);
> 2173,2174d2171
> < netif_carrier_off(dev);
> <

This group is needed to handle a change in a network API.

> 2181,2182c2178,2180
> < err = ssb_dma_set_mask(sdev, DMA_BIT_MASK(30));
> < if (err) {
> —
> >
> > if (dma_set_mask(sdev->dma_dev, DMA_BIT_MASK(30)) ||
> > dma_set_coherent_mask(sdev->dma_dev, DMA_BIT_MASK(30))) {

DMA changes.

> 2186a2185
> >
> 2213a2213,2214
> > netif_carrier_off(dev);
> >
> 2296a2298,2307
> > spin_lock_irq(&bp->lock);
> > b44_init_rings(bp);
> > b44_init_hw(bp, B44_FULL_RESET);
> > spin_unlock_irq(&bp->lock);
> >
> > /*
> > * As a shared interrupt, the handler can be called immediately. To be
> > * able to check the interrupt status the hardware must already be
> > * powered back on (b44_init_hw).
> > */
> 2299a2311,2314
> > spin_lock_irq(&bp->lock);
> > b44_halt(bp);
> > b44_free_rings(bp);
> > spin_unlock_irq(&bp->lock);
> 2303,2306d2317
> < spin_lock_irq(&bp->lock);
> <
> < b44_init_rings(bp);
> < b44_init_hw(bp, B44_FULL_RESET);
> 2308d2318
> < spin_unlock_irq(&bp->lock);

The above changes appear to fix a bug in the older version. From the comment, it
used to be possible to call a shared interrupt routine before the device was
powered on. That would likely cause a freeze.

> 2349d2358
> < dma_desc_align_mask = ~(dma_desc_align_size - 1);

More of the DMA changes.

After reviewing the differences, the only one that might cause a problem is the
change in the power-up sequence.

What exactly happens with the freeze? Are the caps and num lock lights flashing?

With b44 blacklisted, boot the 11.4 system. After it is booted, do the following
sequence:


sudo /sbin/modprobe -r b44
sleep 10 ; sudo /sbin/modprobe b44

The first command will ask for your root password. It is a dummy to make sure
that no password is needed for the second. After the second command is entered,
switch immediately to the logging console with CTRL-ALT-F10 and watch that
screen. Is anything output to the screen? If so, please post what you see. It
will have to be hand written, or you can photograph the screen and post the
photo. Put any postings with the bug report.

I will try to prepsre a patch that will just revert the interrupt part. If/when
it is available, I put it in the bug report.

Hmm … nothing (i.e. I do not get a freeze on the laptop) happens now when I execute ‘modprobe b44’ since eth0 is not configured. But when I execute, ‘sleep 10; yast2 lan’, then switch to CTL-ALT-F10, I receive the flashing CAP-LOCK and the NUMLOCK lights in addition to the following kernel panic message:


 3672.158150] Kernel panic - not syncing: map_single: bounce buffer is not DMA'able
 3672.163300] Pid: 6376, comm: ip Tainted: P 2.6.37.1-1.2-desktop #1
 3672.168549] Call Trace:
 3672.173672]   <ffffffff810059b9>] dump_trace+0x79/0x340
 3672.173672]   <ffffffff81520d03>] dump_stack+0x69/0x6f
 3672.173672]   <ffffffff81520daa>] panic+0xa1/0x1b8
 3672.173672]   <ffffffff81276ce4>] swiotlb_map_page+0xe4/0xf0

There is more to the kernel panic message but the screen freezes and I cannot get the rest.

On 04/10/2011 09:06 PM, revbee wrote:
>
> Hmm … nothing (i.e. I do not get a freeze on the laptop) happens now
> when I execute ‘modprobe b44’ since eth0 is not configured. But when I
> execute, ‘sleep 10; yast2 lan’, then switch to CTL-ALT-F10, I receive
> the flashing CAP-LOCK and the NUMLOCK lights in addition to the
> following kernel panic message:
>
>
> Code:
> --------------------
>
> 3672.158150] Kernel panic - not syncing: map_single: bounce buffer is not DMA’able
> 3672.163300] Pid: 6376, comm: ip Tainted: P 2.6.37.1-1.2-desktop #1
> 3672.168549] Call Trace:
> 3672.173672] <ffffffff810059b9>] dump_trace+0x79/0x340
> 3672.173672] <ffffffff81520d03>] dump_stack+0x69/0x6f
> 3672.173672] <ffffffff81520daa>] panic+0xa1/0x1b8
> 3672.173672] <ffffffff81276ce4>] swiotlb_map_page+0xe4/0xf0
>
> --------------------
>
>
>
>
> There is more to the kernel panic message but the screen freezes and I
> cannot get the rest.

Fortunately, we don’t need more. Your listing shows a problem in swiotlb. It has
been patched in recent kernels and the change was added to mainline’s 2.6.37.3,
but apparently not propagated to the openSUSE kernel. I will try to find out why.

In the meantime, a patch for your 2.6.37 source is posted with the Bugzilla.
Once you apply it, your 11.4 system should be OK.

You did a good job of providing the necessary information.

The problem is that the openSUSE kernel sources are for 2.6.37.1, which is earlier than when the patch was applied.

Thank you Larry. This is now resolved.

On 04/10/2011 11:36 PM, lwfinger wrote:
>
> The problem is that the openSUSE kernel sources are for 2.6.37.1, which
> is earlier than when the patch was applied.

If anyone else runs into this problem before the kernel is updated, the problem
occurs with a NIC that requires b44 and you have more than 1 GB RAM. The patch
to correct this bug is in Bugzilla #686492. If you do not want to rebuild the
kernel and are willing to run with a reduced memory size, add “mem=1024M” to the
boot line.