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

Commit 59a10b17 authored by Albert Lee's avatar Albert Lee Committed by Jeff Garzik
Browse files

[PATCH] libata CHS: reread device identify info (revise #6)



problem:
      id[53-58] might be changed after initializing device CHS settings.

changes:
    - call ata_dev_reread_id() to reread the identify device info,
      after initializing device CHS settings.

Signed-off-by: default avatarAlbert Lee <albertcc@tw.ibm.com>

============
Signed-off-by: default avatarJeff Garzik <jgarzik@pobox.com>
parent 8cbd6df1
Loading
Loading
Loading
Loading
+64 −1
Original line number Diff line number Diff line
@@ -63,6 +63,7 @@
static unsigned int ata_busy_sleep (struct ata_port *ap,
				    unsigned long tmout_pat,
			    	    unsigned long tmout);
static void ata_dev_reread_id(struct ata_port *ap, struct ata_device *dev);
static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev);
static void ata_set_mode(struct ata_port *ap);
static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev);
@@ -1240,9 +1241,15 @@ static void ata_dev_identify(struct ata_port *ap, unsigned int device)
		 * anything else..
		 * Some drives were very specific about that exact sequence.
		 */
		if (major_version < 4 || (!ata_id_has_lba(dev->id)))
		if (major_version < 4 || (!ata_id_has_lba(dev->id))) {
			ata_dev_init_params(ap, dev);

			/* current CHS translation info (id[53-58]) might be
			 * changed. reread the identify device info.
			 */
			ata_dev_reread_id(ap, dev);
		}

		if (ata_id_has_lba(dev->id)) {
			dev->flags |= ATA_DFLAG_LBA;

@@ -2150,6 +2157,62 @@ static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev)
	DPRINTK("EXIT\n");
}

/**
 *	ata_dev_reread_id - Reread the device identify device info
 *	@ap: port where the device is
 *	@dev: device to reread the identify device info
 *
 *	LOCKING:
 */

static void ata_dev_reread_id(struct ata_port *ap, struct ata_device *dev)
{
	DECLARE_COMPLETION(wait);
	struct ata_queued_cmd *qc;
	unsigned long flags;
	int rc;

	qc = ata_qc_new_init(ap, dev);
	BUG_ON(qc == NULL);

	ata_sg_init_one(qc, dev->id, sizeof(dev->id));
	qc->dma_dir = DMA_FROM_DEVICE;

	if (dev->class == ATA_DEV_ATA) {
		qc->tf.command = ATA_CMD_ID_ATA;
		DPRINTK("do ATA identify\n");
	} else {
		qc->tf.command = ATA_CMD_ID_ATAPI;
		DPRINTK("do ATAPI identify\n");
	}

	qc->tf.flags |= ATA_TFLAG_DEVICE;
	qc->tf.protocol = ATA_PROT_PIO;
	qc->nsect = 1;

	qc->waiting = &wait;
	qc->complete_fn = ata_qc_complete_noop;

	spin_lock_irqsave(&ap->host_set->lock, flags);
	rc = ata_qc_issue(qc);
	spin_unlock_irqrestore(&ap->host_set->lock, flags);

	if (rc)
		goto err_out;

	wait_for_completion(&wait);

	swap_buf_le16(dev->id, ATA_ID_WORDS);

	ata_dump_id(dev);

	DPRINTK("EXIT\n");

	return;
err_out:
	ata_port_disable(ap);
}

/**
 *	ata_dev_init_params - Issue INIT DEV PARAMS command
 *	@ap: Port associated with device @dev