Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d1d76714 authored by Bartlomiej Zolnierkiewicz's avatar Bartlomiej Zolnierkiewicz
Browse files

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: default avatarBartlomiej Zolnierkiewicz <bzolnier@gmail.com>
parent c67c216d
Loading
Loading
Loading
Loading
+20 −13
Original line number Diff line number Diff line
@@ -162,7 +162,7 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
	memset(&task, 0, sizeof(task));
	task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;

	if (drive->select.b.lba) {
	if (drive->dev_flags & IDE_DFLAG_LBA) {
		if (lba48) {
			pr_debug("%s: LBA=0x%012llx\n", drive->name,
					(unsigned long long)block);
@@ -187,6 +187,8 @@ static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
			tf->lbah   = block >>= 8;
			tf->device = (block >> 8) & 0xf;
		}

		tf->device |= ATA_LBA;
	} else {
		unsigned int sect, head, cyl, track;

@@ -384,28 +386,32 @@ static void idedisk_check_hpa(ide_drive_t *drive)
static void init_idedisk_capacity(ide_drive_t *drive)
{
	u16 *id = drive->id;
	/*
	 * If this drive supports the Host Protected Area feature set,
	 * then we may need to change our opinion about the drive's capacity.
	 */
	int hpa = ata_id_hpa_enabled(id);
	int lba;

	if (ata_id_lba48_enabled(id)) {
		/* drive speaks 48-bit LBA */
		drive->select.b.lba = 1;
		lba = 1;
		drive->capacity64 = ata_id_u64(id, ATA_ID_LBA_CAPACITY_2);
		if (hpa)
			idedisk_check_hpa(drive);
	} else if (ata_id_has_lba(id) && ata_id_is_lba_capacity_ok(id)) {
		/* drive speaks 28-bit LBA */
		drive->select.b.lba = 1;
		lba = 1;
		drive->capacity64 = ata_id_u32(id, ATA_ID_LBA_CAPACITY);
		if (hpa)
			idedisk_check_hpa(drive);
	} else {
		/* drive speaks boring old 28-bit CHS */
		lba = 0;
		drive->capacity64 = drive->cyl * drive->head * drive->sect;
	}

	if (lba) {
		drive->dev_flags |= IDE_DFLAG_LBA;

		/*
		* If this device supports the Host Protected Area feature set,
		* then we may need to change our opinion about its capacity.
		*/
		if (ata_id_hpa_enabled(id))
			idedisk_check_hpa(drive);
	}
}

static sector_t idedisk_capacity(ide_drive_t *drive)
@@ -1110,7 +1116,8 @@ static int ide_disk_probe(ide_drive_t *drive)
	drive->driver_data = idkp;

	idedisk_setup(drive);
	if ((!drive->head || drive->head > 16) && !drive->select.b.lba) {
	if ((drive->dev_flags & IDE_DFLAG_LBA) == 0 &&
	    (drive->head == 0 || drive->head > 16)) {
		printk(KERN_ERR "%s: INVALID GEOMETRY: %d PHYSICAL HEADS?\n",
			drive->name, drive->head);
		drive->dev_flags &= ~IDE_DFLAG_ATTACH;
+2 −2
Original line number Diff line number Diff line
@@ -383,7 +383,7 @@ static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8
	} else if (stat & ATA_ERR) {
		/* err has different meaning on cdrom and tape */
		if (err == ATA_ABORTED) {
			if (drive->select.b.lba &&
			if ((drive->dev_flags & IDE_DFLAG_LBA) &&
			    /* some newer drives don't support ATA_CMD_INIT_DEV_PARAMS */
			    hwif->tp_ops->read_status(hwif) == ATA_CMD_INIT_DEV_PARAMS)
				return ide_stopped;
@@ -513,7 +513,7 @@ static void ide_tf_set_specify_cmd(ide_drive_t *drive, struct ide_taskfile *tf)
	tf->lbal    = drive->sect;
	tf->lbam    = drive->cyl;
	tf->lbah    = drive->cyl >> 8;
	tf->device  = ((drive->head - 1) | drive->select.all) & ~ATA_LBA;
	tf->device  = (drive->head - 1) | drive->select.all;
	tf->command = ATA_CMD_INIT_DEV_PARAMS;
}

+1 −0
Original line number Diff line number Diff line
@@ -502,6 +502,7 @@ enum {
	IDE_DFLAG_NOWERR		= (1 << 24),
	/* retrying in PIO */
	IDE_DFLAG_DMA_PIO_RETRY		= (1 << 25),
	IDE_DFLAG_LBA			= (1 << 26),
};

struct ide_drive_s {