Skip to content

Commit

Permalink
sata_mv: fix irq mask races
Browse files Browse the repository at this point in the history
Prevent racing on the main interrupt mask during port_start and port_stop.
Otherwise, we end up with IRQs masked on inactive ports,
and hotplug insertions then get missed later on.

Found while debugging (out of tree) target mode operations,
but the bug is present and impacting mainline as well.

This patch should also be considered for -stable.

Signed-off-by: Mark Lord <mlord@pobox.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
  • Loading branch information
Mark Lord authored and Jeff Garzik committed Apr 7, 2009
1 parent 44c65d1 commit 933cb8e
Showing 1 changed file with 9 additions and 0 deletions.
9 changes: 9 additions & 0 deletions drivers/ata/sata_mv.c
Original file line number Diff line number Diff line change
Expand Up @@ -1575,6 +1575,7 @@ static int mv_port_start(struct ata_port *ap)
struct device *dev = ap->host->dev;
struct mv_host_priv *hpriv = ap->host->private_data;
struct mv_port_priv *pp;
unsigned long flags;
int tag;

pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
Expand Down Expand Up @@ -1610,8 +1611,12 @@ static int mv_port_start(struct ata_port *ap)
pp->sg_tbl_dma[tag] = pp->sg_tbl_dma[0];
}
}

spin_lock_irqsave(ap->lock, flags);
mv_save_cached_regs(ap);
mv_edma_cfg(ap, 0, 0);
spin_unlock_irqrestore(ap->lock, flags);

return 0;

out_port_free_dma_mem:
Expand All @@ -1630,8 +1635,12 @@ static int mv_port_start(struct ata_port *ap)
*/
static void mv_port_stop(struct ata_port *ap)
{
unsigned long flags;

spin_lock_irqsave(ap->lock, flags);
mv_stop_edma(ap);
mv_enable_port_irqs(ap, 0);
spin_unlock_irqrestore(ap->lock, flags);
mv_port_free_dma_mem(ap);
}

Expand Down

0 comments on commit 933cb8e

Please sign in to comment.