diff options
author | Harry Zhang <harry.zhang@amd.com> | 2010-04-23 17:27:19 +0800 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2010-05-14 17:35:51 -0400 |
commit | 008dbd61ebee3e647f63bbe8315192e1331cd75f (patch) | |
tree | 2848b7364622cceb29b596c95c7c2681a40adcfc | |
parent | ec86c81dfcc52e313920621b1d1e92343a842afe (diff) |
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: Harry Zhang <harry.zhang@amd.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
-rw-r--r-- | drivers/ata/ahci.c | 2 | ||||
-rw-r--r-- | drivers/ata/ahci.h | 8 | ||||
-rw-r--r-- | drivers/ata/libahci.c | 38 |
3 files changed, 28 insertions, 20 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index c44d11237db4..8ca16f54e1ed 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -1185,7 +1185,7 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) /* set enclosure management message type */ 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 */ diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h index 733def27df07..5edce4447d84 100644 --- a/drivers/ata/ahci.h +++ b/drivers/ata/ahci.h @@ -227,6 +227,12 @@ enum { EM_CTL_RST = (1 << 9), /* Reset */ EM_CTL_TM = (1 << 8), /* Transmit Message */ 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 { @@ -282,9 +288,9 @@ struct ahci_host_priv { u32 saved_cap2; /* saved initial cap2 */ u32 saved_port_map; /* saved initial port_map */ u32 em_loc; /* enclosure management location */ + u32 em_msg_type; /* EM message type */ }; -extern int ahci_em_messages; extern int ahci_ignore_sss; extern struct scsi_host_template ahci_sht; diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c index 34fc57d0a9b8..817bcd023cc0 100644 --- a/drivers/ata/libahci.c +++ b/drivers/ata/libahci.c @@ -184,7 +184,7 @@ EXPORT_SYMBOL_GPL(ahci_em_messages); 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"); + "AHCI Enclosure Management Message control (0 = off, 1 = on)"); 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, return -EBUSY; } - /* - * create message header - this is all zero except for - * the message size, which is 4 bytes. - */ - message[0] |= (4 << 8); + 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. + */ + message[0] |= (4 << 8); - /* ignore 0:4 of byte zero, fill in port info yourself */ - message[1] = ((state & ~EM_MSG_LED_HBA_PORT) | ap->port_no); + /* ignore 0:4 of byte zero, fill in port info yourself */ + message[1] = ((state & ~EM_MSG_LED_HBA_PORT) | ap->port_no); - /* write message to EM_LOC */ - writel(message[0], mmio + hpriv->em_loc); - writel(message[1], mmio + hpriv->em_loc+4); + /* write message to EM_LOC */ + writel(message[0], mmio + hpriv->em_loc); + 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 */ 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); return size; } @@ -2094,10 +2096,10 @@ void ahci_set_em_messages(struct ahci_host_priv *hpriv, messages = (em_ctl & EM_CTRL_MSG_TYPE) >> 16; - /* we only support LED message type right now */ - if ((messages & 0x01) && (ahci_em_messages == 1)) { + if (messages) { /* store em_loc */ hpriv->em_loc = ((em_loc >> 16) * 4); + hpriv->em_msg_type = messages; pi->flags |= ATA_FLAG_EM; if (!(em_ctl & EM_CTL_ALHD)) pi->flags |= ATA_FLAG_SW_ACTIVITY; |