greybus: core: don't set up endo until host device is initialized
authorAlex Elder <elder@linaro.org>
Fri, 22 May 2015 17:56:49 +0000 (12:56 -0500)
committerGreg Kroah-Hartman <gregkh@google.com>
Sat, 23 May 2015 23:45:42 +0000 (16:45 -0700)
Currently, the data structure representing an Endo is set up at the
time a host device gets created.  This is too early.

Once the control infrastructure is in place, there's no sense in
setting up the Endo utnil after we have heard from the SVC via a
probe operation on our control CPort.  And even then, there's
no real point until we've successfully authenticated with the SVC,
which will be indicated by the arrival of the Control protocol
"connected" operation request notifying us that our SVC CPort
is operational.

In addition to this logical argument, we also can't actually
receive any messages on the Control CPort until the host device
is set up and ready to receive messages.  At the point we're
currently setting up the Endo data structure, that has not yet
been done.

Define a new exported function greybus_endo_setup(), which will
be used (for now) as the entry point for setting up the Endo
data structure.  Arrange to call it in the host USB driver
probe method, *after* we are set up for handling messages.

Note: Once the control protocol has been implemented, this function
may no longer need to be exported.

Signed-off-by: Alex Elder <elder@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
drivers/staging/greybus/core.c
drivers/staging/greybus/es1.c
drivers/staging/greybus/es2.c
drivers/staging/greybus/greybus.h

index 223c396..290bee5 100644 (file)
@@ -177,9 +177,6 @@ struct greybus_host_device *greybus_create_hd(struct greybus_host_driver *driver
                                              size_t buffer_size_max)
 {
        struct greybus_host_device *hd;
-       struct gb_endo *endo;
-       u16 endo_id = 0x4755;   // FIXME - get endo "ID" from the SVC
-       u8 ap_intf_id = 0x01;   // FIXME - get AP interface ID from the SVC
 
        /*
         * Validate that the driver implements all of the callbacks
@@ -213,16 +210,23 @@ struct greybus_host_device *greybus_create_hd(struct greybus_host_driver *driver
        ida_init(&hd->cport_id_map);
        hd->buffer_size_max = buffer_size_max;
 
+       return hd;
+}
+EXPORT_SYMBOL_GPL(greybus_create_hd);
+
+int greybus_endo_setup(struct greybus_host_device *hd, u16 endo_id,
+                       u8 ap_intf_id)
+{
+       struct gb_endo *endo;
+
        endo = gb_endo_create(hd, endo_id, ap_intf_id);
-       if (IS_ERR(endo)) {
-               greybus_remove_hd(hd);
-               return ERR_CAST(endo);
-       }
+       if (IS_ERR(endo))
+               return PTR_ERR(endo);
        hd->endo = endo;
 
-       return hd;
+       return 0;
 }
-EXPORT_SYMBOL_GPL(greybus_create_hd);
+EXPORT_SYMBOL_GPL(greybus_endo_setup);
 
 void greybus_remove_hd(struct greybus_host_device *hd)
 {
index 1ed10f4..f653954 100644 (file)
@@ -551,6 +551,8 @@ static int ap_probe(struct usb_interface *interface,
        bool bulk_out_found = false;
        int retval = -ENOMEM;
        int i;
+       u16 endo_id = 0x4755;   // FIXME - get endo "ID" from the SVC
+       u8 ap_intf_id = 0x01;   // FIXME - get endo "ID" from the SVC
        u8 svc_interval = 0;
 
        udev = usb_get_dev(interface_to_usbdev(interface));
@@ -659,6 +661,17 @@ static int ap_probe(struct usb_interface *interface,
                                                        gb_debugfs_get(), es1,
                                                        &apb1_log_enable_fops);
 
+       /*
+        * XXX Soon this will be initiated later, with a combination
+        * XXX of a Control protocol probe operation and a
+        * XXX subsequent Control protocol connected operation for
+        * XXX the SVC connection.  At that point we know we're
+        * XXX properly connected to an Endo.
+        */
+       retval = greybus_endo_setup(hd, endo_id, ap_intf_id);
+       if (retval)
+               goto error;
+
        return 0;
 error:
        ap_disconnect(interface);
index 4733adc..4f676cf 100644 (file)
@@ -551,6 +551,8 @@ static int ap_probe(struct usb_interface *interface,
        bool bulk_out_found = false;
        int retval = -ENOMEM;
        int i;
+       u16 endo_id = 0x4755;   // FIXME - get endo "ID" from the SVC
+       u8 ap_intf_id = 0x01;   // FIXME - get endo "ID" from the SVC
        u8 svc_interval = 0;
 
        udev = usb_get_dev(interface_to_usbdev(interface));
@@ -659,6 +661,17 @@ static int ap_probe(struct usb_interface *interface,
                                                        gb_debugfs_get(), es1,
                                                        &apb1_log_enable_fops);
 
+       /*
+        * XXX Soon this will be initiated later, with a combination
+        * XXX of a Control protocol probe operation and a
+        * XXX subsequent Control protocol connected operation for
+        * XXX the SVC connection.  At that point we know we're
+        * XXX properly connected to an Endo.
+        */
+       retval = greybus_endo_setup(hd, endo_id, ap_intf_id);
+       if (retval)
+               goto error;
+
        return 0;
 error:
        ap_disconnect(interface);
index 4920458..30a93ea 100644 (file)
@@ -108,6 +108,8 @@ struct greybus_host_device {
 struct greybus_host_device *greybus_create_hd(struct greybus_host_driver *hd,
                                              struct device *parent,
                                              size_t buffer_size_max);
+int greybus_endo_setup(struct greybus_host_device *hd, u16 endo_id,
+                       u8 ap_intf_id);
 void greybus_remove_hd(struct greybus_host_device *hd);
 
 struct greybus_driver {