greybus: es2: implement cport reset control request
authorFabien Parent <fparent@baylibre.com>
Tue, 13 Oct 2015 15:34:50 +0000 (17:34 +0200)
committerGreg Kroah-Hartman <gregkh@google.com>
Wed, 14 Oct 2015 18:54:51 +0000 (11:54 -0700)
Toshiba UniPro IP requires to reset the CPort that has been used in a previous
connection. This commit implement a new control request in order to
reset CPorts on an APBridgeA.

Signed-off-by: Fabien Parent <fparent@baylibre.com>
Reviewed-by: Johan Hovold <johan@hovoldconsulting.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
drivers/staging/greybus/es2.c

index 22b67d2ff9df062ce4e0cbe1a6d1d710b4f4c01e..f0770389df7171c818225d709a9a3b7b980b7081 100644 (file)
@@ -58,6 +58,9 @@ static DEFINE_KFIFO(apb1_log_fifo, char, APB1_LOG_SIZE);
 /* vendor request to get the number of cports available */
 #define REQUEST_CPORT_COUNT    0x04
 
+/* vendor request to reset a cport state */
+#define REQUEST_RESET_CPORT    0x05
+
 /*
  * @endpoint: bulk in endpoint for CPort data
  * @urb: array of urbs for the CPort in messages
@@ -376,10 +379,44 @@ static void message_cancel(struct gb_message *message)
        usb_free_urb(urb);
 }
 
+static int cport_reset(struct greybus_host_device *hd, u16 cport_id)
+{
+       struct es1_ap_dev *es1 = hd_to_es1(hd);
+       struct usb_device *udev = es1->usb_dev;
+       int retval;
+
+       retval = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+                                REQUEST_RESET_CPORT,
+                                USB_DIR_OUT | USB_TYPE_VENDOR |
+                                USB_RECIP_INTERFACE, 0, cport_id,
+                                NULL, 0, ES1_TIMEOUT);
+       if (retval < 0) {
+               dev_err(&udev->dev, "failed to reset cport %hu: %d\n", cport_id,
+                       retval);
+               return retval;
+       }
+
+       return 0;
+}
+
+static int cport_enable(struct greybus_host_device *hd, u16 cport_id)
+{
+       int retval;
+
+       if (cport_id != GB_SVC_CPORT_ID) {
+               retval = cport_reset(hd, cport_id);
+               if (retval)
+                       return retval;
+       }
+
+       return 0;
+}
+
 static struct greybus_host_driver es1_driver = {
        .hd_priv_size           = sizeof(struct es1_ap_dev),
        .message_send           = message_send,
        .message_cancel         = message_cancel,
+       .cport_enable           = cport_enable,
 };
 
 /* Common function to report consistent warnings based on URB status */