ahci: EM message type auto detect
authorHarry Zhang <harry.zhang@amd.com>
Fri, 23 Apr 2010 09:27:19 +0000 (17:27 +0800)
committerJeff Garzik <jgarzik@redhat.com>
Fri, 14 May 2010 21:35:51 +0000 (17:35 -0400)
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>
drivers/ata/ahci.c
drivers/ata/ahci.h
drivers/ata/libahci.c

index c44d11237db48e09b43b42121d65f640e11be11a..8ca16f54e1ed6648365f90e935eedc9140372c98 100644 (file)
@@ -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 */
index 733def27df07c6adb6a3f7633ace21fb15b2f5ae..5edce4447d84a696cc786d6eee4cba4ecc40a609 100644 (file)
@@ -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;
index 34fc57d0a9b8fa81fd888f3d5cbc21aaf418f48a..817bcd023cc0f5756a5640f9c377197f74b6e84f 100644 (file)
@@ -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;