diff options
author | Harry Zhang <harry.zhang@amd.com> | 2010-04-23 05:27:19 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2010-05-14 17:35:51 -0400 |
commit | 008dbd61ebee3e647f63bbe8315192e1331cd75f (patch) | |
tree | 2848b7364622cceb29b596c95c7c2681a40adcfc /drivers | |
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>
Diffstat (limited to 'drivers')
-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) | |||
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 | ||
232 | struct ahci_cmd_hdr { | 238 | struct 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 | ||
287 | extern int ahci_em_messages; | ||
288 | extern int ahci_ignore_sss; | 294 | extern int ahci_ignore_sss; |
289 | 295 | ||
290 | extern struct scsi_host_template ahci_sht; | 296 | 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); | |||
184 | module_param(ahci_em_messages, int, 0444); | 184 | module_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 */ |
186 | MODULE_PARM_DESC(ahci_em_messages, | 186 | MODULE_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 | ||
189 | static void ahci_enable_ahci(void __iomem *mmio) | 189 | static 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; |