From 153ff7e76ddb2fd5ab3d790c0139154dfd5464f1 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 29 Mar 2016 18:56:08 -0400 Subject: [PATCH] greybus: interface: read DME attributes at activation Read the DDBL1 and Ara DME attributes when activating an interface. These values are currently provided by the SVC in the intf_hotplug request, which is about to go away. Note that there are currently no standard Ara VID and PID attributes and that Toshiba uses attributes from the reserved space in ES3. For now, we therefore refuse to enumerate any non-Toshiba bridges. Also note that the Ara serial number is currently not supported. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/staging/greybus/interface.c | 72 +++++++++++++++++++++++++++++ drivers/staging/greybus/interface.h | 1 - drivers/staging/greybus/svc.c | 18 +++----- 3 files changed, 78 insertions(+), 13 deletions(-) diff --git a/drivers/staging/greybus/interface.c b/drivers/staging/greybus/interface.c index 823debb40272..c7793a93c802 100644 --- a/drivers/staging/greybus/interface.c +++ b/drivers/staging/greybus/interface.c @@ -12,6 +12,74 @@ #define GB_INTERFACE_DEVICE_ID_BAD 0xff +/* DME attributes */ +#define DME_DDBL1_MANUFACTURERID 0x5003 +#define DME_DDBL1_PRODUCTID 0x5004 + +#define DME_TOSHIBA_ARA_VID 0x6000 +#define DME_TOSHIBA_ARA_PID 0x6001 + +/* DDBL1 Manufacturer and Product ids */ +#define TOSHIBA_DMID 0x0126 +#define TOSHIBA_ES2_BRIDGE_DPID 0x1000 +#define TOSHIBA_ES3_APBRIDGE_DPID 0x1001 +#define TOSHIBA_ES3_GPBRIDGE_DPID 0x1002 + + +static int gb_interface_dme_attr_get(struct gb_interface *intf, + u16 attr, u32 *val) +{ + return gb_svc_dme_peer_get(intf->hd->svc, intf->interface_id, + attr, DME_ATTR_SELECTOR_INDEX_NULL, + val); +} + +static int gb_interface_read_ara_dme(struct gb_interface *intf) +{ + int ret; + + /* + * Unless this is a Toshiba bridge, bail out until we have defined + * standard Ara attributes. + */ + if (intf->ddbl1_manufacturer_id != TOSHIBA_DMID) { + dev_err(&intf->dev, "unknown manufacturer %08x\n", + intf->ddbl1_manufacturer_id); + return -ENODEV; + } + + ret = gb_interface_dme_attr_get(intf, DME_TOSHIBA_ARA_VID, + &intf->vendor_id); + if (ret) + return ret; + + ret = gb_interface_dme_attr_get(intf, DME_TOSHIBA_ARA_PID, + &intf->product_id); + if (ret) + return ret; + + /* FIXME: serial number not implemented */ + intf->serial_number = 0; + + return 0; +} + +static int gb_interface_read_dme(struct gb_interface *intf) +{ + int ret; + + ret = gb_interface_dme_attr_get(intf, DME_DDBL1_MANUFACTURERID, + &intf->ddbl1_manufacturer_id); + if (ret) + return ret; + + ret = gb_interface_dme_attr_get(intf, DME_DDBL1_PRODUCTID, + &intf->ddbl1_product_id); + if (ret) + return ret; + + return gb_interface_read_ara_dme(intf); +} static int gb_interface_route_create(struct gb_interface *intf) { @@ -279,6 +347,10 @@ int gb_interface_activate(struct gb_interface *intf) { int ret; + ret = gb_interface_read_dme(intf); + if (ret) + return ret; + ret = gb_interface_route_create(intf); if (ret) return ret; diff --git a/drivers/staging/greybus/interface.h b/drivers/staging/greybus/interface.h index 8b6fcfe90883..1a6ce5ce6e6c 100644 --- a/drivers/staging/greybus/interface.h +++ b/drivers/staging/greybus/interface.h @@ -27,7 +27,6 @@ struct gb_interface { char *vendor_string; char *product_string; - /* Information taken from the hotplug event */ u32 ddbl1_manufacturer_id; u32 ddbl1_product_id; u32 vendor_id; diff --git a/drivers/staging/greybus/svc.c b/drivers/staging/greybus/svc.c index 96d3d55f54ed..0659815248f9 100644 --- a/drivers/staging/greybus/svc.c +++ b/drivers/staging/greybus/svc.c @@ -460,11 +460,12 @@ static void gb_svc_process_intf_hotplug(struct gb_operation *operation) return; } - intf->ddbl1_manufacturer_id = le32_to_cpu(request->data.ddbl1_mfr_id); - intf->ddbl1_product_id = le32_to_cpu(request->data.ddbl1_prod_id); - intf->vendor_id = le32_to_cpu(request->data.ara_vend_id); - intf->product_id = le32_to_cpu(request->data.ara_prod_id); - intf->serial_number = le64_to_cpu(request->data.serial_number); + ret = gb_interface_activate(intf); + if (ret) { + dev_err(&svc->dev, "failed to activate interface %u: %d\n", + intf_id, ret); + goto err_interface_add; + } /* * Use VID/PID specified at hotplug if: @@ -480,13 +481,6 @@ static void gb_svc_process_intf_hotplug(struct gb_operation *operation) intf->product_id = product_id; } - ret = gb_interface_activate(intf); - if (ret) { - dev_err(&svc->dev, "failed to activate interface %u: %d\n", - intf_id, ret); - goto err_interface_add; - } - ret = gb_interface_enable(intf); if (ret) { dev_err(&svc->dev, "failed to enable interface %u: %d\n", -- 2.20.1