diff options
author | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-10-13 15:39:38 -0400 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2008-10-13 15:39:38 -0400 |
commit | d1d76714e2f0c520b6c2a84ab5b050d0b3244949 (patch) | |
tree | 605b10d60a0bcc59441ebe87503c03016df08dd1 | |
parent | c67c216d810a05fffdbdbdf1b81048f0d4759287 (diff) |
ide: fix HDIO_DRIVE_TASK[FILE] ioctls for CHS commands on LBA devices
Add IDE_DFLAG_LBA device flag and use it instead of ->select.b.lba.
Since ->tf_load uses ->select.all for ATA Device/Head register this
fixes HDIO_DRIVE_TASK[FILE] ioctls for CHS commands on LBA devices.
Signed-off-by: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
-rw-r--r-- | drivers/ide/ide-disk.c | 33 | ||||
-rw-r--r-- | drivers/ide/ide-io.c | 4 | ||||
-rw-r--r-- | include/linux/ide.h | 1 |
3 files changed, 23 insertions, 15 deletions
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index c35de54dfc22..6eb9fea32a56 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c | |||
@@ -162,7 +162,7 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, | |||
162 | memset(&task, 0, sizeof(task)); | 162 | memset(&task, 0, sizeof(task)); |
163 | task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; | 163 | task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE; |
164 | 164 | ||
165 | if (drive->select.b.lba) { | 165 | if (drive->dev_flags & IDE_DFLAG_LBA) { |
166 | if (lba48) { | 166 | if (lba48) { |
167 | pr_debug("%s: LBA=0x%012llx\n", drive->name, | 167 | pr_debug("%s: LBA=0x%012llx\n", drive->name, |
168 | (unsigned long long)block); | 168 | (unsigned long long)block); |
@@ -187,6 +187,8 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq, | |||
187 | tf->lbah = block >>= 8; | 187 | tf->lbah = block >>= 8; |
188 | tf->device = (block >> 8) & 0xf; | 188 | tf->device = (block >> 8) & 0xf; |
189 | } | 189 | } |
190 | |||
191 | tf->device |= ATA_LBA; | ||
190 | } else { | 192 | } else { |
191 | unsigned int sect, head, cyl, track; | 193 | unsigned int sect, head, cyl, track; |
192 | 194 | ||
@@ -384,28 +386,32 @@ static void idedisk_check_hpa(ide_drive_t *drive) | |||
384 | static void init_idedisk_capacity(ide_drive_t *drive) | 386 | static void init_idedisk_capacity(ide_drive_t *drive) |
385 | { | 387 | { |
386 | u16 *id = drive->id; | 388 | u16 *id = drive->id; |
387 | /* | 389 | int lba; |
388 | * If this drive supports the Host Protected Area feature set, | ||
389 | * then we may need to change our opinion about the drive's capacity. | ||
390 | */ | ||
391 | int hpa = ata_id_hpa_enabled(id); | ||
392 | 390 | ||
393 | if (ata_id_lba48_enabled(id)) { | 391 | if (ata_id_lba48_enabled(id)) { |
394 | /* drive speaks 48-bit LBA */ | 392 | /* drive speaks 48-bit LBA */ |
395 | drive->select.b.lba = 1; | 393 | lba = 1; |
396 | drive->capacity64 = ata_id_u64(id, ATA_ID_LBA_CAPACITY_2); | 394 | drive->capacity64 = ata_id_u64(id, ATA_ID_LBA_CAPACITY_2); |
397 | if (hpa) | ||
398 | idedisk_check_hpa(drive); | ||
399 | } else if (ata_id_has_lba(id) && ata_id_is_lba_capacity_ok(id)) { | 395 | } else if (ata_id_has_lba(id) && ata_id_is_lba_capacity_ok(id)) { |
400 | /* drive speaks 28-bit LBA */ | 396 | /* drive speaks 28-bit LBA */ |
401 | drive->select.b.lba = 1; | 397 | lba = 1; |
402 | drive->capacity64 = ata_id_u32(id, ATA_ID_LBA_CAPACITY); | 398 | drive->capacity64 = ata_id_u32(id, ATA_ID_LBA_CAPACITY); |
403 | if (hpa) | ||
404 | idedisk_check_hpa(drive); | ||
405 | } else { | 399 | } else { |
406 | /* drive speaks boring old 28-bit CHS */ | 400 | /* drive speaks boring old 28-bit CHS */ |
401 | lba = 0; | ||
407 | drive->capacity64 = drive->cyl * drive->head * drive->sect; | 402 | drive->capacity64 = drive->cyl * drive->head * drive->sect; |
408 | } | 403 | } |
404 | |||
405 | if (lba) { | ||
406 | drive->dev_flags |= IDE_DFLAG_LBA; | ||
407 | |||
408 | /* | ||
409 | * If this device supports the Host Protected Area feature set, | ||
410 | * then we may need to change our opinion about its capacity. | ||
411 | */ | ||
412 | if (ata_id_hpa_enabled(id)) | ||
413 | idedisk_check_hpa(drive); | ||
414 | } | ||
409 | } | 415 | } |
410 | 416 | ||
411 | static sector_t idedisk_capacity(ide_drive_t *drive) | 417 | static sector_t idedisk_capacity(ide_drive_t *drive) |
@@ -1110,7 +1116,8 @@ static int ide_disk_probe(ide_drive_t *drive) | |||
1110 | drive->driver_data = idkp; | 1116 | drive->driver_data = idkp; |
1111 | 1117 | ||
1112 | idedisk_setup(drive); | 1118 | idedisk_setup(drive); |
1113 | if ((!drive->head || drive->head > 16) && !drive->select.b.lba) { | 1119 | if ((drive->dev_flags & IDE_DFLAG_LBA) == 0 && |
1120 | (drive->head == 0 || drive->head > 16)) { | ||
1114 | printk(KERN_ERR "%s: INVALID GEOMETRY: %d PHYSICAL HEADS?\n", | 1121 | printk(KERN_ERR "%s: INVALID GEOMETRY: %d PHYSICAL HEADS?\n", |
1115 | drive->name, drive->head); | 1122 | drive->name, drive->head); |
1116 | drive->dev_flags &= ~IDE_DFLAG_ATTACH; | 1123 | drive->dev_flags &= ~IDE_DFLAG_ATTACH; |
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 11b602bb5741..623f6c246cf5 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c | |||
@@ -383,7 +383,7 @@ static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8 | |||
383 | } else if (stat & ATA_ERR) { | 383 | } else if (stat & ATA_ERR) { |
384 | /* err has different meaning on cdrom and tape */ | 384 | /* err has different meaning on cdrom and tape */ |
385 | if (err == ATA_ABORTED) { | 385 | if (err == ATA_ABORTED) { |
386 | if (drive->select.b.lba && | 386 | if ((drive->dev_flags & IDE_DFLAG_LBA) && |
387 | /* some newer drives don't support ATA_CMD_INIT_DEV_PARAMS */ | 387 | /* some newer drives don't support ATA_CMD_INIT_DEV_PARAMS */ |
388 | hwif->tp_ops->read_status(hwif) == ATA_CMD_INIT_DEV_PARAMS) | 388 | hwif->tp_ops->read_status(hwif) == ATA_CMD_INIT_DEV_PARAMS) |
389 | return ide_stopped; | 389 | return ide_stopped; |
@@ -513,7 +513,7 @@ static void ide_tf_set_specify_cmd(ide_drive_t *drive, struct ide_taskfile *tf) | |||
513 | tf->lbal = drive->sect; | 513 | tf->lbal = drive->sect; |
514 | tf->lbam = drive->cyl; | 514 | tf->lbam = drive->cyl; |
515 | tf->lbah = drive->cyl >> 8; | 515 | tf->lbah = drive->cyl >> 8; |
516 | tf->device = ((drive->head - 1) | drive->select.all) & ~ATA_LBA; | 516 | tf->device = (drive->head - 1) | drive->select.all; |
517 | tf->command = ATA_CMD_INIT_DEV_PARAMS; | 517 | tf->command = ATA_CMD_INIT_DEV_PARAMS; |
518 | } | 518 | } |
519 | 519 | ||
diff --git a/include/linux/ide.h b/include/linux/ide.h index fdec0108dba1..cf7ec3a9d173 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h | |||
@@ -502,6 +502,7 @@ enum { | |||
502 | IDE_DFLAG_NOWERR = (1 << 24), | 502 | IDE_DFLAG_NOWERR = (1 << 24), |
503 | /* retrying in PIO */ | 503 | /* retrying in PIO */ |
504 | IDE_DFLAG_DMA_PIO_RETRY = (1 << 25), | 504 | IDE_DFLAG_DMA_PIO_RETRY = (1 << 25), |
505 | IDE_DFLAG_LBA = (1 << 26), | ||
505 | }; | 506 | }; |
506 | 507 | ||
507 | struct ide_drive_s { | 508 | struct ide_drive_s { |