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.c68
1 files changed, 47 insertions, 21 deletions
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index 48c38b68bd36..e053e00a7058 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -297,6 +297,48 @@ static void ide_complete_pm_request (ide_drive_t *drive, struct request *rq)
297 spin_unlock_irqrestore(&ide_lock, flags); 297 spin_unlock_irqrestore(&ide_lock, flags);
298} 298}
299 299
300void ide_tf_read(ide_drive_t *drive, ide_task_t *task)
301{
302 ide_hwif_t *hwif = drive->hwif;
303 struct ide_taskfile *tf = &task->tf;
304
305 if (task->tf_flags & IDE_TFLAG_IN_DATA) {
306 u16 data = hwif->INW(IDE_DATA_REG);
307
308 tf->data = data & 0xff;
309 tf->hob_data = (data >> 8) & 0xff;
310 }
311
312 /* be sure we're looking at the low order bits */
313 hwif->OUTB(drive->ctl & ~0x80, IDE_CONTROL_REG);
314
315 if (task->tf_flags & IDE_TFLAG_IN_NSECT)
316 tf->nsect = hwif->INB(IDE_NSECTOR_REG);
317 if (task->tf_flags & IDE_TFLAG_IN_LBAL)
318 tf->lbal = hwif->INB(IDE_SECTOR_REG);
319 if (task->tf_flags & IDE_TFLAG_IN_LBAM)
320 tf->lbam = hwif->INB(IDE_LCYL_REG);
321 if (task->tf_flags & IDE_TFLAG_IN_LBAH)
322 tf->lbah = hwif->INB(IDE_HCYL_REG);
323 if (task->tf_flags & IDE_TFLAG_IN_DEVICE)
324 tf->device = hwif->INB(IDE_SELECT_REG);
325
326 if (task->tf_flags & IDE_TFLAG_LBA48) {
327 hwif->OUTB(drive->ctl | 0x80, IDE_CONTROL_REG);
328
329 if (task->tf_flags & IDE_TFLAG_IN_HOB_FEATURE)
330 tf->hob_feature = hwif->INB(IDE_FEATURE_REG);
331 if (task->tf_flags & IDE_TFLAG_IN_HOB_NSECT)
332 tf->hob_nsect = hwif->INB(IDE_NSECTOR_REG);
333 if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAL)
334 tf->hob_lbal = hwif->INB(IDE_SECTOR_REG);
335 if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAM)
336 tf->hob_lbam = hwif->INB(IDE_LCYL_REG);
337 if (task->tf_flags & IDE_TFLAG_IN_HOB_LBAH)
338 tf->hob_lbah = hwif->INB(IDE_HCYL_REG);
339 }
340}
341
300/** 342/**
301 * ide_end_drive_cmd - end an explicit drive command 343 * ide_end_drive_cmd - end an explicit drive command
302 * @drive: command 344 * @drive: command
@@ -339,30 +381,14 @@ void ide_end_drive_cmd (ide_drive_t *drive, u8 stat, u8 err)
339 if (args) { 381 if (args) {
340 struct ide_taskfile *tf = &args->tf; 382 struct ide_taskfile *tf = &args->tf;
341 383
342 if (args->tf_flags & IDE_TFLAG_IN_DATA) {
343 u16 data = hwif->INW(IDE_DATA_REG);
344
345 tf->data = data & 0xff;
346 tf->hob_data = (data >> 8) & 0xff;
347 }
348 tf->error = err; 384 tf->error = err;
349 /* be sure we're looking at the low order bits */
350 hwif->OUTB(drive->ctl & ~0x80, IDE_CONTROL_REG);
351 tf->nsect = hwif->INB(IDE_NSECTOR_REG);
352 tf->lbal = hwif->INB(IDE_SECTOR_REG);
353 tf->lbam = hwif->INB(IDE_LCYL_REG);
354 tf->lbah = hwif->INB(IDE_HCYL_REG);
355 tf->device = hwif->INB(IDE_SELECT_REG);
356 tf->status = stat; 385 tf->status = stat;
357 386
358 if (args->tf_flags & IDE_TFLAG_LBA48) { 387 args->tf_flags |= (IDE_TFLAG_IN_TF|IDE_TFLAG_IN_DEVICE);
359 hwif->OUTB(drive->ctl|0x80, IDE_CONTROL_REG); 388 if (args->tf_flags & IDE_TFLAG_LBA48)
360 tf->hob_feature = hwif->INB(IDE_FEATURE_REG); 389 args->tf_flags |= IDE_TFLAG_IN_HOB;
361 tf->hob_nsect = hwif->INB(IDE_NSECTOR_REG); 390
362 tf->hob_lbal = hwif->INB(IDE_SECTOR_REG); 391 ide_tf_read(drive, args);
363 tf->hob_lbam = hwif->INB(IDE_LCYL_REG);
364 tf->hob_lbah = hwif->INB(IDE_HCYL_REG);
365 }
366 } 392 }
367 } else if (blk_pm_request(rq)) { 393 } else if (blk_pm_request(rq)) {
368 struct request_pm_state *pm = rq->data; 394 struct request_pm_state *pm = rq->data;