diff options
Diffstat (limited to 'drivers/ide/ide.c')
-rw-r--r-- | drivers/ide/ide.c | 41 |
1 files changed, 15 insertions, 26 deletions
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 90ae00d4aaf5..1ec983b00511 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c | |||
@@ -529,6 +529,19 @@ static int generic_ide_resume(struct device *dev) | |||
529 | return err; | 529 | return err; |
530 | } | 530 | } |
531 | 531 | ||
532 | static void generic_drive_reset(ide_drive_t *drive) | ||
533 | { | ||
534 | struct request *rq; | ||
535 | |||
536 | rq = blk_get_request(drive->queue, READ, __GFP_WAIT); | ||
537 | rq->cmd_type = REQ_TYPE_SPECIAL; | ||
538 | rq->cmd_len = 1; | ||
539 | rq->cmd[0] = REQ_DRIVE_RESET; | ||
540 | rq->cmd_flags |= REQ_SOFTBARRIER; | ||
541 | blk_execute_rq(drive->queue, NULL, rq, 1); | ||
542 | blk_put_request(rq); | ||
543 | } | ||
544 | |||
532 | int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device *bdev, | 545 | int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device *bdev, |
533 | unsigned int cmd, unsigned long arg) | 546 | unsigned int cmd, unsigned long arg) |
534 | { | 547 | { |
@@ -603,33 +616,9 @@ int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device | |||
603 | if (!capable(CAP_SYS_ADMIN)) | 616 | if (!capable(CAP_SYS_ADMIN)) |
604 | return -EACCES; | 617 | return -EACCES; |
605 | 618 | ||
606 | /* | 619 | generic_drive_reset(drive); |
607 | * Abort the current command on the | ||
608 | * group if there is one, taking | ||
609 | * care not to allow anything else | ||
610 | * to be queued and to die on the | ||
611 | * spot if we miss one somehow | ||
612 | */ | ||
613 | |||
614 | spin_lock_irqsave(&ide_lock, flags); | ||
615 | |||
616 | if (HWGROUP(drive)->resetting) { | ||
617 | spin_unlock_irqrestore(&ide_lock, flags); | ||
618 | return -EBUSY; | ||
619 | } | ||
620 | |||
621 | ide_abort(drive, "drive reset"); | ||
622 | |||
623 | BUG_ON(HWGROUP(drive)->handler); | ||
624 | |||
625 | /* Ensure nothing gets queued after we | ||
626 | drop the lock. Reset will clear the busy */ | ||
627 | |||
628 | HWGROUP(drive)->busy = 1; | ||
629 | spin_unlock_irqrestore(&ide_lock, flags); | ||
630 | (void) ide_do_reset(drive); | ||
631 | |||
632 | return 0; | 620 | return 0; |
621 | |||
633 | case HDIO_GET_BUSSTATE: | 622 | case HDIO_GET_BUSSTATE: |
634 | if (!capable(CAP_SYS_ADMIN)) | 623 | if (!capable(CAP_SYS_ADMIN)) |
635 | return -EACCES; | 624 | return -EACCES; |