aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide
diff options
context:
space:
mode:
authorBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2008-10-13 15:39:38 -0400
committerBartlomiej Zolnierkiewicz <bzolnier@gmail.com>2008-10-13 15:39:38 -0400
commitd1d76714e2f0c520b6c2a84ab5b050d0b3244949 (patch)
tree605b10d60a0bcc59441ebe87503c03016df08dd1 /drivers/ide
parentc67c216d810a05fffdbdbdf1b81048f0d4759287 (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>
Diffstat (limited to 'drivers/ide')
-rw-r--r--drivers/ide/ide-disk.c33
-rw-r--r--drivers/ide/ide-io.c4
2 files changed, 22 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)
384static void init_idedisk_capacity(ide_drive_t *drive) 386static 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
411static sector_t idedisk_capacity(ide_drive_t *drive) 417static 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