Re: HPA patches

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, 23 Mar 2007 19:13:21 +0000 Alan Cox wrote:

> For reference this is what I am currently using with 2.6.21-rc4-mm1 and
> it is working for all my test cases so far: Its basically Kyle's patch
> with a libata switch to turn it on/off and some minor fixups from
> the original patch as posted
> 
> diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla-2.6.21-rc4-mm1/drivers/ata/libata-core.c linux-2.6.21-rc4-mm1/drivers/ata/libata-core.c
> --- linux.vanilla-2.6.21-rc4-mm1/drivers/ata/libata-core.c	2007-03-23 11:49:49.000000000 +0000
> +++ linux-2.6.21-rc4-mm1/drivers/ata/libata-core.c	2007-03-23 13:05:15.000000000 +0000
> @@ -89,6 +89,10 @@
>  module_param_named(fua, libata_fua, int, 0444);
>  MODULE_PARM_DESC(fua, "FUA support (0=off, 1=on)");
>  
> +static int ata_ignore_hpa = 0;

Don't init to 0.  Not needed, bloats binary files.

> +module_param_named(ignore_hpa, ata_ignore_hpa, int, 0644);
> +MODULE_PARM_DESC(ignore_hpa, "Ignore HPA (0=off 1=on)");

So 1 = on = ignore, right?

