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

Commit 631de370 authored by Bartlomiej Zolnierkiewicz's avatar Bartlomiej Zolnierkiewicz
Browse files

ide: add ide_[un]lock_hwgroup() helpers



Add ide_[un]lock_hwgroup() inline helpers for obtaining exclusive
access to the given hwgroup and update the core code accordingly.

[ This change besides making code saner results in more efficient
  use of ide_{get,release}_lock(). ]

Cc: Michael Schmitz <schmitz@biophys.uni-duesseldorf.de>
Cc: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: Elias Oltmanns <eo@nebensachen.de>
Signed-off-by: default avatarBartlomiej Zolnierkiewicz <bzolnier@gmail.com>
parent b2cfb05a
Loading
Loading
Loading
Loading
+11 −21
Original line number Diff line number Diff line
@@ -790,10 +790,7 @@ void do_ide_request(struct request_queue *q)
	/* caller must own hwgroup->lock */
	BUG_ON(!irqs_disabled());

	while (!hwgroup->busy) {
		hwgroup->busy = 1;
		/* for atari only */
		ide_get_lock(ide_intr, hwgroup);
	while (!ide_lock_hwgroup(hwgroup)) {
		drive = choose_drive(hwgroup);
		if (drive == NULL) {
			int sleeping = 0;
@@ -825,17 +822,10 @@ void do_ide_request(struct request_queue *q)
				hwgroup->sleeping = 1;
				hwgroup->req_gen_timer = hwgroup->req_gen;
				mod_timer(&hwgroup->timer, sleep);
				/* we purposely leave hwgroup->busy==1
				/* we purposely leave hwgroup locked
				 * while sleeping */
			} else {
				/* Ugly, but how can we sleep for the lock
				 * otherwise? perhaps from tq_disk?
				 */

				/* for atari only */
				ide_release_lock();
				hwgroup->busy = 0;
			}
			} else
				ide_unlock_hwgroup(hwgroup);

			/* no more work for this hwgroup (for now) */
			goto plug_device;
@@ -865,7 +855,7 @@ void do_ide_request(struct request_queue *q)
		 */
		rq = elv_next_request(drive->queue);
		if (!rq) {
			hwgroup->busy = 0;
			ide_unlock_hwgroup(hwgroup);
			break;
		}

@@ -885,8 +875,8 @@ void do_ide_request(struct request_queue *q)
		if ((drive->dev_flags & IDE_DFLAG_BLOCKED) &&
		    blk_pm_request(rq) == 0 &&
		    (rq->cmd_flags & REQ_PREEMPT) == 0) {
			/* We clear busy, there should be no pending ATA command at this point. */
			hwgroup->busy = 0;
			/* there should be no pending command at this point */
			ide_unlock_hwgroup(hwgroup);
			goto plug_device;
		}

@@ -897,7 +887,7 @@ void do_ide_request(struct request_queue *q)
		spin_lock_irq(&hwgroup->lock);

		if (startstop == ide_stopped) {
			hwgroup->busy = 0;
			ide_unlock_hwgroup(hwgroup);
			if (!elv_queue_empty(orig_drive->queue))
				blk_plug_device(orig_drive->queue);
		}
@@ -1001,7 +991,7 @@ void ide_timer_expiry (unsigned long data)
		 */
		if (hwgroup->sleeping) {
			hwgroup->sleeping = 0;
			hwgroup->busy = 0;
			ide_unlock_hwgroup(hwgroup);
		}
	} else {
		ide_drive_t *drive = hwgroup->drive;
@@ -1056,7 +1046,7 @@ void ide_timer_expiry (unsigned long data)
			spin_lock_irq(&hwgroup->lock);
			enable_irq(hwif->irq);
			if (startstop == ide_stopped) {
				hwgroup->busy = 0;
				ide_unlock_hwgroup(hwgroup);
				if (!elv_queue_empty(drive->queue))
					blk_plug_device(drive->queue);
			}
@@ -1249,7 +1239,7 @@ irqreturn_t ide_intr (int irq, void *dev_id)
	drive->service_time = jiffies - drive->service_start;
	if (startstop == ide_stopped) {
		if (hwgroup->handler == NULL) {	/* paranoia */
			hwgroup->busy = 0;
			ide_unlock_hwgroup(hwgroup);
			if (!elv_queue_empty(drive->queue))
				blk_plug_device(drive->queue);
		} else
+1 −1
Original line number Diff line number Diff line
@@ -22,7 +22,7 @@ static void issue_park_cmd(ide_drive_t *drive, unsigned long timeout)
		if (reset_timer && hwgroup->sleeping &&
		    del_timer(&hwgroup->timer)) {
			hwgroup->sleeping = 0;
			hwgroup->busy = 0;
			ide_unlock_hwgroup(hwgroup);
			blk_start_queueing(q);
		}
		spin_unlock_irq(&hwgroup->lock);
+20 −0
Original line number Diff line number Diff line
@@ -1280,6 +1280,26 @@ extern void ide_stall_queue(ide_drive_t *drive, unsigned long timeout);

extern void ide_timer_expiry(unsigned long);
extern irqreturn_t ide_intr(int irq, void *dev_id);

static inline int ide_lock_hwgroup(ide_hwgroup_t *hwgroup)
{
	if (hwgroup->busy)
		return 1;

	hwgroup->busy = 1;
	/* for atari only */
	ide_get_lock(ide_intr, hwgroup);

	return 0;
}

static inline void ide_unlock_hwgroup(ide_hwgroup_t *hwgroup)
{
	/* for atari only */
	ide_release_lock();
	hwgroup->busy = 0;
}

extern void do_ide_request(struct request_queue *);

void ide_init_disk(struct gendisk *, ide_drive_t *);