Skip to contentSkip to conversation

ata: ahci: Enclosure Management via LED

PATCH In review Kristen Carlson Accardi 3 participants 6 messages Nov 29, 2007 – Dec 7, 2007 libata

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 ata: ahci: Enclosure Management via LED

This patch implements Enclosure Management via the LED protocol. See the AHCI 1.1 spec for details.

---
Here's a new version of the Enclosure management patch I sent a few weeks ago. I tried to incorporate all the feedback, although I'm still checking on whether it's ok to use these capability bits on a 1.0 ahci device. Please let me know if there are additional changes needed.

 drivers/ata/ahci.c        |  152 ++++++++++++++++++++++++++++++++++++++++++++-
 drivers/ata/libata-scsi.c |    5 +-
 include/linux/libata.h    |    2 +
 3 files changed, 155 insertions(+), 4 deletions(-)
drivers/ata/ahci.c +150 -2
index 2c686b4..5f22132 100644
@@ -44,6 +44,7 @@
 #include <linux/dmi.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
 #include <linux/libata.h>
 
 #define DRV_NAME	"ahci"
@@ -92,6 +93,8 @@ enum {
 	HOST_IRQ_STAT		= 0x08, /* interrupt status */
 	HOST_PORTS_IMPL		= 0x0c, /* bitmap of implemented ports */
 	HOST_VERSION		= 0x10, /* AHCI spec. version compliancy */
+	HOST_EM_LOC		= 0x1c, /* Enclosure Management location */
+	HOST_EM_CTL		= 0x20, /* Enclosure Management Control */
 
 	/* HOST_CTL bits */
 	HOST_RESET		= (1 << 0),  /* reset controller; self-clear */
@@ -99,6 +102,7 @@ enum {
 	HOST_AHCI_EN		= (1 << 31), /* AHCI enabled */
 
 	/* HOST_CAP bits */
+	HOST_CAP_EMS		= (1 << 6),  /* Enclosure Management support */
 	HOST_CAP_SSC		= (1 << 14), /* Slumber capable */
 	HOST_CAP_PMP		= (1 << 17), /* Port Multiplier support */
 	HOST_CAP_CLO		= (1 << 24), /* Command List Override support */
@@ -193,6 +197,10 @@ enum {
 					  ATA_FLAG_ACPI_SATA | ATA_FLAG_AN |
 					  ATA_FLAG_IPM,
 	AHCI_LFLAG_COMMON		= ATA_LFLAG_SKIP_D2H_BSY,
+
+	/* em_ctl bits */
+	EM_CTL_RST			= (1 << 9), /* Reset */
+	EM_CTL_TM			= (1 << 8), /* Transmit Message */
 };
 
 struct ahci_cmd_hdr {
@@ -216,6 +224,7 @@ struct ahci_host_priv {
 	u32			port_map;	/* port map to use */
 	u32			saved_cap;	/* saved initial cap */
 	u32			saved_port_map;	/* saved initial port_map */
+	u32 			em_loc; /* enclosure management location */
 };
 
 struct ahci_port_priv {
@@ -231,6 +240,7 @@ struct ahci_port_priv {
 	unsigned int		ncq_saw_dmas:1;
 	unsigned int		ncq_saw_sdb:1;
 	u32 			intr_mask;	/* interrupts to enable */
+	u16			led_state;	/* saved current led state */
 };
 
 static int ahci_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val);
@@ -572,6 +582,11 @@ static struct pci_driver ahci_pci_driver = {
 #endif
 };
 
+static int ahci_em_messages = 1;
+module_param(ahci_em_messages, int, 0444);
+/* add other LED protocol types when they become supported */
+MODULE_PARM_DESC(ahci_em_messages,
+	"Set AHCI Enclosure Management Message type (0 = disabled, 1 = LED");
 
 static inline int ahci_nr_ports(u32 cap)
 {
@@ -1082,6 +1097,116 @@ static int ahci_reset_controller(struct ata_host *host)
 	return 0;
 }
 
+/****** LED Enclosure Management routines ********/
+static int ahci_reset_em(struct ata_host *host)
+{
+	void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
+	u32 em_ctl;
+
+	em_ctl = readl(mmio + HOST_EM_CTL);
+	if ((em_ctl & EM_CTL_TM) || (em_ctl & EM_CTL_RST))
+		return -EINVAL;
+
+	writel(em_ctl | EM_CTL_RST, mmio + HOST_EM_CTL);
+	return 0;
+}
+
+static int ahci_transmit_led_message(struct ata_port *ap, int led_num,
+			int state)
+{
+	struct ahci_host_priv *hpriv = ap->host->private_data;
+	void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
+	struct ahci_port_priv *pp = ap->private_data;
+	u32 em_ctl;
+	u32 message[] = {0, 0};
+	unsigned int flags;
+
+	spin_lock_irqsave(ap->lock, flags);
+
+	/*
+	 * if we are still busy transmitting a previous message,
+	 * do not allow
+	 */
+	em_ctl = readl(mmio + HOST_EM_CTL);
+	if (em_ctl & EM_CTL_TM) {
+		spin_unlock_irqrestore(ap->lock, flags);
+		return -EINVAL;
+	}
+
+	/*
+	 * create message header - this is all zero except for
+	 * the message size, which is 4 bytes.
+	 */
+	message[0] |= (4 << 8);
+
+	pp->led_state &= ~(9 << (3*led_num));
+
+	/*
+	 * create the actual message
+	 * XXX will need Port Multiplier support
+	 */
+	message[1] = (ap->port_no | (pp->led_state << 16));
+
+	/* LED bit locations are determined by the led_num */
+	message[1] |= (state << (16 + (3*led_num)));
+
+	/* write message to EM_LOC */
+	writel(message[0], mmio + hpriv->em_loc);
+	writel(message[1], mmio + hpriv->em_loc+4);
+
+	/* save off new led state */
+	pp->led_state = ((message[1] >> 16) & 0x00ff);
+
+	/*
+	 * tell hardware to transmit the message
+	 */
+	writel(em_ctl | EM_CTL_TM, mmio + HOST_EM_CTL);
+
+	spin_unlock_irqrestore(ap->lock, flags);
+	return 0;
+}
+
+static ssize_t ahci_led_store(struct device *dev, const char *buf, int num)
+{
+	struct scsi_device *sdev = to_scsi_device(dev);
+	struct ata_port *ap = ata_shost_to_port(sdev->host);
+	struct ata_device *atadev = ata_scsi_find_dev(ap, sdev);
+	int state;
+	int rc;
+
+	if (!atadev || !ata_dev_enabled(atadev))
+		return -EINVAL;
+
+	state = simple_strtoul(buf, NULL, 0);
+	if (state != 0 && state != 1)
+		return -EINVAL;
+
+	rc = ahci_transmit_led_message(ap, num, state);
+	if (!rc)
+		return count;
+	return rc;
+}
+
+static ssize_t ahci_led_locate_store(struct device *dev,
+	struct device_attribute *attr, const char *buf, size_t count)
+{
+	ahci_led_store(dev, buf, 1);
+}
+static DEVICE_ATTR(locate, S_IWUSR | S_IRUGO, NULL, ahci_led_locate_store);
+
+static ssize_t ahci_led_fault_store(struct device *dev,
+	struct device_attribute *attr, const char *buf, size_t count)
+{
+	ahci_led_store(dev, buf, 2);
+}
+static DEVICE_ATTR(fault, S_IWUGO, NULL, ahci_led_fault_store);
+
+static struct device_attribute *ahci_em_led_attrs[] = {
+	&dev_attr_locate,
+	&dev_attr_fault,
+	NULL
+};
+
 static void ahci_port_init(struct pci_dev *pdev, struct ata_port *ap,
 			   int port_no, void __iomem *mmio,
 			   void __iomem *port_mmio)
@@ -2178,7 +2303,8 @@ static void ahci_print_info(struct ata_host *host)
 	dev_printk(KERN_INFO, &pdev->dev,
 		"flags: "
 		"%s%s%s%s%s%s%s"
-		"%s%s%s%s%s%s%s\n"
+		"%s%s%s%s%s%s%s"
+		"%s\n"
 		,
 
 		cap & (1 << 31) ? "64bit " : "",
@@ -2195,7 +2321,8 @@ static void ahci_print_info(struct ata_host *host)
 		cap & (1 << 17) ? "pmp " : "",
 		cap & (1 << 15) ? "pio " : "",
 		cap & (1 << 14) ? "slum " : "",
-		cap & (1 << 13) ? "part " : ""
+		cap & (1 << 13) ? "part " : "",
+		cap & (1 << 6) ? "ems ": ""
 		);
 }
 
@@ -2331,6 +2458,27 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 	ahci_init_controller(host);
 	ahci_print_info(host);
 
+	if (ahci_em_messages && (hpriv->cap & HOST_CAP_EMS)) {
+		u8 messages;
+		void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
+		u32 em_loc = readl(mmio + HOST_EM_LOC);
+		u32 em_ctl = readl(mmio + HOST_EM_CTL);
+
+		messages = (em_ctl & 0x000f0000) >> 16;
+
+		/* we only support LED message type right now */
+		if ((messages & 0x01) && (ahci_em_messages == 1)) {
+			/* store em_loc */
+			hpriv->em_loc = ((em_loc >> 16) * 4);
+
+			/* reset the LEDs */
+			ahci_reset_em(host);
+
+			/* modify sht to add led sysfs files */
+			ahci_sht.sdev_attrs = ahci_em_led_attrs;
+		}
+	}
+
 	pci_set_master(pdev);
 	return ata_host_activate(host, pdev->irq, ahci_interrupt, IRQF_SHARED,
 				 &ahci_sht);
drivers/ata/libata-scsi.c +3 -2
index fad236d..a49dc19 100644
@@ -55,7 +55,7 @@ typedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc);
 
 static struct ata_device *__ata_scsi_find_dev(struct ata_port *ap,
 					const struct scsi_device *scsidev);
-static struct ata_device *ata_scsi_find_dev(struct ata_port *ap,
+struct ata_device *ata_scsi_find_dev(struct ata_port *ap,
 					    const struct scsi_device *scsidev);
 static int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel,
 			      unsigned int id, unsigned int lun);
@@ -2593,7 +2593,7 @@ static int ata_scsi_dev_enabled(struct ata_device *dev)
  *	RETURNS:
  *	Associated ATA device, or %NULL if not found.
  */
-static struct ata_device *
+struct ata_device *
 ata_scsi_find_dev(struct ata_port *ap, const struct scsi_device *scsidev)
 {
 	struct ata_device *dev = __ata_scsi_find_dev(ap, scsidev);
@@ -2603,6 +2603,7 @@ ata_scsi_find_dev(struct ata_port *ap, const struct scsi_device *scsidev)
 
 	return dev;
 }
+EXPORT_SYMBOL_GPL(ata_scsi_find_dev);
 
 /*
  *	ata_scsi_map_proto - Map pass-thru protocol value to taskfile value.
include/linux/libata.h +2 -0
index ef52a07..1ccbd83 100644
@@ -900,6 +900,8 @@ extern int ata_scsi_slave_config(struct scsi_device *sdev);
 extern void ata_scsi_slave_destroy(struct scsi_device *sdev);
 extern int ata_scsi_change_queue_depth(struct scsi_device *sdev,
 				       int queue_depth);
+struct ata_device *ata_scsi_find_dev(struct ata_port *ap,
+				      const struct scsi_device *scsidev);
 extern struct ata_device *ata_dev_pair(struct ata_device *adev);
 extern int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev);
 extern u8 ata_irq_on(struct ata_port *ap);
Signature · 1 line
1.5.3.4
#1 lore raw

Kristen wrote:
...

drivers/ata/ahci.c static int ahci_reset_controller(struct ata_host *host) · line 1146

Quoted 1 line
drivers/ata/ahci.c +1 -0
+	 * XXX will need Port Multiplier support

What's that all about ?

#2 lore raw
Quoted 6 lines · On Thu, 29 Nov 2007 13:16:07 -0500 Mark Lord <[email protected]> wrote:

Kristen wrote:
...

drivers/ata/ahci.c static int ahci_reset_controller(struct ata_host *host) · line 1146

Quoted 1 line
drivers/ata/ahci.c +1 -0
+	 * XXX will need Port Multiplier support

What's that all about ?

I didn't have any hardware that had LED support as well as Port Multiplier, so I didn't implement port multiplier support for this. I wasn't sure if it was better to just do it anyway, or leave it for when we actually have hardware that needs it.

#3 lore raw
Quoted 5 lines · Kristen Carlson Accardi
Quoted 2 lines · On Thu, 29 Nov 2007 13:16:07 -0500 Mark Lord <[email protected]> wrote:

Kristen wrote:
...

Quoted 8 lines
Quoted 3 lines

drivers/ata/ahci.c static int ahci_reset_controller(struct ata_host *host) · line 1146

Quoted 1 line
drivers/ata/ahci.c +1 -0
+	 * XXX will need Port Multiplier support

What's that all about ?

I didn't have any hardware that had LED support as well as Port Multiplier, so I didn't implement port multiplier support for this. I wasn't sure if it was better to just do it anyway, or leave it for when we actually have hardware that needs it.

..

Good. So please replace the "XXX" comment with the better explanation given in your posting above. That'll make future maintenance a lot less guessy.

Cheers

#4 lore raw
In reply to Kristen Carlson Accardi
Quoted 2 lines · On Thu, 29 Nov 2007 09:48:02 -0800 Kristen Carlson Accardi…

This patch implements Enclosure Management via the LED protocol. See the AHCI 1.1 spec for details.

Whoops, I totally messed up and sent the wrong version of this patch. I'll send an updated one, ignore this.

Kristen

Quoted 296 lines

---
Here's a new version of the Enclosure management patch I sent a few weeks ago. I tried to incorporate all the feedback, although I'm still checking on whether it's ok to use these capability bits on a 1.0 ahci device. Please let me know if there are additional changes needed.

 drivers/ata/ahci.c        |  152
++++++++++++++++++++++++++++++++++++++++++++-
drivers/ata/libata-scsi.c |    5 +- include/linux/libata.h    |    2 +
 3 files changed, 155 insertions(+), 4 deletions(-)
drivers/ata/ahci.c +1 -0
index 2c686b4..5f22132 100644
@@ -44,6 +44,7 @@
 #include <linux/dmi.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
 #include <linux/libata.h>
 
 #define DRV_NAME	"ahci"
@@ -92,6 +93,8 @@ enum {
 	HOST_IRQ_STAT		= 0x08, /* interrupt status */
 	HOST_PORTS_IMPL		= 0x0c, /* bitmap of

implemented ports */ HOST_VERSION = 0x10, /* AHCI
spec. version compliancy */

drivers/ata/ahci.c +1 -0
+	HOST_EM_LOC		= 0x1c, /* Enclosure Management

location */

drivers/ata/ahci.c +1 -0
+	HOST_EM_CTL		= 0x20, /* Enclosure Management

Control */

drivers/ata/ahci.c +0 -0
 	/* HOST_CTL bits */
 	HOST_RESET		= (1 << 0),  /* reset controller;

self-clear */ @@ -99,6 +102,7 @@ enum {

drivers/ata/ahci.c +1 -0
 	HOST_AHCI_EN		= (1 << 31), /* AHCI enabled */
 
 	/* HOST_CAP bits */
+	HOST_CAP_EMS		= (1 << 6),  /* Enclosure

Management support */ HOST_CAP_SSC = (1 << 14), /*
Slumber capable */ HOST_CAP_PMP = (1 << 17), /* Port
Multiplier support */ HOST_CAP_CLO = (1 << 24), /*
Command List Override support */ @@ -193,6 +197,10 @@ enum {
ATA_FLAG_ACPI_SATA |
ATA_FLAG_AN | ATA_FLAG_IPM,

drivers/ata/ahci.c +4 -0
 	AHCI_LFLAG_COMMON		= ATA_LFLAG_SKIP_D2H_BSY,
+
+	/* em_ctl bits */
+	EM_CTL_RST			= (1 << 9), /* Reset */
+	EM_CTL_TM			= (1 << 8), /* Transmit

Message */ };

struct ahci_cmd_hdr {

drivers/ata/ahci.c +0 -0
@@ -216,6 +224,7 @@ struct ahci_host_priv {
 	u32			port_map;	/* port map to

use */ u32 saved_cap; /* saved initial
cap */ u32 saved_port_map; /* saved
initial port_map */

drivers/ata/ahci.c +1 -0
+	u32 			em_loc; /* enclosure management

location */ };

struct ahci_port_priv {

drivers/ata/ahci.c +0 -0
@@ -231,6 +240,7 @@ struct ahci_port_priv {
 	unsigned int		ncq_saw_dmas:1;
 	unsigned int		ncq_saw_sdb:1;
 	u32 			intr_mask;	/* interrupts

to enable */

drivers/ata/ahci.c +1 -0
+	u16			led_state;	/* saved

current led state */ };

static int ahci_scr_read(struct ata_port *ap, unsigned int sc_reg,
u32 *val); @@ -572,6 +582,11 @@ static struct pci_driver ahci_pci_driver = { #endif
};

drivers/ata/ahci.c +5 -0
+static int ahci_em_messages = 1;
+module_param(ahci_em_messages, int, 0444);
+/* add other LED protocol types when they become supported */
+MODULE_PARM_DESC(ahci_em_messages,
+	"Set AHCI Enclosure Management Message type (0 = disabled, 1

= LED");
static inline int ahci_nr_ports(u32 cap)
{

drivers/ata/ahci.c +95 -0
@@ -1082,6 +1097,116 @@ static int ahci_reset_controller(struct
 ata_host *host) return 0;
 }
 
+/****** LED Enclosure Management routines ********/
+static int ahci_reset_em(struct ata_host *host)
+{
+	void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
+	u32 em_ctl;
+
+	em_ctl = readl(mmio + HOST_EM_CTL);
+	if ((em_ctl & EM_CTL_TM) || (em_ctl & EM_CTL_RST))
+		return -EINVAL;
+
+	writel(em_ctl | EM_CTL_RST, mmio + HOST_EM_CTL);
+	return 0;
+}
+
+static int ahci_transmit_led_message(struct ata_port *ap, int
 led_num,
+			int state)
+{
+	struct ahci_host_priv *hpriv = ap->host->private_data;
+	void __iomem *mmio = ap->host->iomap[AHCI_PCI_BAR];
+	struct ahci_port_priv *pp = ap->private_data;
+	u32 em_ctl;
+	u32 message[] = {0, 0};
+	unsigned int flags;
+
+	spin_lock_irqsave(ap->lock, flags);
+
+	/*
+	 * if we are still busy transmitting a previous message,
+	 * do not allow
+	 */
+	em_ctl = readl(mmio + HOST_EM_CTL);
+	if (em_ctl & EM_CTL_TM) {
+		spin_unlock_irqrestore(ap->lock, flags);
+		return -EINVAL;
+	}
+
+	/*
+	 * create message header - this is all zero except for
+	 * the message size, which is 4 bytes.
+	 */
+	message[0] |= (4 << 8);
+
+	pp->led_state &= ~(9 << (3*led_num));
+
+	/*
+	 * create the actual message
+	 * XXX will need Port Multiplier support
+	 */
+	message[1] = (ap->port_no | (pp->led_state << 16));
+
+	/* LED bit locations are determined by the led_num */
+	message[1] |= (state << (16 + (3*led_num)));
+
+	/* write message to EM_LOC */
+	writel(message[0], mmio + hpriv->em_loc);
+	writel(message[1], mmio + hpriv->em_loc+4);
+
+	/* save off new led state */
+	pp->led_state = ((message[1] >> 16) & 0x00ff);
+
+	/*
+	 * tell hardware to transmit the message
+	 */
+	writel(em_ctl | EM_CTL_TM, mmio + HOST_EM_CTL);
+
+	spin_unlock_irqrestore(ap->lock, flags);
+	return 0;
+}
+
+static ssize_t ahci_led_store(struct device *dev, const char *buf,
 int num) +{
+	struct scsi_device *sdev = to_scsi_device(dev);
+	struct ata_port *ap = ata_shost_to_port(sdev->host);
+	struct ata_device *atadev = ata_scsi_find_dev(ap, sdev);
+	int state;
+	int rc;
+
+	if (!atadev || !ata_dev_enabled(atadev))
+		return -EINVAL;
+
+	state = simple_strtoul(buf, NULL, 0);
+	if (state != 0 && state != 1)
+		return -EINVAL;
+
+	rc = ahci_transmit_led_message(ap, num, state);
+	if (!rc)
+		return count;
+	return rc;
+}
+
+static ssize_t ahci_led_locate_store(struct device *dev,
+	struct device_attribute *attr, const char *buf, size_t count)
+{
+	ahci_led_store(dev, buf, 1);
+}
+static DEVICE_ATTR(locate, S_IWUSR | S_IRUGO, NULL,

ahci_led_locate_store); +

drivers/ata/ahci.c +38 -2
+static ssize_t ahci_led_fault_store(struct device *dev,
+	struct device_attribute *attr, const char *buf, size_t count)
+{
+	ahci_led_store(dev, buf, 2);
+}
+static DEVICE_ATTR(fault, S_IWUGO, NULL, ahci_led_fault_store);
+
+static struct device_attribute *ahci_em_led_attrs[] = {
+	&dev_attr_locate,
+	&dev_attr_fault,
+	NULL
+};
+
 static void ahci_port_init(struct pci_dev *pdev, struct ata_port *ap,
 			   int port_no, void __iomem *mmio,
 			   void __iomem *port_mmio)
@@ -2178,7 +2303,8 @@ static void ahci_print_info(struct ata_host
 *host) dev_printk(KERN_INFO, &pdev->dev,
 		"flags: "
 		"%s%s%s%s%s%s%s"
-		"%s%s%s%s%s%s%s\n"
+		"%s%s%s%s%s%s%s"
+		"%s\n"
 		,
 
 		cap & (1 << 31) ? "64bit " : "",
@@ -2195,7 +2321,8 @@ static void ahci_print_info(struct ata_host
 *host) cap & (1 << 17) ? "pmp " : "",
 		cap & (1 << 15) ? "pio " : "",
 		cap & (1 << 14) ? "slum " : "",
-		cap & (1 << 13) ? "part " : ""
+		cap & (1 << 13) ? "part " : "",
+		cap & (1 << 6) ? "ems ": ""
 		);
 }
 
@@ -2331,6 +2458,27 @@ static int ahci_init_one(struct pci_dev *pdev,
 const struct pci_device_id *ent) ahci_init_controller(host);
 	ahci_print_info(host);
 
+	if (ahci_em_messages && (hpriv->cap & HOST_CAP_EMS)) {
+		u8 messages;
+		void __iomem *mmio = host->iomap[AHCI_PCI_BAR];
+		u32 em_loc = readl(mmio + HOST_EM_LOC);
+		u32 em_ctl = readl(mmio + HOST_EM_CTL);
+
+		messages = (em_ctl & 0x000f0000) >> 16;
+
+		/* we only support LED message type right now */
+		if ((messages & 0x01) && (ahci_em_messages == 1)) {
+			/* store em_loc */
+			hpriv->em_loc = ((em_loc >> 16) * 4);
+
+			/* reset the LEDs */
+			ahci_reset_em(host);
+
+			/* modify sht to add led sysfs files */
+			ahci_sht.sdev_attrs = ahci_em_led_attrs;
+		}
+	}
+
 	pci_set_master(pdev);
 	return ata_host_activate(host, pdev->irq, ahci_interrupt,
 IRQF_SHARED, &ahci_sht);
drivers/ata/libata-scsi.c +0 -0
index fad236d..a49dc19 100644
@@ -55,7 +55,7 @@ typedef unsigned int (*ata_xlat_func_t)(struct
 ata_queued_cmd *qc); 
 static struct ata_device *__ata_scsi_find_dev(struct ata_port *ap,
 					const struct scsi_device
 *scsidev); -static struct ata_device *ata_scsi_find_dev(struct

ata_port *ap, +struct ata_device *ata_scsi_find_dev(struct ata_port *ap, const struct scsi_device *scsidev);
static int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int
channel, unsigned int id, unsigned int lun);

drivers/ata/libata-scsi.c +1 -1
@@ -2593,7 +2593,7 @@ static int ata_scsi_dev_enabled(struct
 ata_device *dev)
  *	RETURNS:
  *	Associated ATA device, or %NULL if not found.
  */
-static struct ata_device *
+struct ata_device *
 ata_scsi_find_dev(struct ata_port *ap, const struct scsi_device
 *scsidev) {
drivers/ata/libata-scsi.c +1 -0
 	struct ata_device *dev = __ata_scsi_find_dev(ap, scsidev);
@@ -2603,6 +2603,7 @@ ata_scsi_find_dev(struct ata_port *ap, const
 struct scsi_device *scsidev) 
 	return dev;
 }
+EXPORT_SYMBOL_GPL(ata_scsi_find_dev);
 
 /*
  *	ata_scsi_map_proto - Map pass-thru protocol value to

taskfile value. diff --git a/include/linux/libata.h b/include/linux/libata.h index ef52a07..1ccbd83 100644

include/linux/libata.h +0 -0
@@ -900,6 +900,8 @@ extern int ata_scsi_slave_config(struct

scsi_device *sdev); extern void ata_scsi_slave_destroy(struct scsi_device *sdev); extern int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth);

include/linux/libata.h +2 -0
+struct ata_device *ata_scsi_find_dev(struct ata_port *ap,
+				      const struct scsi_device

*scsidev); extern struct ata_device *ata_dev_pair(struct ata_device *adev); extern int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev); extern u8 ata_irq_on(struct ata_port *ap);

#5 lore raw
In reply to Kristen Carlson Accardi

Hi!

drivers/ata/ahci.c static struct pci_driver ahci_pci_driver = { · line 589

Quoted 6 lines
drivers/ata/ahci.c +5 -0
+static int ahci_em_messages = 1;
+module_param(ahci_em_messages, int, 0444);
+/* add other LED protocol types when they become supported */
+MODULE_PARM_DESC(ahci_em_messages,
+	"Set AHCI Enclosure Management Message type (0 = disabled, 1 = LED");

Should you add line in Doc* somewhere?

Pavel

Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html