diff options
Diffstat (limited to 'drivers/ide/ide-io.c')
-rw-r--r-- | drivers/ide/ide-io.c | 68 |
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 | ||
300 | void 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; |