rndis_host: Halt device if rndis_bind fails.
authorJussi Kivilinna <jussi.kivilinna@mbnet.fi>
Fri, 25 Jan 2008 22:50:55 +0000 (00:50 +0200)
committerDavid S. Miller <davem@davemloft.net>
Fri, 1 Feb 2008 03:26:54 +0000 (19:26 -0800)
When bind fails after device was initialized, shutdown device properly
by sending RNDIS_MSG_HALT.

Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
Signed-off-by: Bjorge Dijkstra <bjd@jooz.net>
Acked-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/usb/rndis_host.c

index 42b161c9461836a71ac11ba20b462b38fbe786d1..c6860250521bf9eb86626e7b2ff3b163fa26cab9 100644 (file)
@@ -467,6 +467,7 @@ static int rndis_bind(struct usbnet *dev, struct usb_interface *intf)
                struct rndis_query_c    *get_c;
                struct rndis_set        *set;
                struct rndis_set_c      *set_c;
+               struct rndis_halt       *halt;
        } u;
        u32                     tmp;
        int                     reply_len;
@@ -517,7 +518,7 @@ static int rndis_bind(struct usbnet *dev, struct usb_interface *intf)
                                "dev can't take %u byte packets (max %u)\n",
                                dev->hard_mtu, tmp);
                        retval = -EINVAL;
-                       goto fail_and_release;
+                       goto halt_fail_and_release;
                }
                dev->hard_mtu = tmp;
                net->mtu = dev->hard_mtu - net->hard_header_len;
@@ -539,7 +540,7 @@ static int rndis_bind(struct usbnet *dev, struct usb_interface *intf)
                        48, (void **) &bp, &reply_len);
        if (unlikely(retval< 0)) {
                dev_err(&intf->dev, "rndis get ethaddr, %d\n", retval);
-               goto fail_and_release;
+               goto halt_fail_and_release;
        }
        memcpy(net->dev_addr, bp, ETH_ALEN);
 
@@ -555,7 +556,7 @@ static int rndis_bind(struct usbnet *dev, struct usb_interface *intf)
        retval = rndis_command(dev, u.header);
        if (unlikely(retval < 0)) {
                dev_err(&intf->dev, "rndis set packet filter, %d\n", retval);
-               goto fail_and_release;
+               goto halt_fail_and_release;
        }
 
        retval = 0;
@@ -563,6 +564,11 @@ static int rndis_bind(struct usbnet *dev, struct usb_interface *intf)
        kfree(u.buf);
        return retval;
 
+halt_fail_and_release:
+       memset(u.halt, 0, sizeof *u.halt);
+       u.halt->msg_type = RNDIS_MSG_HALT;
+       u.halt->msg_len = ccpu2(sizeof *u.halt);
+       (void) rndis_command(dev, (void *)u.halt);
 fail_and_release:
        usb_set_intfdata(info->data, NULL);
        usb_driver_release_interface(driver_of(intf), info->data);