gianfar: Fix a locking bug in gianfar's sysfs code

During sparse cleanup, found a locking bug. Some of the sysfs functions were
acquiring a lock, and then returning in the event of an error. We rearrange
the code so that the lock is released in error conditions, too.

Signed-off-by: Andy Fleming <afleming@freescale.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>

authored by Andy Fleming and committed by Jeff Garzik f162b9d5 569f0c4d

+12 -6
+3 -2
drivers/net/gianfar.c
··· 138 static void gfar_netpoll(struct net_device *dev); 139 #endif 140 int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit); 141 static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, int length); 142 static void gfar_vlan_rx_register(struct net_device *netdev, 143 struct vlan_group *grp); ··· 1142 } 1143 1144 /* Changes the mac address if the controller is not running. */ 1145 - int gfar_set_mac_address(struct net_device *dev) 1146 { 1147 gfar_set_mac_for_addr(dev, 0, dev->dev_addr); 1148 ··· 1261 } 1262 1263 /* Interrupt Handler for Transmit complete */ 1264 - int gfar_clean_tx_ring(struct net_device *dev) 1265 { 1266 struct txbd8 *bdp; 1267 struct gfar_private *priv = netdev_priv(dev);
··· 138 static void gfar_netpoll(struct net_device *dev); 139 #endif 140 int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit); 141 + static int gfar_clean_tx_ring(struct net_device *dev); 142 static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb, int length); 143 static void gfar_vlan_rx_register(struct net_device *netdev, 144 struct vlan_group *grp); ··· 1141 } 1142 1143 /* Changes the mac address if the controller is not running. */ 1144 + static int gfar_set_mac_address(struct net_device *dev) 1145 { 1146 gfar_set_mac_for_addr(dev, 0, dev->dev_addr); 1147 ··· 1260 } 1261 1262 /* Interrupt Handler for Transmit complete */ 1263 + static int gfar_clean_tx_ring(struct net_device *dev) 1264 { 1265 struct txbd8 *bdp; 1266 struct gfar_private *priv = netdev_priv(dev);
+3
drivers/net/gianfar.h
··· 782 extern void gfar_phy_test(struct mii_bus *bus, struct phy_device *phydev, 783 int enable, u32 regnum, u32 read); 784 void gfar_init_sysfs(struct net_device *dev); 785 786 #endif /* __GIANFAR_H */
··· 782 extern void gfar_phy_test(struct mii_bus *bus, struct phy_device *phydev, 783 int enable, u32 regnum, u32 read); 784 void gfar_init_sysfs(struct net_device *dev); 785 + int gfar_local_mdio_write(struct gfar_mii __iomem *regs, int mii_id, 786 + int regnum, u16 value); 787 + int gfar_local_mdio_read(struct gfar_mii __iomem *regs, int mii_id, int regnum); 788 789 #endif /* __GIANFAR_H */
+6 -4
drivers/net/gianfar_sysfs.c
··· 103 104 spin_lock_irqsave(&priv->rxlock, flags); 105 if (length > priv->rx_buffer_size) 106 - return count; 107 108 if (length == priv->rx_stash_size) 109 - return count; 110 111 priv->rx_stash_size = length; 112 ··· 125 126 gfar_write(&priv->regs->attr, temp); 127 128 spin_unlock_irqrestore(&priv->rxlock, flags); 129 130 return count; ··· 155 156 spin_lock_irqsave(&priv->rxlock, flags); 157 if (index > priv->rx_stash_size) 158 - return count; 159 160 if (index == priv->rx_stash_index) 161 - return count; 162 163 priv->rx_stash_index = index; 164 ··· 167 temp |= ATTRELI_EI(index); 168 gfar_write(&priv->regs->attreli, flags); 169 170 spin_unlock_irqrestore(&priv->rxlock, flags); 171 172 return count;
··· 103 104 spin_lock_irqsave(&priv->rxlock, flags); 105 if (length > priv->rx_buffer_size) 106 + goto out; 107 108 if (length == priv->rx_stash_size) 109 + goto out; 110 111 priv->rx_stash_size = length; 112 ··· 125 126 gfar_write(&priv->regs->attr, temp); 127 128 + out: 129 spin_unlock_irqrestore(&priv->rxlock, flags); 130 131 return count; ··· 154 155 spin_lock_irqsave(&priv->rxlock, flags); 156 if (index > priv->rx_stash_size) 157 + goto out; 158 159 if (index == priv->rx_stash_index) 160 + goto out; 161 162 priv->rx_stash_index = index; 163 ··· 166 temp |= ATTRELI_EI(index); 167 gfar_write(&priv->regs->attreli, flags); 168 169 + out: 170 spin_unlock_irqrestore(&priv->rxlock, flags); 171 172 return count;