mirror of
https://github.com/followmsi/android_kernel_google_msm.git
synced 2024-11-06 23:17:41 +00:00
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>
This commit is contained in:
parent
ec86c81dfc
commit
008dbd61eb
3 changed files with 28 additions and 20 deletions
|
@ -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 {
|
||||||
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 {
|
||||||
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);
|
||||||
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,
|
||||||
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,
|
||||||
|
|
||||||
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;
|
||||||
|
|
Loading…
Reference in a new issue