Thread (28 messages) 28 messages, 5 authors, 2005-02-25

Re: [PATCH libata-dev-2.6] Issue INITIALIZE DEVICE PARAMETERS for CHS only devices

From: Albert Lee <hidden>
Date: 2005-02-24 06:42:05

Jeff Garzik wrote:
Thanks.  Please use the logic Mark described:
quoted
if (ATA < 4 || !lba_capable)
    issue IDP command
else
    no need for IDP command 
Thanks for the detailed instruction.
Attached please find the revised patch for your review.

Albert

Signed-off-by: Albert Lee <redacted>
=============================================================================================
--- libata-dev-2.6/include/linux/ata.h	2005-02-21 17:23:19.000000000 +0800
+++ libata-dev-2.6-mod/include/linux/ata.h	2005-02-23 17:28:42.000000000 +0800
@@ -125,6 +125,7 @@
  	ATA_CMD_PACKET		= 0xA0,
  	ATA_CMD_VERIFY		= 0x40,
  	ATA_CMD_VERIFY_EXT	= 0x42,
+	ATA_CMD_INIT_DEV_PARAMS	= 0x91,

  	/* SETFEATURES stuff */
  	SETFEATURES_XFER	= 0x03,
--- libata-dev-2.6/drivers/scsi/libata-core.c	2005-02-21 17:23:03.000000000 +0800
+++ libata-dev-2.6-mod/drivers/scsi/libata-core.c	2005-02-24 14:35:55.000000000 +0800
@@ -52,6 +52,7 @@
  static unsigned int ata_busy_sleep (struct ata_port *ap,
  				    unsigned long tmout_pat,
  			    	    unsigned long tmout);
+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);
  static unsigned int ata_get_mode_mask(struct ata_port *ap, int shift);
@@ -1053,11 +1054,16 @@
  			if (tmp & (1 << major_version))
  				break;

-		/* we require at least ATA-3 */
-		if (major_version < 3) {
-			printk(KERN_DEBUG "ata%u: no ATA-3\n", ap->id);
-			goto err_out_nosup;
-		}
+		/*
+		 * The exact sequence expected by certain pre-ATA4 drives is:
+		 * SRST RESET
+		 * IDENTIFY
+		 * INITIALIZE DEVICE PARAMETERS
+		 * anything else..
+		 * Some drives were very specific about that exact sequence.
+		 */
+		if (major_version < 4 || (!ata_id_has_lba(dev->id)))
+			ata_dev_init_params(ap, dev);

  		if (ata_id_has_lba(dev->id)) {
  			dev->flags |= ATA_DFLAG_LBA;
@@ -1893,6 +1899,54 @@
  }

  /**
+ *	ata_dev_init_params - Issue INIT DEV PARAMS command
+ *	@ap: Port associated with device @dev
+ *	@dev: Device to which command will be sent
+ *
+ *	LOCKING:
+ */
+
+static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev)
+{
+	DECLARE_COMPLETION(wait);
+	struct ata_queued_cmd *qc;
+	int rc;
+	unsigned long flags;
+	u16 sectors = dev->id[6];
+	u16 heads   = dev->id[3];
+
+	/* Number of sectors per track 1-255. Number of heads 1-16 */
+	if (sectors < 1 || sectors > 255 || heads < 1 || heads > 16)
+		return;
+
+	/* set up init dev params taskfile */
+	DPRINTK("init dev params \n");
+
+	qc = ata_qc_new_init(ap, dev);
+	BUG_ON(qc == NULL);
+
+	qc->tf.command = ATA_CMD_INIT_DEV_PARAMS;
+	qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
+	qc->tf.protocol = ATA_PROT_NODATA;
+	qc->tf.nsect = sectors;
+	qc->tf.device |= (heads - 1) & 0x0f; /* max head = number of heads - 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)
+		ata_port_disable(ap);
+	else
+		wait_for_completion(&wait);
+
+	DPRINTK("EXIT\n");
+}
+
+/**
   *	ata_sg_clean -
   *	@qc:
   *
--- libata-dev-2.6/drivers/scsi/libata-scsi.c	2005-02-21 17:23:03.000000000 +0800
+++ libata-dev-2.6-mod/drivers/scsi/libata-scsi.c	2005-02-22 18:32:19.000000000 +0800
@@ -785,6 +785,7 @@
  		if ((cyl >> 16) || (head >> 4) || (sect >> 8) || (!sect))
  			return 1;
  		
+		tf->command = ATA_CMD_VERIFY;
  		tf->nsect = n_block & 0xff; /* Sector count 0 means 256 sectors */
  		tf->lbal = sect;
  		tf->lbam = cyl;
@@ -875,7 +876,7 @@

  	/* Check and compose ATA command */
  	if (!n_block)
-		/* In ATA, sector count 0 are 256 or 65536 sectors, not 0 sectors. */
+		/* In ATA, sector count 0 means 256 or 65536 sectors, not 0 sectors. */
  		return 1;

  	if (lba) {


Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help