aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorHarry Zhang <harry.zhang@amd.com>2010-04-23 05:27:19 -0400
committerJeff Garzik <jgarzik@redhat.com>2010-05-14 17:35:51 -0400
commit008dbd61ebee3e647f63bbe8315192e1331cd75f (patch)
tree2848b7364622cceb29b596c95c7c2681a40adcfc /drivers
parentec86c81dfcc52e313920621b1d1e92343a842afe (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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ata/ahci.c2
-rw-r--r--drivers/ata/ahci.h8
-rw-r--r--drivers/ata/libahci.c38
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)
1185 1185
1186 /* set enclosure management message type */ 1186 /* set enclosure management message type */
1187 if (ap->flags & ATA_FLAG_EM) 1187 if (ap->flags & ATA_FLAG_EM)
1188 ap->em_message_type = ahci_em_messages; 1188 ap->em_message_type = hpriv->em_msg_type;
1189 1189
1190 1190
1191 /* disabled/not-implemented port */ 1191 /* 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 {
227 EM_CTL_RST = (1 << 9), /* Reset */ 227 EM_CTL_RST = (1 << 9), /* Reset */
228 EM_CTL_TM = (1 << 8), /* Transmit Message */ 228 EM_CTL_TM = (1 << 8), /* Transmit Message */
229 EM_CTL_ALHD = (1 << 26), /* Activity LED */ 229 EM_CTL_ALHD = (1 << 26), /* Activity LED */
230
231 /* em message type */
232 EM_MSG_TYPE_LED = (1 << 0), /* LED */
233 EM_MSG_TYPE_SAFTE = (1 << 1), /* SAF-TE */
234 EM_MSG_TYPE_SES2 = (1 << 2), /* SES-2 */
235 EM_MSG_TYPE_SGPIO = (1 << 3), /* SGPIO */
230}; 236};
231 237
232struct ahci_cmd_hdr { 238struct ahci_cmd_hdr {
@@ -282,9 +288,9 @@ struct ahci_host_priv {
282 u32 saved_cap2; /* saved initial cap2 */ 288 u32 saved_cap2; /* saved initial cap2 */
283 u32 saved_port_map; /* saved initial port_map */ 289 u32 saved_port_map; /* saved initial port_map */
284 u32 em_loc; /* enclosure management location */ 290 u32 em_loc; /* enclosure management location */
291 u32 em_msg_type; /* EM message type */
285}; 292};
286 293
287extern int ahci_em_messages;
288extern int ahci_ignore_sss; 294extern int ahci_ignore_sss;
289 295
290extern struct scsi_host_template ahci_sht; 296extern 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);
184module_param(ahci_em_messages, int, 0444); 184module_param(ahci_em_messages, int, 0444);
185/* add other LED protocol types when they become supported */ 185/* add other LED protocol types when they become supported */
186MODULE_PARM_DESC(ahci_em_messages, 186MODULE_PARM_DESC(ahci_em_messages,
187 "Set AHCI Enclosure Management Message type (0 = disabled, 1 = LED"); 187 "AHCI Enclosure Management Message control (0 = off, 1 = on)");
188 188
189static void ahci_enable_ahci(void __iomem *mmio) 189static void ahci_enable_ahci(void __iomem *mmio)
190{ 190{
@@ -931,27 +931,29 @@ static ssize_t ahci_transmit_led_message(struct ata_port *ap, u32 state,
931 return -EBUSY; 931 return -EBUSY;
932 } 932 }
933 933
934 /* 934 if (hpriv->em_msg_type & EM_MSG_TYPE_LED) {
935 * create message header - this is all zero except for 935 /*
936 * the message size, which is 4 bytes. 936 * create message header - this is all zero except for
937 */ 937 * the message size, which is 4 bytes.
938 message[0] |= (4 << 8); 938 */
939 message[0] |= (4 << 8);
939 940
940 /* ignore 0:4 of byte zero, fill in port info yourself */ 941 /* ignore 0:4 of byte zero, fill in port info yourself */
941 message[1] = ((state & ~EM_MSG_LED_HBA_PORT) | ap->port_no); 942 message[1] = ((state & ~EM_MSG_LED_HBA_PORT) | ap->port_no);
942 943
943 /* write message to EM_LOC */ 944 /* write message to EM_LOC */
944 writel(message[0], mmio + hpriv->em_loc); 945 writel(message[0], mmio + hpriv->em_loc);
945 writel(message[1], mmio + hpriv->em_loc+4); 946 writel(message[1], mmio + hpriv->em_loc+4);
947
948 /*
949 * tell hardware to transmit the message
950 */
951 writel(em_ctl | EM_CTL_TM, mmio + HOST_EM_CTL);
952 }
946 953
947 /* save off new led state for port/slot */ 954 /* save off new led state for port/slot */
948 emp->led_state = state; 955 emp->led_state = state;
949 956
950 /*
951 * tell hardware to transmit the message
952 */
953 writel(em_ctl | EM_CTL_TM, mmio + HOST_EM_CTL);
954
955 spin_unlock_irqrestore(ap->lock, flags); 957 spin_unlock_irqrestore(ap->lock, flags);
956 return size; 958 return size;
957} 959}
@@ -2094,10 +2096,10 @@ void ahci_set_em_messages(struct ahci_host_priv *hpriv,
2094 2096
2095 messages = (em_ctl & EM_CTRL_MSG_TYPE) >> 16; 2097 messages = (em_ctl & EM_CTRL_MSG_TYPE) >> 16;
2096 2098
2097 /* we only support LED message type right now */ 2099 if (messages) {
2098 if ((messages & 0x01) && (ahci_em_messages == 1)) {
2099 /* store em_loc */ 2100 /* store em_loc */
2100 hpriv->em_loc = ((em_loc >> 16) * 4); 2101 hpriv->em_loc = ((em_loc >> 16) * 4);
2102 hpriv->em_msg_type = messages;
2101 pi->flags |= ATA_FLAG_EM; 2103 pi->flags |= ATA_FLAG_EM;
2102 if (!(em_ctl & EM_CTL_ALHD)) 2104 if (!(em_ctl & EM_CTL_ALHD))
2103 pi->flags |= ATA_FLAG_SW_ACTIVITY; 2105 pi->flags |= ATA_FLAG_SW_ACTIVITY;