Commit 9f45cbd3f0fc597530aaf85cad7fe52cd63f1fd8

Authored by Kristen Carlson Accardi
Committed by Jeff Garzik
1 parent 05d1efffdc

[libata] check for SATA async notify support

Check to see if an ATAPI device supports Asynchronous Notification.
If so, enable it, if the host controller supports AN.

Signed-off-by: Kristen Carlson Accardi <kristen.c.accardi@intel.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>

Showing 3 changed files with 64 additions and 0 deletions Side-by-side Diff

drivers/ata/libata-core.c
... ... @@ -70,6 +70,7 @@
70 70 static unsigned int ata_dev_init_params(struct ata_device *dev,
71 71 u16 heads, u16 sectors);
72 72 static unsigned int ata_dev_set_xfermode(struct ata_device *dev);
  73 +static unsigned int ata_dev_set_AN(struct ata_device *dev, u8 enable);
73 74 static void ata_dev_xfermask(struct ata_device *dev);
74 75 static unsigned long ata_dev_blacklisted(const struct ata_device *dev);
75 76  
... ... @@ -1987,6 +1988,22 @@
1987 1988 }
1988 1989 dev->cdb_len = (unsigned int) rc;
1989 1990  
  1991 + /*
  1992 + * check to see if this ATAPI device supports
  1993 + * Asynchronous Notification
  1994 + */
  1995 + if ((ap->flags & ATA_FLAG_AN) && ata_id_has_AN(id)) {
  1996 + int err;
  1997 + /* issue SET feature command to turn this on */
  1998 + err = ata_dev_set_AN(dev, SETFEATURES_SATA_ENABLE);
  1999 + if (err)
  2000 + ata_dev_printk(dev, KERN_ERR,
  2001 + "unable to set AN, err %x\n",
  2002 + err);
  2003 + else
  2004 + dev->flags |= ATA_DFLAG_AN;
  2005 + }
  2006 +
1990 2007 if (ata_id_cdb_intr(dev->id)) {
1991 2008 dev->flags |= ATA_DFLAG_CDB_INTR;
1992 2009 cdb_intr_string = ", CDB intr";
... ... @@ -3967,6 +3984,42 @@
3967 3984 tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE | ATA_TFLAG_POLLING;
3968 3985 tf.protocol = ATA_PROT_NODATA;
3969 3986 tf.nsect = dev->xfer_mode;
  3987 +
  3988 + err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
  3989 +
  3990 + DPRINTK("EXIT, err_mask=%x\n", err_mask);
  3991 + return err_mask;
  3992 +}
  3993 +
  3994 +/**
  3995 + * ata_dev_set_AN - Issue SET FEATURES - SATA FEATURES
  3996 + * @dev: Device to which command will be sent
  3997 + * @enable: Whether to enable or disable the feature
  3998 + *
  3999 + * Issue SET FEATURES - SATA FEATURES command to device @dev
  4000 + * on port @ap with sector count set to indicate Asynchronous
  4001 + * Notification feature
  4002 + *
  4003 + * LOCKING:
  4004 + * PCI/etc. bus probe sem.
  4005 + *
  4006 + * RETURNS:
  4007 + * 0 on success, AC_ERR_* mask otherwise.
  4008 + */
  4009 +static unsigned int ata_dev_set_AN(struct ata_device *dev, u8 enable)
  4010 +{
  4011 + struct ata_taskfile tf;
  4012 + unsigned int err_mask;
  4013 +
  4014 + /* set up set-features taskfile */
  4015 + DPRINTK("set features - SATA features\n");
  4016 +
  4017 + ata_tf_init(dev, &tf);
  4018 + tf.command = ATA_CMD_SET_FEATURES;
  4019 + tf.feature = enable;
  4020 + tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
  4021 + tf.protocol = ATA_PROT_NODATA;
  4022 + tf.nsect = SATA_AN;
3970 4023  
3971 4024 err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
3972 4025  
... ... @@ -230,6 +230,12 @@
230 230  
231 231 SETFEATURES_SPINUP = 0x07, /* Spin-up drive */
232 232  
  233 + SETFEATURES_SATA_ENABLE = 0x10, /* Enable use of SATA feature */
  234 + SETFEATURES_SATA_DISABLE = 0x90, /* Disable use of SATA feature */
  235 +
  236 + /* SETFEATURE Sector counts for SATA features */
  237 + SATA_AN = 0x05, /* Asynchronous Notification */
  238 +
233 239 /* ATAPI stuff */
234 240 ATAPI_PKT_DMA = (1 << 0),
235 241 ATAPI_DMADIR = (1 << 2), /* ATAPI data dir:
... ... @@ -357,6 +363,9 @@
357 363 #define ata_id_queue_depth(id) (((id)[75] & 0x1f) + 1)
358 364 #define ata_id_removeable(id) ((id)[0] & (1 << 7))
359 365 #define ata_id_has_dword_io(id) ((id)[50] & (1 << 0))
  366 +#define ata_id_has_AN(id) \
  367 + ( (((id)[76] != 0x0000) && ((id)[76] != 0xffff)) && \
  368 + ((id)[78] & (1 << 5)) )
360 369 #define ata_id_iordy_disable(id) ((id)[49] & (1 << 10))
361 370 #define ata_id_has_iordy(id) ((id)[49] & (1 << 11))
362 371 #define ata_id_u32(id,n) \
include/linux/libata.h
... ... @@ -139,6 +139,7 @@
139 139 ATA_DFLAG_FLUSH_EXT = (1 << 4), /* do FLUSH_EXT instead of FLUSH */
140 140 ATA_DFLAG_ACPI_PENDING = (1 << 5), /* ACPI resume action pending */
141 141 ATA_DFLAG_ACPI_FAILED = (1 << 6), /* ACPI on devcfg has failed */
  142 + ATA_DFLAG_AN = (1 << 7), /* device supports AN */
142 143 ATA_DFLAG_CFG_MASK = (1 << 8) - 1,
143 144  
144 145 ATA_DFLAG_PIO = (1 << 8), /* device limited to PIO mode */
... ... @@ -179,6 +180,7 @@
179 180 ATA_FLAG_IGN_SIMPLEX = (1 << 15), /* ignore SIMPLEX */
180 181 ATA_FLAG_NO_IORDY = (1 << 16), /* controller lacks iordy */
181 182 ATA_FLAG_ACPI_SATA = (1 << 17), /* need native SATA ACPI layout */
  183 + ATA_FLAG_AN = (1 << 18), /* controller supports AN */
182 184  
183 185 /* The following flag belongs to ap->pflags but is kept in
184 186 * ap->flags because it's referenced in many LLDs and will be