Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 69e88d2a authored by Bartlomiej Zolnierkiewicz's avatar Bartlomiej Zolnierkiewicz
Browse files

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 6c5f8cc3.

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: default avatarBartlomiej Zolnierkiewicz <bzolnier@gmail.com>
parent 5bbcf924
Loading
Loading
Loading
Loading
+18 −13
Original line number Diff line number Diff line
@@ -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
 */
@@ -255,7 +257,7 @@ 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
@@ -269,7 +271,7 @@ static void ht_set_prefetch(ide_drive_t *drive, u8 state)
		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"));
@@ -284,18 +286,21 @@ 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);