aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-io.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide/ide-io.c')
-rw-r--r--drivers/ide/ide-io.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index ec6664b0d3a9..1c51949833be 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -716,9 +716,49 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive,
716 return ide_stopped; 716 return ide_stopped;
717} 717}
718 718
719int ide_devset_execute(ide_drive_t *drive, const struct ide_devset *setting,
720 int arg)
721{
722 struct request_queue *q = drive->queue;
723 struct request *rq;
724 int ret = 0;
725
726 if (!(setting->flags & DS_SYNC))
727 return setting->set(drive, arg);
728
729 rq = blk_get_request(q, READ, GFP_KERNEL);
730 if (!rq)
731 return -ENOMEM;
732
733 rq->cmd_type = REQ_TYPE_SPECIAL;
734 rq->cmd_len = 5;
735 rq->cmd[0] = REQ_DEVSET_EXEC;
736 *(int *)&rq->cmd[1] = arg;
737 rq->special = setting->set;
738
739 if (blk_execute_rq(q, NULL, rq, 0))
740 ret = rq->errors;
741 blk_put_request(rq);
742
743 return ret;
744}
745EXPORT_SYMBOL_GPL(ide_devset_execute);
746
719static ide_startstop_t ide_special_rq(ide_drive_t *drive, struct request *rq) 747static ide_startstop_t ide_special_rq(ide_drive_t *drive, struct request *rq)
720{ 748{
721 switch (rq->cmd[0]) { 749 switch (rq->cmd[0]) {
750 case REQ_DEVSET_EXEC:
751 {
752 int err, (*setfunc)(ide_drive_t *, int) = rq->special;
753
754 err = setfunc(drive, *(int *)&rq->cmd[1]);
755 if (err)
756 rq->errors = err;
757 else
758 err = 1;
759 ide_end_request(drive, err, 0);
760 return ide_stopped;
761 }
722 case REQ_DRIVE_RESET: 762 case REQ_DRIVE_RESET:
723 return ide_do_reset(drive); 763 return ide_do_reset(drive);
724 default: 764 default: