aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ide/ide-eh.c11
-rw-r--r--drivers/ide/ide-floppy.c2
-rw-r--r--drivers/ide/ide-io.c40
-rw-r--r--drivers/ide/ide-tape.c2
-rw-r--r--drivers/ide/ide-taskfile.c26
-rw-r--r--include/linux/ide.h3
6 files changed, 43 insertions, 41 deletions
diff --git a/drivers/ide/ide-eh.c b/drivers/ide/ide-eh.c
index 1231b5e486f2..e2c04886616f 100644
--- a/drivers/ide/ide-eh.c
+++ b/drivers/ide/ide-eh.c
@@ -124,7 +124,16 @@ ide_startstop_t ide_error(ide_drive_t *drive, const char *msg, u8 stat)
124 /* retry only "normal" I/O: */ 124 /* retry only "normal" I/O: */
125 if (!blk_fs_request(rq)) { 125 if (!blk_fs_request(rq)) {
126 rq->errors = 1; 126 rq->errors = 1;
127 ide_end_drive_cmd(drive, stat, err); 127 if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
128 ide_task_t *task = rq->special;
129
130 if (task)
131 ide_complete_task(drive, task, stat, err);
132 } else if (blk_pm_request(rq)) {
133 ide_complete_pm_rq(drive, rq);
134 return ide_stopped;
135 }
136 ide_complete_rq(drive, err);
128 return ide_stopped; 137 return ide_stopped;
129 } 138 }
130 139
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index d1a79e8e0d69..39e7fda37c5f 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -101,7 +101,7 @@ static int ide_floppy_end_request(ide_drive_t *drive, int uptodate, int nsecs)
101 } 101 }
102 rq->errors = error; 102 rq->errors = error;
103 /* fixme: need to move this local also */ 103 /* fixme: need to move this local also */
104 ide_end_drive_cmd(drive, 0, 0); 104 ide_complete_rq(drive, 0);
105 return 0; 105 return 0;
106} 106}
107 107
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index b8426e9c0906..4a97a97e56c4 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -144,49 +144,28 @@ int ide_end_dequeued_request(ide_drive_t *drive, struct request *rq,
144} 144}
145EXPORT_SYMBOL_GPL(ide_end_dequeued_request); 145EXPORT_SYMBOL_GPL(ide_end_dequeued_request);
146 146
147static void ide_complete_task(ide_drive_t *drive, ide_task_t *task, 147void ide_complete_task(ide_drive_t *drive, ide_task_t *task, u8 stat, u8 err)
148 u8 stat, u8 err)
149{ 148{
150 struct ide_taskfile *tf = &task->tf; 149 struct ide_taskfile *tf = &task->tf;
150 struct request *rq = task->rq;
151 151
152 tf->error = err; 152 tf->error = err;
153 tf->status = stat; 153 tf->status = stat;
154 154
155 drive->hwif->tp_ops->tf_read(drive, task); 155 drive->hwif->tp_ops->tf_read(drive, task);
156 156
157 if (rq && rq->cmd_type == REQ_TYPE_ATA_TASKFILE)
158 memcpy(rq->special, task, sizeof(*task));
159
157 if (task->tf_flags & IDE_TFLAG_DYN) 160 if (task->tf_flags & IDE_TFLAG_DYN)
158 kfree(task); 161 kfree(task);
159} 162}
160 163
161/** 164void ide_complete_rq(ide_drive_t *drive, u8 err)
162 * ide_end_drive_cmd - end an explicit drive command
163 * @drive: command
164 * @stat: status bits
165 * @err: error bits
166 *
167 * Clean up after success/failure of an explicit drive command.
168 * These get thrown onto the queue so they are synchronized with
169 * real I/O operations on the drive.
170 *
171 * In LBA48 mode we have to read the register set twice to get
172 * all the extra information out.
173 */
174
175void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err)
176{ 165{
177 ide_hwif_t *hwif = drive->hwif; 166 ide_hwif_t *hwif = drive->hwif;
178 struct request *rq = hwif->rq; 167 struct request *rq = hwif->rq;
179 168
180 if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
181 ide_task_t *task = (ide_task_t *)rq->special;
182
183 if (task)
184 ide_complete_task(drive, task, stat, err);
185 } else if (blk_pm_request(rq)) {
186 ide_complete_pm_rq(drive, rq);
187 return;
188 }
189
190 hwif->rq = NULL; 169 hwif->rq = NULL;
191 170
192 rq->errors = err; 171 rq->errors = err;
@@ -195,7 +174,7 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err)
195 blk_rq_bytes(rq)))) 174 blk_rq_bytes(rq))))
196 BUG(); 175 BUG();
197} 176}
198EXPORT_SYMBOL(ide_end_drive_cmd); 177EXPORT_SYMBOL(ide_complete_rq);
199 178
200void ide_kill_rq(ide_drive_t *drive, struct request *rq) 179void ide_kill_rq(ide_drive_t *drive, struct request *rq)
201{ 180{
@@ -358,8 +337,9 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive,
358#ifdef DEBUG 337#ifdef DEBUG
359 printk("%s: DRIVE_CMD (null)\n", drive->name); 338 printk("%s: DRIVE_CMD (null)\n", drive->name);
360#endif 339#endif
361 ide_end_drive_cmd(drive, hwif->tp_ops->read_status(hwif), 340 (void)hwif->tp_ops->read_status(hwif);
362 ide_read_error(drive)); 341
342 ide_complete_rq(drive, ide_read_error(drive));
363 343
364 return ide_stopped; 344 return ide_stopped;
365} 345}
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index 4e6181c7bbda..de2d926e66c2 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -502,7 +502,7 @@ static int idetape_end_request(ide_drive_t *drive, int uptodate, int nr_sects)
502 502
503 spin_lock_irqsave(&tape->lock, flags); 503 spin_lock_irqsave(&tape->lock, flags);
504 504
505 ide_end_drive_cmd(drive, 0, 0); 505 ide_complete_rq(drive, 0);
506 506
507 spin_unlock_irqrestore(&tape->lock, flags); 507 spin_unlock_irqrestore(&tape->lock, flags);
508 return 0; 508 return 0;
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index 02240a3ee0fb..297cf6f4c723 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -147,12 +147,9 @@ static ide_startstop_t task_no_data_intr(ide_drive_t *drive)
147 } 147 }
148 } 148 }
149 return ide_error(drive, "task_no_data_intr", stat); 149 return ide_error(drive, "task_no_data_intr", stat);
150 /* calls ide_end_drive_cmd */
151 } 150 }
152 151
153 if (!custom) 152 if (custom && tf->command == ATA_CMD_IDLEIMMEDIATE) {
154 ide_end_drive_cmd(drive, stat, ide_read_error(drive));
155 else if (tf->command == ATA_CMD_IDLEIMMEDIATE) {
156 hwif->tp_ops->tf_read(drive, task); 153 hwif->tp_ops->tf_read(drive, task);
157 if (tf->lbal != 0xc4) { 154 if (tf->lbal != 0xc4) {
158 printk(KERN_ERR "%s: head unload failed!\n", 155 printk(KERN_ERR "%s: head unload failed!\n",
@@ -160,10 +157,22 @@ static ide_startstop_t task_no_data_intr(ide_drive_t *drive)
160 ide_tf_dump(drive->name, tf); 157 ide_tf_dump(drive->name, tf);
161 } else 158 } else
162 drive->dev_flags |= IDE_DFLAG_PARKED; 159 drive->dev_flags |= IDE_DFLAG_PARKED;
163 ide_end_drive_cmd(drive, stat, ide_read_error(drive)); 160 } else if (custom && tf->command == ATA_CMD_SET_MULTI)
164 } else if (tf->command == ATA_CMD_SET_MULTI)
165 drive->mult_count = drive->mult_req; 161 drive->mult_count = drive->mult_req;
166 162
163 if (custom == 0 || tf->command == ATA_CMD_IDLEIMMEDIATE) {
164 struct request *rq = hwif->rq;
165 u8 err = ide_read_error(drive);
166
167 if (blk_pm_request(rq))
168 ide_complete_pm_rq(drive, rq);
169 else {
170 if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE)
171 ide_complete_task(drive, task, stat, err);
172 ide_complete_rq(drive, err);
173 }
174 }
175
167 return ide_stopped; 176 return ide_stopped;
168} 177}
169 178
@@ -321,9 +330,12 @@ static ide_startstop_t task_error(ide_drive_t *drive, struct request *rq,
321void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat) 330void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat)
322{ 331{
323 if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { 332 if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
333 ide_task_t *task = rq->special;
324 u8 err = ide_read_error(drive); 334 u8 err = ide_read_error(drive);
325 335
326 ide_end_drive_cmd(drive, stat, err); 336 if (task)
337 ide_complete_task(drive, task, stat, err);
338 ide_complete_rq(drive, err);
327 return; 339 return;
328 } 340 }
329 341
diff --git a/include/linux/ide.h b/include/linux/ide.h
index c5ac19e43fc0..83bed2f4378a 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -1158,7 +1158,8 @@ extern ide_startstop_t ide_do_reset (ide_drive_t *);
1158extern int ide_devset_execute(ide_drive_t *drive, 1158extern int ide_devset_execute(ide_drive_t *drive,
1159 const struct ide_devset *setting, int arg); 1159 const struct ide_devset *setting, int arg);
1160 1160
1161extern void ide_end_drive_cmd(ide_drive_t *, u8, u8); 1161void ide_complete_task(ide_drive_t *, ide_task_t *, u8, u8);
1162void ide_complete_rq(ide_drive_t *, u8);
1162 1163
1163void ide_tf_dump(const char *, struct ide_taskfile *); 1164void ide_tf_dump(const char *, struct ide_taskfile *);
1164 1165