> +
>  static int ata_probe_timeout = ATA_TMOUT_INTERNAL / HZ;
>  module_param(ata_probe_timeout, int, 0444);
>  MODULE_PARM_DESC(ata_probe_timeout, "Set ATA probing timeout (seconds)");
> @@ -808,6 +812,202 @@
>  	*p = '\0';
>  }
>  
> +
> +/**
> + *	ata_read_native_max_address_ext	-	LBA48 native max query
> + *	@dev: Device to query
> + *
> + *	Performa an LBA48 size query upon the device in question. Return the

	Perform

> + *	actual LBA48 size or zero if the command fails.
> + */
> +
> +static u64 ata_read_native_max_address_ext(struct ata_device *dev)
> +{
> +	unsigned int err;
> +	struct ata_taskfile tf;
> +
> +	ata_tf_init(dev, &tf);
> +
> +	tf.command = ATA_CMD_READ_NATIVE_MAX_EXT;
> +	tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48 | ATA_TFLAG_ISADDR;
> +	tf.protocol |= ATA_PROT_NODATA;
> +	tf.device = 0x40;

What is 0x40?  can it be #defined (or enum-ed) instead of a magic
value?  please?  (more of same below)

> +
> +	err = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
> +	if (err)
> +		return 0;
> +
> +	return ata_tf_to_lba48(&tf);
> +}
> +
> +/**
> + *	ata_read_native_max_address	-	LBA28 native max query
> + *	@dev: Device to query
> + *
> + *	Performa an LBA28 size query upon the device in question. Return the

	Perform

> + *	actual LBA28 size or zero if the command fails.
> + */
> +
> +static u64 ata_read_native_max_address(struct ata_device *dev)
> +{
> +	unsigned int err;
> +	struct ata_taskfile tf;
> +
> +	ata_tf_init(dev, &tf);
> +
> +	tf.command = ATA_CMD_READ_NATIVE_MAX;
> +	tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;
> +	tf.protocol |= ATA_PROT_NODATA;
> +	tf.device = 0x40;
> +
> +	err = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
> +	if (err)
> +		return 0;
> +
> +	return ata_tf_to_lba(&tf);
> +}
> +
> +/**
> + *	ata_set_native_max_address_ext	-	LBA48 native max set
> + *	@dev: Device to query
> + *
> + *	Perform an LBA48 size set max upon the device in question. Return the
> + *	actual LBA48 size or zero if the command fails.
> + */
> +
> +static u64 ata_set_native_max_address_ext(struct ata_device *dev, u64 new_sectors)
> +{
...
> +}
> +
> +/**
> + *	ata_set_native_max_address	-	LBA28 native max set
> + *	@dev: Device to query
> + *
> + *	Perform an LBA28 size set max upon the device in question. Return the
> + *	actual LBA28 size or zero if the command fails.
> + */
> +
> +static u64 ata_set_native_max_address(struct ata_device *dev, u64 new_sectors)
> +{
...
> +}
> +
> +/**
> + *	ata_hpa_resize		-	Resize a device with an HPA set
> + *	@dev: Device to resize
> + *
> + *	Read the size of an LBA28 or LBA48 disk with HPA features and resize
> + *	it if required to the full size of the media. The caller must check
> + *	the drive has the HPA feature set enabled.
> + */
> +
> +static u64 ata_hpa_resize(struct ata_device *dev)
> +{
> +	u64 sectors = dev->n_sectors;
> +	u64 hpa_sectors;
> +	
> +	if (ata_id_has_lba48(dev->id))
> +		hpa_sectors = ata_read_native_max_address_ext(dev);
> +	else
> +		hpa_sectors = ata_read_native_max_address(dev);
> +
> +	/* if no hpa, both should be equal */
> +	ata_dev_printk(dev, KERN_INFO, "%s 1: sectors = %lld, hpa_sectors = %lld\n",
> +		__FUNCTION__, sectors, hpa_sectors);

(long long) or (unsigned long long) on sectors and hpa_sectors...

> +
> +	if (hpa_sectors > sectors) {
> +		ata_dev_printk(dev, KERN_INFO,
> +			"Host Protected Area detected:\n"
> +			"\tcurrent size: %lld sectors\n"
> +			"\tnative size: %lld sectors\n",
> +			sectors, hpa_sectors);

printk format types ok?

> +
> +		if (ata_ignore_hpa) {
> +			if (ata_id_has_lba48(dev->id))
> +				hpa_sectors = ata_set_native_max_address_ext(dev, hpa_sectors);
> +			else
> +				hpa_sectors = ata_set_native_max_address(dev, hpa_sectors);
> +
> +			if (hpa_sectors) {
> +				ata_dev_printk(dev, KERN_INFO,
> +					"native size increased to %lld sectors\n", hpa_sectors);

Line lengths < 80 and printk format types?

> +				return hpa_sectors;
> +			}
> +		}
> +	}
> +	return sectors;
> +}
> +
>  static u64 ata_id_n_sectors(const u16 *id)
>  {
>  	if (ata_id_has_lba(id)) {
> @@ -1658,6 +1858,7 @@
>  			snprintf(revbuf, 7, "ATA-%d",  ata_id_major_version(id));
>  
>  		dev->n_sectors = ata_id_n_sectors(id);
> +		dev->n_sectors_boot = dev->n_sectors;
>  
>  		/* SCSI only uses 4-char revisions, dump full 8 chars from ATA */
>  		ata_id_c_string(dev->id, fwrevbuf, ATA_ID_FW_REV,
> @@ -1684,6 +1885,9 @@
>  					dev->flags |= ATA_DFLAG_FLUSH_EXT;
>  			}
>  
> +			if (ata_id_hpa_enabled(dev->id))
> +				dev->n_sectors = ata_hpa_resize(dev);
> +
>  			/* config NCQ */
>  			ata_dev_config_ncq(dev, ncq_desc, sizeof(ncq_desc));
>  
> @@ -3384,6 +3595,11 @@
>  			       "%llu != %llu\n",
>  			       (unsigned long long)dev->n_sectors,
>  			       (unsigned long long)new_n_sectors);
> +		/* Are we the boot time size - if so we appear to be the
> +		   same disk at this point and our HPA got reapplied */
> +		if (ata_ignore_hpa && dev->n_sectors_boot == new_n_sectors 
> +		    && ata_id_hpa_enabled(new_id))
> +			return 1;
>  		return 0;
>  	}


---
~Randy
*** Remember to use Documentation/SubmitChecklist when testing your code ***
-
To unsubscribe from this list: send the line "unsubscribe linux-ide" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Filesystems]     [Linux SCSI]     [Linux RAID]     [Git]     [Kernel Newbies]     [Linux Newbie]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Samba]     [Device Mapper]

  Powered by Linux