Skip to content

Commit

Permalink
[PATCH] atiixp: Old drivers/ide layer driver for the ATIIXP hang fix
Browse files Browse the repository at this point in the history
When the old IDE layer calls into methods in the driver during error
handling it is essentially random whether ide_lock is already held.  This
causes a deadlock in the atiixp driver which also uses ide_lock internally
for locking.

Switch to a private lock instead.

[akpm@osl.org: cleanup]
Signed-off-by: Alan Cox <alan@redhat.com>
Acked-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
  • Loading branch information
Alan authored and Linus Torvalds committed Jan 6, 2007
1 parent 406c9b6 commit 6c5f8cc
Showing 1 changed file with 10 additions and 8 deletions.
18 changes: 10 additions & 8 deletions drivers/ide/pci/atiixp.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ static atiixp_ide_timing mdma_timing[] = {

static int save_mdma_mode[4];

static DEFINE_SPINLOCK(atiixp_lock);

/**
* atiixp_ratemask - compute rate mask for ATIIXP IDE
* @drive: IDE drive to compute for
Expand Down Expand Up @@ -105,7 +107,7 @@ static int atiixp_ide_dma_host_on(ide_drive_t *drive)
unsigned long flags;
u16 tmp16;

spin_lock_irqsave(&ide_lock, flags);
spin_lock_irqsave(&atiixp_lock, flags);

pci_read_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, &tmp16);
if (save_mdma_mode[drive->dn])
Expand All @@ -114,7 +116,7 @@ static int atiixp_ide_dma_host_on(ide_drive_t *drive)
tmp16 |= (1 << drive->dn);
pci_write_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, tmp16);

spin_unlock_irqrestore(&ide_lock, flags);
spin_unlock_irqrestore(&atiixp_lock, flags);

return __ide_dma_host_on(drive);
}
Expand All @@ -125,13 +127,13 @@ static int atiixp_ide_dma_host_off(ide_drive_t *drive)
unsigned long flags;
u16 tmp16;

spin_lock_irqsave(&ide_lock, flags);
spin_lock_irqsave(&atiixp_lock, flags);

pci_read_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, &tmp16);
tmp16 &= ~(1 << drive->dn);
pci_write_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, tmp16);

spin_unlock_irqrestore(&ide_lock, flags);
spin_unlock_irqrestore(&atiixp_lock, flags);

return __ide_dma_host_off(drive);
}
Expand All @@ -152,7 +154,7 @@ static void atiixp_tuneproc(ide_drive_t *drive, u8 pio)
u32 pio_timing_data;
u16 pio_mode_data;

spin_lock_irqsave(&ide_lock, flags);
spin_lock_irqsave(&atiixp_lock, flags);

pci_read_config_word(dev, ATIIXP_IDE_PIO_MODE, &pio_mode_data);
pio_mode_data &= ~(0x07 << (drive->dn * 4));
Expand All @@ -165,7 +167,7 @@ static void atiixp_tuneproc(ide_drive_t *drive, u8 pio)
(pio_timing[pio].command_width << (timing_shift + 4));
pci_write_config_dword(dev, ATIIXP_IDE_PIO_TIMING, pio_timing_data);

spin_unlock_irqrestore(&ide_lock, flags);
spin_unlock_irqrestore(&atiixp_lock, flags);
}

/**
Expand All @@ -189,7 +191,7 @@ static int atiixp_speedproc(ide_drive_t *drive, u8 xferspeed)

speed = ide_rate_filter(atiixp_ratemask(drive), xferspeed);

spin_lock_irqsave(&ide_lock, flags);
spin_lock_irqsave(&atiixp_lock, flags);

save_mdma_mode[drive->dn] = 0;
if (speed >= XFER_UDMA_0) {
Expand All @@ -208,7 +210,7 @@ static int atiixp_speedproc(ide_drive_t *drive, u8 xferspeed)
}
}

spin_unlock_irqrestore(&ide_lock, flags);
spin_unlock_irqrestore(&atiixp_lock, flags);

if (speed >= XFER_SW_DMA_0)
pio = atiixp_dma_2_pio(speed);
Expand Down

0 comments on commit 6c5f8cc

Please sign in to comment.