Commit 008dbd61 authored by Harry Zhang's avatar Harry Zhang Committed by Jeff Garzik

ahci: EM message type auto detect

Detect enclosure management message type automatically at driver
initialization, instead of using module parameter "ahci_em_messages".
Signed-off-by: default avatarHarry Zhang <harry.zhang@amd.com>
Signed-off-by: default avatarJeff Garzik <jgarzik@redhat.com>
parent ec86c81d
...@@ -1185,7 +1185,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1185,7 +1185,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
/* set enclosure management message type */ /* set enclosure management message type */
if (ap->flags & ATA_FLAG_EM) if (ap->flags & ATA_FLAG_EM)
ap->em_message_type = ahci_em_messages; ap->em_message_type = hpriv->em_msg_type;
/* disabled/not-implemented port */ /* disabled/not-implemented port */
......
...@@ -227,6 +227,12 @@ enum { ...@@ -227,6 +227,12 @@ enum {
EM_CTL_RST = (1 << 9), /* Reset */ EM_CTL_RST = (1 << 9), /* Reset */
EM_CTL_TM = (1 << 8), /* Transmit Message */ EM_CTL_TM = (1 << 8), /* Transmit Message */
EM_CTL_ALHD = (1 << 26), /* Activity LED */ EM_CTL_ALHD = (1 << 26), /* Activity LED */
/* em message type */
EM_MSG_TYPE_LED = (1 << 0), /* LED */
EM_MSG_TYPE_SAFTE = (1 << 1), /* SAF-TE */
EM_MSG_TYPE_SES2 = (1 << 2), /* SES-2 */
EM_MSG_TYPE_SGPIO = (1 << 3), /* SGPIO */
}; };
struct ahci_cmd_hdr { struct ahci_cmd_hdr {
...@@ -282,9 +288,9 @@ struct ahci_host_priv { ...@@ -282,9 +288,9 @@ struct ahci_host_priv {
u32 saved_cap2; /* saved initial cap2 */ u32 saved_cap2; /* saved initial cap2 */
u32 saved_port_map; /* saved initial port_map */ u32 saved_port_map; /* saved initial port_map */
u32 em_loc; /* enclosure management location */ u32 em_loc; /* enclosure management location */
u32 em_msg_type; /* EM message type */
}; };
extern int ahci_em_messages;
extern int ahci_ignore_sss; extern int ahci_ignore_sss;
extern struct scsi_host_template ahci_sht; extern struct scsi_host_template ahci_sht;
......
...@@ -184,7 +184,7 @@ EXPORT_SYMBOL_GPL(ahci_em_messages); ...@@ -184,7 +184,7 @@ EXPORT_SYMBOL_GPL(ahci_em_messages);
module_param(ahci_em_messages, int, 0444); module_param(ahci_em_messages, int, 0444);
/* add other LED protocol types when they become supported */ /* add other LED protocol types when they become supported */
MODULE_PARM_DESC(ahci_em_messages, MODULE_PARM_DESC(ahci_em_messages,
"Set AHCI Enclosure Management Message type (0 = disabled, 1 = LED"); "AHCI Enclosure Management Message control (0 = off, 1 = on)");
static void ahci_enable_ahci(void __iomem *mmio) static void ahci_enable_ahci(void __iomem *mmio)
{ {
...@@ -931,27 +931,29 @@ static ssize_t ahci_transmit_led_message(struct ata_port *ap, u32 state, ...@@ -931,27 +931,29 @@ static ssize_t ahci_transmit_led_message(struct ata_port *ap, u32 state,
return -EBUSY; return -EBUSY;
} }
/* if (hpriv->em_msg_type & EM_MSG_TYPE_LED) {
* create message header - this is all zero except for /*
* the message size, which is 4 bytes. * create message header - this is all zero except for
*/ * the message size, which is 4 bytes.
message[0] |= (4 << 8); */
message[0] |= (4 << 8);
/* ignore 0:4 of byte zero, fill in port info yourself */ /* ignore 0:4 of byte zero, fill in port info yourself */
message[1] = ((state & ~EM_MSG_LED_HBA_PORT) | ap->port_no); message[1] = ((state & ~EM_MSG_LED_HBA_PORT) | ap->port_no);
/* write message to EM_LOC */ /* write message to EM_LOC */
writel(message[0], mmio + hpriv->em_loc); writel(message[0], mmio + hpriv->em_loc);
writel(message[1], mmio + hpriv->em_loc+4); writel(message[1], mmio + hpriv->em_loc+4);
/*
* tell hardware to transmit the message
*/
writel(em_ctl | EM_CTL_TM, mmio + HOST_EM_CTL);
}
/* save off new led state for port/slot */ /* save off new led state for port/slot */
emp->led_state = state; emp->led_state = state;
/*
* tell hardware to transmit the message
*/
writel(em_ctl | EM_CTL_TM, mmio + HOST_EM_CTL);
spin_unlock_irqrestore(ap->lock, flags); spin_unlock_irqrestore(ap->lock, flags);
return size; return size;
} }
...@@ -2094,10 +2096,10 @@ void ahci_set_em_messages(struct ahci_host_priv *hpriv, ...@@ -2094,10 +2096,10 @@ void ahci_set_em_messages(struct ahci_host_priv *hpriv,
messages = (em_ctl & EM_CTRL_MSG_TYPE) >> 16; messages = (em_ctl & EM_CTRL_MSG_TYPE) >> 16;
/* we only support LED message type right now */ if (messages) {
if ((messages & 0x01) && (ahci_em_messages == 1)) {
/* store em_loc */ /* store em_loc */
hpriv->em_loc = ((em_loc >> 16) * 4); hpriv->em_loc = ((em_loc >> 16) * 4);
hpriv->em_msg_type = messages;
pi->flags |= ATA_FLAG_EM; pi->flags |= ATA_FLAG_EM;
if (!(em_ctl & EM_CTL_ALHD)) if (!(em_ctl & EM_CTL_ALHD))
pi->flags |= ATA_FLAG_SW_ACTIVITY; pi->flags |= ATA_FLAG_SW_ACTIVITY;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment