greybus: interface: clean up ES3-bootroom-quirk handling
authorJohan Hovold <johan@hovoldconsulting.com>
Tue, 29 Mar 2016 22:56:03 +0000 (18:56 -0400)
committerGreg Kroah-Hartman <gregkh@google.com>
Wed, 30 Mar 2016 21:17:40 +0000 (14:17 -0700)
Clean up handling of the ES3-bootrom quirks by adding an interface
quirk-flags field that is set appropriately when we detect that the ES3
bootrom is running.

Note that we need to reserve the DME_DIS_UNIPRO_BOOT_STARTED and
DME_DIS_FALLBACK_UNIPRO_BOOT_STARTED status values for the ES3 bootrom,
which does not support any CPort features (unlike later boot stages).
Add a BOOTROM infix to the defines to make this more clear.

Signed-off-by: Johan Hovold <johan@hovoldconsulting.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
drivers/staging/greybus/connection.c
drivers/staging/greybus/control.c
drivers/staging/greybus/greybus_protocols.h
drivers/staging/greybus/interface.c
drivers/staging/greybus/interface.h

index 64fa20a..1880f8f 100644 (file)
@@ -337,9 +337,12 @@ gb_connection_svc_connection_create(struct gb_connection *connection)
 
        intf = connection->intf;
 
-       /* The ES2/ES3 bootrom requires E2EFC, CSD and CSV to be disabled. */
+       /*
+        * Enable either E2EFC or CSD, unless the interface does not support
+        * any CPort features.
+        */
        cport_flags = GB_SVC_CPORT_FLAG_CSV_N;
-       if (intf->boot_over_unipro) {
+       if (intf->quirks & GB_INTERFACE_QUIRK_NO_CPORT_FEATURES) {
                cport_flags |= GB_SVC_CPORT_FLAG_CSD_N;
        } else if (gb_connection_e2efc_enabled(connection)) {
                cport_flags |= GB_SVC_CPORT_FLAG_CSD_N |
index 83be255..8475f15 100644 (file)
@@ -155,8 +155,7 @@ int gb_control_get_interface_version_operation(struct gb_interface *intf)
        struct gb_connection *connection = intf->control->connection;
        int ret;
 
-       /* The ES3 bootrom fails to boot if this request it sent to it */
-       if (intf->boot_over_unipro)
+       if (intf->quirks & GB_INTERFACE_QUIRK_NO_INTERFACE_VERSION)
                return 0;
 
        ret = gb_operation_sync(connection, GB_CONTROL_TYPE_INTERFACE_VERSION,
index 31e772a..8370cfe 100644 (file)
@@ -894,11 +894,11 @@ struct gb_svc_dme_peer_set_response {
 #define DME_ATTR_ES3_INIT_STATUS               0x6101
 
 /* Return value from init-status attributes listed above */
-#define DME_DIS_SPI_BOOT_STARTED               0x02
-#define DME_DIS_TRUSTED_SPI_BOOT_FINISHED      0x03
-#define DME_DIS_UNTRUSTED_SPI_BOOT_FINISHED    0x04
-#define DME_DIS_UNIPRO_BOOT_STARTED            0x06
-#define DME_DIS_FALLBACK_UNIPRO_BOOT_STARTED   0x09
+#define DME_DIS_SPI_BOOT_STARTED                       0x02
+#define DME_DIS_TRUSTED_SPI_BOOT_FINISHED              0x03
+#define DME_DIS_UNTRUSTED_SPI_BOOT_FINISHED            0x04
+#define DME_DIS_BOOTROM_UNIPRO_BOOT_STARTED            0x06
+#define DME_DIS_BOOTROM_FALLBACK_UNIPRO_BOOT_STARTED   0x09
 
 struct gb_svc_route_create_request {
        __u8    intf1_id;
index 569403c..a13b221 100644 (file)
@@ -55,7 +55,7 @@ static int gb_interface_read_and_clear_init_status(struct gb_interface *intf)
        }
 
        /*
-        * Check if the interface needs to boot over UniPro.
+        * Extract the init status.
         *
         * For ES2: We need to check lowest 8 bits of 'value'.
         * For ES3: We need to check highest 8 bits out of 32 of 'value'.
@@ -67,9 +67,18 @@ static int gb_interface_read_and_clear_init_status(struct gb_interface *intf)
        else
                init_status = value >> 24;
 
-       if (init_status == DME_DIS_UNIPRO_BOOT_STARTED ||
-                       init_status == DME_DIS_FALLBACK_UNIPRO_BOOT_STARTED)
-               intf->boot_over_unipro = true;
+       /*
+        * Check if the interface is executing the quirky ES3 bootrom that
+        * requires E2EFC, CSD and CSV to be disabled and that does not
+        * support the interface-version request.
+        */
+       switch (init_status) {
+       case DME_DIS_BOOTROM_UNIPRO_BOOT_STARTED:
+       case DME_DIS_BOOTROM_FALLBACK_UNIPRO_BOOT_STARTED:
+               intf->quirks |= GB_INTERFACE_QUIRK_NO_CPORT_FEATURES;
+               intf->quirks |= GB_INTERFACE_QUIRK_NO_INTERFACE_VERSION;
+               break;
+       }
 
        /* Clear the init status. */
        return gb_svc_dme_peer_set(hd->svc, intf->interface_id, attr,
index d4c55ab..96caabc 100644 (file)
@@ -10,6 +10,9 @@
 #ifndef __INTERFACE_H
 #define __INTERFACE_H
 
+#define GB_INTERFACE_QUIRK_NO_CPORT_FEATURES           BIT(0)
+#define GB_INTERFACE_QUIRK_NO_INTERFACE_VERSION                BIT(1)
+
 struct gb_interface {
        struct device dev;
        struct gb_control *control;
@@ -36,8 +39,8 @@ struct gb_interface {
 
        struct gb_host_device *hd;
 
-       /* The interface needs to boot over unipro */
-       bool boot_over_unipro;
+       unsigned long quirks;
+
        bool disconnected;
 };
 #define to_gb_interface(d) container_of(d, struct gb_interface, dev)