Re: athn@usb: fixup detach panic

2012-11-10 Thread Stefan Sperling
On Sat, Nov 10, 2012 at 03:52:37AM +0100, Mike Belopuhov wrote:
> On Tue, Nov 06, 2012 at 12:15 +0100, Stefan Sperling wrote:
> > It seems more appropriate to handle this problem entirely within
> > the USB-specific layer of the driver, rather than within dev/ic/athn.c.
> > 
> > If loading the firmware fails, athn_usb_attachhook() doesn't even
> > call athn_attach(). This is what your fix is compensating for. I believe
> > athn_usb_detach() shouldn't be calling athn_detach() unconditionally.
> > 
> > I fixed a similar problem for acx(4) cardbus cards once, where ejecting
> > a card that had failed to attach half way through paniced the kernel.
> > This was in r1.12 of dev/cardbus/if_acx_cardbus.c, which looked like this:
> > 
> 
> works for me. ok?

Yes!
 
> Index: dev/usb/if_athn_usb.c
> ===
> RCS file: /home/cvs/src/sys/dev/usb/if_athn_usb.c,v
> retrieving revision 1.8
> diff -u -p -r1.8 if_athn_usb.c
> --- dev/usb/if_athn_usb.c 3 Jul 2011 15:47:17 -   1.8
> +++ dev/usb/if_athn_usb.c 10 Nov 2012 02:04:12 -
> @@ -289,7 +289,8 @@ athn_usb_detach(struct device *self, int
>   struct athn_usb_softc *usc = (struct athn_usb_softc *)self;
>   struct athn_softc *sc = &usc->sc_sc;
>  
> - athn_detach(sc);
> + if (usc->sc_athn_attached)
> + athn_detach(sc);
>  
>   /* Wait for all async commands to complete. */
>   athn_usb_wait_async(usc);
> @@ -347,6 +348,7 @@ athn_usb_attachhook(void *xsc)
>   splx(s);
>   return;
>   }
> + usc->sc_athn_attached = 1;
>   /* Override some operations for USB. */
>   ifp->if_ioctl = athn_usb_ioctl;
>   ifp->if_start = athn_usb_start;
> Index: dev/usb/if_athn_usb.h
> ===
> RCS file: /home/cvs/src/sys/dev/usb/if_athn_usb.h,v
> retrieving revision 1.2
> diff -u -p -r1.2 if_athn_usb.h
> --- dev/usb/if_athn_usb.h 8 Jan 2011 15:18:01 -   1.2
> +++ dev/usb/if_athn_usb.h 10 Nov 2012 02:04:33 -
> @@ -417,6 +417,7 @@ struct athn_usb_host_cmd_ring {
>  struct athn_usb_softc {
>   struct athn_softc   sc_sc;
>  #define usb_dev  sc_sc.sc_dev
> + int sc_athn_attached;
>  
>   /* USB specific goo. */
>   usbd_device_handle  sc_udev;



Re: athn@usb: fixup detach panic

2012-11-09 Thread Mike Belopuhov
On Tue, Nov 06, 2012 at 12:15 +0100, Stefan Sperling wrote:
> On Tue, Nov 06, 2012 at 11:32:19AM +0100, Mike Belopuhov wrote:
> > attach fails early in case there's no firmware, but
> > athn_detach does ieee80211_ifdetach and if_detach
> > regardless of whether ifnet part got setup correctly
> > leading to a free of an unallocated memory and a
> > panic.
> > 
> > the following diff follows an established practice
> > in the other drivers and fixes the problem here.
> > tested on this device:
> > 
> > athn0 at uhub0 port 3 "NETGEAR WNA WNA1100" rev 2.00/1.08 addr 2
> > athn0: AR9271 rev 1 (1T1R), ROM rev 15, address 20:4e:7f:d9:65:2f
> > 
> > ok?
> 
> It seems more appropriate to handle this problem entirely within
> the USB-specific layer of the driver, rather than within dev/ic/athn.c.
> 
> If loading the firmware fails, athn_usb_attachhook() doesn't even
> call athn_attach(). This is what your fix is compensating for. I believe
> athn_usb_detach() shouldn't be calling athn_detach() unconditionally.
> 
> I fixed a similar problem for acx(4) cardbus cards once, where ejecting
> a card that had failed to attach half way through paniced the kernel.
> This was in r1.12 of dev/cardbus/if_acx_cardbus.c, which looked like this:
> 

works for me. ok?

Index: dev/usb/if_athn_usb.c
===
RCS file: /home/cvs/src/sys/dev/usb/if_athn_usb.c,v
retrieving revision 1.8
diff -u -p -r1.8 if_athn_usb.c
--- dev/usb/if_athn_usb.c   3 Jul 2011 15:47:17 -   1.8
+++ dev/usb/if_athn_usb.c   10 Nov 2012 02:04:12 -
@@ -289,7 +289,8 @@ athn_usb_detach(struct device *self, int
struct athn_usb_softc *usc = (struct athn_usb_softc *)self;
struct athn_softc *sc = &usc->sc_sc;
 
-   athn_detach(sc);
+   if (usc->sc_athn_attached)
+   athn_detach(sc);
 
/* Wait for all async commands to complete. */
athn_usb_wait_async(usc);
@@ -347,6 +348,7 @@ athn_usb_attachhook(void *xsc)
splx(s);
return;
}
+   usc->sc_athn_attached = 1;
/* Override some operations for USB. */
ifp->if_ioctl = athn_usb_ioctl;
ifp->if_start = athn_usb_start;
Index: dev/usb/if_athn_usb.h
===
RCS file: /home/cvs/src/sys/dev/usb/if_athn_usb.h,v
retrieving revision 1.2
diff -u -p -r1.2 if_athn_usb.h
--- dev/usb/if_athn_usb.h   8 Jan 2011 15:18:01 -   1.2
+++ dev/usb/if_athn_usb.h   10 Nov 2012 02:04:33 -
@@ -417,6 +417,7 @@ struct athn_usb_host_cmd_ring {
 struct athn_usb_softc {
struct athn_softc   sc_sc;
 #define usb_devsc_sc.sc_dev
+   int sc_athn_attached;
 
/* USB specific goo. */
usbd_device_handle  sc_udev;



Re: athn@usb: fixup detach panic

2012-11-06 Thread Stefan Sperling
On Tue, Nov 06, 2012 at 11:32:19AM +0100, Mike Belopuhov wrote:
> attach fails early in case there's no firmware, but
> athn_detach does ieee80211_ifdetach and if_detach
> regardless of whether ifnet part got setup correctly
> leading to a free of an unallocated memory and a
> panic.
> 
> the following diff follows an established practice
> in the other drivers and fixes the problem here.
> tested on this device:
> 
> athn0 at uhub0 port 3 "NETGEAR WNA WNA1100" rev 2.00/1.08 addr 2
> athn0: AR9271 rev 1 (1T1R), ROM rev 15, address 20:4e:7f:d9:65:2f
> 
> ok?

It seems more appropriate to handle this problem entirely within
the USB-specific layer of the driver, rather than within dev/ic/athn.c.

If loading the firmware fails, athn_usb_attachhook() doesn't even
call athn_attach(). This is what your fix is compensating for. I believe
athn_usb_detach() shouldn't be calling athn_detach() unconditionally.

I fixed a similar problem for acx(4) cardbus cards once, where ejecting
a card that had failed to attach half way through paniced the kernel.
This was in r1.12 of dev/cardbus/if_acx_cardbus.c, which looked like this:

Index: if_acx_cardbus.c
===
RCS file: /cvs/src/sys/dev/cardbus/if_acx_cardbus.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -p -r1.11 -r1.12
--- if_acx_cardbus.c10 Nov 2006 20:20:04 -  1.11
+++ if_acx_cardbus.c26 Feb 2009 23:03:05 -  1.12
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_acx_cardbus.c,v 1.11 2006/11/10 20:20:04 damien Exp $  */
+/* $OpenBSD: if_acx_cardbus.c,v 1.12 2009/02/26 23:03:05 stsp Exp $  */
 
 /*
  * Copyright (c) 2006 Claudio Jeker 
@@ -77,6 +77,8 @@ struct acx_cardbus_softc {
bus_space_tag_t sc_io_bt;
bus_space_handle_t  sc_io_bh;
bus_size_t  sc_iomapsize;
+
+   int sc_acx_attached;
 };
 
 intacx_cardbus_match(struct device *, void *, void *);
@@ -171,7 +173,8 @@ acx_cardbus_attach(struct device *parent
else
acx100_set_param(sc);
 
-   acx_attach(sc);
+   error = acx_attach(sc);
+   csc->sc_acx_attached = error == 0;
 
Cardbus_function_disable(ct);
 }
@@ -186,9 +189,11 @@ acx_cardbus_detach(struct device *self, 
cardbus_function_tag_t cf = ct->ct_cf;
int error, b1 = CARDBUS_BASE0_REG, b2 = CARDBUS_BASE1_REG;
 
-   error = acx_detach(sc);
-   if (error != 0)
-   return (error);
+   if (csc->sc_acx_attached) {
+   error = acx_detach(sc);
+   if (error != 0)
+   return (error);
+   }
 
/* unhook the interrupt handler */
if (csc->sc_ih != NULL) {

> 
> Index: athn.c
> ===
> RCS file: /home/cvs/src/sys/dev/ic/athn.c,v
> retrieving revision 1.74
> diff -u -p -u -p -r1.74 athn.c
> --- athn.c20 Oct 2012 09:54:20 -  1.74
> +++ athn.c1 Nov 2012 16:33:53 -
> @@ -396,8 +396,10 @@ athn_detach(struct athn_softc *sc)
>   if (sc->eep != NULL)
>   free(sc->eep, M_DEVBUF);
>  
> - ieee80211_ifdetach(ifp);
> - if_detach(ifp);
> + if (ifp->if_softc != NULL) {
> + ieee80211_ifdetach(ifp);
> + if_detach(ifp);
> + }
>  }
>  
>  #if NBPFILTER > 0



athn@usb: fixup detach panic

2012-11-06 Thread Mike Belopuhov
attach fails early in case there's no firmware, but
athn_detach does ieee80211_ifdetach and if_detach
regardless of whether ifnet part got setup correctly
leading to a free of an unallocated memory and a
panic.

the following diff follows an established practice
in the other drivers and fixes the problem here.
tested on this device:

athn0 at uhub0 port 3 "NETGEAR WNA WNA1100" rev 2.00/1.08 addr 2
athn0: AR9271 rev 1 (1T1R), ROM rev 15, address 20:4e:7f:d9:65:2f

ok?

Index: athn.c
===
RCS file: /home/cvs/src/sys/dev/ic/athn.c,v
retrieving revision 1.74
diff -u -p -u -p -r1.74 athn.c
--- athn.c  20 Oct 2012 09:54:20 -  1.74
+++ athn.c  1 Nov 2012 16:33:53 -
@@ -396,8 +396,10 @@ athn_detach(struct athn_softc *sc)
if (sc->eep != NULL)
free(sc->eep, M_DEVBUF);
 
-   ieee80211_ifdetach(ifp);
-   if_detach(ifp);
+   if (ifp->if_softc != NULL) {
+   ieee80211_ifdetach(ifp);
+   if_detach(ifp);
+   }
 }
 
 #if NBPFILTER > 0