Skip to content

Commit

Permalink
ht6560b: fix deadlock on error handling
Browse files Browse the repository at this point in the history
Stop abusing ide_lock lock (switch to a private locking).

Fixes same issue as fixed by Alan Cox in atiixp host driver with
commit 6c5f8cc.

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>
  • Loading branch information
Bartlomiej Zolnierkiewicz committed Oct 19, 2007
1 parent 5bbcf92 commit 69e88d2
Showing 1 changed file with 18 additions and 13 deletions.
31 changes: 18 additions & 13 deletions drivers/ide/legacy/ht6560b.c
Original file line number Diff line number Diff line change
Expand Up @@ -247,16 +247,18 @@ static u8 ht_pio2timings(ide_drive_t *drive, const u8 pio)
}
}

static DEFINE_SPINLOCK(ht6560b_lock);

/*
* Enable/Disable so called prefetch mode
*/
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
*/
Expand All @@ -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
Expand All @@ -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
Expand Down

0 comments on commit 69e88d2

Please sign in to comment.