endianness annotations and fixes for olympic
Subsystems (2)
PATCH 1/1 endianness annotations and fixes for olympic
* missing braces in !readl(...) & ...
* trivial endianness annotations
* in olympic_arb_cmd() the loop collecting fragments of
packet is b0rken on big-endian - we have
(next_ptr && (buf_ptr=olympic_priv->olympic_lap + ntohs(next_ptr)))
as condition and it should have swab16(), not ntohs() - it's host-endian byteswapped, not big-endian. So if we get more than one fragment on big-endian host, we get screwed.
This ntohs() got missed back when the rest of those had been switched
to swab16() in 2.4.0-test2-pre1 - at a guess, nobody had hit fragmented packets during the testing of PPC fixes.
PS: Ken Aaker cc'd on assumption that he is the same guy who'd done the original set of PPC fixes in olympic
---
drivers/net/tokenring/olympic.c +5 -5
@@ -357,7 +357,7 @@ static int __devinit olympic_init(struct net_device *dev)if (!(readl (olympic_mmio+BCTL ) &BCTL_MODE_INDICATOR )) { t=jiffies; -while (!readl (olympic_mmio+CLKCTL ) &CLKCTL_PAUSE ) { +while (!(readl (olympic_mmio+CLKCTL ) &CLKCTL_PAUSE )) {schedule () ;if (time_after (jiffies, t +2 *HZ )) {printk (KERN_ERR "IBM Cardbus tokenring adapter not responsing.\n" ) ;
@@ -671,7 +671,7 @@ static int olympic_open(struct net_device *dev)writel (BMCTL_TX1_DIS ,olympic_mmio+BMCTL_RWM );/* Yes, this enables TX channel 1 */ for (i=0 ;i<OLYMPIC_TX_RING_SIZE ;i++) - olympic_priv->olympic_tx_ring[i].buffer=0xdeadbeef ; + olympic_priv->olympic_tx_ring[i].buffer=cpu_to_le32 (0xdeadbeef ); olympic_priv->free_tx_ring_entries=OLYMPIC_TX_RING_SIZE ; olympic_priv->tx_ring_dma_addr = pci_map_single(olympic_priv->pdev,olympic_priv->olympic_tx_ring,
@@ -897,7 +897,7 @@ static void olympic_freemem(struct net_device *dev)dev_kfree_skb_irq (olympic_priv->rx_ring_skb[olympic_priv->rx_status_last_received]); olympic_priv->rx_ring_skb[olympic_priv->rx_status_last_received] =NULL ; } -if (olympic_priv->olympic_rx_ring[olympic_priv->rx_status_last_received].buffer !=0xdeadbeef ) { +if (olympic_priv->olympic_rx_ring[olympic_priv->rx_status_last_received].buffer !=cpu_to_le32 (0xdeadbeef )) {pci_unmap_single (olympic_priv->pdev,le32_to_cpu (olympic_priv->olympic_rx_ring[olympic_priv->rx_status_last_received].buffer), olympic_priv->pkt_buf_sz,PCI_DMA_FROMDEVICE );
@@ -983,7 +983,7 @@ static irqreturn_t olympic_interrupt(int irq, void *dev_id)le32_to_cpu (olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_last_status].buffer), olympic_priv->tx_ring_skb[olympic_priv->tx_ring_last_status]->len,PCI_DMA_TODEVICE);dev_kfree_skb_irq (olympic_priv->tx_ring_skb[olympic_priv->tx_ring_last_status]); - olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_last_status].buffer=0xdeadbeef ; + olympic_priv->olympic_tx_ring[olympic_priv->tx_ring_last_status].buffer=cpu_to_le32 (0xdeadbeef ); olympic_priv->olympic_tx_status_ring[olympic_priv->tx_ring_last_status].status=0 ; }netif_wake_queue (dev);
@@ -1432,7 +1432,7 @@ static void olympic_arb_cmd(struct net_device *dev) buffer_len =swab16 (readw (buf_ptr+offsetof(struct mac_receive_buffer ,buffer_length)));memcpy_fromio (skb_put (mac_frame, buffer_len), frame_data , buffer_len ) ; next_ptr=readw (buf_ptr+offsetof(struct mac_receive_buffer ,next)); - }while (next_ptr && (buf_ptr=olympic_priv->olympic_lap +ntohs (next_ptr))); + }while (next_ptr && (buf_ptr=olympic_priv->olympic_lap +swab16 (next_ptr))); mac_frame->protocol =tr_type_trans (mac_frame, dev);
drivers/net/tokenring/olympic.h +9 -9
@@ -216,31 +216,31 @@/* xxxx These structures are all little endian in hardware. */ struct olympic_tx_desc { -u32 buffer; -u32 status_length; +__le32 buffer; +__le32 status_length; };struct olympic_tx_status { -u32 status; +__le32 status; };struct olympic_rx_desc { -u32 buffer; -u32 res_length; +__le32 buffer; +__le32 res_length; };struct olympic_rx_status { -u32 fragmentcnt_framelen; -u32 status_buffercnt; +__le32 fragmentcnt_framelen; +__le32 status_buffercnt; };/* xxxx END These structures are all little endian in hardware. */ /* xxxx There may be more, but I'm pretty sure about these */ struct mac_receive_buffer { -u16 next ; +__le16 next ;u8 padding ;u8 frame_status ; -u16 buffer_length ; +__le16 buffer_length ;u8 frame_data ; };
Quoted 12 lines · Al Viro
* missing braces in !readl(...) & ...
* trivial endianness annotations
* inolympic_arb_cmd()the loop collecting fragments of
packet is b0rken on big-endian - we have(next_ptr && (buf_ptr=olympic_priv->olympic_lap + ntohs(next_ptr)))as condition and it should have
swab16(), notntohs()- it's host-endian byteswapped, not big-endian. So if we get more than one fragment on big-endian host, we get screwed.
Thisntohs()got missed back when the rest of those had been switched
toswab16()in 2.4.0-test2-pre1 - at a guess, nobody had hit fragmented packets during the testing of PPC fixes.
Quoted 4 lines
PS: Ken Aaker cc'd on assumption that he is the same guy who'd done the original set of PPC fixes in olympic
Signed-off-by Al Viro <[email protected]>
applied #upstream