[PATCH] Fix locking in gianfar
This patch fixes several bugs in the gianfar driver, including a major one where spinlocks were horribly broken: * Split gianfar locks into two types: TX and RX * Made it so gfar_start() now clears RHALT * Fixed a bug where calling gfar_start_xmit() with interrupts off would corrupt the interrupt state * Fixed a bug where a frame could potentially arrive, and never be handled (if no more frames arrived * Fixed a bug where the rx_work_limit would never be observed by the rx completion code * Fixed a bug where the interrupt handlers were not actually protected by their spinlocks Signed-off-by: Andy Fleming <afleming@freescale.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
This commit is contained in:
committed by
Jeff Garzik
parent
f18b95c3e2
commit
fef6108d45
@@ -82,7 +82,7 @@ static ssize_t gfar_set_bd_stash(struct class_device *cdev,
|
||||
else
|
||||
return count;
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
spin_lock_irqsave(&priv->rxlock, flags);
|
||||
|
||||
/* Set the new stashing value */
|
||||
priv->bd_stash_en = new_setting;
|
||||
@@ -96,7 +96,7 @@ static ssize_t gfar_set_bd_stash(struct class_device *cdev,
|
||||
|
||||
gfar_write(&priv->regs->attr, temp);
|
||||
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
spin_unlock_irqrestore(&priv->rxlock, flags);
|
||||
|
||||
return count;
|
||||
}
|
||||
@@ -118,7 +118,7 @@ static ssize_t gfar_set_rx_stash_size(struct class_device *cdev,
|
||||
u32 temp;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
spin_lock_irqsave(&priv->rxlock, flags);
|
||||
if (length > priv->rx_buffer_size)
|
||||
return count;
|
||||
|
||||
@@ -142,7 +142,7 @@ static ssize_t gfar_set_rx_stash_size(struct class_device *cdev,
|
||||
|
||||
gfar_write(&priv->regs->attr, temp);
|
||||
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
spin_unlock_irqrestore(&priv->rxlock, flags);
|
||||
|
||||
return count;
|
||||
}
|
||||
@@ -166,7 +166,7 @@ static ssize_t gfar_set_rx_stash_index(struct class_device *cdev,
|
||||
u32 temp;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
spin_lock_irqsave(&priv->rxlock, flags);
|
||||
if (index > priv->rx_stash_size)
|
||||
return count;
|
||||
|
||||
@@ -180,7 +180,7 @@ static ssize_t gfar_set_rx_stash_index(struct class_device *cdev,
|
||||
temp |= ATTRELI_EI(index);
|
||||
gfar_write(&priv->regs->attreli, flags);
|
||||
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
spin_unlock_irqrestore(&priv->rxlock, flags);
|
||||
|
||||
return count;
|
||||
}
|
||||
@@ -205,7 +205,7 @@ static ssize_t gfar_set_fifo_threshold(struct class_device *cdev,
|
||||
if (length > GFAR_MAX_FIFO_THRESHOLD)
|
||||
return count;
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
spin_lock_irqsave(&priv->txlock, flags);
|
||||
|
||||
priv->fifo_threshold = length;
|
||||
|
||||
@@ -214,7 +214,7 @@ static ssize_t gfar_set_fifo_threshold(struct class_device *cdev,
|
||||
temp |= length;
|
||||
gfar_write(&priv->regs->fifo_tx_thr, temp);
|
||||
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
spin_unlock_irqrestore(&priv->txlock, flags);
|
||||
|
||||
return count;
|
||||
}
|
||||
@@ -240,7 +240,7 @@ static ssize_t gfar_set_fifo_starve(struct class_device *cdev,
|
||||
if (num > GFAR_MAX_FIFO_STARVE)
|
||||
return count;
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
spin_lock_irqsave(&priv->txlock, flags);
|
||||
|
||||
priv->fifo_starve = num;
|
||||
|
||||
@@ -249,7 +249,7 @@ static ssize_t gfar_set_fifo_starve(struct class_device *cdev,
|
||||
temp |= num;
|
||||
gfar_write(&priv->regs->fifo_tx_starve, temp);
|
||||
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
spin_unlock_irqrestore(&priv->txlock, flags);
|
||||
|
||||
return count;
|
||||
}
|
||||
@@ -274,7 +274,7 @@ static ssize_t gfar_set_fifo_starve_off(struct class_device *cdev,
|
||||
if (num > GFAR_MAX_FIFO_STARVE_OFF)
|
||||
return count;
|
||||
|
||||
spin_lock_irqsave(&priv->lock, flags);
|
||||
spin_lock_irqsave(&priv->txlock, flags);
|
||||
|
||||
priv->fifo_starve_off = num;
|
||||
|
||||
@@ -283,7 +283,7 @@ static ssize_t gfar_set_fifo_starve_off(struct class_device *cdev,
|
||||
temp |= num;
|
||||
gfar_write(&priv->regs->fifo_tx_starve_shutoff, temp);
|
||||
|
||||
spin_unlock_irqrestore(&priv->lock, flags);
|
||||
spin_unlock_irqrestore(&priv->txlock, flags);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
Reference in New Issue
Block a user