forked from Minki/linux
ht6560b: fix deadlock on error handling
Stop abusing ide_lock lock (switch to a private locking).
Fixes same issue as fixed by Alan Cox in atiixp host driver with
commit 6c5f8cc33e
.
ht6560b is a bit special cause we still need to leave ide_lock for
->set_pio_mode with 'pio' argument == 8/9 (prefetch disable/enable).
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
This commit is contained in:
parent
5bbcf9242d
commit
69e88d2a75
@ -247,6 +247,8 @@ static u8 ht_pio2timings(ide_drive_t *drive, const u8 pio)
|
||||
}
|
||||
}
|
||||
|
||||
static DEFINE_SPINLOCK(ht6560b_lock);
|
||||
|
||||
/*
|
||||
* Enable/Disable so called prefetch mode
|
||||
*/
|
||||
@ -254,9 +256,9 @@ static void ht_set_prefetch(ide_drive_t *drive, u8 state)
|
||||
{
|
||||
unsigned long flags;
|
||||
int t = HT_PREFETCH_MODE << 8;
|
||||
|
||||
spin_lock_irqsave(&ide_lock, flags);
|
||||
|
||||
|
||||
spin_lock_irqsave(&ht6560b_lock, flags);
|
||||
|
||||
/*
|
||||
* Prefetch mode and unmask irq seems to conflict
|
||||
*/
|
||||
@ -268,9 +270,9 @@ static void ht_set_prefetch(ide_drive_t *drive, u8 state)
|
||||
drive->drive_data &= ~t; /* disable prefetch mode */
|
||||
drive->no_unmask = 0;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&ide_lock, flags);
|
||||
|
||||
|
||||
spin_unlock_irqrestore(&ht6560b_lock, flags);
|
||||
|
||||
#ifdef DEBUG
|
||||
printk("ht6560b: drive %s prefetch mode %sabled\n", drive->name, (state ? "en" : "dis"));
|
||||
#endif
|
||||
@ -284,19 +286,22 @@ static void ht6560b_set_pio_mode(ide_drive_t *drive, const u8 pio)
|
||||
switch (pio) {
|
||||
case 8: /* set prefetch off */
|
||||
case 9: /* set prefetch on */
|
||||
/*
|
||||
* take ide_lock for drive->[no_]unmask
|
||||
*/
|
||||
spin_lock_irqsave(&ide_lock, flags);
|
||||
ht_set_prefetch(drive, pio & 1);
|
||||
spin_unlock_irqrestore(&ide_lock, flags);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
timing = ht_pio2timings(drive, pio);
|
||||
|
||||
spin_lock_irqsave(&ide_lock, flags);
|
||||
|
||||
|
||||
spin_lock_irqsave(&ht6560b_lock, flags);
|
||||
drive->drive_data &= 0xff00;
|
||||
drive->drive_data |= timing;
|
||||
|
||||
spin_unlock_irqrestore(&ide_lock, flags);
|
||||
|
||||
spin_unlock_irqrestore(&ht6560b_lock, flags);
|
||||
|
||||
#ifdef DEBUG
|
||||
printk("ht6560b: drive %s tuned to pio mode %#x timing=%#x\n", drive->name, pio, timing);
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user