From e007beddca9f1cdf4e41cbf7beace4891fe808ef Mon Sep 17 00:00:00 2001 From: Chiranjeevi Velempati Date: Tue, 24 Jan 2012 09:54:11 +0530 Subject: [PATCH] USB: f_rmnet: Drop DTR on host suspend Some Windows hosts are not dropping DTR during suspend, but are setting DTR as part of resume. Hence, send DTR set to zero to the Modem when the rmnet interface is suspended. Change-Id: I9137021e2c4074c71e9142e7dbac2042311b3c4d Signed-off-by: Chiranjeevi Velempati --- drivers/usb/gadget/f_rmnet.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/drivers/usb/gadget/f_rmnet.c b/drivers/usb/gadget/f_rmnet.c index 177176e7d4d..86f8a255cab 100644 --- a/drivers/usb/gadget/f_rmnet.c +++ b/drivers/usb/gadget/f_rmnet.c @@ -426,6 +426,23 @@ static void frmnet_unbind(struct usb_configuration *c, struct usb_function *f) kfree(f->name); } +static void frmnet_suspend(struct usb_function *f) +{ + struct f_rmnet *dev = func_to_rmnet(f); + unsigned port_num; + + if (!atomic_read(&dev->online)) + return; + /* This is a workaround for a bug in Windows 7/XP hosts in which + * the DTR bit is not set low when going into suspend. Hence force it + * low here when this function driver is suspended. + */ + if (dev->port.notify_modem) { + port_num = rmnet_ports[dev->port_num].ctrl_xport_num; + dev->port.notify_modem(&dev->port, port_num, ~ACM_CTRL_DTR); + } +} + static void frmnet_disable(struct usb_function *f) { struct f_rmnet *dev = func_to_rmnet(f); @@ -937,6 +954,7 @@ static int frmnet_bind_config(struct usb_configuration *c, unsigned portno) f->disable = frmnet_disable; f->set_alt = frmnet_set_alt; f->setup = frmnet_setup; + f->suspend = frmnet_suspend; dev->port.send_cpkt_response = frmnet_send_cpkt_response; dev->port.disconnect = frmnet_disconnect; dev->port.connect = frmnet_connect;