Wed Aug 28 06:07:21 2019 UTC ()
in usbnet_detach(), check both that the private pointer has
been allocated and that unp_attached is true before trying
to access anything else.

fixes a detach problem noticed by maxv when, eg, the call
to usbd_set_config_no() fails and attach bails early.


(mrg)
diff -r1.23 -r1.24 src/sys/dev/usb/usbnet.c

cvs diff -r1.23 -r1.24 src/sys/dev/usb/usbnet.c (switch to unified diff)

--- src/sys/dev/usb/usbnet.c 2019/08/23 04:29:28 1.23
+++ src/sys/dev/usb/usbnet.c 2019/08/28 06:07:21 1.24
@@ -1,1565 +1,1566 @@ @@ -1,1565 +1,1566 @@
1/* $NetBSD: usbnet.c,v 1.23 2019/08/23 04:29:28 mrg Exp $ */ 1/* $NetBSD: usbnet.c,v 1.24 2019/08/28 06:07:21 mrg Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2019 Matthew R. Green 4 * Copyright (c) 2019 Matthew R. Green
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products 15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission. 16 * derived from this software without specific prior written permission.
17 * 17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 25 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE. 28 * SUCH DAMAGE.
29 */ 29 */
30 30
31/* 31/*
32 * Common code shared between USB network drivers. 32 * Common code shared between USB network drivers.
33 */ 33 */
34 34
35#include <sys/cdefs.h> 35#include <sys/cdefs.h>
36__KERNEL_RCSID(0, "$NetBSD: usbnet.c,v 1.23 2019/08/23 04:29:28 mrg Exp $"); 36__KERNEL_RCSID(0, "$NetBSD: usbnet.c,v 1.24 2019/08/28 06:07:21 mrg Exp $");
37 37
38#include <sys/param.h> 38#include <sys/param.h>
39#include <sys/kernel.h> 39#include <sys/kernel.h>
40#include <sys/kmem.h> 40#include <sys/kmem.h>
41#include <sys/module.h> 41#include <sys/module.h>
42#include <sys/atomic.h> 42#include <sys/atomic.h>
43 43
44#include <dev/usb/usbnet.h> 44#include <dev/usb/usbnet.h>
45#include <dev/usb/usbhist.h> 45#include <dev/usb/usbhist.h>
46 46
47struct usbnet_cdata { 47struct usbnet_cdata {
48 struct usbnet_chain *uncd_tx_chain; 48 struct usbnet_chain *uncd_tx_chain;
49 struct usbnet_chain *uncd_rx_chain; 49 struct usbnet_chain *uncd_rx_chain;
50 50
51 int uncd_tx_prod; 51 int uncd_tx_prod;
52 int uncd_tx_cnt; 52 int uncd_tx_cnt;
53}; 53};
54 54
55struct usbnet_private { 55struct usbnet_private {
56 /* 56 /*
57 * - unp_lock protects most of the structure, and the public one 57 * - unp_lock protects most of the structure, and the public one
58 * - unp_miilock must be held to access this device's MII bus 58 * - unp_miilock must be held to access this device's MII bus
59 * - unp_rxlock protects the rx path and its data 59 * - unp_rxlock protects the rx path and its data
60 * - unp_txlock protects the tx path and its data 60 * - unp_txlock protects the tx path and its data
61 * - unp_detachcv handles detach vs open references 61 * - unp_detachcv handles detach vs open references
62 */ 62 */
63 kmutex_t unp_lock; 63 kmutex_t unp_lock;
64 kmutex_t unp_miilock; 64 kmutex_t unp_miilock;
65 kmutex_t unp_rxlock; 65 kmutex_t unp_rxlock;
66 kmutex_t unp_txlock; 66 kmutex_t unp_txlock;
67 kcondvar_t unp_detachcv; 67 kcondvar_t unp_detachcv;
68 68
69 struct usbnet_cdata unp_cdata; 69 struct usbnet_cdata unp_cdata;
70 70
71 struct ethercom unp_ec; 71 struct ethercom unp_ec;
72 struct mii_data unp_mii; 72 struct mii_data unp_mii;
73 struct usb_task unp_ticktask; 73 struct usb_task unp_ticktask;
74 struct callout unp_stat_ch; 74 struct callout unp_stat_ch;
75 struct usbd_pipe *unp_ep[USBNET_ENDPT_MAX]; 75 struct usbd_pipe *unp_ep[USBNET_ENDPT_MAX];
76 76
77 bool unp_dying; 77 bool unp_dying;
78 bool unp_stopping; 78 bool unp_stopping;
79 bool unp_attached; 79 bool unp_attached;
80 bool unp_link; 80 bool unp_link;
81 81
82 int unp_refcnt; 82 int unp_refcnt;
83 int unp_timer; 83 int unp_timer;
84 int unp_if_flags; 84 int unp_if_flags;
85 unsigned unp_number; 85 unsigned unp_number;
86 86
87 krndsource_t unp_rndsrc; 87 krndsource_t unp_rndsrc;
88 88
89 struct timeval unp_rx_notice; 89 struct timeval unp_rx_notice;
90 struct timeval unp_tx_notice; 90 struct timeval unp_tx_notice;
91 struct timeval unp_intr_notice; 91 struct timeval unp_intr_notice;
92}; 92};
93 93
94#define un_cdata(un) (&(un)->un_pri->unp_cdata) 94#define un_cdata(un) (&(un)->un_pri->unp_cdata)
95 95
96volatile unsigned usbnet_number; 96volatile unsigned usbnet_number;
97 97
98static int usbnet_modcmd(modcmd_t, void *); 98static int usbnet_modcmd(modcmd_t, void *);
99 99
100#ifdef USB_DEBUG 100#ifdef USB_DEBUG
101#ifndef USBNET_DEBUG 101#ifndef USBNET_DEBUG
102#define usbnetdebug 0 102#define usbnetdebug 0
103#else 103#else
104static int usbnetdebug = 1; 104static int usbnetdebug = 1;
105 105
106SYSCTL_SETUP(sysctl_hw_usbnet_setup, "sysctl hw.usbnet setup") 106SYSCTL_SETUP(sysctl_hw_usbnet_setup, "sysctl hw.usbnet setup")
107{ 107{
108 int err; 108 int err;
109 const struct sysctlnode *rnode; 109 const struct sysctlnode *rnode;
110 const struct sysctlnode *cnode; 110 const struct sysctlnode *cnode;
111 111
112 err = sysctl_createv(clog, 0, NULL, &rnode, 112 err = sysctl_createv(clog, 0, NULL, &rnode,
113 CTLFLAG_PERMANENT, CTLTYPE_NODE, "usbnet", 113 CTLFLAG_PERMANENT, CTLTYPE_NODE, "usbnet",
114 SYSCTL_DESCR("usbnet global controls"), 114 SYSCTL_DESCR("usbnet global controls"),
115 NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL); 115 NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL);
116 116
117 if (err) 117 if (err)
118 goto fail; 118 goto fail;
119 119
120 /* control debugging printfs */ 120 /* control debugging printfs */
121 err = sysctl_createv(clog, 0, &rnode, &cnode, 121 err = sysctl_createv(clog, 0, &rnode, &cnode,
122 CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT, 122 CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_INT,
123 "debug", SYSCTL_DESCR("Enable debugging output"), 123 "debug", SYSCTL_DESCR("Enable debugging output"),
124 NULL, 0, &usbnetdebug, sizeof(usbnetdebug), CTL_CREATE, CTL_EOL); 124 NULL, 0, &usbnetdebug, sizeof(usbnetdebug), CTL_CREATE, CTL_EOL);
125 if (err) 125 if (err)
126 goto fail; 126 goto fail;
127 127
128 return; 128 return;
129fail: 129fail:
130 aprint_error("%s: sysctl_createv failed (err = %d)\n", __func__, err); 130 aprint_error("%s: sysctl_createv failed (err = %d)\n", __func__, err);
131} 131}
132 132
133#endif /* USBNET_DEBUG */ 133#endif /* USBNET_DEBUG */
134#endif /* USB_DEBUG */ 134#endif /* USB_DEBUG */
135 135
136#define DPRINTF(FMT,A,B,C,D) USBHIST_LOGN(usbnetdebug,1,FMT,A,B,C,D) 136#define DPRINTF(FMT,A,B,C,D) USBHIST_LOGN(usbnetdebug,1,FMT,A,B,C,D)
137#define DPRINTFN(N,FMT,A,B,C,D) USBHIST_LOGN(usbnetdebug,N,FMT,A,B,C,D) 137#define DPRINTFN(N,FMT,A,B,C,D) USBHIST_LOGN(usbnetdebug,N,FMT,A,B,C,D)
138#define USBNETHIST_FUNC() USBHIST_FUNC() 138#define USBNETHIST_FUNC() USBHIST_FUNC()
139#define USBNETHIST_CALLED(name) USBHIST_CALLED(usbnetdebug) 139#define USBNETHIST_CALLED(name) USBHIST_CALLED(usbnetdebug)
140#define USBNETHIST_CALLARGS(FMT,A,B,C,D) \ 140#define USBNETHIST_CALLARGS(FMT,A,B,C,D) \
141 USBHIST_CALLARGS(usbnetdebug,FMT,A,B,C,D) 141 USBHIST_CALLARGS(usbnetdebug,FMT,A,B,C,D)
142#define USBNETHIST_CALLARGSN(N,FMT,A,B,C,D) \ 142#define USBNETHIST_CALLARGSN(N,FMT,A,B,C,D) \
143 USBHIST_CALLARGSN(usbnetdebug,N,FMT,A,B,C,D) 143 USBHIST_CALLARGSN(usbnetdebug,N,FMT,A,B,C,D)
144 144
145/* Callback vectors. */ 145/* Callback vectors. */
146 146
147static void 147static void
148uno_stop(struct usbnet *un, struct ifnet *ifp, int disable) 148uno_stop(struct usbnet *un, struct ifnet *ifp, int disable)
149{ 149{
150 if (un->un_ops->uno_stop) 150 if (un->un_ops->uno_stop)
151 (*un->un_ops->uno_stop)(ifp, disable); 151 (*un->un_ops->uno_stop)(ifp, disable);
152} 152}
153 153
154static int 154static int
155uno_ioctl(struct usbnet *un, struct ifnet *ifp, u_long cmd, void *data) 155uno_ioctl(struct usbnet *un, struct ifnet *ifp, u_long cmd, void *data)
156{ 156{
157 if (un->un_ops->uno_ioctl) 157 if (un->un_ops->uno_ioctl)
158 return (*un->un_ops->uno_ioctl)(ifp, cmd, data); 158 return (*un->un_ops->uno_ioctl)(ifp, cmd, data);
159 return 0; 159 return 0;
160} 160}
161 161
162static int 162static int
163uno_override_ioctl(struct usbnet *un, struct ifnet *ifp, u_long cmd, void *data) 163uno_override_ioctl(struct usbnet *un, struct ifnet *ifp, u_long cmd, void *data)
164{ 164{
165 return (*un->un_ops->uno_override_ioctl)(ifp, cmd, data); 165 return (*un->un_ops->uno_override_ioctl)(ifp, cmd, data);
166} 166}
167 167
168static int 168static int
169uno_init(struct usbnet *un, struct ifnet *ifp) 169uno_init(struct usbnet *un, struct ifnet *ifp)
170{ 170{
171 return (*un->un_ops->uno_init)(ifp); 171 return (*un->un_ops->uno_init)(ifp);
172} 172}
173 173
174static int 174static int
175uno_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val) 175uno_read_reg(struct usbnet *un, int phy, int reg, uint16_t *val)
176{ 176{
177 return (*un->un_ops->uno_read_reg)(un, phy, reg, val); 177 return (*un->un_ops->uno_read_reg)(un, phy, reg, val);
178} 178}
179 179
180static int 180static int
181uno_write_reg(struct usbnet *un, int phy, int reg, uint16_t val) 181uno_write_reg(struct usbnet *un, int phy, int reg, uint16_t val)
182{ 182{
183 return (*un->un_ops->uno_write_reg)(un, phy, reg, val); 183 return (*un->un_ops->uno_write_reg)(un, phy, reg, val);
184} 184}
185 185
186static void 186static void
187uno_mii_statchg(struct usbnet *un, struct ifnet *ifp) 187uno_mii_statchg(struct usbnet *un, struct ifnet *ifp)
188{ 188{
189 (*un->un_ops->uno_statchg)(ifp); 189 (*un->un_ops->uno_statchg)(ifp);
190} 190}
191 191
192static unsigned 192static unsigned
193uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c) 193uno_tx_prepare(struct usbnet *un, struct mbuf *m, struct usbnet_chain *c)
194{ 194{
195 return (*un->un_ops->uno_tx_prepare)(un, m, c); 195 return (*un->un_ops->uno_tx_prepare)(un, m, c);
196} 196}
197 197
198static void 198static void
199uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len) 199uno_rx_loop(struct usbnet *un, struct usbnet_chain *c, uint32_t total_len)
200{ 200{
201 (*un->un_ops->uno_rx_loop)(un, c, total_len); 201 (*un->un_ops->uno_rx_loop)(un, c, total_len);
202} 202}
203 203
204static void 204static void
205uno_tick(struct usbnet *un) 205uno_tick(struct usbnet *un)
206{ 206{
207 if (un->un_ops->uno_tick) 207 if (un->un_ops->uno_tick)
208 (*un->un_ops->uno_tick)(un); 208 (*un->un_ops->uno_tick)(un);
209} 209}
210 210
211static void 211static void
212uno_intr(struct usbnet *un, usbd_status status) 212uno_intr(struct usbnet *un, usbd_status status)
213{ 213{
214 if (un->un_ops->uno_intr) 214 if (un->un_ops->uno_intr)
215 (*un->un_ops->uno_intr)(un, status); 215 (*un->un_ops->uno_intr)(un, status);
216} 216}
217 217
218/* Interrupt handling. */ 218/* Interrupt handling. */
219 219
220static struct mbuf * 220static struct mbuf *
221usbnet_newbuf(size_t buflen) 221usbnet_newbuf(size_t buflen)
222{ 222{
223 struct mbuf *m; 223 struct mbuf *m;
224 224
225 MGETHDR(m, M_DONTWAIT, MT_DATA); 225 MGETHDR(m, M_DONTWAIT, MT_DATA);
226 if (m == NULL) 226 if (m == NULL)
227 return NULL; 227 return NULL;
228 228
229 if (buflen > MHLEN - ETHER_ALIGN) { 229 if (buflen > MHLEN - ETHER_ALIGN) {
230 MCLGET(m, M_DONTWAIT); 230 MCLGET(m, M_DONTWAIT);
231 if (!(m->m_flags & M_EXT)) { 231 if (!(m->m_flags & M_EXT)) {
232 m_freem(m); 232 m_freem(m);
233 return NULL; 233 return NULL;
234 } 234 }
235 } 235 }
236 236
237 m_adj(m, ETHER_ALIGN); 237 m_adj(m, ETHER_ALIGN);
238 m->m_len = m->m_pkthdr.len = buflen; 238 m->m_len = m->m_pkthdr.len = buflen;
239 239
240 return m; 240 return m;
241} 241}
242 242
243/* 243/*
244 * usbnet_rxeof() is designed to be the done callback for rx completion. 244 * usbnet_rxeof() is designed to be the done callback for rx completion.
245 * it provides generic setup and finalisation, calls a different usbnet 245 * it provides generic setup and finalisation, calls a different usbnet
246 * rx_loop callback in the middle, which can use usbnet_enqueue() to 246 * rx_loop callback in the middle, which can use usbnet_enqueue() to
247 * enqueue a packet for higher levels (or usbnet_input() if previously 247 * enqueue a packet for higher levels (or usbnet_input() if previously
248 * using if_input() path.) 248 * using if_input() path.)
249 */ 249 */
250void 250void
251usbnet_enqueue(struct usbnet * const un, uint8_t *buf, size_t buflen, 251usbnet_enqueue(struct usbnet * const un, uint8_t *buf, size_t buflen,
252 int csum_flags, uint32_t csum_data, int mbuf_flags) 252 int csum_flags, uint32_t csum_data, int mbuf_flags)
253{ 253{
254 USBNETHIST_FUNC(); 254 USBNETHIST_FUNC();
255 struct ifnet * const ifp = usbnet_ifp(un); 255 struct ifnet * const ifp = usbnet_ifp(un);
256 struct usbnet_private * const unp __unused = un->un_pri; 256 struct usbnet_private * const unp __unused = un->un_pri;
257 struct mbuf *m; 257 struct mbuf *m;
258 258
259 USBNETHIST_CALLARGSN(5, "%d: enter: len=%zu csf %x mbf %x", 259 USBNETHIST_CALLARGSN(5, "%d: enter: len=%zu csf %x mbf %x",
260 unp->unp_number, buflen, csum_flags, mbuf_flags); 260 unp->unp_number, buflen, csum_flags, mbuf_flags);
261 261
262 usbnet_isowned_rx(un); 262 usbnet_isowned_rx(un);
263 263
264 m = usbnet_newbuf(buflen); 264 m = usbnet_newbuf(buflen);
265 if (m == NULL) { 265 if (m == NULL) {
266 DPRINTF("%d: no memory", unp->unp_number, 0, 0, 0); 266 DPRINTF("%d: no memory", unp->unp_number, 0, 0, 0);
267 ifp->if_ierrors++; 267 ifp->if_ierrors++;
268 return; 268 return;
269 } 269 }
270 270
271 m_set_rcvif(m, ifp); 271 m_set_rcvif(m, ifp);
272 m->m_pkthdr.csum_flags = csum_flags; 272 m->m_pkthdr.csum_flags = csum_flags;
273 m->m_pkthdr.csum_data = csum_data; 273 m->m_pkthdr.csum_data = csum_data;
274 m->m_flags |= mbuf_flags; 274 m->m_flags |= mbuf_flags;
275 memcpy(mtod(m, uint8_t *), buf, buflen); 275 memcpy(mtod(m, uint8_t *), buf, buflen);
276 276
277 /* push the packet up */ 277 /* push the packet up */
278 if_percpuq_enqueue(ifp->if_percpuq, m); 278 if_percpuq_enqueue(ifp->if_percpuq, m);
279} 279}
280 280
281void 281void
282usbnet_input(struct usbnet * const un, uint8_t *buf, size_t buflen) 282usbnet_input(struct usbnet * const un, uint8_t *buf, size_t buflen)
283{ 283{
284 USBNETHIST_FUNC(); 284 USBNETHIST_FUNC();
285 struct ifnet * const ifp = usbnet_ifp(un); 285 struct ifnet * const ifp = usbnet_ifp(un);
286 struct usbnet_private * const unp __unused = un->un_pri; 286 struct usbnet_private * const unp __unused = un->un_pri;
287 struct mbuf *m; 287 struct mbuf *m;
288 288
289 USBNETHIST_CALLARGSN(5, "%d: enter: buf %jx len %ju", 289 USBNETHIST_CALLARGSN(5, "%d: enter: buf %jx len %ju",
290 unp->unp_number, (uintptr_t)buf, buflen, 0); 290 unp->unp_number, (uintptr_t)buf, buflen, 0);
291 291
292 usbnet_isowned_rx(un); 292 usbnet_isowned_rx(un);
293 293
294 m = usbnet_newbuf(buflen); 294 m = usbnet_newbuf(buflen);
295 if (m == NULL) { 295 if (m == NULL) {
296 ifp->if_ierrors++; 296 ifp->if_ierrors++;
297 return; 297 return;
298 } 298 }
299 299
300 m_set_rcvif(m, ifp); 300 m_set_rcvif(m, ifp);
301 memcpy(mtod(m, char *), buf, buflen); 301 memcpy(mtod(m, char *), buf, buflen);
302 302
303 /* push the packet up */ 303 /* push the packet up */
304 if_input(ifp, m); 304 if_input(ifp, m);
305} 305}
306 306
307/* 307/*
308 * A frame has been uploaded: pass the resulting mbuf chain up to 308 * A frame has been uploaded: pass the resulting mbuf chain up to
309 * the higher level protocols. 309 * the higher level protocols.
310 */ 310 */
311static void 311static void
312usbnet_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status) 312usbnet_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
313{ 313{
314 USBNETHIST_FUNC(); 314 USBNETHIST_FUNC();
315 struct usbnet_chain * const c = priv; 315 struct usbnet_chain * const c = priv;
316 struct usbnet * const un = c->unc_un; 316 struct usbnet * const un = c->unc_un;
317 struct usbnet_private * const unp = un->un_pri; 317 struct usbnet_private * const unp = un->un_pri;
318 struct ifnet * const ifp = usbnet_ifp(un); 318 struct ifnet * const ifp = usbnet_ifp(un);
319 uint32_t total_len; 319 uint32_t total_len;
320 320
321 USBNETHIST_CALLARGSN(5, "%d: enter: status %x xfer %jx", 321 USBNETHIST_CALLARGSN(5, "%d: enter: status %x xfer %jx",
322 unp->unp_number, status, (uintptr_t)xfer, 0); 322 unp->unp_number, status, (uintptr_t)xfer, 0);
323 323
324 mutex_enter(&unp->unp_rxlock); 324 mutex_enter(&unp->unp_rxlock);
325 325
326 if (unp->unp_dying || unp->unp_stopping || 326 if (unp->unp_dying || unp->unp_stopping ||
327 status == USBD_INVAL || status == USBD_NOT_STARTED || 327 status == USBD_INVAL || status == USBD_NOT_STARTED ||
328 status == USBD_CANCELLED || !(ifp->if_flags & IFF_RUNNING)) 328 status == USBD_CANCELLED || !(ifp->if_flags & IFF_RUNNING))
329 goto out; 329 goto out;
330 330
331 if (status != USBD_NORMAL_COMPLETION) { 331 if (status != USBD_NORMAL_COMPLETION) {
332 if (usbd_ratecheck(&unp->unp_rx_notice)) 332 if (usbd_ratecheck(&unp->unp_rx_notice))
333 aprint_error_dev(un->un_dev, "usb errors on rx: %s\n", 333 aprint_error_dev(un->un_dev, "usb errors on rx: %s\n",
334 usbd_errstr(status)); 334 usbd_errstr(status));
335 if (status == USBD_STALLED) 335 if (status == USBD_STALLED)
336 usbd_clear_endpoint_stall_async(unp->unp_ep[USBNET_ENDPT_RX]); 336 usbd_clear_endpoint_stall_async(unp->unp_ep[USBNET_ENDPT_RX]);
337 goto done; 337 goto done;
338 } 338 }
339 339
340 usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL); 340 usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
341 341
342 if (total_len > un->un_rx_bufsz) { 342 if (total_len > un->un_rx_bufsz) {
343 aprint_error_dev(un->un_dev, 343 aprint_error_dev(un->un_dev,
344 "rxeof: too large transfer (%u > %u)\n", 344 "rxeof: too large transfer (%u > %u)\n",
345 total_len, un->un_rx_bufsz); 345 total_len, un->un_rx_bufsz);
346 goto done; 346 goto done;
347 } 347 }
348 348
349 uno_rx_loop(un, c, total_len); 349 uno_rx_loop(un, c, total_len);
350 usbnet_isowned_rx(un); 350 usbnet_isowned_rx(un);
351 351
352done: 352done:
353 if (unp->unp_dying || unp->unp_stopping) 353 if (unp->unp_dying || unp->unp_stopping)
354 goto out; 354 goto out;
355 355
356 mutex_exit(&unp->unp_rxlock); 356 mutex_exit(&unp->unp_rxlock);
357 357
358 /* Setup new transfer. */ 358 /* Setup new transfer. */
359 usbd_setup_xfer(xfer, c, c->unc_buf, un->un_rx_bufsz, 359 usbd_setup_xfer(xfer, c, c->unc_buf, un->un_rx_bufsz,
360 un->un_rx_xfer_flags, USBD_NO_TIMEOUT, usbnet_rxeof); 360 un->un_rx_xfer_flags, USBD_NO_TIMEOUT, usbnet_rxeof);
361 usbd_transfer(xfer); 361 usbd_transfer(xfer);
362 return; 362 return;
363 363
364out: 364out:
365 mutex_exit(&unp->unp_rxlock); 365 mutex_exit(&unp->unp_rxlock);
366} 366}
367 367
368static void 368static void
369usbnet_txeof(struct usbd_xfer *xfer, void *priv, usbd_status status) 369usbnet_txeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
370{ 370{
371 USBNETHIST_FUNC(); USBNETHIST_CALLED(); 371 USBNETHIST_FUNC(); USBNETHIST_CALLED();
372 struct usbnet_chain * const c = priv; 372 struct usbnet_chain * const c = priv;
373 struct usbnet * const un = c->unc_un; 373 struct usbnet * const un = c->unc_un;
374 struct usbnet_cdata * const cd = un_cdata(un); 374 struct usbnet_cdata * const cd = un_cdata(un);
375 struct usbnet_private * const unp = un->un_pri; 375 struct usbnet_private * const unp = un->un_pri;
376 struct ifnet * const ifp = usbnet_ifp(un); 376 struct ifnet * const ifp = usbnet_ifp(un);
377 377
378 USBNETHIST_CALLARGSN(5, "%d: enter: status %x xfer %jx", 378 USBNETHIST_CALLARGSN(5, "%d: enter: status %x xfer %jx",
379 unp->unp_number, status, (uintptr_t)xfer, 0); 379 unp->unp_number, status, (uintptr_t)xfer, 0);
380 380
381 mutex_enter(&unp->unp_txlock); 381 mutex_enter(&unp->unp_txlock);
382 if (unp->unp_stopping || unp->unp_dying) { 382 if (unp->unp_stopping || unp->unp_dying) {
383 mutex_exit(&unp->unp_txlock); 383 mutex_exit(&unp->unp_txlock);
384 return; 384 return;
385 } 385 }
386 386
387 KASSERT(cd->uncd_tx_cnt > 0); 387 KASSERT(cd->uncd_tx_cnt > 0);
388 cd->uncd_tx_cnt--; 388 cd->uncd_tx_cnt--;
389 389
390 unp->unp_timer = 0; 390 unp->unp_timer = 0;
391 391
392 switch (status) { 392 switch (status) {
393 case USBD_NOT_STARTED: 393 case USBD_NOT_STARTED:
394 case USBD_CANCELLED: 394 case USBD_CANCELLED:
395 break; 395 break;
396 396
397 case USBD_NORMAL_COMPLETION: 397 case USBD_NORMAL_COMPLETION:
398 ifp->if_opackets++; 398 ifp->if_opackets++;
399 break; 399 break;
400 400
401 default: 401 default:
402 402
403 ifp->if_oerrors++; 403 ifp->if_oerrors++;
404 if (usbd_ratecheck(&unp->unp_tx_notice)) 404 if (usbd_ratecheck(&unp->unp_tx_notice))
405 aprint_error_dev(un->un_dev, "usb error on tx: %s\n", 405 aprint_error_dev(un->un_dev, "usb error on tx: %s\n",
406 usbd_errstr(status)); 406 usbd_errstr(status));
407 if (status == USBD_STALLED) 407 if (status == USBD_STALLED)
408 usbd_clear_endpoint_stall_async(unp->unp_ep[USBNET_ENDPT_TX]); 408 usbd_clear_endpoint_stall_async(unp->unp_ep[USBNET_ENDPT_TX]);
409 break; 409 break;
410 } 410 }
411 411
412 mutex_exit(&unp->unp_txlock); 412 mutex_exit(&unp->unp_txlock);
413 413
414 if (status == USBD_NORMAL_COMPLETION && !IFQ_IS_EMPTY(&ifp->if_snd)) 414 if (status == USBD_NORMAL_COMPLETION && !IFQ_IS_EMPTY(&ifp->if_snd))
415 (*ifp->if_start)(ifp); 415 (*ifp->if_start)(ifp);
416} 416}
417 417
418static void 418static void
419usbnet_pipe_intr(struct usbd_xfer *xfer, void *priv, usbd_status status) 419usbnet_pipe_intr(struct usbd_xfer *xfer, void *priv, usbd_status status)
420{ 420{
421 struct usbnet * const un = priv; 421 struct usbnet * const un = priv;
422 struct usbnet_private * const unp = un->un_pri; 422 struct usbnet_private * const unp = un->un_pri;
423 struct usbnet_intr * const uni = un->un_intr; 423 struct usbnet_intr * const uni = un->un_intr;
424 struct ifnet * const ifp = usbnet_ifp(un); 424 struct ifnet * const ifp = usbnet_ifp(un);
425 425
426 if (uni == NULL || unp->unp_dying || unp->unp_stopping || 426 if (uni == NULL || unp->unp_dying || unp->unp_stopping ||
427 status == USBD_INVAL || status == USBD_NOT_STARTED || 427 status == USBD_INVAL || status == USBD_NOT_STARTED ||
428 status == USBD_CANCELLED || !(ifp->if_flags & IFF_RUNNING)) 428 status == USBD_CANCELLED || !(ifp->if_flags & IFF_RUNNING))
429 return; 429 return;
430 430
431 if (status != USBD_NORMAL_COMPLETION) { 431 if (status != USBD_NORMAL_COMPLETION) {
432 if (usbd_ratecheck(&unp->unp_intr_notice)) { 432 if (usbd_ratecheck(&unp->unp_intr_notice)) {
433 aprint_error_dev(un->un_dev, "usb error on intr: %s\n", 433 aprint_error_dev(un->un_dev, "usb error on intr: %s\n",
434 usbd_errstr(status)); 434 usbd_errstr(status));
435 } 435 }
436 if (status == USBD_STALLED) 436 if (status == USBD_STALLED)
437 usbd_clear_endpoint_stall_async(unp->unp_ep[USBNET_ENDPT_INTR]); 437 usbd_clear_endpoint_stall_async(unp->unp_ep[USBNET_ENDPT_INTR]);
438 return; 438 return;
439 } 439 }
440 440
441 uno_intr(un, status); 441 uno_intr(un, status);
442} 442}
443 443
444static void 444static void
445usbnet_start_locked(struct ifnet *ifp) 445usbnet_start_locked(struct ifnet *ifp)
446{ 446{
447 USBNETHIST_FUNC(); USBNETHIST_CALLED(); 447 USBNETHIST_FUNC(); USBNETHIST_CALLED();
448 struct usbnet * const un = ifp->if_softc; 448 struct usbnet * const un = ifp->if_softc;
449 struct usbnet_cdata * const cd = un_cdata(un); 449 struct usbnet_cdata * const cd = un_cdata(un);
450 struct usbnet_private * const unp = un->un_pri; 450 struct usbnet_private * const unp = un->un_pri;
451 struct mbuf *m; 451 struct mbuf *m;
452 unsigned length; 452 unsigned length;
453 int idx; 453 int idx;
454 454
455 usbnet_isowned_tx(un); 455 usbnet_isowned_tx(un);
456 KASSERT(cd->uncd_tx_cnt <= un->un_tx_list_cnt); 456 KASSERT(cd->uncd_tx_cnt <= un->un_tx_list_cnt);
457 457
458 if (!unp->unp_link || (ifp->if_flags & IFF_RUNNING) == 0) { 458 if (!unp->unp_link || (ifp->if_flags & IFF_RUNNING) == 0) {
459 DPRINTF("start called no link (%x) or running (flags %x)", 459 DPRINTF("start called no link (%x) or running (flags %x)",
460 unp->unp_link, ifp->if_flags, 0, 0); 460 unp->unp_link, ifp->if_flags, 0, 0);
461 return; 461 return;
462 } 462 }
463 463
464 if (cd->uncd_tx_cnt == un->un_tx_list_cnt) { 464 if (cd->uncd_tx_cnt == un->un_tx_list_cnt) {
465 DPRINTF("start called, tx busy (%jx == %jx)", 465 DPRINTF("start called, tx busy (%jx == %jx)",
466 cd->uncd_tx_cnt, un->un_tx_list_cnt, 0, 0); 466 cd->uncd_tx_cnt, un->un_tx_list_cnt, 0, 0);
467 return; 467 return;
468 } 468 }
469 469
470 idx = cd->uncd_tx_prod; 470 idx = cd->uncd_tx_prod;
471 while (cd->uncd_tx_cnt < un->un_tx_list_cnt) { 471 while (cd->uncd_tx_cnt < un->un_tx_list_cnt) {
472 IFQ_POLL(&ifp->if_snd, m); 472 IFQ_POLL(&ifp->if_snd, m);
473 if (m == NULL) { 473 if (m == NULL) {
474 DPRINTF("start called, queue empty", 0, 0, 0, 0); 474 DPRINTF("start called, queue empty", 0, 0, 0, 0);
475 break; 475 break;
476 } 476 }
477 KASSERT(m->m_pkthdr.len <= un->un_tx_bufsz); 477 KASSERT(m->m_pkthdr.len <= un->un_tx_bufsz);
478 478
479 struct usbnet_chain *c = &cd->uncd_tx_chain[idx]; 479 struct usbnet_chain *c = &cd->uncd_tx_chain[idx];
480 480
481 length = uno_tx_prepare(un, m, c); 481 length = uno_tx_prepare(un, m, c);
482 if (length == 0) { 482 if (length == 0) {
483 DPRINTF("uno_tx_prepare gave zero length", 0, 0, 0, 0); 483 DPRINTF("uno_tx_prepare gave zero length", 0, 0, 0, 0);
484 ifp->if_oerrors++; 484 ifp->if_oerrors++;
485 break; 485 break;
486 } 486 }
487 487
488 if (__predict_false(c->unc_xfer == NULL)) { 488 if (__predict_false(c->unc_xfer == NULL)) {
489 DPRINTF("unc_xfer is NULL", 0, 0, 0, 0); 489 DPRINTF("unc_xfer is NULL", 0, 0, 0, 0);
490 ifp->if_oerrors++; 490 ifp->if_oerrors++;
491 break; 491 break;
492 } 492 }
493 493
494 usbd_setup_xfer(c->unc_xfer, c, c->unc_buf, length, 494 usbd_setup_xfer(c->unc_xfer, c, c->unc_buf, length,
495 un->un_tx_xfer_flags, 10000, usbnet_txeof); 495 un->un_tx_xfer_flags, 10000, usbnet_txeof);
496 496
497 /* Transmit */ 497 /* Transmit */
498 usbd_status err = usbd_transfer(c->unc_xfer); 498 usbd_status err = usbd_transfer(c->unc_xfer);
499 if (err != USBD_IN_PROGRESS) { 499 if (err != USBD_IN_PROGRESS) {
500 DPRINTF("usbd_transfer on %jx for %ju bytes: %d", 500 DPRINTF("usbd_transfer on %jx for %ju bytes: %d",
501 (uintptr_t)c->unc_buf, length, err, 0); 501 (uintptr_t)c->unc_buf, length, err, 0);
502 ifp->if_oerrors++; 502 ifp->if_oerrors++;
503 break; 503 break;
504 } 504 }
505 505
506 IFQ_DEQUEUE(&ifp->if_snd, m); 506 IFQ_DEQUEUE(&ifp->if_snd, m);
507 507
508 /* 508 /*
509 * If there's a BPF listener, bounce a copy of this frame 509 * If there's a BPF listener, bounce a copy of this frame
510 * to him. 510 * to him.
511 */ 511 */
512 bpf_mtap(ifp, m, BPF_D_OUT); 512 bpf_mtap(ifp, m, BPF_D_OUT);
513 m_freem(m); 513 m_freem(m);
514 514
515 idx = (idx + 1) % un->un_tx_list_cnt; 515 idx = (idx + 1) % un->un_tx_list_cnt;
516 cd->uncd_tx_cnt++; 516 cd->uncd_tx_cnt++;
517 } 517 }
518 cd->uncd_tx_prod = idx; 518 cd->uncd_tx_prod = idx;
519 519
520 /* 520 /*
521 * Set a timeout in case the chip goes out to lunch. 521 * Set a timeout in case the chip goes out to lunch.
522 */ 522 */
523 unp->unp_timer = 5; 523 unp->unp_timer = 5;
524} 524}
525 525
526static void 526static void
527usbnet_start(struct ifnet *ifp) 527usbnet_start(struct ifnet *ifp)
528{ 528{
529 struct usbnet * const un = ifp->if_softc; 529 struct usbnet * const un = ifp->if_softc;
530 struct usbnet_private * const unp = un->un_pri; 530 struct usbnet_private * const unp = un->un_pri;
531 531
532 mutex_enter(&unp->unp_txlock); 532 mutex_enter(&unp->unp_txlock);
533 if (!unp->unp_stopping) 533 if (!unp->unp_stopping)
534 usbnet_start_locked(ifp); 534 usbnet_start_locked(ifp);
535 mutex_exit(&unp->unp_txlock); 535 mutex_exit(&unp->unp_txlock);
536} 536}
537 537
538/* 538/*
539 * Chain management. 539 * Chain management.
540 * 540 *
541 * RX and TX are identical. Keep them that way. 541 * RX and TX are identical. Keep them that way.
542 */ 542 */
543 543
544/* Start of common RX functions */ 544/* Start of common RX functions */
545 545
546static size_t 546static size_t
547usbnet_rx_list_size(struct usbnet_cdata * const cd, struct usbnet * const un) 547usbnet_rx_list_size(struct usbnet_cdata * const cd, struct usbnet * const un)
548{ 548{
549 return sizeof(*cd->uncd_rx_chain) * un->un_rx_list_cnt; 549 return sizeof(*cd->uncd_rx_chain) * un->un_rx_list_cnt;
550} 550}
551 551
552static void 552static void
553usbnet_rx_list_alloc(struct usbnet * const un) 553usbnet_rx_list_alloc(struct usbnet * const un)
554{ 554{
555 struct usbnet_cdata * const cd = un_cdata(un); 555 struct usbnet_cdata * const cd = un_cdata(un);
556 556
557 cd->uncd_rx_chain = kmem_zalloc(usbnet_rx_list_size(cd, un), KM_SLEEP); 557 cd->uncd_rx_chain = kmem_zalloc(usbnet_rx_list_size(cd, un), KM_SLEEP);
558} 558}
559 559
560static void 560static void
561usbnet_rx_list_free(struct usbnet * const un) 561usbnet_rx_list_free(struct usbnet * const un)
562{ 562{
563 struct usbnet_cdata * const cd = un_cdata(un); 563 struct usbnet_cdata * const cd = un_cdata(un);
564 564
565 if (cd->uncd_rx_chain) { 565 if (cd->uncd_rx_chain) {
566 kmem_free(cd->uncd_rx_chain, usbnet_rx_list_size(cd, un)); 566 kmem_free(cd->uncd_rx_chain, usbnet_rx_list_size(cd, un));
567 cd->uncd_rx_chain = NULL; 567 cd->uncd_rx_chain = NULL;
568 } 568 }
569} 569}
570 570
571static int 571static int
572usbnet_rx_list_init(struct usbnet * const un) 572usbnet_rx_list_init(struct usbnet * const un)
573{ 573{
574 struct usbnet_cdata * const cd = un_cdata(un); 574 struct usbnet_cdata * const cd = un_cdata(un);
575 struct usbnet_private * const unp = un->un_pri; 575 struct usbnet_private * const unp = un->un_pri;
576 576
577 for (size_t i = 0; i < un->un_rx_list_cnt; i++) { 577 for (size_t i = 0; i < un->un_rx_list_cnt; i++) {
578 struct usbnet_chain *c = &cd->uncd_rx_chain[i]; 578 struct usbnet_chain *c = &cd->uncd_rx_chain[i];
579 579
580 c->unc_un = un; 580 c->unc_un = un;
581 if (c->unc_xfer == NULL) { 581 if (c->unc_xfer == NULL) {
582 int err = usbd_create_xfer(unp->unp_ep[USBNET_ENDPT_RX], 582 int err = usbd_create_xfer(unp->unp_ep[USBNET_ENDPT_RX],
583 un->un_rx_bufsz, un->un_rx_xfer_flags, 0, 583 un->un_rx_bufsz, un->un_rx_xfer_flags, 0,
584 &c->unc_xfer); 584 &c->unc_xfer);
585 if (err) 585 if (err)
586 return err; 586 return err;
587 c->unc_buf = usbd_get_buffer(c->unc_xfer); 587 c->unc_buf = usbd_get_buffer(c->unc_xfer);
588 } 588 }
589 } 589 }
590 590
591 return 0; 591 return 0;
592} 592}
593 593
594static void 594static void
595usbnet_rx_list_fini(struct usbnet * const un) 595usbnet_rx_list_fini(struct usbnet * const un)
596{ 596{
597 struct usbnet_cdata * const cd = un_cdata(un); 597 struct usbnet_cdata * const cd = un_cdata(un);
598 598
599 for (size_t i = 0; i < un->un_rx_list_cnt; i++) { 599 for (size_t i = 0; i < un->un_rx_list_cnt; i++) {
600 struct usbnet_chain *c = &cd->uncd_rx_chain[i]; 600 struct usbnet_chain *c = &cd->uncd_rx_chain[i];
601 601
602 if (c->unc_xfer != NULL) { 602 if (c->unc_xfer != NULL) {
603 usbd_destroy_xfer(c->unc_xfer); 603 usbd_destroy_xfer(c->unc_xfer);
604 c->unc_xfer = NULL; 604 c->unc_xfer = NULL;
605 c->unc_buf = NULL; 605 c->unc_buf = NULL;
606 } 606 }
607 } 607 }
608} 608}
609 609
610/* End of common RX functions */ 610/* End of common RX functions */
611 611
612static void 612static void
613usbnet_rx_start_pipes(struct usbnet * const un) 613usbnet_rx_start_pipes(struct usbnet * const un)
614{ 614{
615 struct usbnet_cdata * const cd = un_cdata(un); 615 struct usbnet_cdata * const cd = un_cdata(un);
616 struct usbnet_private * const unp = un->un_pri; 616 struct usbnet_private * const unp = un->un_pri;
617 617
618 mutex_enter(&unp->unp_rxlock); 618 mutex_enter(&unp->unp_rxlock);
619 mutex_enter(&unp->unp_txlock); 619 mutex_enter(&unp->unp_txlock);
620 unp->unp_stopping = false; 620 unp->unp_stopping = false;
621 621
622 for (size_t i = 0; i < un->un_rx_list_cnt; i++) { 622 for (size_t i = 0; i < un->un_rx_list_cnt; i++) {
623 struct usbnet_chain *c = &cd->uncd_rx_chain[i]; 623 struct usbnet_chain *c = &cd->uncd_rx_chain[i];
624 624
625 usbd_setup_xfer(c->unc_xfer, c, c->unc_buf, un->un_rx_bufsz, 625 usbd_setup_xfer(c->unc_xfer, c, c->unc_buf, un->un_rx_bufsz,
626 un->un_rx_xfer_flags, USBD_NO_TIMEOUT, usbnet_rxeof); 626 un->un_rx_xfer_flags, USBD_NO_TIMEOUT, usbnet_rxeof);
627 usbd_transfer(c->unc_xfer); 627 usbd_transfer(c->unc_xfer);
628 } 628 }
629 629
630 mutex_exit(&unp->unp_txlock); 630 mutex_exit(&unp->unp_txlock);
631 mutex_exit(&unp->unp_rxlock); 631 mutex_exit(&unp->unp_rxlock);
632} 632}
633 633
634/* Start of common TX functions */ 634/* Start of common TX functions */
635 635
636static size_t 636static size_t
637usbnet_tx_list_size(struct usbnet_cdata * const cd, struct usbnet * const un) 637usbnet_tx_list_size(struct usbnet_cdata * const cd, struct usbnet * const un)
638{ 638{
639 return sizeof(*cd->uncd_tx_chain) * un->un_tx_list_cnt; 639 return sizeof(*cd->uncd_tx_chain) * un->un_tx_list_cnt;
640} 640}
641 641
642static void 642static void
643usbnet_tx_list_alloc(struct usbnet * const un) 643usbnet_tx_list_alloc(struct usbnet * const un)
644{ 644{
645 struct usbnet_cdata * const cd = un_cdata(un); 645 struct usbnet_cdata * const cd = un_cdata(un);
646 646
647 cd->uncd_tx_chain = kmem_zalloc(usbnet_tx_list_size(cd, un), KM_SLEEP); 647 cd->uncd_tx_chain = kmem_zalloc(usbnet_tx_list_size(cd, un), KM_SLEEP);
648} 648}
649 649
650static void 650static void
651usbnet_tx_list_free(struct usbnet * const un) 651usbnet_tx_list_free(struct usbnet * const un)
652{ 652{
653 struct usbnet_cdata * const cd = un_cdata(un); 653 struct usbnet_cdata * const cd = un_cdata(un);
654 654
655 if (cd->uncd_tx_chain) { 655 if (cd->uncd_tx_chain) {
656 kmem_free(cd->uncd_tx_chain, usbnet_tx_list_size(cd, un)); 656 kmem_free(cd->uncd_tx_chain, usbnet_tx_list_size(cd, un));
657 cd->uncd_tx_chain = NULL; 657 cd->uncd_tx_chain = NULL;
658 } 658 }
659} 659}
660 660
661static int 661static int
662usbnet_tx_list_init(struct usbnet * const un) 662usbnet_tx_list_init(struct usbnet * const un)
663{ 663{
664 struct usbnet_cdata * const cd = un_cdata(un); 664 struct usbnet_cdata * const cd = un_cdata(un);
665 struct usbnet_private * const unp = un->un_pri; 665 struct usbnet_private * const unp = un->un_pri;
666 666
667 for (size_t i = 0; i < un->un_tx_list_cnt; i++) { 667 for (size_t i = 0; i < un->un_tx_list_cnt; i++) {
668 struct usbnet_chain *c = &cd->uncd_tx_chain[i]; 668 struct usbnet_chain *c = &cd->uncd_tx_chain[i];
669 669
670 c->unc_un = un; 670 c->unc_un = un;
671 if (c->unc_xfer == NULL) { 671 if (c->unc_xfer == NULL) {
672 int err = usbd_create_xfer(unp->unp_ep[USBNET_ENDPT_TX], 672 int err = usbd_create_xfer(unp->unp_ep[USBNET_ENDPT_TX],
673 un->un_tx_bufsz, un->un_tx_xfer_flags, 0, 673 un->un_tx_bufsz, un->un_tx_xfer_flags, 0,
674 &c->unc_xfer); 674 &c->unc_xfer);
675 if (err) 675 if (err)
676 return err; 676 return err;
677 c->unc_buf = usbd_get_buffer(c->unc_xfer); 677 c->unc_buf = usbd_get_buffer(c->unc_xfer);
678 } 678 }
679 } 679 }
680 680
681 return 0; 681 return 0;
682} 682}
683 683
684static void 684static void
685usbnet_tx_list_fini(struct usbnet * const un) 685usbnet_tx_list_fini(struct usbnet * const un)
686{ 686{
687 struct usbnet_cdata * const cd = un_cdata(un); 687 struct usbnet_cdata * const cd = un_cdata(un);
688 688
689 for (size_t i = 0; i < un->un_tx_list_cnt; i++) { 689 for (size_t i = 0; i < un->un_tx_list_cnt; i++) {
690 struct usbnet_chain *c = &cd->uncd_tx_chain[i]; 690 struct usbnet_chain *c = &cd->uncd_tx_chain[i];
691 691
692 if (c->unc_xfer != NULL) { 692 if (c->unc_xfer != NULL) {
693 usbd_destroy_xfer(c->unc_xfer); 693 usbd_destroy_xfer(c->unc_xfer);
694 c->unc_xfer = NULL; 694 c->unc_xfer = NULL;
695 c->unc_buf = NULL; 695 c->unc_buf = NULL;
696 } 696 }
697 } 697 }
698 cd->uncd_tx_prod = cd->uncd_tx_cnt = 0; 698 cd->uncd_tx_prod = cd->uncd_tx_cnt = 0;
699} 699}
700 700
701/* End of common TX functions */ 701/* End of common TX functions */
702 702
703/* Endpoint pipe management. */ 703/* Endpoint pipe management. */
704 704
705static void 705static void
706usbnet_ep_close_pipes(struct usbnet * const un) 706usbnet_ep_close_pipes(struct usbnet * const un)
707{ 707{
708 struct usbnet_private * const unp = un->un_pri; 708 struct usbnet_private * const unp = un->un_pri;
709 709
710 for (size_t i = 0; i < __arraycount(unp->unp_ep); i++) { 710 for (size_t i = 0; i < __arraycount(unp->unp_ep); i++) {
711 if (unp->unp_ep[i] == NULL) 711 if (unp->unp_ep[i] == NULL)
712 continue; 712 continue;
713 usbd_status err = usbd_close_pipe(unp->unp_ep[i]); 713 usbd_status err = usbd_close_pipe(unp->unp_ep[i]);
714 if (err) 714 if (err)
715 aprint_error_dev(un->un_dev, "close pipe %zu: %s\n", i, 715 aprint_error_dev(un->un_dev, "close pipe %zu: %s\n", i,
716 usbd_errstr(err)); 716 usbd_errstr(err));
717 unp->unp_ep[i] = NULL; 717 unp->unp_ep[i] = NULL;
718 } 718 }
719} 719}
720 720
721static usbd_status 721static usbd_status
722usbnet_ep_open_pipes(struct usbnet * const un) 722usbnet_ep_open_pipes(struct usbnet * const un)
723{ 723{
724 struct usbnet_intr * const uni = un->un_intr; 724 struct usbnet_intr * const uni = un->un_intr;
725 struct usbnet_private * const unp = un->un_pri; 725 struct usbnet_private * const unp = un->un_pri;
726 726
727 for (size_t i = 0; i < __arraycount(unp->unp_ep); i++) { 727 for (size_t i = 0; i < __arraycount(unp->unp_ep); i++) {
728 usbd_status err; 728 usbd_status err;
729 729
730 if (un->un_ed[i] == 0) 730 if (un->un_ed[i] == 0)
731 continue; 731 continue;
732 732
733 if (i == USBNET_ENDPT_INTR && uni) { 733 if (i == USBNET_ENDPT_INTR && uni) {
734 err = usbd_open_pipe_intr(un->un_iface, un->un_ed[i], 734 err = usbd_open_pipe_intr(un->un_iface, un->un_ed[i],
735 USBD_EXCLUSIVE_USE | USBD_MPSAFE, &unp->unp_ep[i], un, 735 USBD_EXCLUSIVE_USE | USBD_MPSAFE, &unp->unp_ep[i], un,
736 uni->uni_buf, uni->uni_bufsz, usbnet_pipe_intr, 736 uni->uni_buf, uni->uni_bufsz, usbnet_pipe_intr,
737 uni->uni_interval); 737 uni->uni_interval);
738 } else { 738 } else {
739 err = usbd_open_pipe(un->un_iface, un->un_ed[i], 739 err = usbd_open_pipe(un->un_iface, un->un_ed[i],
740 USBD_EXCLUSIVE_USE | USBD_MPSAFE, &unp->unp_ep[i]); 740 USBD_EXCLUSIVE_USE | USBD_MPSAFE, &unp->unp_ep[i]);
741 } 741 }
742 if (err) { 742 if (err) {
743 usbnet_ep_close_pipes(un); 743 usbnet_ep_close_pipes(un);
744 return err; 744 return err;
745 } 745 }
746 } 746 }
747 747
748 return USBD_NORMAL_COMPLETION; 748 return USBD_NORMAL_COMPLETION;
749} 749}
750 750
751static usbd_status 751static usbd_status
752usbnet_ep_stop_pipes(struct usbnet * const un) 752usbnet_ep_stop_pipes(struct usbnet * const un)
753{ 753{
754 struct usbnet_private * const unp = un->un_pri; 754 struct usbnet_private * const unp = un->un_pri;
755 usbd_status err = USBD_NORMAL_COMPLETION; 755 usbd_status err = USBD_NORMAL_COMPLETION;
756 756
757 for (size_t i = 0; i < __arraycount(unp->unp_ep); i++) { 757 for (size_t i = 0; i < __arraycount(unp->unp_ep); i++) {
758 if (unp->unp_ep[i] == NULL) 758 if (unp->unp_ep[i] == NULL)
759 continue; 759 continue;
760 usbd_status err2 = usbd_abort_pipe(unp->unp_ep[i]); 760 usbd_status err2 = usbd_abort_pipe(unp->unp_ep[i]);
761 if (err == USBD_NORMAL_COMPLETION && err2) 761 if (err == USBD_NORMAL_COMPLETION && err2)
762 err = err2; 762 err = err2;
763 } 763 }
764 764
765 return err; 765 return err;
766} 766}
767 767
768int 768int
769usbnet_init_rx_tx(struct usbnet * const un) 769usbnet_init_rx_tx(struct usbnet * const un)
770{ 770{
771 USBNETHIST_FUNC(); USBNETHIST_CALLED(); 771 USBNETHIST_FUNC(); USBNETHIST_CALLED();
772 struct usbnet_private * const unp = un->un_pri; 772 struct usbnet_private * const unp = un->un_pri;
773 struct ifnet * const ifp = usbnet_ifp(un); 773 struct ifnet * const ifp = usbnet_ifp(un);
774 usbd_status err; 774 usbd_status err;
775 int error = 0; 775 int error = 0;
776 776
777 usbnet_isowned(un); 777 usbnet_isowned(un);
778 778
779 if (unp->unp_dying) { 779 if (unp->unp_dying) {
780 return EIO; 780 return EIO;
781 } 781 }
782 unp->unp_refcnt++; 782 unp->unp_refcnt++;
783 783
784 /* Open RX and TX pipes. */ 784 /* Open RX and TX pipes. */
785 err = usbnet_ep_open_pipes(un); 785 err = usbnet_ep_open_pipes(un);
786 if (err) { 786 if (err) {
787 aprint_error_dev(un->un_dev, "open rx/tx pipes failed: %s\n", 787 aprint_error_dev(un->un_dev, "open rx/tx pipes failed: %s\n",
788 usbd_errstr(err)); 788 usbd_errstr(err));
789 error = EIO; 789 error = EIO;
790 goto out; 790 goto out;
791 } 791 }
792 792
793 /* Init RX ring. */ 793 /* Init RX ring. */
794 if (usbnet_rx_list_init(un)) { 794 if (usbnet_rx_list_init(un)) {
795 aprint_error_dev(un->un_dev, "rx list init failed\n"); 795 aprint_error_dev(un->un_dev, "rx list init failed\n");
796 error = ENOBUFS; 796 error = ENOBUFS;
797 goto out; 797 goto out;
798 } 798 }
799 799
800 /* Init TX ring. */ 800 /* Init TX ring. */
801 if (usbnet_tx_list_init(un)) { 801 if (usbnet_tx_list_init(un)) {
802 aprint_error_dev(un->un_dev, "tx list init failed\n"); 802 aprint_error_dev(un->un_dev, "tx list init failed\n");
803 error = ENOBUFS; 803 error = ENOBUFS;
804 goto out; 804 goto out;
805 } 805 }
806 806
807 /* Start up the receive pipe(s). */ 807 /* Start up the receive pipe(s). */
808 usbnet_rx_start_pipes(un); 808 usbnet_rx_start_pipes(un);
809 809
810 /* Indicate we are up and running. */ 810 /* Indicate we are up and running. */
811#if 0 811#if 0
812 /* XXX if_mcast_op() can call this without ifnet locked */ 812 /* XXX if_mcast_op() can call this without ifnet locked */
813 KASSERT(ifp->if_softc == NULL || IFNET_LOCKED(ifp)); 813 KASSERT(ifp->if_softc == NULL || IFNET_LOCKED(ifp));
814#endif 814#endif
815 ifp->if_flags |= IFF_RUNNING; 815 ifp->if_flags |= IFF_RUNNING;
816 816
817 callout_schedule(&unp->unp_stat_ch, hz); 817 callout_schedule(&unp->unp_stat_ch, hz);
818 818
819out: 819out:
820 if (error) { 820 if (error) {
821 usbnet_rx_list_fini(un); 821 usbnet_rx_list_fini(un);
822 usbnet_tx_list_fini(un); 822 usbnet_tx_list_fini(un);
823 usbnet_ep_close_pipes(un); 823 usbnet_ep_close_pipes(un);
824 } 824 }
825 if (--unp->unp_refcnt < 0) 825 if (--unp->unp_refcnt < 0)
826 cv_broadcast(&unp->unp_detachcv); 826 cv_broadcast(&unp->unp_detachcv);
827 827
828 usbnet_isowned(un); 828 usbnet_isowned(un);
829 829
830 return error; 830 return error;
831} 831}
832 832
833/* MII management. */ 833/* MII management. */
834 834
835/* 835/*
836 * Access functions for MII. Take the MII lock to call access MII regs. 836 * Access functions for MII. Take the MII lock to call access MII regs.
837 * Two forms: usbnet (softc) lock currently held or not. 837 * Two forms: usbnet (softc) lock currently held or not.
838 */ 838 */
839void 839void
840usbnet_lock_mii(struct usbnet *un) 840usbnet_lock_mii(struct usbnet *un)
841{ 841{
842 struct usbnet_private * const unp = un->un_pri; 842 struct usbnet_private * const unp = un->un_pri;
843 843
844 mutex_enter(&unp->unp_lock); 844 mutex_enter(&unp->unp_lock);
845 unp->unp_refcnt++; 845 unp->unp_refcnt++;
846 mutex_exit(&unp->unp_lock); 846 mutex_exit(&unp->unp_lock);
847 847
848 mutex_enter(&unp->unp_miilock); 848 mutex_enter(&unp->unp_miilock);
849} 849}
850 850
851void 851void
852usbnet_lock_mii_un_locked(struct usbnet *un) 852usbnet_lock_mii_un_locked(struct usbnet *un)
853{ 853{
854 struct usbnet_private * const unp = un->un_pri; 854 struct usbnet_private * const unp = un->un_pri;
855 855
856 usbnet_isowned(un); 856 usbnet_isowned(un);
857 857
858 unp->unp_refcnt++; 858 unp->unp_refcnt++;
859 mutex_enter(&unp->unp_miilock); 859 mutex_enter(&unp->unp_miilock);
860} 860}
861 861
862void 862void
863usbnet_unlock_mii(struct usbnet *un) 863usbnet_unlock_mii(struct usbnet *un)
864{ 864{
865 struct usbnet_private * const unp = un->un_pri; 865 struct usbnet_private * const unp = un->un_pri;
866 866
867 mutex_exit(&unp->unp_miilock); 867 mutex_exit(&unp->unp_miilock);
868 mutex_enter(&unp->unp_lock); 868 mutex_enter(&unp->unp_lock);
869 if (--unp->unp_refcnt < 0) 869 if (--unp->unp_refcnt < 0)
870 cv_broadcast(&unp->unp_detachcv); 870 cv_broadcast(&unp->unp_detachcv);
871 mutex_exit(&unp->unp_lock); 871 mutex_exit(&unp->unp_lock);
872} 872}
873 873
874void 874void
875usbnet_unlock_mii_un_locked(struct usbnet *un) 875usbnet_unlock_mii_un_locked(struct usbnet *un)
876{ 876{
877 struct usbnet_private * const unp = un->un_pri; 877 struct usbnet_private * const unp = un->un_pri;
878 878
879 usbnet_isowned(un); 879 usbnet_isowned(un);
880 880
881 mutex_exit(&unp->unp_miilock); 881 mutex_exit(&unp->unp_miilock);
882 if (--unp->unp_refcnt < 0) 882 if (--unp->unp_refcnt < 0)
883 cv_broadcast(&unp->unp_detachcv); 883 cv_broadcast(&unp->unp_detachcv);
884} 884}
885 885
886kmutex_t * 886kmutex_t *
887usbnet_mutex_mii(struct usbnet *un) 887usbnet_mutex_mii(struct usbnet *un)
888{ 888{
889 struct usbnet_private * const unp = un->un_pri; 889 struct usbnet_private * const unp = un->un_pri;
890 890
891 return &unp->unp_miilock; 891 return &unp->unp_miilock;
892} 892}
893 893
894int 894int
895usbnet_mii_readreg(device_t dev, int phy, int reg, uint16_t *val) 895usbnet_mii_readreg(device_t dev, int phy, int reg, uint16_t *val)
896{ 896{
897 USBNETHIST_FUNC(); 897 USBNETHIST_FUNC();
898 struct usbnet * const un = device_private(dev); 898 struct usbnet * const un = device_private(dev);
899 struct usbnet_private * const unp = un->un_pri; 899 struct usbnet_private * const unp = un->un_pri;
900 int err; 900 int err;
901 901
902 mutex_enter(&unp->unp_lock); 902 mutex_enter(&unp->unp_lock);
903 if (unp->unp_dying) { 903 if (unp->unp_dying) {
904 mutex_exit(&unp->unp_lock); 904 mutex_exit(&unp->unp_lock);
905 return EIO; 905 return EIO;
906 } 906 }
907 907
908 usbnet_lock_mii_un_locked(un); 908 usbnet_lock_mii_un_locked(un);
909 mutex_exit(&unp->unp_lock); 909 mutex_exit(&unp->unp_lock);
910 err = uno_read_reg(un, phy, reg, val); 910 err = uno_read_reg(un, phy, reg, val);
911 usbnet_unlock_mii(un); 911 usbnet_unlock_mii(un);
912 912
913 if (err) { 913 if (err) {
914 USBNETHIST_CALLARGS("read PHY failed: %d", err, 0, 0, 0); 914 USBNETHIST_CALLARGS("read PHY failed: %d", err, 0, 0, 0);
915 return err; 915 return err;
916 } 916 }
917 917
918 return 0; 918 return 0;
919} 919}
920 920
921int 921int
922usbnet_mii_writereg(device_t dev, int phy, int reg, uint16_t val) 922usbnet_mii_writereg(device_t dev, int phy, int reg, uint16_t val)
923{ 923{
924 USBNETHIST_FUNC(); 924 USBNETHIST_FUNC();
925 struct usbnet * const un = device_private(dev); 925 struct usbnet * const un = device_private(dev);
926 struct usbnet_private * const unp = un->un_pri; 926 struct usbnet_private * const unp = un->un_pri;
927 int err; 927 int err;
928 928
929 mutex_enter(&unp->unp_lock); 929 mutex_enter(&unp->unp_lock);
930 if (unp->unp_dying) { 930 if (unp->unp_dying) {
931 mutex_exit(&unp->unp_lock); 931 mutex_exit(&unp->unp_lock);
932 return EIO; 932 return EIO;
933 } 933 }
934 934
935 usbnet_lock_mii_un_locked(un); 935 usbnet_lock_mii_un_locked(un);
936 mutex_exit(&unp->unp_lock); 936 mutex_exit(&unp->unp_lock);
937 err = uno_write_reg(un, phy, reg, val); 937 err = uno_write_reg(un, phy, reg, val);
938 usbnet_unlock_mii(un); 938 usbnet_unlock_mii(un);
939 939
940 if (err) { 940 if (err) {
941 USBNETHIST_CALLARGS("write PHY failed: %d", err, 0, 0, 0); 941 USBNETHIST_CALLARGS("write PHY failed: %d", err, 0, 0, 0);
942 return err; 942 return err;
943 } 943 }
944 944
945 return 0; 945 return 0;
946} 946}
947 947
948void 948void
949usbnet_mii_statchg(struct ifnet *ifp) 949usbnet_mii_statchg(struct ifnet *ifp)
950{ 950{
951 USBNETHIST_FUNC(); USBNETHIST_CALLED(); 951 USBNETHIST_FUNC(); USBNETHIST_CALLED();
952 struct usbnet * const un = ifp->if_softc; 952 struct usbnet * const un = ifp->if_softc;
953 953
954 uno_mii_statchg(un, ifp); 954 uno_mii_statchg(un, ifp);
955} 955}
956 956
957static int 957static int
958usbnet_media_upd(struct ifnet *ifp) 958usbnet_media_upd(struct ifnet *ifp)
959{ 959{
960 USBNETHIST_FUNC(); USBNETHIST_CALLED(); 960 USBNETHIST_FUNC(); USBNETHIST_CALLED();
961 struct usbnet * const un = ifp->if_softc; 961 struct usbnet * const un = ifp->if_softc;
962 struct usbnet_private * const unp = un->un_pri; 962 struct usbnet_private * const unp = un->un_pri;
963 struct mii_data * const mii = usbnet_mii(un); 963 struct mii_data * const mii = usbnet_mii(un);
964 964
965 if (unp->unp_dying) 965 if (unp->unp_dying)
966 return EIO; 966 return EIO;
967 967
968 unp->unp_link = false; 968 unp->unp_link = false;
969 969
970 if (mii->mii_instance) { 970 if (mii->mii_instance) {
971 struct mii_softc *miisc; 971 struct mii_softc *miisc;
972 972
973 LIST_FOREACH(miisc, &mii->mii_phys, mii_list) 973 LIST_FOREACH(miisc, &mii->mii_phys, mii_list)
974 mii_phy_reset(miisc); 974 mii_phy_reset(miisc);
975 } 975 }
976 976
977 return ether_mediachange(ifp); 977 return ether_mediachange(ifp);
978} 978}
979 979
980/* ioctl */ 980/* ioctl */
981 981
982static int 982static int
983usbnet_ifflags_cb(struct ethercom *ec) 983usbnet_ifflags_cb(struct ethercom *ec)
984{ 984{
985 USBNETHIST_FUNC(); USBNETHIST_CALLED(); 985 USBNETHIST_FUNC(); USBNETHIST_CALLED();
986 struct ifnet *ifp = &ec->ec_if; 986 struct ifnet *ifp = &ec->ec_if;
987 struct usbnet *un = ifp->if_softc; 987 struct usbnet *un = ifp->if_softc;
988 struct usbnet_private * const unp = un->un_pri; 988 struct usbnet_private * const unp = un->un_pri;
989 int rv = 0; 989 int rv = 0;
990 990
991 mutex_enter(&unp->unp_lock); 991 mutex_enter(&unp->unp_lock);
992 992
993 const int changed = ifp->if_flags ^ unp->unp_if_flags; 993 const int changed = ifp->if_flags ^ unp->unp_if_flags;
994 if ((changed & ~(IFF_CANTCHANGE | IFF_DEBUG)) == 0) { 994 if ((changed & ~(IFF_CANTCHANGE | IFF_DEBUG)) == 0) {
995 unp->unp_if_flags = ifp->if_flags; 995 unp->unp_if_flags = ifp->if_flags;
996 if ((changed & IFF_PROMISC) != 0) 996 if ((changed & IFF_PROMISC) != 0)
997 rv = ENETRESET; 997 rv = ENETRESET;
998 } else { 998 } else {
999 rv = ENETRESET; 999 rv = ENETRESET;
1000 } 1000 }
1001 1001
1002 mutex_exit(&unp->unp_lock); 1002 mutex_exit(&unp->unp_lock);
1003 1003
1004 return rv; 1004 return rv;
1005} 1005}
1006 1006
1007static int 1007static int
1008usbnet_ioctl(struct ifnet *ifp, u_long cmd, void *data) 1008usbnet_ioctl(struct ifnet *ifp, u_long cmd, void *data)
1009{ 1009{
1010 USBNETHIST_FUNC(); 1010 USBNETHIST_FUNC();
1011 struct usbnet * const un = ifp->if_softc; 1011 struct usbnet * const un = ifp->if_softc;
1012 struct usbnet_private * const unp __unused = un->un_pri; 1012 struct usbnet_private * const unp __unused = un->un_pri;
1013 int error; 1013 int error;
1014 1014
1015 USBNETHIST_CALLARGSN(11, "%d: enter %jx data %x", 1015 USBNETHIST_CALLARGSN(11, "%d: enter %jx data %x",
1016 unp->unp_number, cmd, (uintptr_t)data, 0); 1016 unp->unp_number, cmd, (uintptr_t)data, 0);
1017 1017
1018 if (un->un_ops->uno_override_ioctl) 1018 if (un->un_ops->uno_override_ioctl)
1019 return uno_override_ioctl(un, ifp, cmd, data); 1019 return uno_override_ioctl(un, ifp, cmd, data);
1020 1020
1021 error = ether_ioctl(ifp, cmd, data); 1021 error = ether_ioctl(ifp, cmd, data);
1022 if (error == ENETRESET) 1022 if (error == ENETRESET)
1023 error = uno_ioctl(un, ifp, cmd, data); 1023 error = uno_ioctl(un, ifp, cmd, data);
1024 1024
1025 return error; 1025 return error;
1026} 1026}
1027 1027
1028/* 1028/*
1029 * Generic stop network function: 1029 * Generic stop network function:
1030 * - mark as stopping 1030 * - mark as stopping
1031 * - call DD routine to stop the device 1031 * - call DD routine to stop the device
1032 * - turn off running, timer, statchg callout, link 1032 * - turn off running, timer, statchg callout, link
1033 * - stop transfers 1033 * - stop transfers
1034 * - free RX and TX resources 1034 * - free RX and TX resources
1035 * - close pipes 1035 * - close pipes
1036 * 1036 *
1037 * usbnet_stop() is exported for drivers to use, expects lock held. 1037 * usbnet_stop() is exported for drivers to use, expects lock held.
1038 * 1038 *
1039 * usbnet_stop_ifp() is for the if_stop handler. 1039 * usbnet_stop_ifp() is for the if_stop handler.
1040 */ 1040 */
1041void 1041void
1042usbnet_stop(struct usbnet *un, struct ifnet *ifp, int disable) 1042usbnet_stop(struct usbnet *un, struct ifnet *ifp, int disable)
1043{ 1043{
1044 struct usbnet_private * const unp = un->un_pri; 1044 struct usbnet_private * const unp = un->un_pri;
1045 1045
1046 USBNETHIST_FUNC(); USBNETHIST_CALLED(); 1046 USBNETHIST_FUNC(); USBNETHIST_CALLED();
1047 1047
1048 usbnet_isowned(un); 1048 usbnet_isowned(un);
1049 1049
1050 mutex_enter(&unp->unp_rxlock); 1050 mutex_enter(&unp->unp_rxlock);
1051 mutex_enter(&unp->unp_txlock); 1051 mutex_enter(&unp->unp_txlock);
1052 unp->unp_stopping = true; 1052 unp->unp_stopping = true;
1053 mutex_exit(&unp->unp_txlock); 1053 mutex_exit(&unp->unp_txlock);
1054 mutex_exit(&unp->unp_rxlock); 1054 mutex_exit(&unp->unp_rxlock);
1055 1055
1056 uno_stop(un, ifp, disable); 1056 uno_stop(un, ifp, disable);
1057 1057
1058 /* 1058 /*
1059 * XXXSMP Would like to 1059 * XXXSMP Would like to
1060 * KASSERT(IFNET_LOCKED(ifp)) 1060 * KASSERT(IFNET_LOCKED(ifp))
1061 * here but the locking order is: 1061 * here but the locking order is:
1062 * ifnet -> unlock -> rxlock -> txlock 1062 * ifnet -> unlock -> rxlock -> txlock
1063 * and unlock is already held. 1063 * and unlock is already held.
1064 */ 1064 */
1065 ifp->if_flags &= ~IFF_RUNNING; 1065 ifp->if_flags &= ~IFF_RUNNING;
1066 unp->unp_timer = 0; 1066 unp->unp_timer = 0;
1067 1067
1068 callout_stop(&unp->unp_stat_ch); 1068 callout_stop(&unp->unp_stat_ch);
1069 1069
1070 /* Stop transfers. */ 1070 /* Stop transfers. */
1071 usbnet_ep_stop_pipes(un); 1071 usbnet_ep_stop_pipes(un);
1072 1072
1073 /* Free RX/TX resources. */ 1073 /* Free RX/TX resources. */
1074 usbnet_rx_list_fini(un); 1074 usbnet_rx_list_fini(un);
1075 usbnet_tx_list_fini(un); 1075 usbnet_tx_list_fini(un);
1076 1076
1077 /* Close pipes. */ 1077 /* Close pipes. */
1078 usbnet_ep_close_pipes(un); 1078 usbnet_ep_close_pipes(un);
1079} 1079}
1080 1080
1081static void 1081static void
1082usbnet_stop_ifp(struct ifnet *ifp, int disable) 1082usbnet_stop_ifp(struct ifnet *ifp, int disable)
1083{ 1083{
1084 struct usbnet * const un = ifp->if_softc; 1084 struct usbnet * const un = ifp->if_softc;
1085 struct usbnet_private * const unp = un->un_pri; 1085 struct usbnet_private * const unp = un->un_pri;
1086 1086
1087 mutex_enter(&unp->unp_lock); 1087 mutex_enter(&unp->unp_lock);
1088 usbnet_stop(un, ifp, disable); 1088 usbnet_stop(un, ifp, disable);
1089 mutex_exit(&unp->unp_lock); 1089 mutex_exit(&unp->unp_lock);
1090} 1090}
1091 1091
1092/* 1092/*
1093 * Generic tick task function. 1093 * Generic tick task function.
1094 * 1094 *
1095 * usbnet_tick() is triggered from a callout, and triggers a call to 1095 * usbnet_tick() is triggered from a callout, and triggers a call to
1096 * usbnet_tick_task() from the usb_task subsystem. 1096 * usbnet_tick_task() from the usb_task subsystem.
1097 */ 1097 */
1098static void 1098static void
1099usbnet_tick(void *arg) 1099usbnet_tick(void *arg)
1100{ 1100{
1101 struct usbnet * const un = arg; 1101 struct usbnet * const un = arg;
1102 struct usbnet_private * const unp = un->un_pri; 1102 struct usbnet_private * const unp = un->un_pri;
1103 1103
1104 mutex_enter(&unp->unp_lock); 1104 mutex_enter(&unp->unp_lock);
1105 if (!unp->unp_stopping && !unp->unp_dying) { 1105 if (!unp->unp_stopping && !unp->unp_dying) {
1106 /* Perform periodic stuff in process context */ 1106 /* Perform periodic stuff in process context */
1107 usb_add_task(un->un_udev, &unp->unp_ticktask, USB_TASKQ_DRIVER); 1107 usb_add_task(un->un_udev, &unp->unp_ticktask, USB_TASKQ_DRIVER);
1108 } 1108 }
1109 mutex_exit(&unp->unp_lock); 1109 mutex_exit(&unp->unp_lock);
1110} 1110}
1111 1111
1112static void 1112static void
1113usbnet_watchdog(struct ifnet *ifp) 1113usbnet_watchdog(struct ifnet *ifp)
1114{ 1114{
1115 USBNETHIST_FUNC(); USBNETHIST_CALLED(); 1115 USBNETHIST_FUNC(); USBNETHIST_CALLED();
1116 struct usbnet * const un = ifp->if_softc; 1116 struct usbnet * const un = ifp->if_softc;
1117 struct usbnet_private * const unp = un->un_pri; 1117 struct usbnet_private * const unp = un->un_pri;
1118 struct usbnet_cdata * const cd = un_cdata(un); 1118 struct usbnet_cdata * const cd = un_cdata(un);
1119 usbd_status err; 1119 usbd_status err;
1120 1120
1121 ifp->if_oerrors++; 1121 ifp->if_oerrors++;
1122 aprint_error_dev(un->un_dev, "watchdog timeout\n"); 1122 aprint_error_dev(un->un_dev, "watchdog timeout\n");
1123 1123
1124 if (cd->uncd_tx_cnt > 0) { 1124 if (cd->uncd_tx_cnt > 0) {
1125 DPRINTF("uncd_tx_cnt=%u non zero, aborting pipe", 0, 0, 0, 0); 1125 DPRINTF("uncd_tx_cnt=%u non zero, aborting pipe", 0, 0, 0, 0);
1126 err = usbd_abort_pipe(unp->unp_ep[USBNET_ENDPT_TX]); 1126 err = usbd_abort_pipe(unp->unp_ep[USBNET_ENDPT_TX]);
1127 if (err) 1127 if (err)
1128 aprint_error_dev(un->un_dev, "pipe abort failed: %s\n", 1128 aprint_error_dev(un->un_dev, "pipe abort failed: %s\n",
1129 usbd_errstr(err)); 1129 usbd_errstr(err));
1130 if (cd->uncd_tx_cnt != 0) 1130 if (cd->uncd_tx_cnt != 0)
1131 DPRINTF("uncd_tx_cnt now %u", cd->uncd_tx_cnt, 0, 0, 0); 1131 DPRINTF("uncd_tx_cnt now %u", cd->uncd_tx_cnt, 0, 0, 0);
1132 } 1132 }
1133 1133
1134 if (!IFQ_IS_EMPTY(&ifp->if_snd)) 1134 if (!IFQ_IS_EMPTY(&ifp->if_snd))
1135 (*ifp->if_start)(ifp); 1135 (*ifp->if_start)(ifp);
1136} 1136}
1137 1137
1138static void 1138static void
1139usbnet_tick_task(void *arg) 1139usbnet_tick_task(void *arg)
1140{ 1140{
1141 struct usbnet * const un = arg; 1141 struct usbnet * const un = arg;
1142 struct usbnet_private * const unp = un->un_pri; 1142 struct usbnet_private * const unp = un->un_pri;
1143 1143
1144 mutex_enter(&unp->unp_lock); 1144 mutex_enter(&unp->unp_lock);
1145 if (unp->unp_stopping || unp->unp_dying) { 1145 if (unp->unp_stopping || unp->unp_dying) {
1146 mutex_exit(&unp->unp_lock); 1146 mutex_exit(&unp->unp_lock);
1147 return; 1147 return;
1148 } 1148 }
1149 1149
1150 struct ifnet * const ifp = usbnet_ifp(un); 1150 struct ifnet * const ifp = usbnet_ifp(un);
1151 struct mii_data * const mii = usbnet_mii(un); 1151 struct mii_data * const mii = usbnet_mii(un);
1152 1152
1153 unp->unp_refcnt++; 1153 unp->unp_refcnt++;
1154 mutex_exit(&unp->unp_lock); 1154 mutex_exit(&unp->unp_lock);
1155 1155
1156 if (ifp && unp->unp_timer != 0 && --unp->unp_timer == 0) 1156 if (ifp && unp->unp_timer != 0 && --unp->unp_timer == 0)
1157 usbnet_watchdog(ifp); 1157 usbnet_watchdog(ifp);
1158 1158
1159 if (mii && ifp) { 1159 if (mii && ifp) {
1160 mii_tick(mii); 1160 mii_tick(mii);
1161 1161
1162 if (!unp->unp_link) 1162 if (!unp->unp_link)
1163 (*mii->mii_statchg)(ifp); 1163 (*mii->mii_statchg)(ifp);
1164 } 1164 }
1165 1165
1166 /* Call driver if requested. */ 1166 /* Call driver if requested. */
1167 uno_tick(un); 1167 uno_tick(un);
1168 1168
1169 mutex_enter(&unp->unp_lock); 1169 mutex_enter(&unp->unp_lock);
1170 if (--unp->unp_refcnt < 0) 1170 if (--unp->unp_refcnt < 0)
1171 cv_broadcast(&unp->unp_detachcv); 1171 cv_broadcast(&unp->unp_detachcv);
1172 if (!unp->unp_stopping && !unp->unp_dying) 1172 if (!unp->unp_stopping && !unp->unp_dying)
1173 callout_schedule(&unp->unp_stat_ch, hz); 1173 callout_schedule(&unp->unp_stat_ch, hz);
1174 mutex_exit(&unp->unp_lock); 1174 mutex_exit(&unp->unp_lock);
1175} 1175}
1176 1176
1177static int 1177static int
1178usbnet_init(struct ifnet *ifp) 1178usbnet_init(struct ifnet *ifp)
1179{ 1179{
1180 USBNETHIST_FUNC(); USBNETHIST_CALLED(); 1180 USBNETHIST_FUNC(); USBNETHIST_CALLED();
1181 struct usbnet * const un = ifp->if_softc; 1181 struct usbnet * const un = ifp->if_softc;
1182 1182
1183 return uno_init(un, ifp); 1183 return uno_init(un, ifp);
1184} 1184}
1185 1185
1186 1186
1187/* Various accessors. */ 1187/* Various accessors. */
1188 1188
1189void 1189void
1190usbnet_set_link(struct usbnet *un, bool link) 1190usbnet_set_link(struct usbnet *un, bool link)
1191{ 1191{
1192 un->un_pri->unp_link = link; 1192 un->un_pri->unp_link = link;
1193} 1193}
1194 1194
1195void 1195void
1196usbnet_set_dying(struct usbnet *un, bool link) 1196usbnet_set_dying(struct usbnet *un, bool link)
1197{ 1197{
1198 un->un_pri->unp_dying = link; 1198 un->un_pri->unp_dying = link;
1199} 1199}
1200 1200
1201struct ifnet * 1201struct ifnet *
1202usbnet_ifp(struct usbnet *un) 1202usbnet_ifp(struct usbnet *un)
1203{ 1203{
1204 return &un->un_pri->unp_ec.ec_if; 1204 return &un->un_pri->unp_ec.ec_if;
1205} 1205}
1206 1206
1207struct ethercom * 1207struct ethercom *
1208usbnet_ec(struct usbnet *un) 1208usbnet_ec(struct usbnet *un)
1209{ 1209{
1210 return &un->un_pri->unp_ec; 1210 return &un->un_pri->unp_ec;
1211} 1211}
1212 1212
1213struct mii_data * 1213struct mii_data *
1214usbnet_mii(struct usbnet *un) 1214usbnet_mii(struct usbnet *un)
1215{ 1215{
1216 return un->un_pri->unp_ec.ec_mii; 1216 return un->un_pri->unp_ec.ec_mii;
1217} 1217}
1218 1218
1219krndsource_t * 1219krndsource_t *
1220usbnet_rndsrc(struct usbnet *un) 1220usbnet_rndsrc(struct usbnet *un)
1221{ 1221{
1222 return &un->un_pri->unp_rndsrc; 1222 return &un->un_pri->unp_rndsrc;
1223} 1223}
1224 1224
1225void * 1225void *
1226usbnet_softc(struct usbnet *un) 1226usbnet_softc(struct usbnet *un)
1227{ 1227{
1228 //return un->un_pri->unp_sc; 1228 //return un->un_pri->unp_sc;
1229 return un->un_sc; 1229 return un->un_sc;
1230} 1230}
1231 1231
1232bool 1232bool
1233usbnet_havelink(struct usbnet *un) 1233usbnet_havelink(struct usbnet *un)
1234{ 1234{
1235 return un->un_pri->unp_link; 1235 return un->un_pri->unp_link;
1236} 1236}
1237 1237
1238bool 1238bool
1239usbnet_isdying(struct usbnet *un) 1239usbnet_isdying(struct usbnet *un)
1240{ 1240{
1241 return un->un_pri->unp_dying; 1241 return un->un_pri->unp_dying;
1242} 1242}
1243 1243
1244 1244
1245/* Locking. */ 1245/* Locking. */
1246 1246
1247void 1247void
1248usbnet_lock(struct usbnet *un) 1248usbnet_lock(struct usbnet *un)
1249{ 1249{
1250 mutex_enter(&un->un_pri->unp_lock); 1250 mutex_enter(&un->un_pri->unp_lock);
1251} 1251}
1252 1252
1253void 1253void
1254usbnet_unlock(struct usbnet *un) 1254usbnet_unlock(struct usbnet *un)
1255{ 1255{
1256 mutex_exit(&un->un_pri->unp_lock); 1256 mutex_exit(&un->un_pri->unp_lock);
1257} 1257}
1258 1258
1259kmutex_t * 1259kmutex_t *
1260usbnet_mutex(struct usbnet *un) 1260usbnet_mutex(struct usbnet *un)
1261{ 1261{
1262 return &un->un_pri->unp_lock; 1262 return &un->un_pri->unp_lock;
1263} 1263}
1264 1264
1265void 1265void
1266usbnet_lock_rx(struct usbnet *un) 1266usbnet_lock_rx(struct usbnet *un)
1267{ 1267{
1268 mutex_enter(&un->un_pri->unp_rxlock); 1268 mutex_enter(&un->un_pri->unp_rxlock);
1269} 1269}
1270 1270
1271void 1271void
1272usbnet_unlock_rx(struct usbnet *un) 1272usbnet_unlock_rx(struct usbnet *un)
1273{ 1273{
1274 mutex_exit(&un->un_pri->unp_rxlock); 1274 mutex_exit(&un->un_pri->unp_rxlock);
1275} 1275}
1276 1276
1277kmutex_t * 1277kmutex_t *
1278usbnet_mutex_rx(struct usbnet *un) 1278usbnet_mutex_rx(struct usbnet *un)
1279{ 1279{
1280 return &un->un_pri->unp_rxlock; 1280 return &un->un_pri->unp_rxlock;
1281} 1281}
1282 1282
1283void 1283void
1284usbnet_lock_tx(struct usbnet *un) 1284usbnet_lock_tx(struct usbnet *un)
1285{ 1285{
1286 mutex_enter(&un->un_pri->unp_txlock); 1286 mutex_enter(&un->un_pri->unp_txlock);
1287} 1287}
1288 1288
1289void 1289void
1290usbnet_unlock_tx(struct usbnet *un) 1290usbnet_unlock_tx(struct usbnet *un)
1291{ 1291{
1292 mutex_exit(&un->un_pri->unp_txlock); 1292 mutex_exit(&un->un_pri->unp_txlock);
1293} 1293}
1294 1294
1295kmutex_t * 1295kmutex_t *
1296usbnet_mutex_tx(struct usbnet *un) 1296usbnet_mutex_tx(struct usbnet *un)
1297{ 1297{
1298 return &un->un_pri->unp_txlock; 1298 return &un->un_pri->unp_txlock;
1299} 1299}
1300 1300
1301/* Autoconf management. */ 1301/* Autoconf management. */
1302 1302
1303static bool 1303static bool
1304usbnet_empty_eaddr(struct usbnet * const un) 1304usbnet_empty_eaddr(struct usbnet * const un)
1305{ 1305{
1306 return (un->un_eaddr[0] == 0 && un->un_eaddr[1] == 0 && 1306 return (un->un_eaddr[0] == 0 && un->un_eaddr[1] == 0 &&
1307 un->un_eaddr[2] == 0 && un->un_eaddr[3] == 0 && 1307 un->un_eaddr[2] == 0 && un->un_eaddr[3] == 0 &&
1308 un->un_eaddr[4] == 0 && un->un_eaddr[5] == 0); 1308 un->un_eaddr[4] == 0 && un->un_eaddr[5] == 0);
1309} 1309}
1310 1310
1311/* 1311/*
1312 * usbnet_attach() and usbnet_attach_ifp() perform setup of the relevant 1312 * usbnet_attach() and usbnet_attach_ifp() perform setup of the relevant
1313 * 'usbnet'. The first is enough to enable device access (eg, endpoints 1313 * 'usbnet'. The first is enough to enable device access (eg, endpoints
1314 * are connected and commands can be sent), and the second connects the 1314 * are connected and commands can be sent), and the second connects the
1315 * device to the system networking. 1315 * device to the system networking.
1316 * 1316 *
1317 * Always call usbnet_detach(), even if usbnet_attach_ifp() is skippped. 1317 * Always call usbnet_detach(), even if usbnet_attach_ifp() is skippped.
1318 * Also usable as driver detach directly. 1318 * Also usable as driver detach directly.
1319 * 1319 *
1320 * To skip ethernet configuration (eg, point-to-point), make sure that 1320 * To skip ethernet configuration (eg, point-to-point), make sure that
1321 * the un_eaddr[] is fully zero. 1321 * the un_eaddr[] is fully zero.
1322 */ 1322 */
1323 1323
1324void 1324void
1325usbnet_attach(struct usbnet *un, 1325usbnet_attach(struct usbnet *un,
1326 const char *detname) /* detach cv name */ 1326 const char *detname) /* detach cv name */
1327{ 1327{
1328 USBNETHIST_FUNC(); USBNETHIST_CALLED(); 1328 USBNETHIST_FUNC(); USBNETHIST_CALLED();
1329 1329
1330 /* Required inputs. */ 1330 /* Required inputs. */
1331 KASSERT(un->un_ops->uno_tx_prepare); 1331 KASSERT(un->un_ops->uno_tx_prepare);
1332 KASSERT(un->un_ops->uno_rx_loop); 1332 KASSERT(un->un_ops->uno_rx_loop);
1333 KASSERT(un->un_ops->uno_init); 1333 KASSERT(un->un_ops->uno_init);
1334 KASSERT(un->un_rx_bufsz); 1334 KASSERT(un->un_rx_bufsz);
1335 KASSERT(un->un_tx_bufsz); 1335 KASSERT(un->un_tx_bufsz);
1336 KASSERT(un->un_rx_list_cnt); 1336 KASSERT(un->un_rx_list_cnt);
1337 KASSERT(un->un_tx_list_cnt); 1337 KASSERT(un->un_tx_list_cnt);
1338 1338
1339 /* Unfortunate fact. */ 1339 /* Unfortunate fact. */
1340 KASSERT(un == device_private(un->un_dev)); 1340 KASSERT(un == device_private(un->un_dev));
1341 1341
1342 un->un_pri = kmem_zalloc(sizeof(*un->un_pri), KM_SLEEP); 1342 un->un_pri = kmem_zalloc(sizeof(*un->un_pri), KM_SLEEP);
1343 struct usbnet_private * const unp = un->un_pri; 1343 struct usbnet_private * const unp = un->un_pri;
1344 1344
1345 usb_init_task(&unp->unp_ticktask, usbnet_tick_task, un, USB_TASKQ_MPSAFE); 1345 usb_init_task(&unp->unp_ticktask, usbnet_tick_task, un, USB_TASKQ_MPSAFE);
1346 callout_init(&unp->unp_stat_ch, CALLOUT_MPSAFE); 1346 callout_init(&unp->unp_stat_ch, CALLOUT_MPSAFE);
1347 callout_setfunc(&unp->unp_stat_ch, usbnet_tick, un); 1347 callout_setfunc(&unp->unp_stat_ch, usbnet_tick, un);
1348 1348
1349 mutex_init(&unp->unp_miilock, MUTEX_DEFAULT, IPL_NONE); 1349 mutex_init(&unp->unp_miilock, MUTEX_DEFAULT, IPL_NONE);
1350 mutex_init(&unp->unp_txlock, MUTEX_DEFAULT, IPL_SOFTUSB); 1350 mutex_init(&unp->unp_txlock, MUTEX_DEFAULT, IPL_SOFTUSB);
1351 mutex_init(&unp->unp_rxlock, MUTEX_DEFAULT, IPL_SOFTUSB); 1351 mutex_init(&unp->unp_rxlock, MUTEX_DEFAULT, IPL_SOFTUSB);
1352 mutex_init(&unp->unp_lock, MUTEX_DEFAULT, IPL_NONE); 1352 mutex_init(&unp->unp_lock, MUTEX_DEFAULT, IPL_NONE);
1353 cv_init(&unp->unp_detachcv, detname); 1353 cv_init(&unp->unp_detachcv, detname);
1354 1354
1355 rnd_attach_source(&unp->unp_rndsrc, device_xname(un->un_dev), 1355 rnd_attach_source(&unp->unp_rndsrc, device_xname(un->un_dev),
1356 RND_TYPE_NET, RND_FLAG_DEFAULT); 1356 RND_TYPE_NET, RND_FLAG_DEFAULT);
1357 1357
1358 usbnet_rx_list_alloc(un); 1358 usbnet_rx_list_alloc(un);
1359 usbnet_tx_list_alloc(un); 1359 usbnet_tx_list_alloc(un);
1360 1360
1361 unp->unp_number = atomic_inc_uint_nv(&usbnet_number); 1361 unp->unp_number = atomic_inc_uint_nv(&usbnet_number);
1362 1362
1363 unp->unp_attached = true; 1363 unp->unp_attached = true;
1364} 1364}
1365 1365
1366static void 1366static void
1367usbnet_attach_mii(struct usbnet *un, const struct usbnet_mii *unm) 1367usbnet_attach_mii(struct usbnet *un, const struct usbnet_mii *unm)
1368{ 1368{
1369 USBNETHIST_FUNC(); USBNETHIST_CALLED(); 1369 USBNETHIST_FUNC(); USBNETHIST_CALLED();
1370 struct usbnet_private * const unp = un->un_pri; 1370 struct usbnet_private * const unp = un->un_pri;
1371 struct mii_data * const mii = &unp->unp_mii; 1371 struct mii_data * const mii = &unp->unp_mii;
1372 struct ifnet * const ifp = usbnet_ifp(un); 1372 struct ifnet * const ifp = usbnet_ifp(un);
1373 1373
1374 KASSERT(un->un_ops->uno_read_reg); 1374 KASSERT(un->un_ops->uno_read_reg);
1375 KASSERT(un->un_ops->uno_write_reg); 1375 KASSERT(un->un_ops->uno_write_reg);
1376 KASSERT(un->un_ops->uno_statchg); 1376 KASSERT(un->un_ops->uno_statchg);
1377 1377
1378 mii->mii_ifp = ifp; 1378 mii->mii_ifp = ifp;
1379 mii->mii_readreg = usbnet_mii_readreg; 1379 mii->mii_readreg = usbnet_mii_readreg;
1380 mii->mii_writereg = usbnet_mii_writereg; 1380 mii->mii_writereg = usbnet_mii_writereg;
1381 mii->mii_statchg = usbnet_mii_statchg; 1381 mii->mii_statchg = usbnet_mii_statchg;
1382 mii->mii_flags = MIIF_AUTOTSLEEP; 1382 mii->mii_flags = MIIF_AUTOTSLEEP;
1383 1383
1384 usbnet_ec(un)->ec_mii = mii; 1384 usbnet_ec(un)->ec_mii = mii;
1385 ifmedia_init(&mii->mii_media, 0, usbnet_media_upd, ether_mediastatus); 1385 ifmedia_init(&mii->mii_media, 0, usbnet_media_upd, ether_mediastatus);
1386 mii_attach(un->un_dev, mii, unm->un_mii_capmask, unm->un_mii_phyloc, 1386 mii_attach(un->un_dev, mii, unm->un_mii_capmask, unm->un_mii_phyloc,
1387 unm->un_mii_offset, unm->un_mii_flags); 1387 unm->un_mii_offset, unm->un_mii_flags);
1388 1388
1389 if (LIST_FIRST(&mii->mii_phys) == NULL) { 1389 if (LIST_FIRST(&mii->mii_phys) == NULL) {
1390 ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE, 0, NULL); 1390 ifmedia_add(&mii->mii_media, IFM_ETHER | IFM_NONE, 0, NULL);
1391 ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_NONE); 1391 ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_NONE);
1392 } else 1392 } else
1393 ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_AUTO); 1393 ifmedia_set(&mii->mii_media, IFM_ETHER | IFM_AUTO);
1394} 1394}
1395 1395
1396void 1396void
1397usbnet_attach_ifp(struct usbnet *un, 1397usbnet_attach_ifp(struct usbnet *un,
1398 unsigned if_flags, /* additional if_flags */ 1398 unsigned if_flags, /* additional if_flags */
1399 unsigned if_extflags, /* additional if_extflags */ 1399 unsigned if_extflags, /* additional if_extflags */
1400 const struct usbnet_mii *unm) /* additional mii_attach flags */ 1400 const struct usbnet_mii *unm) /* additional mii_attach flags */
1401{ 1401{
1402 USBNETHIST_FUNC(); USBNETHIST_CALLED(); 1402 USBNETHIST_FUNC(); USBNETHIST_CALLED();
1403 struct usbnet_private * const unp = un->un_pri; 1403 struct usbnet_private * const unp = un->un_pri;
1404 struct ifnet * const ifp = usbnet_ifp(un); 1404 struct ifnet * const ifp = usbnet_ifp(un);
1405 1405
1406 KASSERT(unp->unp_attached); 1406 KASSERT(unp->unp_attached);
1407 1407
1408 strlcpy(ifp->if_xname, device_xname(un->un_dev), IFNAMSIZ); 1408 strlcpy(ifp->if_xname, device_xname(un->un_dev), IFNAMSIZ);
1409 ifp->if_flags = if_flags; 1409 ifp->if_flags = if_flags;
1410 ifp->if_extflags = IFEF_MPSAFE | if_extflags; 1410 ifp->if_extflags = IFEF_MPSAFE | if_extflags;
1411 ifp->if_ioctl = usbnet_ioctl; 1411 ifp->if_ioctl = usbnet_ioctl;
1412 ifp->if_start = usbnet_start; 1412 ifp->if_start = usbnet_start;
1413 ifp->if_init = usbnet_init; 1413 ifp->if_init = usbnet_init;
1414 ifp->if_stop = usbnet_stop_ifp; 1414 ifp->if_stop = usbnet_stop_ifp;
1415 1415
1416 if (unm) 1416 if (unm)
1417 usbnet_attach_mii(un, unm); 1417 usbnet_attach_mii(un, unm);
1418 else 1418 else
1419 unp->unp_link = true; 1419 unp->unp_link = true;
1420 1420
1421 /* Attach the interface. */ 1421 /* Attach the interface. */
1422 int rv = if_initialize(ifp); 1422 int rv = if_initialize(ifp);
1423 if (rv != 0) { 1423 if (rv != 0) {
1424 aprint_error_dev(un->un_dev, "if_initialize failed(%d)\n", rv); 1424 aprint_error_dev(un->un_dev, "if_initialize failed(%d)\n", rv);
1425 return; 1425 return;
1426 } 1426 }
1427 if (ifp->_if_input == NULL) 1427 if (ifp->_if_input == NULL)
1428 ifp->if_percpuq = if_percpuq_create(ifp); 1428 ifp->if_percpuq = if_percpuq_create(ifp);
1429 if_register(ifp); 1429 if_register(ifp);
1430 1430
1431 /* 1431 /*
1432 * If ethernet address is all zero, skip ether_ifattach() and 1432 * If ethernet address is all zero, skip ether_ifattach() and
1433 * instead attach bpf here.. 1433 * instead attach bpf here..
1434 */ 1434 */
1435 if (!usbnet_empty_eaddr(un)) { 1435 if (!usbnet_empty_eaddr(un)) {
1436 ether_set_ifflags_cb(&unp->unp_ec, usbnet_ifflags_cb); 1436 ether_set_ifflags_cb(&unp->unp_ec, usbnet_ifflags_cb);
1437 aprint_normal_dev(un->un_dev, "Ethernet address %s\n", 1437 aprint_normal_dev(un->un_dev, "Ethernet address %s\n",
1438 ether_sprintf(un->un_eaddr)); 1438 ether_sprintf(un->un_eaddr));
1439 ether_ifattach(ifp, un->un_eaddr); 1439 ether_ifattach(ifp, un->un_eaddr);
1440 } else { 1440 } else {
1441 if_alloc_sadl(ifp); 1441 if_alloc_sadl(ifp);
1442 bpf_attach(ifp, DLT_RAW, 0); 1442 bpf_attach(ifp, DLT_RAW, 0);
1443 } 1443 }
1444 1444
1445 /* Now ready, and attached. */ 1445 /* Now ready, and attached. */
1446 IFQ_SET_READY(&ifp->if_snd); 1446 IFQ_SET_READY(&ifp->if_snd);
1447 ifp->if_softc = un; 1447 ifp->if_softc = un;
1448 1448
1449 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, un->un_udev, un->un_dev); 1449 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, un->un_udev, un->un_dev);
1450 1450
1451 if (!pmf_device_register(un->un_dev, NULL, NULL)) 1451 if (!pmf_device_register(un->un_dev, NULL, NULL))
1452 aprint_error_dev(un->un_dev, "couldn't establish power handler\n"); 1452 aprint_error_dev(un->un_dev, "couldn't establish power handler\n");
1453} 1453}
1454 1454
1455int 1455int
1456usbnet_detach(device_t self, int flags) 1456usbnet_detach(device_t self, int flags)
1457{ 1457{
1458 USBNETHIST_FUNC(); USBNETHIST_CALLED(); 1458 USBNETHIST_FUNC(); USBNETHIST_CALLED();
1459 struct usbnet * const un = device_private(self); 1459 struct usbnet * const un = device_private(self);
 1460 struct usbnet_private * const unp = un->un_pri;
 1461
 1462 /* Detached before attached finished, so just bail out. */
 1463 if (unp == NULL || !unp->unp_attached)
 1464 return 0;
 1465
1460 struct ifnet * const ifp = usbnet_ifp(un); 1466 struct ifnet * const ifp = usbnet_ifp(un);
1461 struct mii_data * const mii = usbnet_mii(un); 1467 struct mii_data * const mii = usbnet_mii(un);
1462 struct usbnet_private * const unp = un->un_pri; 
1463 1468
1464 mutex_enter(&unp->unp_lock); 1469 mutex_enter(&unp->unp_lock);
1465 unp->unp_dying = true; 1470 unp->unp_dying = true;
1466 mutex_exit(&unp->unp_lock); 1471 mutex_exit(&unp->unp_lock);
1467 1472
1468 /* Detached before attached finished, so just bail out. */ 
1469 if (!unp->unp_attached) 
1470 return 0; 
1471 
1472 callout_halt(&unp->unp_stat_ch, NULL); 1473 callout_halt(&unp->unp_stat_ch, NULL);
1473 usb_rem_task_wait(un->un_udev, &unp->unp_ticktask, USB_TASKQ_DRIVER, NULL); 1474 usb_rem_task_wait(un->un_udev, &unp->unp_ticktask, USB_TASKQ_DRIVER, NULL);
1474 1475
1475 if (ifp->if_flags & IFF_RUNNING) { 1476 if (ifp->if_flags & IFF_RUNNING) {
1476 IFNET_LOCK(ifp); 1477 IFNET_LOCK(ifp);
1477 usbnet_stop_ifp(ifp, 1); 1478 usbnet_stop_ifp(ifp, 1);
1478 IFNET_UNLOCK(ifp); 1479 IFNET_UNLOCK(ifp);
1479 } 1480 }
1480 1481
1481 mutex_enter(&unp->unp_lock); 1482 mutex_enter(&unp->unp_lock);
1482 unp->unp_refcnt--; 1483 unp->unp_refcnt--;
1483 while (unp->unp_refcnt > 0) { 1484 while (unp->unp_refcnt > 0) {
1484 /* Wait for processes to go away */ 1485 /* Wait for processes to go away */
1485 cv_wait(&unp->unp_detachcv, &unp->unp_lock); 1486 cv_wait(&unp->unp_detachcv, &unp->unp_lock);
1486 } 1487 }
1487 mutex_exit(&unp->unp_lock); 1488 mutex_exit(&unp->unp_lock);
1488 1489
1489 usbnet_rx_list_free(un); 1490 usbnet_rx_list_free(un);
1490 usbnet_tx_list_free(un); 1491 usbnet_tx_list_free(un);
1491 1492
1492 callout_destroy(&unp->unp_stat_ch); 1493 callout_destroy(&unp->unp_stat_ch);
1493 rnd_detach_source(&unp->unp_rndsrc); 1494 rnd_detach_source(&unp->unp_rndsrc);
1494 1495
1495 if (mii) { 1496 if (mii) {
1496 mii_detach(mii, MII_PHY_ANY, MII_OFFSET_ANY); 1497 mii_detach(mii, MII_PHY_ANY, MII_OFFSET_ANY);
1497 ifmedia_delete_instance(&mii->mii_media, IFM_INST_ANY); 1498 ifmedia_delete_instance(&mii->mii_media, IFM_INST_ANY);
1498 } 1499 }
1499 if (ifp->if_softc) { 1500 if (ifp->if_softc) {
1500 if (!usbnet_empty_eaddr(un)) 1501 if (!usbnet_empty_eaddr(un))
1501 ether_ifdetach(ifp); 1502 ether_ifdetach(ifp);
1502 else 1503 else
1503 bpf_detach(ifp); 1504 bpf_detach(ifp);
1504 if_detach(ifp); 1505 if_detach(ifp);
1505 } 1506 }
1506 1507
1507 cv_destroy(&unp->unp_detachcv); 1508 cv_destroy(&unp->unp_detachcv);
1508 mutex_destroy(&unp->unp_lock); 1509 mutex_destroy(&unp->unp_lock);
1509 mutex_destroy(&unp->unp_rxlock); 1510 mutex_destroy(&unp->unp_rxlock);
1510 mutex_destroy(&unp->unp_txlock); 1511 mutex_destroy(&unp->unp_txlock);
1511 mutex_destroy(&unp->unp_miilock); 1512 mutex_destroy(&unp->unp_miilock);
1512 1513
1513 pmf_device_deregister(un->un_dev); 1514 pmf_device_deregister(un->un_dev);
1514 1515
1515 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, un->un_udev, un->un_dev); 1516 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, un->un_udev, un->un_dev);
1516 1517
1517 kmem_free(unp, sizeof(*unp)); 1518 kmem_free(unp, sizeof(*unp));
1518 1519
1519 return 0; 1520 return 0;
1520} 1521}
1521 1522
1522int 1523int
1523usbnet_activate(device_t self, devact_t act) 1524usbnet_activate(device_t self, devact_t act)
1524{ 1525{
1525 USBNETHIST_FUNC(); USBNETHIST_CALLED(); 1526 USBNETHIST_FUNC(); USBNETHIST_CALLED();
1526 struct usbnet * const un = device_private(self); 1527 struct usbnet * const un = device_private(self);
1527 struct usbnet_private * const unp = un->un_pri; 1528 struct usbnet_private * const unp = un->un_pri;
1528 struct ifnet * const ifp = usbnet_ifp(un); 1529 struct ifnet * const ifp = usbnet_ifp(un);
1529 1530
1530 switch (act) { 1531 switch (act) {
1531 case DVACT_DEACTIVATE: 1532 case DVACT_DEACTIVATE:
1532 if_deactivate(ifp); 1533 if_deactivate(ifp);
1533 1534
1534 mutex_enter(&unp->unp_lock); 1535 mutex_enter(&unp->unp_lock);
1535 unp->unp_dying = true; 1536 unp->unp_dying = true;
1536 mutex_exit(&unp->unp_lock); 1537 mutex_exit(&unp->unp_lock);
1537 1538
1538 mutex_enter(&unp->unp_rxlock); 1539 mutex_enter(&unp->unp_rxlock);
1539 mutex_enter(&unp->unp_txlock); 1540 mutex_enter(&unp->unp_txlock);
1540 unp->unp_stopping = true; 1541 unp->unp_stopping = true;
1541 mutex_exit(&unp->unp_txlock); 1542 mutex_exit(&unp->unp_txlock);
1542 mutex_exit(&unp->unp_rxlock); 1543 mutex_exit(&unp->unp_rxlock);
1543 1544
1544 return 0; 1545 return 0;
1545 default: 1546 default:
1546 return EOPNOTSUPP; 1547 return EOPNOTSUPP;
1547 } 1548 }
1548} 1549}
1549 1550
1550MODULE(MODULE_CLASS_MISC, usbnet, NULL); 1551MODULE(MODULE_CLASS_MISC, usbnet, NULL);
1551 1552
1552static int 1553static int
1553usbnet_modcmd(modcmd_t cmd, void *arg) 1554usbnet_modcmd(modcmd_t cmd, void *arg)
1554{ 1555{
1555 switch (cmd) { 1556 switch (cmd) {
1556 case MODULE_CMD_INIT: 1557 case MODULE_CMD_INIT:
1557 return 0; 1558 return 0;
1558 case MODULE_CMD_FINI: 1559 case MODULE_CMD_FINI:
1559 return 0; 1560 return 0;
1560 case MODULE_CMD_STAT: 1561 case MODULE_CMD_STAT:
1561 case MODULE_CMD_AUTOUNLOAD: 1562 case MODULE_CMD_AUTOUNLOAD:
1562 default: 1563 default:
1563 return ENOTTY; 1564 return ENOTTY;
1564 } 1565 }
1565} 1566}