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: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
This commit is contained in:
@@ -790,10 +790,7 @@ void do_ide_request(struct request_queue *q)
|
|||||||
/* caller must own hwgroup->lock */
|
/* caller must own hwgroup->lock */
|
||||||
BUG_ON(!irqs_disabled());
|
BUG_ON(!irqs_disabled());
|
||||||
|
|
||||||
while (!hwgroup->busy) {
|
while (!ide_lock_hwgroup(hwgroup)) {
|
||||||
hwgroup->busy = 1;
|
|
||||||
/* for atari only */
|
|
||||||
ide_get_lock(ide_intr, hwgroup);
|
|
||||||
drive = choose_drive(hwgroup);
|
drive = choose_drive(hwgroup);
|
||||||
if (drive == NULL) {
|
if (drive == NULL) {
|
||||||
int sleeping = 0;
|
int sleeping = 0;
|
||||||
@@ -825,17 +822,10 @@ void do_ide_request(struct request_queue *q)
|
|||||||
hwgroup->sleeping = 1;
|
hwgroup->sleeping = 1;
|
||||||
hwgroup->req_gen_timer = hwgroup->req_gen;
|
hwgroup->req_gen_timer = hwgroup->req_gen;
|
||||||
mod_timer(&hwgroup->timer, sleep);
|
mod_timer(&hwgroup->timer, sleep);
|
||||||
/* we purposely leave hwgroup->busy==1
|
/* we purposely leave hwgroup locked
|
||||||
* while sleeping */
|
* while sleeping */
|
||||||
} else {
|
} else
|
||||||
/* Ugly, but how can we sleep for the lock
|
ide_unlock_hwgroup(hwgroup);
|
||||||
* otherwise? perhaps from tq_disk?
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* for atari only */
|
|
||||||
ide_release_lock();
|
|
||||||
hwgroup->busy = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* no more work for this hwgroup (for now) */
|
/* no more work for this hwgroup (for now) */
|
||||||
goto plug_device;
|
goto plug_device;
|
||||||
@@ -865,7 +855,7 @@ void do_ide_request(struct request_queue *q)
|
|||||||
*/
|
*/
|
||||||
rq = elv_next_request(drive->queue);
|
rq = elv_next_request(drive->queue);
|
||||||
if (!rq) {
|
if (!rq) {
|
||||||
hwgroup->busy = 0;
|
ide_unlock_hwgroup(hwgroup);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -885,8 +875,8 @@ void do_ide_request(struct request_queue *q)
|
|||||||
if ((drive->dev_flags & IDE_DFLAG_BLOCKED) &&
|
if ((drive->dev_flags & IDE_DFLAG_BLOCKED) &&
|
||||||
blk_pm_request(rq) == 0 &&
|
blk_pm_request(rq) == 0 &&
|
||||||
(rq->cmd_flags & REQ_PREEMPT) == 0) {
|
(rq->cmd_flags & REQ_PREEMPT) == 0) {
|
||||||
/* We clear busy, there should be no pending ATA command at this point. */
|
/* there should be no pending command at this point */
|
||||||
hwgroup->busy = 0;
|
ide_unlock_hwgroup(hwgroup);
|
||||||
goto plug_device;
|
goto plug_device;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -897,7 +887,7 @@ void do_ide_request(struct request_queue *q)
|
|||||||
spin_lock_irq(&hwgroup->lock);
|
spin_lock_irq(&hwgroup->lock);
|
||||||
|
|
||||||
if (startstop == ide_stopped) {
|
if (startstop == ide_stopped) {
|
||||||
hwgroup->busy = 0;
|
ide_unlock_hwgroup(hwgroup);
|
||||||
if (!elv_queue_empty(orig_drive->queue))
|
if (!elv_queue_empty(orig_drive->queue))
|
||||||
blk_plug_device(orig_drive->queue);
|
blk_plug_device(orig_drive->queue);
|
||||||
}
|
}
|
||||||
@@ -1001,7 +991,7 @@ void ide_timer_expiry (unsigned long data)
|
|||||||
*/
|
*/
|
||||||
if (hwgroup->sleeping) {
|
if (hwgroup->sleeping) {
|
||||||
hwgroup->sleeping = 0;
|
hwgroup->sleeping = 0;
|
||||||
hwgroup->busy = 0;
|
ide_unlock_hwgroup(hwgroup);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ide_drive_t *drive = hwgroup->drive;
|
ide_drive_t *drive = hwgroup->drive;
|
||||||
@@ -1056,7 +1046,7 @@ void ide_timer_expiry (unsigned long data)
|
|||||||
spin_lock_irq(&hwgroup->lock);
|
spin_lock_irq(&hwgroup->lock);
|
||||||
enable_irq(hwif->irq);
|
enable_irq(hwif->irq);
|
||||||
if (startstop == ide_stopped) {
|
if (startstop == ide_stopped) {
|
||||||
hwgroup->busy = 0;
|
ide_unlock_hwgroup(hwgroup);
|
||||||
if (!elv_queue_empty(drive->queue))
|
if (!elv_queue_empty(drive->queue))
|
||||||
blk_plug_device(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;
|
drive->service_time = jiffies - drive->service_start;
|
||||||
if (startstop == ide_stopped) {
|
if (startstop == ide_stopped) {
|
||||||
if (hwgroup->handler == NULL) { /* paranoia */
|
if (hwgroup->handler == NULL) { /* paranoia */
|
||||||
hwgroup->busy = 0;
|
ide_unlock_hwgroup(hwgroup);
|
||||||
if (!elv_queue_empty(drive->queue))
|
if (!elv_queue_empty(drive->queue))
|
||||||
blk_plug_device(drive->queue);
|
blk_plug_device(drive->queue);
|
||||||
} else
|
} else
|
||||||
|
@@ -22,7 +22,7 @@ static void issue_park_cmd(ide_drive_t *drive, unsigned long timeout)
|
|||||||
if (reset_timer && hwgroup->sleeping &&
|
if (reset_timer && hwgroup->sleeping &&
|
||||||
del_timer(&hwgroup->timer)) {
|
del_timer(&hwgroup->timer)) {
|
||||||
hwgroup->sleeping = 0;
|
hwgroup->sleeping = 0;
|
||||||
hwgroup->busy = 0;
|
ide_unlock_hwgroup(hwgroup);
|
||||||
blk_start_queueing(q);
|
blk_start_queueing(q);
|
||||||
}
|
}
|
||||||
spin_unlock_irq(&hwgroup->lock);
|
spin_unlock_irq(&hwgroup->lock);
|
||||||
|
@@ -1280,6 +1280,26 @@ extern void ide_stall_queue(ide_drive_t *drive, unsigned long timeout);
|
|||||||
|
|
||||||
extern void ide_timer_expiry(unsigned long);
|
extern void ide_timer_expiry(unsigned long);
|
||||||
extern irqreturn_t ide_intr(int irq, void *dev_id);
|
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 *);
|
extern void do_ide_request(struct request_queue *);
|
||||||
|
|
||||||
void ide_init_disk(struct gendisk *, ide_drive_t *);
|
void ide_init_disk(struct gendisk *, ide_drive_t *);
|
||||||
|
Reference in New Issue
Block a user