aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-io.c
diff options
context:
space:
mode:
authorElias Oltmanns <eo@nebensachen.de>2008-07-16 14:33:48 -0400
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2008-07-16 14:33:48 -0400
commit79e36a9f54aaf4a52eb2d9520953aa3960e99294 (patch)
tree70fae17d64a1facde8541184d7139c4bc12d03bf /drivers/ide/ide-io.c
parent72a3d651b2fe341a8ae2ca164c395aa3007350cd (diff)
IDE: Fix HDIO_DRIVE_RESET handling
Currently, the code path executing an HDIO_DRIVE_RESET ioctl is broken in various ways. Most importantly, it is treated as an out of band request in an illegal way which may very likely lead to system lock ups. Use the drive's request queue to avoid this problem (and fix a locking issue for free along the way). Signed-off-by: Elias Oltmanns <eo@nebensachen.de> Cc: "Alan Cox" <alan@lxorguk.ukuu.org.uk> Cc: "Randy Dunlap" <randy.dunlap@oracle.com> Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
Diffstat (limited to 'drivers/ide/ide-io.c')
-rw-r--r--drivers/ide/ide-io.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index 28057747c1f8..2b33c129740b 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -766,6 +766,18 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive,
766 return ide_stopped; 766 return ide_stopped;
767} 767}
768 768
769static ide_startstop_t ide_special_rq(ide_drive_t *drive, struct request *rq)
770{
771 switch (rq->cmd[0]) {
772 case REQ_DRIVE_RESET:
773 return ide_do_reset(drive);
774 default:
775 blk_dump_rq_flags(rq, "ide_special_rq - bad request");
776 ide_end_request(drive, 0, 0);
777 return ide_stopped;
778 }
779}
780
769static void ide_check_pm_state(ide_drive_t *drive, struct request *rq) 781static void ide_check_pm_state(ide_drive_t *drive, struct request *rq)
770{ 782{
771 struct request_pm_state *pm = rq->data; 783 struct request_pm_state *pm = rq->data;
@@ -869,7 +881,16 @@ static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
869 pm->pm_step == ide_pm_state_completed) 881 pm->pm_step == ide_pm_state_completed)
870 ide_complete_pm_request(drive, rq); 882 ide_complete_pm_request(drive, rq);
871 return startstop; 883 return startstop;
872 } 884 } else if (!rq->rq_disk && blk_special_request(rq))
885 /*
886 * TODO: Once all ULDs have been modified to
887 * check for specific op codes rather than
888 * blindly accepting any special request, the
889 * check for ->rq_disk above may be replaced
890 * by a more suitable mechanism or even
891 * dropped entirely.
892 */
893 return ide_special_rq(drive, rq);
873 894
874 drv = *(ide_driver_t **)rq->rq_disk->private_data; 895 drv = *(ide_driver_t **)rq->rq_disk->private_data;
875 return drv->do_request(drive, rq, block); 896 return drv->do_request(drive, rq, block);