Thu Mar 3 06:05:38 2022 UTC ()
usb: usbd_abort_pipe never fails.  Make it return void.

Prune dead branches as a result of this change.


(riastradh)
diff -r1.73 -r1.74 src/sys/dev/usb/if_atu.c
diff -r1.13 -r1.14 src/sys/dev/usb/ualea.c
diff -r1.223 -r1.224 src/sys/dev/usb/usbdi.c
diff -r1.104 -r1.105 src/sys/dev/usb/usbdi.h
diff -r1.91 -r1.92 src/sys/dev/usb/usbnet.c
diff -r1.35 -r1.36 src/sys/dev/usb/utoppy.c

cvs diff -r1.73 -r1.74 src/sys/dev/usb/if_atu.c (switch to unified diff)

--- src/sys/dev/usb/if_atu.c 2020/08/28 19:02:19 1.73
+++ src/sys/dev/usb/if_atu.c 2022/03/03 06:05:38 1.74
@@ -1,1050 +1,1050 @@ @@ -1,1050 +1,1050 @@
1/* $NetBSD: if_atu.c,v 1.73 2020/08/28 19:02:19 riastradh Exp $ */ 1/* $NetBSD: if_atu.c,v 1.74 2022/03/03 06:05:38 riastradh Exp $ */
2/* $OpenBSD: if_atu.c,v 1.48 2004/12/30 01:53:21 dlg Exp $ */ 2/* $OpenBSD: if_atu.c,v 1.48 2004/12/30 01:53:21 dlg Exp $ */
3/* 3/*
4 * Copyright (c) 2003, 2004 4 * Copyright (c) 2003, 2004
5 * Daan Vreeken <Danovitsch@Vitsch.net>. All rights reserved. 5 * Daan Vreeken <Danovitsch@Vitsch.net>. 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. All advertising materials mentioning features or use of this software 15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement: 16 * must display the following acknowledgement:
17 * This product includes software developed by Daan Vreeken. 17 * This product includes software developed by Daan Vreeken.
18 * 4. Neither the name of the author nor the names of any co-contributors 18 * 4. Neither the name of the author nor the names of any co-contributors
19 * may be used to endorse or promote products derived from this software 19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission. 20 * without specific prior written permission.
21 * 21 *
22 * THIS SOFTWARE IS PROVIDED BY Daan Vreeken AND CONTRIBUTORS ``AS IS'' AND 22 * THIS SOFTWARE IS PROVIDED BY Daan Vreeken AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL Daan Vreeken OR THE VOICES IN HIS HEAD 25 * ARE DISCLAIMED. IN NO EVENT SHALL Daan Vreeken OR THE VOICES IN HIS HEAD
26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
32 * THE POSSIBILITY OF SUCH DAMAGE. 32 * THE POSSIBILITY OF SUCH DAMAGE.
33 */ 33 */
34 34
35/* 35/*
36 * Atmel AT76c503 / AT76c503a / AT76c505 / AT76c505a USB WLAN driver 36 * Atmel AT76c503 / AT76c503a / AT76c505 / AT76c505a USB WLAN driver
37 * version 0.5 - 2004-08-03 37 * version 0.5 - 2004-08-03
38 * 38 *
39 * Originally written by Daan Vreeken <Danovitsch @ Vitsch . net> 39 * Originally written by Daan Vreeken <Danovitsch @ Vitsch . net>
40 * http://vitsch.net/bsd/atuwi 40 * http://vitsch.net/bsd/atuwi
41 * 41 *
42 * Contributed to by : 42 * Contributed to by :
43 * Chris Whitehouse, Alistair Phillips, Peter Pilka, Martijn van Buul, 43 * Chris Whitehouse, Alistair Phillips, Peter Pilka, Martijn van Buul,
44 * Suihong Liang, Arjan van Leeuwen, Stuart Walsh 44 * Suihong Liang, Arjan van Leeuwen, Stuart Walsh
45 * 45 *
46 * Ported to OpenBSD by Theo de Raadt and David Gwynne. 46 * Ported to OpenBSD by Theo de Raadt and David Gwynne.
47 * Ported to NetBSD by Jesse Off 47 * Ported to NetBSD by Jesse Off
48 */ 48 */
49 49
50#include <sys/cdefs.h> 50#include <sys/cdefs.h>
51__KERNEL_RCSID(0, "$NetBSD: if_atu.c,v 1.73 2020/08/28 19:02:19 riastradh Exp $"); 51__KERNEL_RCSID(0, "$NetBSD: if_atu.c,v 1.74 2022/03/03 06:05:38 riastradh Exp $");
52 52
53#ifdef _KERNEL_OPT 53#ifdef _KERNEL_OPT
54#include "opt_usb.h" 54#include "opt_usb.h"
55#endif 55#endif
56 56
57#include <sys/param.h> 57#include <sys/param.h>
58#include <sys/sockio.h> 58#include <sys/sockio.h>
59#include <sys/mbuf.h> 59#include <sys/mbuf.h>
60#include <sys/kernel.h> 60#include <sys/kernel.h>
61#include <sys/socket.h> 61#include <sys/socket.h>
62#include <sys/systm.h> 62#include <sys/systm.h>
63#include <sys/kthread.h> 63#include <sys/kthread.h>
64#include <sys/queue.h> 64#include <sys/queue.h>
65#include <sys/device.h> 65#include <sys/device.h>
66#include <sys/bus.h> 66#include <sys/bus.h>
67 67
68#include <dev/usb/usb.h> 68#include <dev/usb/usb.h>
69#include <dev/usb/usbdi.h> 69#include <dev/usb/usbdi.h>
70#include <dev/usb/usbdi_util.h> 70#include <dev/usb/usbdi_util.h>
71#include <dev/usb/usbdivar.h> 71#include <dev/usb/usbdivar.h>
72#include <dev/usb/usbdevs.h> 72#include <dev/usb/usbdevs.h>
73 73
74#include <dev/microcode/atmel/atmel_intersil_fw.h> 74#include <dev/microcode/atmel/atmel_intersil_fw.h>
75#include <dev/microcode/atmel/atmel_rfmd2958-smc_fw.h> 75#include <dev/microcode/atmel/atmel_rfmd2958-smc_fw.h>
76#include <dev/microcode/atmel/atmel_rfmd2958_fw.h> 76#include <dev/microcode/atmel/atmel_rfmd2958_fw.h>
77#include <dev/microcode/atmel/atmel_rfmd_fw.h> 77#include <dev/microcode/atmel/atmel_rfmd_fw.h>
78 78
79#include <net/bpf.h> 79#include <net/bpf.h>
80#include <net/if.h> 80#include <net/if.h>
81#include <net/if_dl.h> 81#include <net/if_dl.h>
82#include <net/if_media.h> 82#include <net/if_media.h>
83#include <net/if_ether.h> 83#include <net/if_ether.h>
84 84
85#ifdef INET 85#ifdef INET
86#include <netinet/in.h> 86#include <netinet/in.h>
87#include <netinet/if_ether.h> 87#include <netinet/if_ether.h>
88#endif 88#endif
89 89
90#include <net80211/ieee80211_var.h> 90#include <net80211/ieee80211_var.h>
91#include <net80211/ieee80211_radiotap.h> 91#include <net80211/ieee80211_radiotap.h>
92 92
93#include <dev/usb/if_atureg.h> 93#include <dev/usb/if_atureg.h>
94 94
95#ifdef ATU_DEBUG 95#ifdef ATU_DEBUG
96#define DPRINTF(x) do { if (atudebug) printf x; } while (0) 96#define DPRINTF(x) do { if (atudebug) printf x; } while (0)
97#define DPRINTFN(n,x) do { if (atudebug>(n)) printf x; } while (0) 97#define DPRINTFN(n,x) do { if (atudebug>(n)) printf x; } while (0)
98int atudebug = 1; 98int atudebug = 1;
99#else 99#else
100#define DPRINTF(x) 100#define DPRINTF(x)
101#define DPRINTFN(n,x) 101#define DPRINTFN(n,x)
102#endif 102#endif
103 103
104/* 104/*
105 * Various supported device vendors/products/radio type. 105 * Various supported device vendors/products/radio type.
106 */ 106 */
107static const struct atu_type atu_devs[] = { 107static const struct atu_type atu_devs[] = {
108 { USB_VENDOR_3COM, USB_PRODUCT_3COM_3CRSHEW696, 108 { USB_VENDOR_3COM, USB_PRODUCT_3COM_3CRSHEW696,
109 RadioRFMD, ATU_NO_QUIRK }, 109 RadioRFMD, ATU_NO_QUIRK },
110 { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_BWU613, 110 { USB_VENDOR_ABOCOM, USB_PRODUCT_ABOCOM_BWU613,
111 RadioRFMD, ATU_NO_QUIRK }, 111 RadioRFMD, ATU_NO_QUIRK },
112 { USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_2664W, 112 { USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_2664W,
113 AT76C503_rfmd_acc, ATU_NO_QUIRK }, 113 AT76C503_rfmd_acc, ATU_NO_QUIRK },
114 { USB_VENDOR_ACERP, USB_PRODUCT_ACERP_AWL300, 114 { USB_VENDOR_ACERP, USB_PRODUCT_ACERP_AWL300,
115 RadioIntersil, ATU_NO_QUIRK }, 115 RadioIntersil, ATU_NO_QUIRK },
116 { USB_VENDOR_ACERP, USB_PRODUCT_ACERP_AWL400, 116 { USB_VENDOR_ACERP, USB_PRODUCT_ACERP_AWL400,
117 RadioRFMD, ATU_NO_QUIRK }, 117 RadioRFMD, ATU_NO_QUIRK },
118 { USB_VENDOR_ACTIONTEC, USB_PRODUCT_ACTIONTEC_UAT1, 118 { USB_VENDOR_ACTIONTEC, USB_PRODUCT_ACTIONTEC_UAT1,
119 RadioRFMD, ATU_NO_QUIRK }, 119 RadioRFMD, ATU_NO_QUIRK },
120 { USB_VENDOR_ADDTRON, USB_PRODUCT_ADDTRON_AWU120, 120 { USB_VENDOR_ADDTRON, USB_PRODUCT_ADDTRON_AWU120,
121 RadioIntersil, ATU_NO_QUIRK }, 121 RadioIntersil, ATU_NO_QUIRK },
122 { USB_VENDOR_AINCOMM, USB_PRODUCT_AINCOMM_AWU2000B, 122 { USB_VENDOR_AINCOMM, USB_PRODUCT_AINCOMM_AWU2000B,
123 RadioRFMD2958, ATU_NO_QUIRK }, 123 RadioRFMD2958, ATU_NO_QUIRK },
124 { USB_VENDOR_ASKEY, USB_PRODUCT_ASKEY_VOYAGER1010, 124 { USB_VENDOR_ASKEY, USB_PRODUCT_ASKEY_VOYAGER1010,
125 RadioIntersil, ATU_NO_QUIRK }, 125 RadioIntersil, ATU_NO_QUIRK },
126 { USB_VENDOR_ASKEY, USB_PRODUCT_ASKEY_WLL013I, 126 { USB_VENDOR_ASKEY, USB_PRODUCT_ASKEY_WLL013I,
127 RadioIntersil, ATU_NO_QUIRK }, 127 RadioIntersil, ATU_NO_QUIRK },
128 { USB_VENDOR_ASKEY, USB_PRODUCT_ASKEY_WLL013, 128 { USB_VENDOR_ASKEY, USB_PRODUCT_ASKEY_WLL013,
129 RadioRFMD, ATU_NO_QUIRK }, 129 RadioRFMD, ATU_NO_QUIRK },
130 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C503I1, 130 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C503I1,
131 RadioIntersil, ATU_NO_QUIRK }, 131 RadioIntersil, ATU_NO_QUIRK },
132 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C503I2, 132 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C503I2,
133 AT76C503_i3863, ATU_NO_QUIRK }, 133 AT76C503_i3863, ATU_NO_QUIRK },
134 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C503RFMD, 134 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C503RFMD,
135 RadioRFMD, ATU_NO_QUIRK }, 135 RadioRFMD, ATU_NO_QUIRK },
136 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C505RFMD, 136 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C505RFMD,
137 AT76C505_rfmd, ATU_NO_QUIRK }, 137 AT76C505_rfmd, ATU_NO_QUIRK },
138 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C505RFMD2958, 138 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C505RFMD2958,
139 RadioRFMD2958, ATU_NO_QUIRK }, 139 RadioRFMD2958, ATU_NO_QUIRK },
140 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C505A, /* SMC2662 V.4 */ 140 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C505A, /* SMC2662 V.4 */
141 RadioRFMD2958_SMC, ATU_QUIRK_NO_REMAP | ATU_QUIRK_FW_DELAY }, 141 RadioRFMD2958_SMC, ATU_QUIRK_NO_REMAP | ATU_QUIRK_FW_DELAY },
142 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C505AS, /* quirk? */ 142 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_AT76C505AS, /* quirk? */
143 RadioRFMD2958_SMC, ATU_QUIRK_NO_REMAP | ATU_QUIRK_FW_DELAY }, 143 RadioRFMD2958_SMC, ATU_QUIRK_NO_REMAP | ATU_QUIRK_FW_DELAY },
144 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_WN210, 144 { USB_VENDOR_ATMEL, USB_PRODUCT_ATMEL_WN210,
145 RadioRFMD, ATU_NO_QUIRK }, 145 RadioRFMD, ATU_NO_QUIRK },
146 { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D6050, 146 { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D6050,
147 RadioRFMD, ATU_NO_QUIRK }, 147 RadioRFMD, ATU_NO_QUIRK },
148 { USB_VENDOR_CONCEPTRONIC, USB_PRODUCT_CONCEPTRONIC_C11U, 148 { USB_VENDOR_CONCEPTRONIC, USB_PRODUCT_CONCEPTRONIC_C11U,
149 RadioIntersil, ATU_NO_QUIRK }, 149 RadioIntersil, ATU_NO_QUIRK },
150 { USB_VENDOR_CONCEPTRONIC, USB_PRODUCT_CONCEPTRONIC_WL210, 150 { USB_VENDOR_CONCEPTRONIC, USB_PRODUCT_CONCEPTRONIC_WL210,
151 RadioIntersil, ATU_NO_QUIRK }, 151 RadioIntersil, ATU_NO_QUIRK },
152 { USB_VENDOR_COMPAQ, USB_PRODUCT_COMPAQ_IPAQWLAN, 152 { USB_VENDOR_COMPAQ, USB_PRODUCT_COMPAQ_IPAQWLAN,
153 RadioRFMD, ATU_NO_QUIRK }, 153 RadioRFMD, ATU_NO_QUIRK },
154 { USB_VENDOR_COREGA, USB_PRODUCT_COREGA_WLUSB_11_STICK, 154 { USB_VENDOR_COREGA, USB_PRODUCT_COREGA_WLUSB_11_STICK,
155 RadioRFMD2958, ATU_NO_QUIRK }, 155 RadioRFMD2958, ATU_NO_QUIRK },
156 { USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_CHUSB611G, 156 { USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_CHUSB611G,
157 RadioRFMD2958, ATU_NO_QUIRK }, 157 RadioRFMD2958, ATU_NO_QUIRK },
158 { USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_WL200U, 158 { USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_WL200U,
159 RadioRFMD, ATU_NO_QUIRK }, 159 RadioRFMD, ATU_NO_QUIRK },
160 { USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_WL240U, 160 { USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_WL240U,
161 RadioRFMD2958, ATU_NO_QUIRK }, 161 RadioRFMD2958, ATU_NO_QUIRK },
162 { USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_XH1153, 162 { USB_VENDOR_DICKSMITH, USB_PRODUCT_DICKSMITH_XH1153,
163 RadioRFMD, ATU_NO_QUIRK }, 163 RadioRFMD, ATU_NO_QUIRK },
164 { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWL120E, 164 { USB_VENDOR_DLINK, USB_PRODUCT_DLINK_DWL120E,
165 RadioRFMD, ATU_NO_QUIRK }, 165 RadioRFMD, ATU_NO_QUIRK },
166 { USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNWLBM101, 166 { USB_VENDOR_GIGABYTE, USB_PRODUCT_GIGABYTE_GNWLBM101,
167 RadioRFMD, ATU_NO_QUIRK }, 167 RadioRFMD, ATU_NO_QUIRK },
168 { USB_VENDOR_GIGASET, USB_PRODUCT_GIGASET_WLAN, /* quirk? */ 168 { USB_VENDOR_GIGASET, USB_PRODUCT_GIGASET_WLAN, /* quirk? */
169 RadioRFMD2958_SMC, ATU_QUIRK_NO_REMAP | ATU_QUIRK_FW_DELAY }, 169 RadioRFMD2958_SMC, ATU_QUIRK_NO_REMAP | ATU_QUIRK_FW_DELAY },
170 { USB_VENDOR_HP, USB_PRODUCT_HP_HN210W, 170 { USB_VENDOR_HP, USB_PRODUCT_HP_HN210W,
171 RadioIntersil, ATU_NO_QUIRK }, 171 RadioIntersil, ATU_NO_QUIRK },
172 { USB_VENDOR_INTEL, USB_PRODUCT_INTEL_AP310, 172 { USB_VENDOR_INTEL, USB_PRODUCT_INTEL_AP310,
173 RadioIntersil, ATU_NO_QUIRK }, 173 RadioIntersil, ATU_NO_QUIRK },
174 { USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBWNB11A, 174 { USB_VENDOR_IODATA, USB_PRODUCT_IODATA_USBWNB11A,
175 RadioIntersil, ATU_NO_QUIRK }, 175 RadioIntersil, ATU_NO_QUIRK },
176 { USB_VENDOR_LEXAR, USB_PRODUCT_LEXAR_2662WAR, 176 { USB_VENDOR_LEXAR, USB_PRODUCT_LEXAR_2662WAR,
177 RadioRFMD, ATU_NO_QUIRK }, 177 RadioRFMD, ATU_NO_QUIRK },
178 { USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_WUSB11, 178 { USB_VENDOR_LINKSYS, USB_PRODUCT_LINKSYS_WUSB11,
179 RadioIntersil, ATU_NO_QUIRK }, 179 RadioIntersil, ATU_NO_QUIRK },
180 { USB_VENDOR_LINKSYS2, USB_PRODUCT_LINKSYS2_WUSB11, 180 { USB_VENDOR_LINKSYS2, USB_PRODUCT_LINKSYS2_WUSB11,
181 RadioRFMD, ATU_NO_QUIRK }, 181 RadioRFMD, ATU_NO_QUIRK },
182 { USB_VENDOR_LINKSYS2, USB_PRODUCT_LINKSYS2_NWU11B, 182 { USB_VENDOR_LINKSYS2, USB_PRODUCT_LINKSYS2_NWU11B,
183 RadioRFMD, ATU_NO_QUIRK }, 183 RadioRFMD, ATU_NO_QUIRK },
184 { USB_VENDOR_LINKSYS3, USB_PRODUCT_LINKSYS3_WUSB11V28, 184 { USB_VENDOR_LINKSYS3, USB_PRODUCT_LINKSYS3_WUSB11V28,
185 RadioRFMD2958, ATU_NO_QUIRK }, 185 RadioRFMD2958, ATU_NO_QUIRK },
186 { USB_VENDOR_MSI, USB_PRODUCT_MSI_WLAN, 186 { USB_VENDOR_MSI, USB_PRODUCT_MSI_WLAN,
187 RadioRFMD2958, ATU_NO_QUIRK }, 187 RadioRFMD2958, ATU_NO_QUIRK },
188 { USB_VENDOR_NETGEAR2, USB_PRODUCT_NETGEAR2_MA101, 188 { USB_VENDOR_NETGEAR2, USB_PRODUCT_NETGEAR2_MA101,
189 RadioIntersil, ATU_NO_QUIRK }, 189 RadioIntersil, ATU_NO_QUIRK },
190 { USB_VENDOR_NETGEAR2, USB_PRODUCT_NETGEAR2_MA101B, 190 { USB_VENDOR_NETGEAR2, USB_PRODUCT_NETGEAR2_MA101B,
191 RadioRFMD, ATU_NO_QUIRK }, 191 RadioRFMD, ATU_NO_QUIRK },
192 { USB_VENDOR_OQO, USB_PRODUCT_OQO_WIFI01, 192 { USB_VENDOR_OQO, USB_PRODUCT_OQO_WIFI01,
193 RadioRFMD2958_SMC, ATU_QUIRK_NO_REMAP | ATU_QUIRK_FW_DELAY }, 193 RadioRFMD2958_SMC, ATU_QUIRK_NO_REMAP | ATU_QUIRK_FW_DELAY },
194 { USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GW_US11S, 194 { USB_VENDOR_PLANEX2, USB_PRODUCT_PLANEX2_GW_US11S,
195 RadioRFMD, ATU_NO_QUIRK }, 195 RadioRFMD, ATU_NO_QUIRK },
196 { USB_VENDOR_SAMSUNG, USB_PRODUCT_SAMSUNG_SWL2100W, 196 { USB_VENDOR_SAMSUNG, USB_PRODUCT_SAMSUNG_SWL2100W,
197 AT76C503_i3863, ATU_NO_QUIRK }, 197 AT76C503_i3863, ATU_NO_QUIRK },
198 { USB_VENDOR_SIEMENS2, USB_PRODUCT_SIEMENS2_WLL013, 198 { USB_VENDOR_SIEMENS2, USB_PRODUCT_SIEMENS2_WLL013,
199 RadioRFMD, ATU_NO_QUIRK }, 199 RadioRFMD, ATU_NO_QUIRK },
200 { USB_VENDOR_SMC3, USB_PRODUCT_SMC3_2662WV1, 200 { USB_VENDOR_SMC3, USB_PRODUCT_SMC3_2662WV1,
201 RadioIntersil, ATU_NO_QUIRK }, 201 RadioIntersil, ATU_NO_QUIRK },
202 { USB_VENDOR_SMC3, USB_PRODUCT_SMC3_2662WV2, 202 { USB_VENDOR_SMC3, USB_PRODUCT_SMC3_2662WV2,
203 AT76C503_rfmd_acc, ATU_NO_QUIRK }, 203 AT76C503_rfmd_acc, ATU_NO_QUIRK },
204 { USB_VENDOR_TEKRAM, USB_PRODUCT_TEKRAM_U300C, 204 { USB_VENDOR_TEKRAM, USB_PRODUCT_TEKRAM_U300C,
205 RadioIntersil, ATU_NO_QUIRK }, 205 RadioIntersil, ATU_NO_QUIRK },
206 { USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_M4Y750, 206 { USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_M4Y750,
207 RadioIntersil, ATU_NO_QUIRK }, 207 RadioIntersil, ATU_NO_QUIRK },
208}; 208};
209 209
210static const struct atu_radfirm { 210static const struct atu_radfirm {
211 enum atu_radio_type atur_type; 211 enum atu_radio_type atur_type;
212 unsigned char *atur_internal; 212 unsigned char *atur_internal;
213 size_t atur_internal_sz; 213 size_t atur_internal_sz;
214 unsigned char *atur_external; 214 unsigned char *atur_external;
215 size_t atur_external_sz; 215 size_t atur_external_sz;
216} atu_radfirm[] = { 216} atu_radfirm[] = {
217 { RadioRFMD, 217 { RadioRFMD,
218 atmel_fw_rfmd_int, sizeof(atmel_fw_rfmd_int), 218 atmel_fw_rfmd_int, sizeof(atmel_fw_rfmd_int),
219 atmel_fw_rfmd_ext, sizeof(atmel_fw_rfmd_ext) }, 219 atmel_fw_rfmd_ext, sizeof(atmel_fw_rfmd_ext) },
220 { RadioRFMD2958, 220 { RadioRFMD2958,
221 atmel_fw_rfmd2958_int, sizeof(atmel_fw_rfmd2958_int), 221 atmel_fw_rfmd2958_int, sizeof(atmel_fw_rfmd2958_int),
222 atmel_fw_rfmd2958_ext, sizeof(atmel_fw_rfmd2958_ext) }, 222 atmel_fw_rfmd2958_ext, sizeof(atmel_fw_rfmd2958_ext) },
223 { RadioRFMD2958_SMC, 223 { RadioRFMD2958_SMC,
224 atmel_fw_rfmd2958_smc_int, sizeof(atmel_fw_rfmd2958_smc_int), 224 atmel_fw_rfmd2958_smc_int, sizeof(atmel_fw_rfmd2958_smc_int),
225 atmel_fw_rfmd2958_smc_ext, sizeof(atmel_fw_rfmd2958_smc_ext) }, 225 atmel_fw_rfmd2958_smc_ext, sizeof(atmel_fw_rfmd2958_smc_ext) },
226 { RadioIntersil, 226 { RadioIntersil,
227 atmel_fw_intersil_int, sizeof(atmel_fw_intersil_int), 227 atmel_fw_intersil_int, sizeof(atmel_fw_intersil_int),
228 atmel_fw_intersil_ext, sizeof(atmel_fw_intersil_ext) } 228 atmel_fw_intersil_ext, sizeof(atmel_fw_intersil_ext) }
229}; 229};
230 230
231static int atu_newbuf(struct atu_softc *, struct atu_chain *, struct mbuf *); 231static int atu_newbuf(struct atu_softc *, struct atu_chain *, struct mbuf *);
232static void atu_rxeof(struct usbd_xfer *, void *, usbd_status); 232static void atu_rxeof(struct usbd_xfer *, void *, usbd_status);
233static void atu_txeof(struct usbd_xfer *, void *, usbd_status); 233static void atu_txeof(struct usbd_xfer *, void *, usbd_status);
234static void atu_start(struct ifnet *); 234static void atu_start(struct ifnet *);
235static int atu_ioctl(struct ifnet *, u_long, void *); 235static int atu_ioctl(struct ifnet *, u_long, void *);
236static int atu_init(struct ifnet *); 236static int atu_init(struct ifnet *);
237static void atu_stop(struct ifnet *, int); 237static void atu_stop(struct ifnet *, int);
238static void atu_watchdog(struct ifnet *); 238static void atu_watchdog(struct ifnet *);
239static usbd_status atu_usb_request(struct atu_softc *, uint8_t, 239static usbd_status atu_usb_request(struct atu_softc *, uint8_t,
240 uint8_t, uint16_t, uint16_t, 240 uint8_t, uint16_t, uint16_t,
241 uint16_t, uint8_t *); 241 uint16_t, uint8_t *);
242static int atu_send_command(struct atu_softc *, uint8_t *, int); 242static int atu_send_command(struct atu_softc *, uint8_t *, int);
243static int atu_get_cmd_status(struct atu_softc *, uint8_t, 243static int atu_get_cmd_status(struct atu_softc *, uint8_t,
244 uint8_t *); 244 uint8_t *);
245static int atu_wait_completion(struct atu_softc *, uint8_t, 245static int atu_wait_completion(struct atu_softc *, uint8_t,
246 uint8_t *); 246 uint8_t *);
247static int atu_send_mib(struct atu_softc *, uint8_t, 247static int atu_send_mib(struct atu_softc *, uint8_t,
248 uint8_t, uint8_t, void *); 248 uint8_t, uint8_t, void *);
249static int atu_get_mib(struct atu_softc *, uint8_t, 249static int atu_get_mib(struct atu_softc *, uint8_t,
250 uint8_t, uint8_t, uint8_t *); 250 uint8_t, uint8_t, uint8_t *);
251#if 0 251#if 0
252int atu_start_ibss(struct atu_softc *); 252int atu_start_ibss(struct atu_softc *);
253#endif 253#endif
254static int atu_start_scan(struct atu_softc *); 254static int atu_start_scan(struct atu_softc *);
255static int atu_switch_radio(struct atu_softc *, int); 255static int atu_switch_radio(struct atu_softc *, int);
256static int atu_initial_config(struct atu_softc *); 256static int atu_initial_config(struct atu_softc *);
257static int atu_join(struct atu_softc *, struct ieee80211_node *); 257static int atu_join(struct atu_softc *, struct ieee80211_node *);
258static int8_t atu_get_dfu_state(struct atu_softc *); 258static int8_t atu_get_dfu_state(struct atu_softc *);
259static uint8_t atu_get_opmode(struct atu_softc *, uint8_t *); 259static uint8_t atu_get_opmode(struct atu_softc *, uint8_t *);
260static void atu_internal_firmware(device_t); 260static void atu_internal_firmware(device_t);
261static void atu_external_firmware(device_t); 261static void atu_external_firmware(device_t);
262static int atu_get_card_config(struct atu_softc *); 262static int atu_get_card_config(struct atu_softc *);
263static int atu_media_change(struct ifnet *); 263static int atu_media_change(struct ifnet *);
264static void atu_media_status(struct ifnet *, struct ifmediareq *); 264static void atu_media_status(struct ifnet *, struct ifmediareq *);
265static int atu_tx_list_init(struct atu_softc *); 265static int atu_tx_list_init(struct atu_softc *);
266static int atu_rx_list_init(struct atu_softc *); 266static int atu_rx_list_init(struct atu_softc *);
267static void atu_xfer_list_free(struct atu_softc *, struct atu_chain *, 267static void atu_xfer_list_free(struct atu_softc *, struct atu_chain *,
268 int); 268 int);
269 269
270static void atu_task(void *); 270static void atu_task(void *);
271static int atu_newstate(struct ieee80211com *, enum ieee80211_state, int); 271static int atu_newstate(struct ieee80211com *, enum ieee80211_state, int);
272static int atu_tx_start(struct atu_softc *, struct ieee80211_node *, 272static int atu_tx_start(struct atu_softc *, struct ieee80211_node *,
273 struct atu_chain *, struct mbuf *); 273 struct atu_chain *, struct mbuf *);
274static void atu_complete_attach(struct atu_softc *); 274static void atu_complete_attach(struct atu_softc *);
275static uint8_t atu_calculate_padding(int); 275static uint8_t atu_calculate_padding(int);
276 276
277static int atu_match(device_t, cfdata_t, void *); 277static int atu_match(device_t, cfdata_t, void *);
278static void atu_attach(device_t, device_t, void *); 278static void atu_attach(device_t, device_t, void *);
279static int atu_detach(device_t, int); 279static int atu_detach(device_t, int);
280static int atu_activate(device_t, enum devact); 280static int atu_activate(device_t, enum devact);
281 281
282CFATTACH_DECL_NEW(atu, sizeof(struct atu_softc), atu_match, atu_attach, 282CFATTACH_DECL_NEW(atu, sizeof(struct atu_softc), atu_match, atu_attach,
283 atu_detach, atu_activate); 283 atu_detach, atu_activate);
284 284
285static usbd_status 285static usbd_status
286atu_usb_request(struct atu_softc *sc, uint8_t type, 286atu_usb_request(struct atu_softc *sc, uint8_t type,
287 uint8_t request, uint16_t value, uint16_t index, uint16_t length, 287 uint8_t request, uint16_t value, uint16_t index, uint16_t length,
288 uint8_t *data) 288 uint8_t *data)
289{ 289{
290 usb_device_request_t req; 290 usb_device_request_t req;
291 struct usbd_xfer *xfer; 291 struct usbd_xfer *xfer;
292 usbd_status err; 292 usbd_status err;
293 int total_len = 0, s; 293 int total_len = 0, s;
294 294
295 req.bmRequestType = type; 295 req.bmRequestType = type;
296 req.bRequest = request; 296 req.bRequest = request;
297 USETW(req.wValue, value); 297 USETW(req.wValue, value);
298 USETW(req.wIndex, index); 298 USETW(req.wIndex, index);
299 USETW(req.wLength, length); 299 USETW(req.wLength, length);
300 300
301#ifdef ATU_DEBUG 301#ifdef ATU_DEBUG
302 if (atudebug) { 302 if (atudebug) {
303 DPRINTFN(20, ("%s: req=%02x val=%02x ind=%02x " 303 DPRINTFN(20, ("%s: req=%02x val=%02x ind=%02x "
304 "len=%02x\n", device_xname(sc->atu_dev), request, 304 "len=%02x\n", device_xname(sc->atu_dev), request,
305 value, index, length)); 305 value, index, length));
306 } 306 }
307#endif /* ATU_DEBUG */ 307#endif /* ATU_DEBUG */
308 308
309 s = splnet(); 309 s = splnet();
310 310
311 struct usbd_pipe *pipe0 = usbd_get_pipe0(sc->atu_udev); 311 struct usbd_pipe *pipe0 = usbd_get_pipe0(sc->atu_udev);
312 int error = usbd_create_xfer(pipe0, length, 0, 0, 312 int error = usbd_create_xfer(pipe0, length, 0, 0,
313 &xfer); 313 &xfer);
314 if (error) { 314 if (error) {
315 splx(s); 315 splx(s);
316 return USBD_IOERROR; 316 return USBD_IOERROR;
317 } 317 }
318 usbd_setup_default_xfer(xfer, sc->atu_udev, 0, 500000, &req, data, 318 usbd_setup_default_xfer(xfer, sc->atu_udev, 0, 500000, &req, data,
319 length, USBD_SHORT_XFER_OK, NULL); 319 length, USBD_SHORT_XFER_OK, NULL);
320 320
321 err = usbd_sync_transfer(xfer); 321 err = usbd_sync_transfer(xfer);
322 322
323 usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL); 323 usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL);
324 324
325#ifdef ATU_DEBUG 325#ifdef ATU_DEBUG
326 if (atudebug) { 326 if (atudebug) {
327 if (type & UT_READ) { 327 if (type & UT_READ) {
328 DPRINTFN(20, ("%s: transferred %#x bytes in\n", 328 DPRINTFN(20, ("%s: transferred %#x bytes in\n",
329 device_xname(sc->atu_dev), total_len)); 329 device_xname(sc->atu_dev), total_len));
330 } else { 330 } else {
331 if (total_len != length) 331 if (total_len != length)
332 DPRINTF(("%s: wrote only %x bytes\n", 332 DPRINTF(("%s: wrote only %x bytes\n",
333 device_xname(sc->atu_dev), total_len)); 333 device_xname(sc->atu_dev), total_len));
334 } 334 }
335 } 335 }
336#endif /* ATU_DEBUG */ 336#endif /* ATU_DEBUG */
337 337
338 usbd_destroy_xfer(xfer); 338 usbd_destroy_xfer(xfer);
339 339
340 splx(s); 340 splx(s);
341 return err; 341 return err;
342} 342}
343 343
344static int 344static int
345atu_send_command(struct atu_softc *sc, uint8_t *command, int size) 345atu_send_command(struct atu_softc *sc, uint8_t *command, int size)
346{ 346{
347 return atu_usb_request(sc, UT_WRITE_VENDOR_DEVICE, 0x0e, 0x0000, 347 return atu_usb_request(sc, UT_WRITE_VENDOR_DEVICE, 0x0e, 0x0000,
348 0x0000, size, command); 348 0x0000, size, command);
349} 349}
350 350
351static int 351static int
352atu_get_cmd_status(struct atu_softc *sc, uint8_t cmd, uint8_t *status) 352atu_get_cmd_status(struct atu_softc *sc, uint8_t cmd, uint8_t *status)
353{ 353{
354 /* 354 /*
355 * all other drivers (including Windoze) request 40 bytes of status 355 * all other drivers (including Windoze) request 40 bytes of status
356 * and get a short-xfer of just 6 bytes. we can save 34 bytes of 356 * and get a short-xfer of just 6 bytes. we can save 34 bytes of
357 * buffer if we just request those 6 bytes in the first place :) 357 * buffer if we just request those 6 bytes in the first place :)
358 */ 358 */
359 /* 359 /*
360 return atu_usb_request(sc, UT_READ_VENDOR_INTERFACE, 0x22, cmd, 360 return atu_usb_request(sc, UT_READ_VENDOR_INTERFACE, 0x22, cmd,
361 0x0000, 40, status); 361 0x0000, 40, status);
362 */ 362 */
363 return atu_usb_request(sc, UT_READ_VENDOR_INTERFACE, 0x22, cmd, 363 return atu_usb_request(sc, UT_READ_VENDOR_INTERFACE, 0x22, cmd,
364 0x0000, 6, status); 364 0x0000, 6, status);
365} 365}
366 366
367static int 367static int
368atu_wait_completion(struct atu_softc *sc, uint8_t cmd, uint8_t *status) 368atu_wait_completion(struct atu_softc *sc, uint8_t cmd, uint8_t *status)
369{ 369{
370 int idle_count = 0, err; 370 int idle_count = 0, err;
371 uint8_t statusreq[6]; 371 uint8_t statusreq[6];
372 372
373 DPRINTFN(15, ("%s: wait-completion: cmd=%02x\n", 373 DPRINTFN(15, ("%s: wait-completion: cmd=%02x\n",
374 device_xname(sc->atu_dev), cmd)); 374 device_xname(sc->atu_dev), cmd));
375 375
376 while (1) { 376 while (1) {
377 err = atu_get_cmd_status(sc, cmd, statusreq); 377 err = atu_get_cmd_status(sc, cmd, statusreq);
378 if (err) 378 if (err)
379 return err; 379 return err;
380 380
381#ifdef ATU_DEBUG 381#ifdef ATU_DEBUG
382 if (atudebug) { 382 if (atudebug) {
383 DPRINTFN(20, ("%s: status=%s cmd=%02x\n", 383 DPRINTFN(20, ("%s: status=%s cmd=%02x\n",
384 device_xname(sc->atu_dev), 384 device_xname(sc->atu_dev),
385 ether_sprintf(statusreq), cmd)); 385 ether_sprintf(statusreq), cmd));
386 } 386 }
387#endif /* ATU_DEBUG */ 387#endif /* ATU_DEBUG */
388 388
389 /* 389 /*
390 * during normal operations waiting on STATUS_IDLE 390 * during normal operations waiting on STATUS_IDLE
391 * will never happen more than once 391 * will never happen more than once
392 */ 392 */
393 if ((statusreq[5] == STATUS_IDLE) && (idle_count++ > 20)) { 393 if ((statusreq[5] == STATUS_IDLE) && (idle_count++ > 20)) {
394 DPRINTF(("%s: idle_count > 20!\n", 394 DPRINTF(("%s: idle_count > 20!\n",
395 device_xname(sc->atu_dev))); 395 device_xname(sc->atu_dev)));
396 return 0; 396 return 0;
397 } 397 }
398 398
399 if ((statusreq[5] != STATUS_IN_PROGRESS) && 399 if ((statusreq[5] != STATUS_IN_PROGRESS) &&
400 (statusreq[5] != STATUS_IDLE)) { 400 (statusreq[5] != STATUS_IDLE)) {
401 if (status != NULL) 401 if (status != NULL)
402 *status = statusreq[5]; 402 *status = statusreq[5];
403 return 0; 403 return 0;
404 } 404 }
405 usbd_delay_ms(sc->atu_udev, 25); 405 usbd_delay_ms(sc->atu_udev, 25);
406 } 406 }
407} 407}
408 408
409static int 409static int
410atu_send_mib(struct atu_softc *sc, uint8_t type, uint8_t size, 410atu_send_mib(struct atu_softc *sc, uint8_t type, uint8_t size,
411 uint8_t index, void *data) 411 uint8_t index, void *data)
412{ 412{
413 int err; 413 int err;
414 struct atu_cmd_set_mib request; 414 struct atu_cmd_set_mib request;
415 415
416 /* 416 /*
417 * We don't construct a MIB packet first and then memcpy it into an 417 * We don't construct a MIB packet first and then memcpy it into an
418 * Atmel-command-packet, we just construct it the right way at once :) 418 * Atmel-command-packet, we just construct it the right way at once :)
419 */ 419 */
420 420
421 memset(&request, 0, sizeof(request)); 421 memset(&request, 0, sizeof(request));
422 422
423 request.AtCmd = CMD_SET_MIB; 423 request.AtCmd = CMD_SET_MIB;
424 USETW(request.AtSize, size + 4); 424 USETW(request.AtSize, size + 4);
425 425
426 request.MIBType = type; 426 request.MIBType = type;
427 request.MIBSize = size; 427 request.MIBSize = size;
428 request.MIBIndex = index; 428 request.MIBIndex = index;
429 request.MIBReserved = 0; 429 request.MIBReserved = 0;
430 430
431 /* 431 /*
432 * For 1 and 2 byte requests we assume a direct value, 432 * For 1 and 2 byte requests we assume a direct value,
433 * everything bigger than 2 bytes we assume a pointer to the data 433 * everything bigger than 2 bytes we assume a pointer to the data
434 */ 434 */
435 switch (size) { 435 switch (size) {
436 case 0: 436 case 0:
437 break; 437 break;
438 case 1: 438 case 1:
439 request.data[0]=(long)data & 0x000000ff; 439 request.data[0]=(long)data & 0x000000ff;
440 break; 440 break;
441 case 2: 441 case 2:
442 request.data[0]=(long)data & 0x000000ff; 442 request.data[0]=(long)data & 0x000000ff;
443 request.data[1]=(long)data >> 8; 443 request.data[1]=(long)data >> 8;
444 break; 444 break;
445 default: 445 default:
446 memcpy(request.data, data, size); 446 memcpy(request.data, data, size);
447 break; 447 break;
448 } 448 }
449 449
450 err = atu_usb_request(sc, UT_WRITE_VENDOR_DEVICE, 0x0e, 0x0000, 450 err = atu_usb_request(sc, UT_WRITE_VENDOR_DEVICE, 0x0e, 0x0000,
451 0x0000, size+8, (uByte *)&request); 451 0x0000, size+8, (uByte *)&request);
452 if (err) 452 if (err)
453 return err; 453 return err;
454 454
455 DPRINTFN(15, ("%s: sendmib : waitcompletion...\n", 455 DPRINTFN(15, ("%s: sendmib : waitcompletion...\n",
456 device_xname(sc->atu_dev))); 456 device_xname(sc->atu_dev)));
457 return atu_wait_completion(sc, CMD_SET_MIB, NULL); 457 return atu_wait_completion(sc, CMD_SET_MIB, NULL);
458} 458}
459 459
460static int 460static int
461atu_get_mib(struct atu_softc *sc, uint8_t type, uint8_t size, 461atu_get_mib(struct atu_softc *sc, uint8_t type, uint8_t size,
462 uint8_t index, uint8_t *buf) 462 uint8_t index, uint8_t *buf)
463{ 463{
464 464
465 /* linux/at76c503.c - 478 */ 465 /* linux/at76c503.c - 478 */
466 return atu_usb_request(sc, UT_READ_VENDOR_INTERFACE, 0x033, 466 return atu_usb_request(sc, UT_READ_VENDOR_INTERFACE, 0x033,
467 type << 8, index, size, buf); 467 type << 8, index, size, buf);
468} 468}
469 469
470#if 0 470#if 0
471int 471int
472atu_start_ibss(struct atu_softc *sc) 472atu_start_ibss(struct atu_softc *sc)
473{ 473{
474 struct ieee80211com *ic = &sc->sc_ic; 474 struct ieee80211com *ic = &sc->sc_ic;
475 int err; 475 int err;
476 struct atu_cmd_start_ibss Request; 476 struct atu_cmd_start_ibss Request;
477 477
478 Request.Cmd = CMD_START_IBSS; 478 Request.Cmd = CMD_START_IBSS;
479 Request.Reserved = 0; 479 Request.Reserved = 0;
480 Request.Size = sizeof(Request) - 4; 480 Request.Size = sizeof(Request) - 4;
481 481
482 memset(Request.BSSID, 0x00, sizeof(Request.BSSID)); 482 memset(Request.BSSID, 0x00, sizeof(Request.BSSID));
483 memset(Request.SSID, 0x00, sizeof(Request.SSID)); 483 memset(Request.SSID, 0x00, sizeof(Request.SSID));
484 memcpy(Request.SSID, ic->ic_des_ssid, ic->ic_des_ssidlen); 484 memcpy(Request.SSID, ic->ic_des_ssid, ic->ic_des_ssidlen);
485 Request.SSIDSize = ic->ic_des_ssidlen; 485 Request.SSIDSize = ic->ic_des_ssidlen;
486 if (sc->atu_desired_channel != IEEE80211_CHAN_ANY) 486 if (sc->atu_desired_channel != IEEE80211_CHAN_ANY)
487 Request.Channel = (uint8_t)sc->atu_desired_channel; 487 Request.Channel = (uint8_t)sc->atu_desired_channel;
488 else 488 else
489 Request.Channel = ATU_DEFAULT_CHANNEL; 489 Request.Channel = ATU_DEFAULT_CHANNEL;
490 Request.BSSType = AD_HOC_MODE; 490 Request.BSSType = AD_HOC_MODE;
491 memset(Request.Res, 0x00, sizeof(Request.Res)); 491 memset(Request.Res, 0x00, sizeof(Request.Res));
492 492
493 /* Write config to adapter */ 493 /* Write config to adapter */
494 err = atu_send_command(sc, (uint8_t *)&Request, sizeof(Request)); 494 err = atu_send_command(sc, (uint8_t *)&Request, sizeof(Request));
495 if (err) { 495 if (err) {
496 DPRINTF(("%s: start ibss failed!\n", 496 DPRINTF(("%s: start ibss failed!\n",
497 device_xname(sc->atu_dev))); 497 device_xname(sc->atu_dev)));
498 return err; 498 return err;
499 } 499 }
500 500
501 /* Wait for the adapter to do its thing */ 501 /* Wait for the adapter to do its thing */
502 err = atu_wait_completion(sc, CMD_START_IBSS, NULL); 502 err = atu_wait_completion(sc, CMD_START_IBSS, NULL);
503 if (err) { 503 if (err) {
504 DPRINTF(("%s: error waiting for start_ibss\n", 504 DPRINTF(("%s: error waiting for start_ibss\n",
505 device_xname(sc->atu_dev))); 505 device_xname(sc->atu_dev)));
506 return err; 506 return err;
507 } 507 }
508 508
509 /* Get the current BSSID */ 509 /* Get the current BSSID */
510 err = atu_get_mib(sc, MIB_MAC_MGMT__CURRENT_BSSID, sc->atu_bssid); 510 err = atu_get_mib(sc, MIB_MAC_MGMT__CURRENT_BSSID, sc->atu_bssid);
511 if (err) { 511 if (err) {
512 DPRINTF(("%s: could not get BSSID!\n", 512 DPRINTF(("%s: could not get BSSID!\n",
513 device_xname(sc->atu_dev))); 513 device_xname(sc->atu_dev)));
514 return err; 514 return err;
515 } 515 }
516 516
517 DPRINTF(("%s: started a new IBSS (BSSID=%s)\n", 517 DPRINTF(("%s: started a new IBSS (BSSID=%s)\n",
518 device_xname(sc->atu_dev), ether_sprintf(sc->atu_bssid))); 518 device_xname(sc->atu_dev), ether_sprintf(sc->atu_bssid)));
519 return 0; 519 return 0;
520} 520}
521#endif 521#endif
522 522
523static int 523static int
524atu_start_scan(struct atu_softc *sc) 524atu_start_scan(struct atu_softc *sc)
525{ 525{
526 struct ieee80211com *ic = &sc->sc_ic; 526 struct ieee80211com *ic = &sc->sc_ic;
527 struct atu_cmd_do_scan Scan; 527 struct atu_cmd_do_scan Scan;
528 usbd_status err; 528 usbd_status err;
529 int Cnt; 529 int Cnt;
530 530
531 memset(&Scan, 0, sizeof(Scan)); 531 memset(&Scan, 0, sizeof(Scan));
532 532
533 Scan.Cmd = CMD_START_SCAN; 533 Scan.Cmd = CMD_START_SCAN;
534 Scan.Reserved = 0; 534 Scan.Reserved = 0;
535 USETW(Scan.Size, sizeof(Scan) - 4); 535 USETW(Scan.Size, sizeof(Scan) - 4);
536 536
537 /* use the broadcast BSSID (in active scan) */ 537 /* use the broadcast BSSID (in active scan) */
538 for (Cnt=0; Cnt<6; Cnt++) 538 for (Cnt=0; Cnt<6; Cnt++)
539 Scan.BSSID[Cnt] = 0xff; 539 Scan.BSSID[Cnt] = 0xff;
540 540
541 memset(Scan.SSID, 0x00, sizeof(Scan.SSID)); 541 memset(Scan.SSID, 0x00, sizeof(Scan.SSID));
542 memcpy(Scan.SSID, ic->ic_des_essid, ic->ic_des_esslen); 542 memcpy(Scan.SSID, ic->ic_des_essid, ic->ic_des_esslen);
543 Scan.SSID_Len = ic->ic_des_esslen; 543 Scan.SSID_Len = ic->ic_des_esslen;
544 544
545 /* default values for scan */ 545 /* default values for scan */
546 Scan.ScanType = ATU_SCAN_ACTIVE; 546 Scan.ScanType = ATU_SCAN_ACTIVE;
547 if (sc->atu_desired_channel != IEEE80211_CHAN_ANY) 547 if (sc->atu_desired_channel != IEEE80211_CHAN_ANY)
548 Scan.Channel = (uint8_t)sc->atu_desired_channel; 548 Scan.Channel = (uint8_t)sc->atu_desired_channel;
549 else 549 else
550 Scan.Channel = sc->atu_channel; 550 Scan.Channel = sc->atu_channel;
551 551
552 ic->ic_curchan = &ic->ic_channels[Scan.Channel]; 552 ic->ic_curchan = &ic->ic_channels[Scan.Channel];
553 553
554 /* we like scans to be quick :) */ 554 /* we like scans to be quick :) */
555 /* the time we wait before sending probe's */ 555 /* the time we wait before sending probe's */
556 USETW(Scan.ProbeDelay, 0); 556 USETW(Scan.ProbeDelay, 0);
557 /* the time we stay on one channel */ 557 /* the time we stay on one channel */
558 USETW(Scan.MinChannelTime, 100); 558 USETW(Scan.MinChannelTime, 100);
559 USETW(Scan.MaxChannelTime, 200); 559 USETW(Scan.MaxChannelTime, 200);
560 /* whether or not we scan all channels */ 560 /* whether or not we scan all channels */
561 Scan.InternationalScan = 0xc1; 561 Scan.InternationalScan = 0xc1;
562 562
563#ifdef ATU_DEBUG 563#ifdef ATU_DEBUG
564 if (atudebug) { 564 if (atudebug) {
565 DPRINTFN(20, ("%s: scan cmd len=%02zx\n", 565 DPRINTFN(20, ("%s: scan cmd len=%02zx\n",
566 device_xname(sc->atu_dev), sizeof(Scan))); 566 device_xname(sc->atu_dev), sizeof(Scan)));
567 } 567 }
568#endif /* ATU_DEBUG */ 568#endif /* ATU_DEBUG */
569 569
570 /* Write config to adapter */ 570 /* Write config to adapter */
571 err = atu_send_command(sc, (uint8_t *)&Scan, sizeof(Scan)); 571 err = atu_send_command(sc, (uint8_t *)&Scan, sizeof(Scan));
572 if (err) 572 if (err)
573 return err; 573 return err;
574 574
575 /* 575 /*
576 * We don't wait for the command to finish... the mgmt-thread will do 576 * We don't wait for the command to finish... the mgmt-thread will do
577 * that for us 577 * that for us
578 */ 578 */
579 /* 579 /*
580 err = atu_wait_completion(sc, CMD_START_SCAN, NULL); 580 err = atu_wait_completion(sc, CMD_START_SCAN, NULL);
581 if (err) 581 if (err)
582 return err; 582 return err;
583 */ 583 */
584 return 0; 584 return 0;
585} 585}
586 586
587static int 587static int
588atu_switch_radio(struct atu_softc *sc, int state) 588atu_switch_radio(struct atu_softc *sc, int state)
589{ 589{
590 usbd_status err; 590 usbd_status err;
591 struct atu_cmd CmdRadio; 591 struct atu_cmd CmdRadio;
592 592
593 if (sc->atu_radio == RadioIntersil) { 593 if (sc->atu_radio == RadioIntersil) {
594 /* 594 /*
595 * Intersil doesn't seem to need/support switching the radio 595 * Intersil doesn't seem to need/support switching the radio
596 * on/off 596 * on/off
597 */ 597 */
598 return 0; 598 return 0;
599 } 599 }
600 600
601 memset(&CmdRadio, 0, sizeof(CmdRadio)); 601 memset(&CmdRadio, 0, sizeof(CmdRadio));
602 CmdRadio.Cmd = CMD_RADIO_ON; 602 CmdRadio.Cmd = CMD_RADIO_ON;
603 603
604 if (sc->atu_radio_on != state) { 604 if (sc->atu_radio_on != state) {
605 if (state == 0) 605 if (state == 0)
606 CmdRadio.Cmd = CMD_RADIO_OFF; 606 CmdRadio.Cmd = CMD_RADIO_OFF;
607 607
608 err = atu_send_command(sc, (uint8_t *)&CmdRadio, 608 err = atu_send_command(sc, (uint8_t *)&CmdRadio,
609 sizeof(CmdRadio)); 609 sizeof(CmdRadio));
610 if (err) 610 if (err)
611 return err; 611 return err;
612 612
613 err = atu_wait_completion(sc, CmdRadio.Cmd, NULL); 613 err = atu_wait_completion(sc, CmdRadio.Cmd, NULL);
614 if (err) 614 if (err)
615 return err; 615 return err;
616 616
617 DPRINTFN(10, ("%s: radio turned %s\n", 617 DPRINTFN(10, ("%s: radio turned %s\n",
618 device_xname(sc->atu_dev), state ? "on" : "off")); 618 device_xname(sc->atu_dev), state ? "on" : "off"));
619 sc->atu_radio_on = state; 619 sc->atu_radio_on = state;
620 } 620 }
621 return 0; 621 return 0;
622} 622}
623 623
624static int 624static int
625atu_initial_config(struct atu_softc *sc) 625atu_initial_config(struct atu_softc *sc)
626{ 626{
627 struct ieee80211com *ic = &sc->sc_ic; 627 struct ieee80211com *ic = &sc->sc_ic;
628 uint32_t i; 628 uint32_t i;
629 usbd_status err; 629 usbd_status err;
630/* uint8_t rates[4] = {0x82, 0x84, 0x8B, 0x96};*/ 630/* uint8_t rates[4] = {0x82, 0x84, 0x8B, 0x96};*/
631 uint8_t rates[4] = {0x82, 0x04, 0x0B, 0x16}; 631 uint8_t rates[4] = {0x82, 0x04, 0x0B, 0x16};
632 struct atu_cmd_card_config cmd; 632 struct atu_cmd_card_config cmd;
633 uint8_t reg_domain; 633 uint8_t reg_domain;
634 634
635 DPRINTFN(10, ("%s: sending mac-addr\n", device_xname(sc->atu_dev))); 635 DPRINTFN(10, ("%s: sending mac-addr\n", device_xname(sc->atu_dev)));
636 err = atu_send_mib(sc, MIB_MAC_ADDR__ADDR, ic->ic_myaddr); 636 err = atu_send_mib(sc, MIB_MAC_ADDR__ADDR, ic->ic_myaddr);
637 if (err) { 637 if (err) {
638 DPRINTF(("%s: error setting mac-addr\n", 638 DPRINTF(("%s: error setting mac-addr\n",
639 device_xname(sc->atu_dev))); 639 device_xname(sc->atu_dev)));
640 return err; 640 return err;
641 } 641 }
642 642
643 /* 643 /*
644 DPRINTF(("%s: sending reg-domain\n", device_xname(sc->atu_dev))); 644 DPRINTF(("%s: sending reg-domain\n", device_xname(sc->atu_dev)));
645 err = atu_send_mib(sc, MIB_PHY__REG_DOMAIN, NR(0x30)); 645 err = atu_send_mib(sc, MIB_PHY__REG_DOMAIN, NR(0x30));
646 if (err) { 646 if (err) {
647 DPRINTF(("%s: error setting mac-addr\n", 647 DPRINTF(("%s: error setting mac-addr\n",
648 device_xname(sc->atu_dev))); 648 device_xname(sc->atu_dev)));
649 return err; 649 return err;
650 } 650 }
651 */ 651 */
652 652
653 memset(&cmd, 0, sizeof(cmd)); 653 memset(&cmd, 0, sizeof(cmd));
654 cmd.Cmd = CMD_STARTUP; 654 cmd.Cmd = CMD_STARTUP;
655 cmd.Reserved = 0; 655 cmd.Reserved = 0;
656 USETW(cmd.Size, sizeof(cmd) - 4); 656 USETW(cmd.Size, sizeof(cmd) - 4);
657 657
658 if (sc->atu_desired_channel != IEEE80211_CHAN_ANY) 658 if (sc->atu_desired_channel != IEEE80211_CHAN_ANY)
659 cmd.Channel = (uint8_t)sc->atu_desired_channel; 659 cmd.Channel = (uint8_t)sc->atu_desired_channel;
660 else 660 else
661 cmd.Channel = sc->atu_channel; 661 cmd.Channel = sc->atu_channel;
662 cmd.AutoRateFallback = 1; 662 cmd.AutoRateFallback = 1;
663 memcpy(cmd.BasicRateSet, rates, 4); 663 memcpy(cmd.BasicRateSet, rates, 4);
664 664
665 /* ShortRetryLimit should be 7 according to 802.11 spec */ 665 /* ShortRetryLimit should be 7 according to 802.11 spec */
666 cmd.ShortRetryLimit = 7; 666 cmd.ShortRetryLimit = 7;
667 USETW(cmd.RTS_Threshold, 2347); 667 USETW(cmd.RTS_Threshold, 2347);
668 USETW(cmd.FragThreshold, 2346); 668 USETW(cmd.FragThreshold, 2346);
669 669
670 /* Doesn't seem to work, but we'll set it to 1 anyway */ 670 /* Doesn't seem to work, but we'll set it to 1 anyway */
671 cmd.PromiscuousMode = 1; 671 cmd.PromiscuousMode = 1;
672 672
673 /* this goes into the beacon we transmit */ 673 /* this goes into the beacon we transmit */
674 if (ic->ic_flags & IEEE80211_F_PRIVACY) 674 if (ic->ic_flags & IEEE80211_F_PRIVACY)
675 cmd.PrivacyInvoked = 1; 675 cmd.PrivacyInvoked = 1;
676 else 676 else
677 cmd.PrivacyInvoked = 0; 677 cmd.PrivacyInvoked = 0;
678 678
679 cmd.ExcludeUnencrypted = 0; 679 cmd.ExcludeUnencrypted = 0;
680 680
681 if (ic->ic_flags & IEEE80211_F_PRIVACY) { 681 if (ic->ic_flags & IEEE80211_F_PRIVACY) {
682 switch (ic->ic_nw_keys[ic->ic_def_txkey].wk_keylen) { 682 switch (ic->ic_nw_keys[ic->ic_def_txkey].wk_keylen) {
683 case 5: 683 case 5:
684 cmd.EncryptionType = ATU_WEP_40BITS; 684 cmd.EncryptionType = ATU_WEP_40BITS;
685 break; 685 break;
686 case 13: 686 case 13:
687 cmd.EncryptionType = ATU_WEP_104BITS; 687 cmd.EncryptionType = ATU_WEP_104BITS;
688 break; 688 break;
689 default: 689 default:
690 cmd.EncryptionType = ATU_WEP_OFF; 690 cmd.EncryptionType = ATU_WEP_OFF;
691 break; 691 break;
692 } 692 }
693 693
694 694
695 cmd.WEP_DefaultKeyID = ic->ic_def_txkey; 695 cmd.WEP_DefaultKeyID = ic->ic_def_txkey;
696 for (i = 0; i < IEEE80211_WEP_NKID; i++) { 696 for (i = 0; i < IEEE80211_WEP_NKID; i++) {
697 memcpy(cmd.WEP_DefaultKey[i], ic->ic_nw_keys[i].wk_key, 697 memcpy(cmd.WEP_DefaultKey[i], ic->ic_nw_keys[i].wk_key,
698 ic->ic_nw_keys[i].wk_keylen); 698 ic->ic_nw_keys[i].wk_keylen);
699 } 699 }
700 } 700 }
701 701
702 /* Setting the SSID here doesn't seem to do anything */ 702 /* Setting the SSID here doesn't seem to do anything */
703 memset(cmd.SSID, 0x00, sizeof(cmd.SSID)); 703 memset(cmd.SSID, 0x00, sizeof(cmd.SSID));
704 memcpy(cmd.SSID, ic->ic_des_essid, ic->ic_des_esslen); 704 memcpy(cmd.SSID, ic->ic_des_essid, ic->ic_des_esslen);
705 cmd.SSID_Len = ic->ic_des_esslen; 705 cmd.SSID_Len = ic->ic_des_esslen;
706 706
707 cmd.ShortPreamble = 0; 707 cmd.ShortPreamble = 0;
708 USETW(cmd.BeaconPeriod, 100); 708 USETW(cmd.BeaconPeriod, 100);
709 /* cmd.BeaconPeriod = 65535; */ 709 /* cmd.BeaconPeriod = 65535; */
710 710
711 /* 711 /*
712 * TODO: 712 * TODO:
713 * read reg domain MIB_PHY @ 0x17 (1 byte), (reply = 0x30) 713 * read reg domain MIB_PHY @ 0x17 (1 byte), (reply = 0x30)
714 * we should do something useful with this info. right now it's just 714 * we should do something useful with this info. right now it's just
715 * ignored 715 * ignored
716 */ 716 */
717 err = atu_get_mib(sc, MIB_PHY__REG_DOMAIN, &reg_domain); 717 err = atu_get_mib(sc, MIB_PHY__REG_DOMAIN, &reg_domain);
718 if (err) { 718 if (err) {
719 DPRINTF(("%s: could not get regdomain!\n", 719 DPRINTF(("%s: could not get regdomain!\n",
720 device_xname(sc->atu_dev))); 720 device_xname(sc->atu_dev)));
721 } else { 721 } else {
722 DPRINTF(("%s: in reg domain %#x according to the " 722 DPRINTF(("%s: in reg domain %#x according to the "
723 "adapter\n", device_xname(sc->atu_dev), reg_domain)); 723 "adapter\n", device_xname(sc->atu_dev), reg_domain));
724 } 724 }
725 725
726#ifdef ATU_DEBUG 726#ifdef ATU_DEBUG
727 if (atudebug) { 727 if (atudebug) {
728 DPRINTFN(20, ("%s: configlen=%02zx\n", 728 DPRINTFN(20, ("%s: configlen=%02zx\n",
729 device_xname(sc->atu_dev), sizeof(cmd))); 729 device_xname(sc->atu_dev), sizeof(cmd)));
730 } 730 }
731#endif /* ATU_DEBUG */ 731#endif /* ATU_DEBUG */
732 732
733 /* Windoze : driver says exclude-unencrypted=1 & encr-type=1 */ 733 /* Windoze : driver says exclude-unencrypted=1 & encr-type=1 */
734 734
735 err = atu_send_command(sc, (uint8_t *)&cmd, sizeof(cmd)); 735 err = atu_send_command(sc, (uint8_t *)&cmd, sizeof(cmd));
736 if (err) 736 if (err)
737 return err; 737 return err;
738 err = atu_wait_completion(sc, CMD_STARTUP, NULL); 738 err = atu_wait_completion(sc, CMD_STARTUP, NULL);
739 if (err) 739 if (err)
740 return err; 740 return err;
741 741
742 /* Turn on radio now */ 742 /* Turn on radio now */
743 err = atu_switch_radio(sc, 1); 743 err = atu_switch_radio(sc, 1);
744 if (err) 744 if (err)
745 return err; 745 return err;
746 746
747 /* preamble type = short */ 747 /* preamble type = short */
748 err = atu_send_mib(sc, MIB_LOCAL__PREAMBLE, NR(PREAMBLE_SHORT)); 748 err = atu_send_mib(sc, MIB_LOCAL__PREAMBLE, NR(PREAMBLE_SHORT));
749 if (err) 749 if (err)
750 return err; 750 return err;
751 751
752 /* frag = 1536 */ 752 /* frag = 1536 */
753 err = atu_send_mib(sc, MIB_MAC__FRAG, NR(2346)); 753 err = atu_send_mib(sc, MIB_MAC__FRAG, NR(2346));
754 if (err) 754 if (err)
755 return err; 755 return err;
756 756
757 /* rts = 1536 */ 757 /* rts = 1536 */
758 err = atu_send_mib(sc, MIB_MAC__RTS, NR(2347)); 758 err = atu_send_mib(sc, MIB_MAC__RTS, NR(2347));
759 if (err) 759 if (err)
760 return err; 760 return err;
761 761
762 /* auto rate fallback = 1 */ 762 /* auto rate fallback = 1 */
763 err = atu_send_mib(sc, MIB_LOCAL__AUTO_RATE_FALLBACK, NR(1)); 763 err = atu_send_mib(sc, MIB_LOCAL__AUTO_RATE_FALLBACK, NR(1));
764 if (err) 764 if (err)
765 return err; 765 return err;
766 766
767 /* power mode = full on, no power saving */ 767 /* power mode = full on, no power saving */
768 err = atu_send_mib(sc, MIB_MAC_MGMT__POWER_MODE, 768 err = atu_send_mib(sc, MIB_MAC_MGMT__POWER_MODE,
769 NR(POWER_MODE_ACTIVE)); 769 NR(POWER_MODE_ACTIVE));
770 if (err) 770 if (err)
771 return err; 771 return err;
772 772
773 DPRINTFN(10, ("%s: completed initial config\n", 773 DPRINTFN(10, ("%s: completed initial config\n",
774 device_xname(sc->atu_dev))); 774 device_xname(sc->atu_dev)));
775 return 0; 775 return 0;
776} 776}
777 777
778static int 778static int
779atu_join(struct atu_softc *sc, struct ieee80211_node *node) 779atu_join(struct atu_softc *sc, struct ieee80211_node *node)
780{ 780{
781 struct atu_cmd_join join; 781 struct atu_cmd_join join;
782 uint8_t status = 0; /* XXX: GCC */ 782 uint8_t status = 0; /* XXX: GCC */
783 usbd_status err; 783 usbd_status err;
784 784
785 memset(&join, 0, sizeof(join)); 785 memset(&join, 0, sizeof(join));
786 786
787 join.Cmd = CMD_JOIN; 787 join.Cmd = CMD_JOIN;
788 join.Reserved = 0x00; 788 join.Reserved = 0x00;
789 USETW(join.Size, sizeof(join) - 4); 789 USETW(join.Size, sizeof(join) - 4);
790 790
791 DPRINTFN(15, ("%s: pre-join sc->atu_bssid=%s\n", 791 DPRINTFN(15, ("%s: pre-join sc->atu_bssid=%s\n",
792 device_xname(sc->atu_dev), ether_sprintf(sc->atu_bssid))); 792 device_xname(sc->atu_dev), ether_sprintf(sc->atu_bssid)));
793 DPRINTFN(15, ("%s: mode=%d\n", device_xname(sc->atu_dev), 793 DPRINTFN(15, ("%s: mode=%d\n", device_xname(sc->atu_dev),
794 sc->atu_mode)); 794 sc->atu_mode));
795 memcpy(join.bssid, node->ni_bssid, IEEE80211_ADDR_LEN); 795 memcpy(join.bssid, node->ni_bssid, IEEE80211_ADDR_LEN);
796 memset(join.essid, 0x00, 32); 796 memset(join.essid, 0x00, 32);
797 memcpy(join.essid, node->ni_essid, node->ni_esslen); 797 memcpy(join.essid, node->ni_essid, node->ni_esslen);
798 join.essid_size = node->ni_esslen; 798 join.essid_size = node->ni_esslen;
799 if (node->ni_capinfo & IEEE80211_CAPINFO_IBSS) 799 if (node->ni_capinfo & IEEE80211_CAPINFO_IBSS)
800 join.bss_type = AD_HOC_MODE; 800 join.bss_type = AD_HOC_MODE;
801 else 801 else
802 join.bss_type = INFRASTRUCTURE_MODE; 802 join.bss_type = INFRASTRUCTURE_MODE;
803 join.channel = ieee80211_chan2ieee(&sc->sc_ic, node->ni_chan); 803 join.channel = ieee80211_chan2ieee(&sc->sc_ic, node->ni_chan);
804 804
805 USETW(join.timeout, ATU_JOIN_TIMEOUT); 805 USETW(join.timeout, ATU_JOIN_TIMEOUT);
806 join.reserved = 0x00; 806 join.reserved = 0x00;
807 807
808 DPRINTFN(10, ("%s: trying to join BSSID=%s\n", 808 DPRINTFN(10, ("%s: trying to join BSSID=%s\n",
809 device_xname(sc->atu_dev), ether_sprintf(join.bssid))); 809 device_xname(sc->atu_dev), ether_sprintf(join.bssid)));
810 err = atu_send_command(sc, (uint8_t *)&join, sizeof(join)); 810 err = atu_send_command(sc, (uint8_t *)&join, sizeof(join));
811 if (err) { 811 if (err) {
812 DPRINTF(("%s: ERROR trying to join IBSS\n", 812 DPRINTF(("%s: ERROR trying to join IBSS\n",
813 device_xname(sc->atu_dev))); 813 device_xname(sc->atu_dev)));
814 return err; 814 return err;
815 } 815 }
816 err = atu_wait_completion(sc, CMD_JOIN, &status); 816 err = atu_wait_completion(sc, CMD_JOIN, &status);
817 if (err) { 817 if (err) {
818 DPRINTF(("%s: error joining BSS!\n", 818 DPRINTF(("%s: error joining BSS!\n",
819 device_xname(sc->atu_dev))); 819 device_xname(sc->atu_dev)));
820 return err; 820 return err;
821 } 821 }
822 if (status != STATUS_COMPLETE) { 822 if (status != STATUS_COMPLETE) {
823 DPRINTF(("%s: error joining... [status=%02x]\n", 823 DPRINTF(("%s: error joining... [status=%02x]\n",
824 device_xname(sc->atu_dev), status)); 824 device_xname(sc->atu_dev), status));
825 return status; 825 return status;
826 } else { 826 } else {
827 DPRINTFN(10, ("%s: joined BSS\n", device_xname(sc->atu_dev))); 827 DPRINTFN(10, ("%s: joined BSS\n", device_xname(sc->atu_dev)));
828 } 828 }
829 return err; 829 return err;
830} 830}
831 831
832/* 832/*
833 * Get the state of the DFU unit 833 * Get the state of the DFU unit
834 */ 834 */
835static int8_t 835static int8_t
836atu_get_dfu_state(struct atu_softc *sc) 836atu_get_dfu_state(struct atu_softc *sc)
837{ 837{
838 uint8_t state; 838 uint8_t state;
839 839
840 if (atu_usb_request(sc, DFU_GETSTATE, 0, 0, 1, &state)) 840 if (atu_usb_request(sc, DFU_GETSTATE, 0, 0, 1, &state))
841 return -1; 841 return -1;
842 return state; 842 return state;
843} 843}
844 844
845/* 845/*
846 * Get MAC opmode 846 * Get MAC opmode
847 */ 847 */
848static uint8_t 848static uint8_t
849atu_get_opmode(struct atu_softc *sc, uint8_t *mode) 849atu_get_opmode(struct atu_softc *sc, uint8_t *mode)
850{ 850{
851 851
852 return atu_usb_request(sc, UT_READ_VENDOR_INTERFACE, 0x33, 0x0001, 852 return atu_usb_request(sc, UT_READ_VENDOR_INTERFACE, 0x33, 0x0001,
853 0x0000, 1, mode); 853 0x0000, 1, mode);
854} 854}
855 855
856/* 856/*
857 * Upload the internal firmware into the device 857 * Upload the internal firmware into the device
858 */ 858 */
859static void 859static void
860atu_internal_firmware(device_t arg) 860atu_internal_firmware(device_t arg)
861{ 861{
862 struct atu_softc *sc = device_private(arg); 862 struct atu_softc *sc = device_private(arg);
863 u_char state, *ptr = NULL, *firm = NULL, status[6]; 863 u_char state, *ptr = NULL, *firm = NULL, status[6];
864 int block_size, block = 0, err, i; 864 int block_size, block = 0, err, i;
865 size_t bytes_left = 0; 865 size_t bytes_left = 0;
866 866
867 /* 867 /*
868 * Uploading firmware is done with the DFU (Device Firmware Upgrade) 868 * Uploading firmware is done with the DFU (Device Firmware Upgrade)
869 * interface. See "Universal Serial Bus - Device Class Specification 869 * interface. See "Universal Serial Bus - Device Class Specification
870 * for Device Firmware Upgrade" pdf for details of the protocol. 870 * for Device Firmware Upgrade" pdf for details of the protocol.
871 * Maybe this could be moved to a separate 'firmware driver' once more 871 * Maybe this could be moved to a separate 'firmware driver' once more
872 * device drivers need it... For now we'll just do it here. 872 * device drivers need it... For now we'll just do it here.
873 * 873 *
874 * Just for your information, the Atmel's DFU descriptor looks like 874 * Just for your information, the Atmel's DFU descriptor looks like
875 * this: 875 * this:
876 * 876 *
877 * 07 size 877 * 07 size
878 * 21 type 878 * 21 type
879 * 01 capabilities : only firmware download, need reset 879 * 01 capabilities : only firmware download, need reset
880 * after download 880 * after download
881 * 13 05 detach timeout : max 1299ms between DFU_DETACH and 881 * 13 05 detach timeout : max 1299ms between DFU_DETACH and
882 * reset 882 * reset
883 * 00 04 max bytes of firmware per transaction : 1024 883 * 00 04 max bytes of firmware per transaction : 1024
884 */ 884 */
885 885
886 /* Choose the right firmware for the device */ 886 /* Choose the right firmware for the device */
887 for (i = 0; i < __arraycount(atu_radfirm); i++) 887 for (i = 0; i < __arraycount(atu_radfirm); i++)
888 if (sc->atu_radio == atu_radfirm[i].atur_type) { 888 if (sc->atu_radio == atu_radfirm[i].atur_type) {
889 firm = atu_radfirm[i].atur_internal; 889 firm = atu_radfirm[i].atur_internal;
890 bytes_left = atu_radfirm[i].atur_internal_sz; 890 bytes_left = atu_radfirm[i].atur_internal_sz;
891 } 891 }
892 892
893 if (firm == NULL) { 893 if (firm == NULL) {
894 aprint_error_dev(arg, "no firmware found\n"); 894 aprint_error_dev(arg, "no firmware found\n");
895 return; 895 return;
896 } 896 }
897 897
898 ptr = firm; 898 ptr = firm;
899 state = atu_get_dfu_state(sc); 899 state = atu_get_dfu_state(sc);
900 900
901 while (block >= 0 && state > 0) { 901 while (block >= 0 && state > 0) {
902 switch (state) { 902 switch (state) {
903 case DFUState_DnLoadSync: 903 case DFUState_DnLoadSync:
904 /* get DFU status */ 904 /* get DFU status */
905 err = atu_usb_request(sc, DFU_GETSTATUS, 0, 0 , 6, 905 err = atu_usb_request(sc, DFU_GETSTATUS, 0, 0 , 6,
906 status); 906 status);
907 if (err) { 907 if (err) {
908 DPRINTF(("%s: dfu_getstatus failed!\n", 908 DPRINTF(("%s: dfu_getstatus failed!\n",
909 device_xname(sc->atu_dev))); 909 device_xname(sc->atu_dev)));
910 return; 910 return;
911 } 911 }
912 /* success means state => DnLoadIdle */ 912 /* success means state => DnLoadIdle */
913 state = DFUState_DnLoadIdle; 913 state = DFUState_DnLoadIdle;
914 continue; 914 continue;
915 break; 915 break;
916 916
917 case DFUState_DFUIdle: 917 case DFUState_DFUIdle:
918 case DFUState_DnLoadIdle: 918 case DFUState_DnLoadIdle:
919 if (bytes_left>=DFU_MaxBlockSize) 919 if (bytes_left>=DFU_MaxBlockSize)
920 block_size = DFU_MaxBlockSize; 920 block_size = DFU_MaxBlockSize;
921 else 921 else
922 block_size = bytes_left; 922 block_size = bytes_left;
923 DPRINTFN(15, ("%s: firmware block %d\n", 923 DPRINTFN(15, ("%s: firmware block %d\n",
924 device_xname(sc->atu_dev), block)); 924 device_xname(sc->atu_dev), block));
925 925
926 err = atu_usb_request(sc, DFU_DNLOAD, block++, 0, 926 err = atu_usb_request(sc, DFU_DNLOAD, block++, 0,
927 block_size, ptr); 927 block_size, ptr);
928 if (err) { 928 if (err) {
929 DPRINTF(("%s: dfu_dnload failed\n", 929 DPRINTF(("%s: dfu_dnload failed\n",
930 device_xname(sc->atu_dev))); 930 device_xname(sc->atu_dev)));
931 return; 931 return;
932 } 932 }
933 933
934 ptr += block_size; 934 ptr += block_size;
935 bytes_left -= block_size; 935 bytes_left -= block_size;
936 if (block_size == 0) 936 if (block_size == 0)
937 block = -1; 937 block = -1;
938 break; 938 break;
939 939
940 default: 940 default:
941 usbd_delay_ms(sc->atu_udev, 100); 941 usbd_delay_ms(sc->atu_udev, 100);
942 DPRINTFN(20, ("%s: sleeping for a while\n", 942 DPRINTFN(20, ("%s: sleeping for a while\n",
943 device_xname(sc->atu_dev))); 943 device_xname(sc->atu_dev)));
944 break; 944 break;
945 } 945 }
946 946
947 state = atu_get_dfu_state(sc); 947 state = atu_get_dfu_state(sc);
948 } 948 }
949 949
950 if (state != DFUState_ManifestSync) { 950 if (state != DFUState_ManifestSync) {
951 DPRINTF(("%s: state != manifestsync... eek!\n", 951 DPRINTF(("%s: state != manifestsync... eek!\n",
952 device_xname(sc->atu_dev))); 952 device_xname(sc->atu_dev)));
953 } 953 }
954 954
955 err = atu_usb_request(sc, DFU_GETSTATUS, 0, 0, 6, status); 955 err = atu_usb_request(sc, DFU_GETSTATUS, 0, 0, 6, status);
956 if (err) { 956 if (err) {
957 DPRINTF(("%s: dfu_getstatus failed!\n", 957 DPRINTF(("%s: dfu_getstatus failed!\n",
958 device_xname(sc->atu_dev))); 958 device_xname(sc->atu_dev)));
959 return; 959 return;
960 } 960 }
961 961
962 DPRINTFN(15, ("%s: sending remap\n", device_xname(sc->atu_dev))); 962 DPRINTFN(15, ("%s: sending remap\n", device_xname(sc->atu_dev)));
963 err = atu_usb_request(sc, DFU_REMAP, 0, 0, 0, NULL); 963 err = atu_usb_request(sc, DFU_REMAP, 0, 0, 0, NULL);
964 if ((err) && !(sc->atu_quirk & ATU_QUIRK_NO_REMAP)) { 964 if ((err) && !(sc->atu_quirk & ATU_QUIRK_NO_REMAP)) {
965 DPRINTF(("%s: remap failed!\n", device_xname(sc->atu_dev))); 965 DPRINTF(("%s: remap failed!\n", device_xname(sc->atu_dev)));
966 return; 966 return;
967 } 967 }
968 968
969 /* after a lot of trying and measuring I found out the device needs 969 /* after a lot of trying and measuring I found out the device needs
970 * about 56 miliseconds after sending the remap command before 970 * about 56 miliseconds after sending the remap command before
971 * it's ready to communicate again. So we'll wait just a little bit 971 * it's ready to communicate again. So we'll wait just a little bit
972 * longer than that to be sure... 972 * longer than that to be sure...
973 */ 973 */
974 usbd_delay_ms(sc->atu_udev, 56+100); 974 usbd_delay_ms(sc->atu_udev, 56+100);
975 975
976 aprint_error_dev(arg, "reattaching after firmware upload\n"); 976 aprint_error_dev(arg, "reattaching after firmware upload\n");
977 usb_needs_reattach(sc->atu_udev); 977 usb_needs_reattach(sc->atu_udev);
978} 978}
979 979
980static void 980static void
981atu_external_firmware(device_t arg) 981atu_external_firmware(device_t arg)
982{ 982{
983 struct atu_softc *sc = device_private(arg); 983 struct atu_softc *sc = device_private(arg);
984 u_char *ptr = NULL, *firm = NULL; 984 u_char *ptr = NULL, *firm = NULL;
985 int block_size, block = 0, err, i; 985 int block_size, block = 0, err, i;
986 size_t bytes_left = 0; 986 size_t bytes_left = 0;
987 987
988 for (i = 0; i < __arraycount(atu_radfirm); i++) 988 for (i = 0; i < __arraycount(atu_radfirm); i++)
989 if (sc->atu_radio == atu_radfirm[i].atur_type) { 989 if (sc->atu_radio == atu_radfirm[i].atur_type) {
990 firm = atu_radfirm[i].atur_external; 990 firm = atu_radfirm[i].atur_external;
991 bytes_left = atu_radfirm[i].atur_external_sz; 991 bytes_left = atu_radfirm[i].atur_external_sz;
992 } 992 }
993 993
994 if (firm == NULL) { 994 if (firm == NULL) {
995 aprint_error_dev(arg, "no firmware found\n"); 995 aprint_error_dev(arg, "no firmware found\n");
996 return; 996 return;
997 } 997 }
998 ptr = firm; 998 ptr = firm;
999 999
1000 while (bytes_left) { 1000 while (bytes_left) {
1001 if (bytes_left > 1024) 1001 if (bytes_left > 1024)
1002 block_size = 1024; 1002 block_size = 1024;
1003 else 1003 else
1004 block_size = bytes_left; 1004 block_size = bytes_left;
1005 1005
1006 DPRINTFN(15, ("%s: block:%d size:%d\n", 1006 DPRINTFN(15, ("%s: block:%d size:%d\n",
1007 device_xname(sc->atu_dev), block, block_size)); 1007 device_xname(sc->atu_dev), block, block_size));
1008 err = atu_usb_request(sc, UT_WRITE_VENDOR_DEVICE, 0x0e, 1008 err = atu_usb_request(sc, UT_WRITE_VENDOR_DEVICE, 0x0e,
1009 0x0802, block, block_size, ptr); 1009 0x0802, block, block_size, ptr);
1010 if (err) { 1010 if (err) {
1011 DPRINTF(("%s: could not load external firmware " 1011 DPRINTF(("%s: could not load external firmware "
1012 "block\n", device_xname(sc->atu_dev))); 1012 "block\n", device_xname(sc->atu_dev)));
1013 return; 1013 return;
1014 } 1014 }
1015 1015
1016 ptr += block_size; 1016 ptr += block_size;
1017 block++; 1017 block++;
1018 bytes_left -= block_size; 1018 bytes_left -= block_size;
1019 } 1019 }
1020 1020
1021 err = atu_usb_request(sc, UT_WRITE_VENDOR_DEVICE, 0x0e, 0x0802, 1021 err = atu_usb_request(sc, UT_WRITE_VENDOR_DEVICE, 0x0e, 0x0802,
1022 block, 0, NULL); 1022 block, 0, NULL);
1023 if (err) { 1023 if (err) {
1024 DPRINTF(("%s: could not load last zero-length firmware " 1024 DPRINTF(("%s: could not load last zero-length firmware "
1025 "block\n", device_xname(sc->atu_dev))); 1025 "block\n", device_xname(sc->atu_dev)));
1026 return; 1026 return;
1027 } 1027 }
1028 1028
1029 /* 1029 /*
1030 * The SMC2662w V.4 seems to require some time to do its thing with 1030 * The SMC2662w V.4 seems to require some time to do its thing with
1031 * the external firmware... 20 ms isn't enough, but 21 ms works 100 1031 * the external firmware... 20 ms isn't enough, but 21 ms works 100
1032 * times out of 100 tries. We'll wait a bit longer just to be sure 1032 * times out of 100 tries. We'll wait a bit longer just to be sure
1033 */ 1033 */
1034 if (sc->atu_quirk & ATU_QUIRK_FW_DELAY) 1034 if (sc->atu_quirk & ATU_QUIRK_FW_DELAY)
1035 usbd_delay_ms(sc->atu_udev, 21 + 100); 1035 usbd_delay_ms(sc->atu_udev, 21 + 100);
1036 1036
1037 DPRINTFN(10, ("%s: external firmware upload done\n", 1037 DPRINTFN(10, ("%s: external firmware upload done\n",
1038 device_xname(sc->atu_dev))); 1038 device_xname(sc->atu_dev)));
1039 /* complete configuration after the firmwares have been uploaded */ 1039 /* complete configuration after the firmwares have been uploaded */
1040 atu_complete_attach(sc); 1040 atu_complete_attach(sc);
1041} 1041}
1042 1042
1043static int 1043static int
1044atu_get_card_config(struct atu_softc *sc) 1044atu_get_card_config(struct atu_softc *sc)
1045{ 1045{
1046 struct ieee80211com *ic = &sc->sc_ic; 1046 struct ieee80211com *ic = &sc->sc_ic;
1047 struct atu_rfmd_conf rfmd_conf; 1047 struct atu_rfmd_conf rfmd_conf;
1048 struct atu_intersil_conf intersil_conf; 1048 struct atu_intersil_conf intersil_conf;
1049 int err; 1049 int err;
1050 1050
@@ -1239,1043 +1239,1035 @@ atu_attach(device_t parent, device_t sel @@ -1239,1043 +1239,1035 @@ atu_attach(device_t parent, device_t sel
1239 usbd_status err; 1239 usbd_status err;
1240 struct usbd_device *dev = uaa->uaa_device; 1240 struct usbd_device *dev = uaa->uaa_device;
1241 uint8_t mode, channel; 1241 uint8_t mode, channel;
1242 int i; 1242 int i;
1243 1243
1244 sc->atu_dev = self; 1244 sc->atu_dev = self;
1245 sc->sc_state = ATU_S_UNCONFIG; 1245 sc->sc_state = ATU_S_UNCONFIG;
1246 1246
1247 aprint_naive("\n"); 1247 aprint_naive("\n");
1248 aprint_normal("\n"); 1248 aprint_normal("\n");
1249 1249
1250 devinfop = usbd_devinfo_alloc(dev, 0); 1250 devinfop = usbd_devinfo_alloc(dev, 0);
1251 aprint_normal_dev(self, "%s\n", devinfop); 1251 aprint_normal_dev(self, "%s\n", devinfop);
1252 usbd_devinfo_free(devinfop); 1252 usbd_devinfo_free(devinfop);
1253 1253
1254 err = usbd_set_config_no(dev, ATU_CONFIG_NO, 1); 1254 err = usbd_set_config_no(dev, ATU_CONFIG_NO, 1);
1255 if (err) { 1255 if (err) {
1256 aprint_error_dev(self, "failed to set configuration" 1256 aprint_error_dev(self, "failed to set configuration"
1257 ", err=%s\n", usbd_errstr(err)); 1257 ", err=%s\n", usbd_errstr(err));
1258 return; 1258 return;
1259 } 1259 }
1260 1260
1261 err = usbd_device2interface_handle(dev, ATU_IFACE_IDX, &sc->atu_iface); 1261 err = usbd_device2interface_handle(dev, ATU_IFACE_IDX, &sc->atu_iface);
1262 if (err) { 1262 if (err) {
1263 aprint_error_dev(self, "getting interface handle failed\n"); 1263 aprint_error_dev(self, "getting interface handle failed\n");
1264 return; 1264 return;
1265 } 1265 }
1266 1266
1267 sc->atu_unit = device_unit(self); 1267 sc->atu_unit = device_unit(self);
1268 sc->atu_udev = dev; 1268 sc->atu_udev = dev;
1269 1269
1270 /* 1270 /*
1271 * look up the radio_type for the device 1271 * look up the radio_type for the device
1272 * basically does the same as atu_match 1272 * basically does the same as atu_match
1273 */ 1273 */
1274 for (i = 0; i < __arraycount(atu_devs); i++) { 1274 for (i = 0; i < __arraycount(atu_devs); i++) {
1275 const struct atu_type *t = &atu_devs[i]; 1275 const struct atu_type *t = &atu_devs[i];
1276 1276
1277 if (uaa->uaa_vendor == t->atu_vid && 1277 if (uaa->uaa_vendor == t->atu_vid &&
1278 uaa->uaa_product == t->atu_pid) { 1278 uaa->uaa_product == t->atu_pid) {
1279 sc->atu_radio = t->atu_radio; 1279 sc->atu_radio = t->atu_radio;
1280 sc->atu_quirk = t->atu_quirk; 1280 sc->atu_quirk = t->atu_quirk;
1281 } 1281 }
1282 } 1282 }
1283 1283
1284 /* 1284 /*
1285 * Check in the interface descriptor if we're in DFU mode 1285 * Check in the interface descriptor if we're in DFU mode
1286 * If we're in DFU mode, we upload the external firmware 1286 * If we're in DFU mode, we upload the external firmware
1287 * If we're not, the PC must have rebooted without power-cycling 1287 * If we're not, the PC must have rebooted without power-cycling
1288 * the device.. I've tried this out, a reboot only requeres the 1288 * the device.. I've tried this out, a reboot only requeres the
1289 * external firmware to be reloaded :) 1289 * external firmware to be reloaded :)
1290 * 1290 *
1291 * Hmm. The at76c505a doesn't report a DFU descriptor when it's 1291 * Hmm. The at76c505a doesn't report a DFU descriptor when it's
1292 * in DFU mode... Let's just try to get the opmode 1292 * in DFU mode... Let's just try to get the opmode
1293 */ 1293 */
1294 err = atu_get_opmode(sc, &mode); 1294 err = atu_get_opmode(sc, &mode);
1295 DPRINTFN(20, ("%s: opmode: %d\n", device_xname(sc->atu_dev), mode)); 1295 DPRINTFN(20, ("%s: opmode: %d\n", device_xname(sc->atu_dev), mode));
1296 if (err || (mode != MODE_NETCARD && mode != MODE_NOFLASHNETCARD)) { 1296 if (err || (mode != MODE_NETCARD && mode != MODE_NOFLASHNETCARD)) {
1297 DPRINTF(("%s: starting internal firmware download\n", 1297 DPRINTF(("%s: starting internal firmware download\n",
1298 device_xname(sc->atu_dev))); 1298 device_xname(sc->atu_dev)));
1299 1299
1300 atu_internal_firmware(sc->atu_dev); 1300 atu_internal_firmware(sc->atu_dev);
1301 /* 1301 /*
1302 * atu_internal_firmware will cause a reset of the device 1302 * atu_internal_firmware will cause a reset of the device
1303 * so we don't want to do any more configuration after this 1303 * so we don't want to do any more configuration after this
1304 * point. 1304 * point.
1305 */ 1305 */
1306 return; 1306 return;
1307 } 1307 }
1308 1308
1309 if (mode != MODE_NETCARD) { 1309 if (mode != MODE_NETCARD) {
1310 DPRINTFN(15, ("%s: device needs external firmware\n", 1310 DPRINTFN(15, ("%s: device needs external firmware\n",
1311 device_xname(sc->atu_dev))); 1311 device_xname(sc->atu_dev)));
1312 1312
1313 if (mode != MODE_NOFLASHNETCARD) { 1313 if (mode != MODE_NOFLASHNETCARD) {
1314 DPRINTF(("%s: unexpected opmode=%d\n", 1314 DPRINTF(("%s: unexpected opmode=%d\n",
1315 device_xname(sc->atu_dev), mode)); 1315 device_xname(sc->atu_dev), mode));
1316 } 1316 }
1317 1317
1318 /* 1318 /*
1319 * There is no difference in opmode before and after external 1319 * There is no difference in opmode before and after external
1320 * firmware upload with the SMC2662 V.4 . So instead we'll try 1320 * firmware upload with the SMC2662 V.4 . So instead we'll try
1321 * to read the channel number. If we succeed, external 1321 * to read the channel number. If we succeed, external
1322 * firmwaremust have been already uploaded... 1322 * firmwaremust have been already uploaded...
1323 */ 1323 */
1324 if (sc->atu_radio != RadioIntersil) { 1324 if (sc->atu_radio != RadioIntersil) {
1325 err = atu_get_mib(sc, MIB_PHY__CHANNEL, &channel); 1325 err = atu_get_mib(sc, MIB_PHY__CHANNEL, &channel);
1326 if (!err) { 1326 if (!err) {
1327 DPRINTF(("%s: external firmware has already" 1327 DPRINTF(("%s: external firmware has already"
1328 " been downloaded\n", 1328 " been downloaded\n",
1329 device_xname(sc->atu_dev))); 1329 device_xname(sc->atu_dev)));
1330 atu_complete_attach(sc); 1330 atu_complete_attach(sc);
1331 return; 1331 return;
1332 } 1332 }
1333 } 1333 }
1334 1334
1335 atu_external_firmware(sc->atu_dev); 1335 atu_external_firmware(sc->atu_dev);
1336 1336
1337 /* 1337 /*
1338 * atu_external_firmware will call atu_complete_attach after 1338 * atu_external_firmware will call atu_complete_attach after
1339 * it's finished so we can just return. 1339 * it's finished so we can just return.
1340 */ 1340 */
1341 } else { 1341 } else {
1342 /* all the firmwares are in place, so complete the attach */ 1342 /* all the firmwares are in place, so complete the attach */
1343 atu_complete_attach(sc); 1343 atu_complete_attach(sc);
1344 } 1344 }
1345 1345
1346 return; 1346 return;
1347} 1347}
1348 1348
1349static void 1349static void
1350atu_complete_attach(struct atu_softc *sc) 1350atu_complete_attach(struct atu_softc *sc)
1351{ 1351{
1352 struct ieee80211com *ic = &sc->sc_ic; 1352 struct ieee80211com *ic = &sc->sc_ic;
1353 struct ifnet *ifp = &sc->sc_if; 1353 struct ifnet *ifp = &sc->sc_if;
1354 usb_interface_descriptor_t *id; 1354 usb_interface_descriptor_t *id;
1355 usb_endpoint_descriptor_t *ed; 1355 usb_endpoint_descriptor_t *ed;
1356 usbd_status err; 1356 usbd_status err;
1357 int i; 1357 int i;
1358#ifdef ATU_DEBUG 1358#ifdef ATU_DEBUG
1359 struct atu_fw fw; 1359 struct atu_fw fw;
1360#endif 1360#endif
1361 1361
1362 id = usbd_get_interface_descriptor(sc->atu_iface); 1362 id = usbd_get_interface_descriptor(sc->atu_iface);
1363 1363
1364 /* Find endpoints. */ 1364 /* Find endpoints. */
1365 for (i = 0; i < id->bNumEndpoints; i++) { 1365 for (i = 0; i < id->bNumEndpoints; i++) {
1366 ed = usbd_interface2endpoint_descriptor(sc->atu_iface, i); 1366 ed = usbd_interface2endpoint_descriptor(sc->atu_iface, i);
1367 if (!ed) { 1367 if (!ed) {
1368 DPRINTF(("%s: num_endp:%d\n", device_xname(sc->atu_dev), 1368 DPRINTF(("%s: num_endp:%d\n", device_xname(sc->atu_dev),
1369 sc->atu_iface->ui_idesc->bNumEndpoints)); 1369 sc->atu_iface->ui_idesc->bNumEndpoints));
1370 DPRINTF(("%s: couldn't get ep %d\n", 1370 DPRINTF(("%s: couldn't get ep %d\n",
1371 device_xname(sc->atu_dev), i)); 1371 device_xname(sc->atu_dev), i));
1372 return; 1372 return;
1373 } 1373 }
1374 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 1374 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
1375 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 1375 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
1376 sc->atu_ed[ATU_ENDPT_RX] = ed->bEndpointAddress; 1376 sc->atu_ed[ATU_ENDPT_RX] = ed->bEndpointAddress;
1377 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && 1377 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
1378 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 1378 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
1379 sc->atu_ed[ATU_ENDPT_TX] = ed->bEndpointAddress; 1379 sc->atu_ed[ATU_ENDPT_TX] = ed->bEndpointAddress;
1380 } 1380 }
1381 } 1381 }
1382 1382
1383 /* read device config & get MAC address */ 1383 /* read device config & get MAC address */
1384 err = atu_get_card_config(sc); 1384 err = atu_get_card_config(sc);
1385 if (err) { 1385 if (err) {
1386 aprint_error("\n%s: could not get card cfg!\n", 1386 aprint_error("\n%s: could not get card cfg!\n",
1387 device_xname(sc->atu_dev)); 1387 device_xname(sc->atu_dev));
1388 return; 1388 return;
1389 } 1389 }
1390 1390
1391#ifdef ATU_DEBUG 1391#ifdef ATU_DEBUG
1392 /* DEBUG : try to get firmware version */ 1392 /* DEBUG : try to get firmware version */
1393 err = atu_get_mib(sc, MIB_FW_VERSION, sizeof(fw), 0, (uint8_t *)&fw); 1393 err = atu_get_mib(sc, MIB_FW_VERSION, sizeof(fw), 0, (uint8_t *)&fw);
1394 if (!err) { 1394 if (!err) {
1395 DPRINTFN(15, ("%s: firmware: maj:%d min:%d patch:%d " 1395 DPRINTFN(15, ("%s: firmware: maj:%d min:%d patch:%d "
1396 "build:%d\n", device_xname(sc->atu_dev), fw.major, 1396 "build:%d\n", device_xname(sc->atu_dev), fw.major,
1397 fw.minor, fw.patch, fw.build)); 1397 fw.minor, fw.patch, fw.build));
1398 } else { 1398 } else {
1399 DPRINTF(("%s: get firmware version failed\n", 1399 DPRINTF(("%s: get firmware version failed\n",
1400 device_xname(sc->atu_dev))); 1400 device_xname(sc->atu_dev)));
1401 } 1401 }
1402#endif /* ATU_DEBUG */ 1402#endif /* ATU_DEBUG */
1403 1403
1404 /* Show the world our MAC address */ 1404 /* Show the world our MAC address */
1405 aprint_normal_dev(sc->atu_dev, "MAC address %s\n", 1405 aprint_normal_dev(sc->atu_dev, "MAC address %s\n",
1406 ether_sprintf(ic->ic_myaddr)); 1406 ether_sprintf(ic->ic_myaddr));
1407 1407
1408 sc->atu_cdata.atu_tx_inuse = 0; 1408 sc->atu_cdata.atu_tx_inuse = 0;
1409 sc->atu_encrypt = ATU_WEP_OFF; 1409 sc->atu_encrypt = ATU_WEP_OFF;
1410 sc->atu_wepkeylen = ATU_WEP_104BITS; 1410 sc->atu_wepkeylen = ATU_WEP_104BITS;
1411 sc->atu_wepkey = 0; 1411 sc->atu_wepkey = 0;
1412 1412
1413 memset(sc->atu_bssid, 0, ETHER_ADDR_LEN); 1413 memset(sc->atu_bssid, 0, ETHER_ADDR_LEN);
1414 sc->atu_channel = ATU_DEFAULT_CHANNEL; 1414 sc->atu_channel = ATU_DEFAULT_CHANNEL;
1415 sc->atu_desired_channel = IEEE80211_CHAN_ANY; 1415 sc->atu_desired_channel = IEEE80211_CHAN_ANY;
1416 sc->atu_mode = INFRASTRUCTURE_MODE; 1416 sc->atu_mode = INFRASTRUCTURE_MODE;
1417 1417
1418 ic->ic_ifp = ifp; 1418 ic->ic_ifp = ifp;
1419 ic->ic_phytype = IEEE80211_T_DS; 1419 ic->ic_phytype = IEEE80211_T_DS;
1420 ic->ic_opmode = IEEE80211_M_STA; 1420 ic->ic_opmode = IEEE80211_M_STA;
1421 ic->ic_state = IEEE80211_S_INIT; 1421 ic->ic_state = IEEE80211_S_INIT;
1422#ifdef FIXME 1422#ifdef FIXME
1423 ic->ic_caps = IEEE80211_C_IBSS | IEEE80211_C_WEP | IEEE80211_C_SCANALL; 1423 ic->ic_caps = IEEE80211_C_IBSS | IEEE80211_C_WEP | IEEE80211_C_SCANALL;
1424#else 1424#else
1425 ic->ic_caps = IEEE80211_C_IBSS | IEEE80211_C_WEP; 1425 ic->ic_caps = IEEE80211_C_IBSS | IEEE80211_C_WEP;
1426#endif 1426#endif
1427 1427
1428 i = 0; 1428 i = 0;
1429 ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b; 1429 ic->ic_sup_rates[IEEE80211_MODE_11B] = ieee80211_std_rateset_11b;
1430 1430
1431 for (i = 1; i <= 14; i++) { 1431 for (i = 1; i <= 14; i++) {
1432 ic->ic_channels[i].ic_flags = IEEE80211_CHAN_B | 1432 ic->ic_channels[i].ic_flags = IEEE80211_CHAN_B |
1433 IEEE80211_CHAN_PASSIVE; 1433 IEEE80211_CHAN_PASSIVE;
1434 ic->ic_channels[i].ic_freq = ieee80211_ieee2mhz(i, 1434 ic->ic_channels[i].ic_freq = ieee80211_ieee2mhz(i,
1435 ic->ic_channels[i].ic_flags); 1435 ic->ic_channels[i].ic_flags);
1436 } 1436 }
1437 1437
1438 ic->ic_ibss_chan = &ic->ic_channels[0]; 1438 ic->ic_ibss_chan = &ic->ic_channels[0];
1439 1439
1440 ifp->if_softc = sc; 1440 ifp->if_softc = sc;
1441 memcpy(ifp->if_xname, device_xname(sc->atu_dev), IFNAMSIZ); 1441 memcpy(ifp->if_xname, device_xname(sc->atu_dev), IFNAMSIZ);
1442 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 1442 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
1443 ifp->if_init = atu_init; 1443 ifp->if_init = atu_init;
1444 ifp->if_stop = atu_stop; 1444 ifp->if_stop = atu_stop;
1445 ifp->if_start = atu_start; 1445 ifp->if_start = atu_start;
1446 ifp->if_ioctl = atu_ioctl; 1446 ifp->if_ioctl = atu_ioctl;
1447 ifp->if_watchdog = atu_watchdog; 1447 ifp->if_watchdog = atu_watchdog;
1448 ifp->if_mtu = ATU_DEFAULT_MTU; 1448 ifp->if_mtu = ATU_DEFAULT_MTU;
1449 IFQ_SET_READY(&ifp->if_snd); 1449 IFQ_SET_READY(&ifp->if_snd);
1450 1450
1451 /* Call MI attach routine. */ 1451 /* Call MI attach routine. */
1452 if_attach(ifp); 1452 if_attach(ifp);
1453 ieee80211_ifattach(ic); 1453 ieee80211_ifattach(ic);
1454 1454
1455 sc->sc_newstate = ic->ic_newstate; 1455 sc->sc_newstate = ic->ic_newstate;
1456 ic->ic_newstate = atu_newstate; 1456 ic->ic_newstate = atu_newstate;
1457 1457
1458 /* setup ifmedia interface */ 1458 /* setup ifmedia interface */
1459 /* XXX media locking needs revisiting */ 1459 /* XXX media locking needs revisiting */
1460 mutex_init(&sc->sc_media_mtx, MUTEX_DEFAULT, IPL_SOFTUSB); 1460 mutex_init(&sc->sc_media_mtx, MUTEX_DEFAULT, IPL_SOFTUSB);
1461 ieee80211_media_init_with_lock(ic, 1461 ieee80211_media_init_with_lock(ic,
1462 atu_media_change, atu_media_status, &sc->sc_media_mtx); 1462 atu_media_change, atu_media_status, &sc->sc_media_mtx);
1463 1463
1464 usb_init_task(&sc->sc_task, atu_task, sc, 0); 1464 usb_init_task(&sc->sc_task, atu_task, sc, 0);
1465 1465
1466 sc->sc_state = ATU_S_OK; 1466 sc->sc_state = ATU_S_OK;
1467} 1467}
1468 1468
1469static int 1469static int
1470atu_detach(device_t self, int flags) 1470atu_detach(device_t self, int flags)
1471{ 1471{
1472 struct atu_softc *sc = device_private(self); 1472 struct atu_softc *sc = device_private(self);
1473 struct ifnet *ifp = &sc->sc_if; 1473 struct ifnet *ifp = &sc->sc_if;
1474 1474
1475 DPRINTFN(10, ("%s: atu_detach state=%d\n", device_xname(sc->atu_dev), 1475 DPRINTFN(10, ("%s: atu_detach state=%d\n", device_xname(sc->atu_dev),
1476 sc->sc_state)); 1476 sc->sc_state));
1477 1477
1478 if (sc->sc_state != ATU_S_UNCONFIG) { 1478 if (sc->sc_state != ATU_S_UNCONFIG) {
1479 atu_stop(ifp, 1); 1479 atu_stop(ifp, 1);
1480 1480
1481 ieee80211_ifdetach(&sc->sc_ic); 1481 ieee80211_ifdetach(&sc->sc_ic);
1482 if_detach(ifp); 1482 if_detach(ifp);
1483 } 1483 }
1484 1484
1485 return 0; 1485 return 0;
1486} 1486}
1487 1487
1488static int 1488static int
1489atu_activate(device_t self, enum devact act) 1489atu_activate(device_t self, enum devact act)
1490{ 1490{
1491 struct atu_softc *sc = device_private(self); 1491 struct atu_softc *sc = device_private(self);
1492 1492
1493 switch (act) { 1493 switch (act) {
1494 case DVACT_DEACTIVATE: 1494 case DVACT_DEACTIVATE:
1495 if (sc->sc_state != ATU_S_UNCONFIG) { 1495 if (sc->sc_state != ATU_S_UNCONFIG) {
1496 if_deactivate(&sc->atu_ec.ec_if); 1496 if_deactivate(&sc->atu_ec.ec_if);
1497 sc->sc_state = ATU_S_DEAD; 1497 sc->sc_state = ATU_S_DEAD;
1498 } 1498 }
1499 return 0; 1499 return 0;
1500 default: 1500 default:
1501 return EOPNOTSUPP; 1501 return EOPNOTSUPP;
1502 } 1502 }
1503} 1503}
1504 1504
1505/* 1505/*
1506 * Initialize an RX descriptor and attach an MBUF cluster. 1506 * Initialize an RX descriptor and attach an MBUF cluster.
1507 */ 1507 */
1508static int 1508static int
1509atu_newbuf(struct atu_softc *sc, struct atu_chain *c, struct mbuf *m) 1509atu_newbuf(struct atu_softc *sc, struct atu_chain *c, struct mbuf *m)
1510{ 1510{
1511 struct mbuf *m_new = NULL; 1511 struct mbuf *m_new = NULL;
1512 1512
1513 if (m == NULL) { 1513 if (m == NULL) {
1514 MGETHDR(m_new, M_DONTWAIT, MT_DATA); 1514 MGETHDR(m_new, M_DONTWAIT, MT_DATA);
1515 if (m_new == NULL) { 1515 if (m_new == NULL) {
1516 DPRINTF(("%s: no memory for rx list\n", 1516 DPRINTF(("%s: no memory for rx list\n",
1517 device_xname(sc->atu_dev))); 1517 device_xname(sc->atu_dev)));
1518 return ENOBUFS; 1518 return ENOBUFS;
1519 } 1519 }
1520 1520
1521 MCLGET(m_new, M_DONTWAIT); 1521 MCLGET(m_new, M_DONTWAIT);
1522 if (!(m_new->m_flags & M_EXT)) { 1522 if (!(m_new->m_flags & M_EXT)) {
1523 DPRINTF(("%s: no memory for rx list\n", 1523 DPRINTF(("%s: no memory for rx list\n",
1524 device_xname(sc->atu_dev))); 1524 device_xname(sc->atu_dev)));
1525 m_freem(m_new); 1525 m_freem(m_new);
1526 return ENOBUFS; 1526 return ENOBUFS;
1527 } 1527 }
1528 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; 1528 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
1529 } else { 1529 } else {
1530 m_new = m; 1530 m_new = m;
1531 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; 1531 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
1532 m_new->m_data = m_new->m_ext.ext_buf; 1532 m_new->m_data = m_new->m_ext.ext_buf;
1533 } 1533 }
1534 c->atu_mbuf = m_new; 1534 c->atu_mbuf = m_new;
1535 return 0; 1535 return 0;
1536} 1536}
1537 1537
1538static int 1538static int
1539atu_rx_list_init(struct atu_softc *sc) 1539atu_rx_list_init(struct atu_softc *sc)
1540{ 1540{
1541 struct atu_cdata *cd = &sc->atu_cdata; 1541 struct atu_cdata *cd = &sc->atu_cdata;
1542 struct atu_chain *c; 1542 struct atu_chain *c;
1543 int i; 1543 int i;
1544 1544
1545 DPRINTFN(15, ("%s: atu_rx_list_init: enter\n", 1545 DPRINTFN(15, ("%s: atu_rx_list_init: enter\n",
1546 device_xname(sc->atu_dev))); 1546 device_xname(sc->atu_dev)));
1547 1547
1548 for (i = 0; i < ATU_RX_LIST_CNT; i++) { 1548 for (i = 0; i < ATU_RX_LIST_CNT; i++) {
1549 c = &cd->atu_rx_chain[i]; 1549 c = &cd->atu_rx_chain[i];
1550 c->atu_sc = sc; 1550 c->atu_sc = sc;
1551 c->atu_idx = i; 1551 c->atu_idx = i;
1552 if (c->atu_xfer == NULL) { 1552 if (c->atu_xfer == NULL) {
1553 int err = usbd_create_xfer(sc->atu_ep[ATU_ENDPT_RX], 1553 int err = usbd_create_xfer(sc->atu_ep[ATU_ENDPT_RX],
1554 ATU_RX_BUFSZ, 0, 0, &c->atu_xfer); 1554 ATU_RX_BUFSZ, 0, 0, &c->atu_xfer);
1555 if (err) 1555 if (err)
1556 return err; 1556 return err;
1557 c->atu_buf = usbd_get_buffer(c->atu_xfer); 1557 c->atu_buf = usbd_get_buffer(c->atu_xfer);
1558 if (atu_newbuf(sc, c, NULL) == ENOBUFS) /* XXX free? */ 1558 if (atu_newbuf(sc, c, NULL) == ENOBUFS) /* XXX free? */
1559 return ENOBUFS; 1559 return ENOBUFS;
1560 } 1560 }
1561 } 1561 }
1562 return 0; 1562 return 0;
1563} 1563}
1564 1564
1565static int 1565static int
1566atu_tx_list_init(struct atu_softc *sc) 1566atu_tx_list_init(struct atu_softc *sc)
1567{ 1567{
1568 struct atu_cdata *cd = &sc->atu_cdata; 1568 struct atu_cdata *cd = &sc->atu_cdata;
1569 struct atu_chain *c; 1569 struct atu_chain *c;
1570 int i; 1570 int i;
1571 1571
1572 DPRINTFN(15, ("%s: atu_tx_list_init\n", 1572 DPRINTFN(15, ("%s: atu_tx_list_init\n",
1573 device_xname(sc->atu_dev))); 1573 device_xname(sc->atu_dev)));
1574 1574
1575 SLIST_INIT(&cd->atu_tx_free); 1575 SLIST_INIT(&cd->atu_tx_free);
1576 sc->atu_cdata.atu_tx_inuse = 0; 1576 sc->atu_cdata.atu_tx_inuse = 0;
1577 1577
1578 for (i = 0; i < ATU_TX_LIST_CNT; i++) { 1578 for (i = 0; i < ATU_TX_LIST_CNT; i++) {
1579 c = &cd->atu_tx_chain[i]; 1579 c = &cd->atu_tx_chain[i];
1580 c->atu_sc = sc; 1580 c->atu_sc = sc;
1581 c->atu_idx = i; 1581 c->atu_idx = i;
1582 if (c->atu_xfer == NULL) { 1582 if (c->atu_xfer == NULL) {
1583 int err = usbd_create_xfer(sc->atu_ep[ATU_ENDPT_TX], 1583 int err = usbd_create_xfer(sc->atu_ep[ATU_ENDPT_TX],
1584 ATU_TX_BUFSZ, 0, 0, &c->atu_xfer); 1584 ATU_TX_BUFSZ, 0, 0, &c->atu_xfer);
1585 if (err) { 1585 if (err) {
1586 return err; 1586 return err;
1587 } 1587 }
1588 c->atu_buf = usbd_get_buffer(c->atu_xfer); 1588 c->atu_buf = usbd_get_buffer(c->atu_xfer);
1589 SLIST_INSERT_HEAD(&cd->atu_tx_free, c, atu_list); 1589 SLIST_INSERT_HEAD(&cd->atu_tx_free, c, atu_list);
1590 } 1590 }
1591 } 1591 }
1592 return 0; 1592 return 0;
1593} 1593}
1594 1594
1595static void 1595static void
1596atu_xfer_list_free(struct atu_softc *sc, struct atu_chain *ch, int listlen) 1596atu_xfer_list_free(struct atu_softc *sc, struct atu_chain *ch, int listlen)
1597{ 1597{
1598 int i; 1598 int i;
1599 1599
1600 /* Free resources. */ 1600 /* Free resources. */
1601 for (i = 0; i < listlen; i++) { 1601 for (i = 0; i < listlen; i++) {
1602 if (ch[i].atu_buf != NULL) 1602 if (ch[i].atu_buf != NULL)
1603 ch[i].atu_buf = NULL; 1603 ch[i].atu_buf = NULL;
1604 if (ch[i].atu_mbuf != NULL) { 1604 if (ch[i].atu_mbuf != NULL) {
1605 m_freem(ch[i].atu_mbuf); 1605 m_freem(ch[i].atu_mbuf);
1606 ch[i].atu_mbuf = NULL; 1606 ch[i].atu_mbuf = NULL;
1607 } 1607 }
1608 if (ch[i].atu_xfer != NULL) { 1608 if (ch[i].atu_xfer != NULL) {
1609 usbd_destroy_xfer(ch[i].atu_xfer); 1609 usbd_destroy_xfer(ch[i].atu_xfer);
1610 ch[i].atu_xfer = NULL; 1610 ch[i].atu_xfer = NULL;
1611 } 1611 }
1612 } 1612 }
1613} 1613}
1614 1614
1615/* 1615/*
1616 * A frame has been uploaded: pass the resulting mbuf chain up to 1616 * A frame has been uploaded: pass the resulting mbuf chain up to
1617 * the higher level protocols. 1617 * the higher level protocols.
1618 */ 1618 */
1619static void 1619static void
1620atu_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status) 1620atu_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
1621{ 1621{
1622 struct atu_chain *c = (struct atu_chain *)priv; 1622 struct atu_chain *c = (struct atu_chain *)priv;
1623 struct atu_softc *sc = c->atu_sc; 1623 struct atu_softc *sc = c->atu_sc;
1624 struct ieee80211com *ic = &sc->sc_ic; 1624 struct ieee80211com *ic = &sc->sc_ic;
1625 struct ifnet *ifp = &sc->sc_if; 1625 struct ifnet *ifp = &sc->sc_if;
1626 struct atu_rx_hdr *h; 1626 struct atu_rx_hdr *h;
1627 struct ieee80211_frame_min *wh; 1627 struct ieee80211_frame_min *wh;
1628 struct ieee80211_node *ni; 1628 struct ieee80211_node *ni;
1629 struct mbuf *m; 1629 struct mbuf *m;
1630 uint32_t len; 1630 uint32_t len;
1631 int s; 1631 int s;
1632 1632
1633 DPRINTFN(25, ("%s: atu_rxeof\n", device_xname(sc->atu_dev))); 1633 DPRINTFN(25, ("%s: atu_rxeof\n", device_xname(sc->atu_dev)));
1634 1634
1635 if (sc->sc_state != ATU_S_OK) 1635 if (sc->sc_state != ATU_S_OK)
1636 return; 1636 return;
1637 1637
1638 if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) != (IFF_RUNNING|IFF_UP)) 1638 if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) != (IFF_RUNNING|IFF_UP))
1639 goto done; 1639 goto done;
1640 1640
1641 if (status != USBD_NORMAL_COMPLETION) { 1641 if (status != USBD_NORMAL_COMPLETION) {
1642 DPRINTF(("%s: status != USBD_NORMAL_COMPLETION\n", 1642 DPRINTF(("%s: status != USBD_NORMAL_COMPLETION\n",
1643 device_xname(sc->atu_dev))); 1643 device_xname(sc->atu_dev)));
1644 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) { 1644 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) {
1645 return; 1645 return;
1646 } 1646 }
1647#if 0 1647#if 0
1648 if (status == USBD_IOERROR) { 1648 if (status == USBD_IOERROR) {
1649 DPRINTF(("%s: rx: EEK! lost device?\n", 1649 DPRINTF(("%s: rx: EEK! lost device?\n",
1650 device_xname(sc->atu_dev))); 1650 device_xname(sc->atu_dev)));
1651 1651
1652 /* 1652 /*
1653 * My experience with USBD_IOERROR is that trying to 1653 * My experience with USBD_IOERROR is that trying to
1654 * restart the transfer will always fail and we'll 1654 * restart the transfer will always fail and we'll
1655 * keep on looping restarting transfers untill someone 1655 * keep on looping restarting transfers untill someone
1656 * pulls the plug of the device. 1656 * pulls the plug of the device.
1657 * So we don't restart the transfer, but just let it 1657 * So we don't restart the transfer, but just let it
1658 * die... If someone knows of a situation where we can 1658 * die... If someone knows of a situation where we can
1659 * recover from USBD_IOERROR, let me know. 1659 * recover from USBD_IOERROR, let me know.
1660 */ 1660 */
1661 splx(s); 1661 splx(s);
1662 return; 1662 return;
1663 } 1663 }
1664#endif /* 0 */ 1664#endif /* 0 */
1665 1665
1666 if (usbd_ratecheck(&sc->atu_rx_notice)) { 1666 if (usbd_ratecheck(&sc->atu_rx_notice)) {
1667 DPRINTF(("%s: usb error on rx: %s\n", 1667 DPRINTF(("%s: usb error on rx: %s\n",
1668 device_xname(sc->atu_dev), usbd_errstr(status))); 1668 device_xname(sc->atu_dev), usbd_errstr(status)));
1669 } 1669 }
1670 if (status == USBD_STALLED) 1670 if (status == USBD_STALLED)
1671 usbd_clear_endpoint_stall_async( 1671 usbd_clear_endpoint_stall_async(
1672 sc->atu_ep[ATU_ENDPT_RX]); 1672 sc->atu_ep[ATU_ENDPT_RX]);
1673 goto done; 1673 goto done;
1674 } 1674 }
1675 1675
1676 usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL); 1676 usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL);
1677 1677
1678 if (len <= 1) { 1678 if (len <= 1) {
1679 DPRINTF(("%s: atu_rxeof: too short\n", 1679 DPRINTF(("%s: atu_rxeof: too short\n",
1680 device_xname(sc->atu_dev))); 1680 device_xname(sc->atu_dev)));
1681 goto done; 1681 goto done;
1682 } else if (len > MCLBYTES) { 1682 } else if (len > MCLBYTES) {
1683 DPRINTF(("%s: atu_rxeof: too long\n", 1683 DPRINTF(("%s: atu_rxeof: too long\n",
1684 device_xname(sc->atu_dev))); 1684 device_xname(sc->atu_dev)));
1685 goto done; 1685 goto done;
1686 } 1686 }
1687 1687
1688 h = (struct atu_rx_hdr *)c->atu_buf; 1688 h = (struct atu_rx_hdr *)c->atu_buf;
1689 len = UGETW(h->length) - 4; /* XXX magic number */ 1689 len = UGETW(h->length) - 4; /* XXX magic number */
1690 1690
1691 m = c->atu_mbuf; 1691 m = c->atu_mbuf;
1692 memcpy(mtod(m, char *), c->atu_buf + ATU_RX_HDRLEN, len); 1692 memcpy(mtod(m, char *), c->atu_buf + ATU_RX_HDRLEN, len);
1693 m_set_rcvif(m, ifp); 1693 m_set_rcvif(m, ifp);
1694 m->m_pkthdr.len = m->m_len = len; 1694 m->m_pkthdr.len = m->m_len = len;
1695 1695
1696 wh = mtod(m, struct ieee80211_frame_min *); 1696 wh = mtod(m, struct ieee80211_frame_min *);
1697 ni = ieee80211_find_rxnode(ic, wh); 1697 ni = ieee80211_find_rxnode(ic, wh);
1698 1698
1699 if_statinc(ifp, if_ipackets); 1699 if_statinc(ifp, if_ipackets);
1700 1700
1701 s = splnet(); 1701 s = splnet();
1702 1702
1703 if (atu_newbuf(sc, c, NULL) == ENOBUFS) { 1703 if (atu_newbuf(sc, c, NULL) == ENOBUFS) {
1704 if_statinc(ifp, if_ierrors); 1704 if_statinc(ifp, if_ierrors);
1705 goto done1; /* XXX if we can't allocate, why restart it? */ 1705 goto done1; /* XXX if we can't allocate, why restart it? */
1706 } 1706 }
1707 1707
1708 if (wh->i_fc[1] & IEEE80211_FC1_WEP) { 1708 if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
1709 /* 1709 /*
1710 * WEP is decrypted by hardware. Clear WEP bit 1710 * WEP is decrypted by hardware. Clear WEP bit
1711 * header for ieee80211_input(). 1711 * header for ieee80211_input().
1712 */ 1712 */
1713 wh->i_fc[1] &= ~IEEE80211_FC1_WEP; 1713 wh->i_fc[1] &= ~IEEE80211_FC1_WEP;
1714 } 1714 }
1715 1715
1716 ieee80211_input(ic, m, ni, h->rssi, UGETDW(h->rx_time)); 1716 ieee80211_input(ic, m, ni, h->rssi, UGETDW(h->rx_time));
1717 1717
1718 ieee80211_free_node(ni); 1718 ieee80211_free_node(ni);
1719done1: 1719done1:
1720 splx(s); 1720 splx(s);
1721done: 1721done:
1722 /* Setup new transfer. */ 1722 /* Setup new transfer. */
1723 usbd_setup_xfer(c->atu_xfer, c, c->atu_buf, ATU_RX_BUFSZ, 1723 usbd_setup_xfer(c->atu_xfer, c, c->atu_buf, ATU_RX_BUFSZ,
1724 USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, atu_rxeof); 1724 USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, atu_rxeof);
1725 usbd_transfer(c->atu_xfer); 1725 usbd_transfer(c->atu_xfer);
1726} 1726}
1727 1727
1728/* 1728/*
1729 * A frame was downloaded to the chip. It's safe for us to clean up 1729 * A frame was downloaded to the chip. It's safe for us to clean up
1730 * the list buffers. 1730 * the list buffers.
1731 */ 1731 */
1732static void 1732static void
1733atu_txeof(struct usbd_xfer *xfer, void *priv, usbd_status status) 1733atu_txeof(struct usbd_xfer *xfer, void *priv, usbd_status status)
1734{ 1734{
1735 struct atu_chain *c = (struct atu_chain *)priv; 1735 struct atu_chain *c = (struct atu_chain *)priv;
1736 struct atu_softc *sc = c->atu_sc; 1736 struct atu_softc *sc = c->atu_sc;
1737 struct ifnet *ifp = &sc->sc_if; 1737 struct ifnet *ifp = &sc->sc_if;
1738 usbd_status err; 1738 usbd_status err;
1739 int s; 1739 int s;
1740 1740
1741 DPRINTFN(25, ("%s: atu_txeof status=%d\n", device_xname(sc->atu_dev), 1741 DPRINTFN(25, ("%s: atu_txeof status=%d\n", device_xname(sc->atu_dev),
1742 status)); 1742 status));
1743 1743
1744 if (c->atu_mbuf) { 1744 if (c->atu_mbuf) {
1745 m_freem(c->atu_mbuf); 1745 m_freem(c->atu_mbuf);
1746 c->atu_mbuf = NULL; 1746 c->atu_mbuf = NULL;
1747 } 1747 }
1748 1748
1749 if (status != USBD_NORMAL_COMPLETION) { 1749 if (status != USBD_NORMAL_COMPLETION) {
1750 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) 1750 if (status == USBD_NOT_STARTED || status == USBD_CANCELLED)
1751 return; 1751 return;
1752 1752
1753 DPRINTF(("%s: usb error on tx: %s\n", 1753 DPRINTF(("%s: usb error on tx: %s\n",
1754 device_xname(sc->atu_dev), usbd_errstr(status))); 1754 device_xname(sc->atu_dev), usbd_errstr(status)));
1755 if (status == USBD_STALLED) 1755 if (status == USBD_STALLED)
1756 usbd_clear_endpoint_stall_async( 1756 usbd_clear_endpoint_stall_async(
1757 sc->atu_ep[ATU_ENDPT_TX]); 1757 sc->atu_ep[ATU_ENDPT_TX]);
1758 return; 1758 return;
1759 } 1759 }
1760 1760
1761 usbd_get_xfer_status(c->atu_xfer, NULL, NULL, NULL, &err); 1761 usbd_get_xfer_status(c->atu_xfer, NULL, NULL, NULL, &err);
1762 1762
1763 if (err) 1763 if (err)
1764 if_statinc(ifp, if_oerrors); 1764 if_statinc(ifp, if_oerrors);
1765 else 1765 else
1766 if_statinc(ifp, if_opackets); 1766 if_statinc(ifp, if_opackets);
1767 1767
1768 s = splnet(); 1768 s = splnet();
1769 SLIST_INSERT_HEAD(&sc->atu_cdata.atu_tx_free, c, atu_list); 1769 SLIST_INSERT_HEAD(&sc->atu_cdata.atu_tx_free, c, atu_list);
1770 sc->atu_cdata.atu_tx_inuse--; 1770 sc->atu_cdata.atu_tx_inuse--;
1771 if (sc->atu_cdata.atu_tx_inuse == 0) 1771 if (sc->atu_cdata.atu_tx_inuse == 0)
1772 ifp->if_timer = 0; 1772 ifp->if_timer = 0;
1773 ifp->if_flags &= ~IFF_OACTIVE; 1773 ifp->if_flags &= ~IFF_OACTIVE;
1774 splx(s); 1774 splx(s);
1775 1775
1776 atu_start(ifp); 1776 atu_start(ifp);
1777} 1777}
1778 1778
1779static uint8_t 1779static uint8_t
1780atu_calculate_padding(int size) 1780atu_calculate_padding(int size)
1781{ 1781{
1782 size %= 64; 1782 size %= 64;
1783 1783
1784 if (size < 50) 1784 if (size < 50)
1785 return 50 - size; 1785 return 50 - size;
1786 if (size >=61) 1786 if (size >=61)
1787 return 64 + 50 - size; 1787 return 64 + 50 - size;
1788 return 0; 1788 return 0;
1789} 1789}
1790 1790
1791static int 1791static int
1792atu_tx_start(struct atu_softc *sc, struct ieee80211_node *ni, 1792atu_tx_start(struct atu_softc *sc, struct ieee80211_node *ni,
1793 struct atu_chain *c, struct mbuf *m) 1793 struct atu_chain *c, struct mbuf *m)
1794{ 1794{
1795 int len; 1795 int len;
1796 struct atu_tx_hdr *h; 1796 struct atu_tx_hdr *h;
1797 usbd_status err; 1797 usbd_status err;
1798 uint8_t pad; 1798 uint8_t pad;
1799 1799
1800 DPRINTFN(25, ("%s: atu_tx_start\n", device_xname(sc->atu_dev))); 1800 DPRINTFN(25, ("%s: atu_tx_start\n", device_xname(sc->atu_dev)));
1801 1801
1802 /* Don't try to send when we're shutting down the driver */ 1802 /* Don't try to send when we're shutting down the driver */
1803 if (sc->sc_state != ATU_S_OK) { 1803 if (sc->sc_state != ATU_S_OK) {
1804 m_freem(m); 1804 m_freem(m);
1805 return EIO; 1805 return EIO;
1806 } 1806 }
1807 1807
1808 /* 1808 /*
1809 * Copy the mbuf data into a contiguous buffer, leaving 1809 * Copy the mbuf data into a contiguous buffer, leaving
1810 * enough room for the atmel headers 1810 * enough room for the atmel headers
1811 */ 1811 */
1812 len = m->m_pkthdr.len; 1812 len = m->m_pkthdr.len;
1813 1813
1814 m_copydata(m, 0, m->m_pkthdr.len, c->atu_buf + ATU_TX_HDRLEN); 1814 m_copydata(m, 0, m->m_pkthdr.len, c->atu_buf + ATU_TX_HDRLEN);
1815 1815
1816 h = (struct atu_tx_hdr *)c->atu_buf; 1816 h = (struct atu_tx_hdr *)c->atu_buf;
1817 memset(h, 0, ATU_TX_HDRLEN); 1817 memset(h, 0, ATU_TX_HDRLEN);
1818 USETW(h->length, len); 1818 USETW(h->length, len);
1819 h->tx_rate = 4; /* XXX rate = auto */ 1819 h->tx_rate = 4; /* XXX rate = auto */
1820 len += ATU_TX_HDRLEN; 1820 len += ATU_TX_HDRLEN;
1821 1821
1822 pad = atu_calculate_padding(len); 1822 pad = atu_calculate_padding(len);
1823 len += pad; 1823 len += pad;
1824 h->padding = pad; 1824 h->padding = pad;
1825 1825
1826 c->atu_length = len; 1826 c->atu_length = len;
1827 c->atu_mbuf = m; 1827 c->atu_mbuf = m;
1828 1828
1829 usbd_setup_xfer(c->atu_xfer, c, c->atu_buf, c->atu_length, 0, 1829 usbd_setup_xfer(c->atu_xfer, c, c->atu_buf, c->atu_length, 0,
1830 ATU_TX_TIMEOUT, atu_txeof); 1830 ATU_TX_TIMEOUT, atu_txeof);
1831 1831
1832 /* Let's get this thing into the air! */ 1832 /* Let's get this thing into the air! */
1833 c->atu_in_xfer = 1; 1833 c->atu_in_xfer = 1;
1834 err = usbd_transfer(c->atu_xfer); 1834 err = usbd_transfer(c->atu_xfer);
1835 if (err != USBD_IN_PROGRESS) { 1835 if (err != USBD_IN_PROGRESS) {
1836 DPRINTFN(25, ("%s: atu_tx_start, err=%d", 1836 DPRINTFN(25, ("%s: atu_tx_start, err=%d",
1837 device_xname(sc->atu_dev), err)); 1837 device_xname(sc->atu_dev), err));
1838 c->atu_mbuf = NULL; 1838 c->atu_mbuf = NULL;
1839 m_freem(m); 1839 m_freem(m);
1840 return EIO; 1840 return EIO;
1841 } 1841 }
1842 1842
1843 return 0; 1843 return 0;
1844} 1844}
1845 1845
1846static void 1846static void
1847atu_start(struct ifnet *ifp) 1847atu_start(struct ifnet *ifp)
1848{ 1848{
1849 struct atu_softc *sc = ifp->if_softc; 1849 struct atu_softc *sc = ifp->if_softc;
1850 struct ieee80211com *ic = &sc->sc_ic; 1850 struct ieee80211com *ic = &sc->sc_ic;
1851 struct atu_cdata *cd = &sc->atu_cdata; 1851 struct atu_cdata *cd = &sc->atu_cdata;
1852 struct ieee80211_node *ni; 1852 struct ieee80211_node *ni;
1853 struct atu_chain *c; 1853 struct atu_chain *c;
1854 struct mbuf *m = NULL; 1854 struct mbuf *m = NULL;
1855 int s; 1855 int s;
1856 1856
1857 DPRINTFN(25, ("%s: atu_start: enter\n", device_xname(sc->atu_dev))); 1857 DPRINTFN(25, ("%s: atu_start: enter\n", device_xname(sc->atu_dev)));
1858 1858
1859 if ((ifp->if_flags & IFF_RUNNING) == 0) { 1859 if ((ifp->if_flags & IFF_RUNNING) == 0) {
1860 return; 1860 return;
1861 } 1861 }
1862 if (ifp->if_flags & IFF_OACTIVE) { 1862 if (ifp->if_flags & IFF_OACTIVE) {
1863 DPRINTFN(30, ("%s: atu_start: IFF_OACTIVE\n", 1863 DPRINTFN(30, ("%s: atu_start: IFF_OACTIVE\n",
1864 device_xname(sc->atu_dev))); 1864 device_xname(sc->atu_dev)));
1865 return; 1865 return;
1866 } 1866 }
1867 1867
1868 for (;;) { 1868 for (;;) {
1869 /* grab a TX buffer */ 1869 /* grab a TX buffer */
1870 s = splnet(); 1870 s = splnet();
1871 c = SLIST_FIRST(&cd->atu_tx_free); 1871 c = SLIST_FIRST(&cd->atu_tx_free);
1872 if (c != NULL) { 1872 if (c != NULL) {
1873 SLIST_REMOVE_HEAD(&cd->atu_tx_free, atu_list); 1873 SLIST_REMOVE_HEAD(&cd->atu_tx_free, atu_list);
1874 cd->atu_tx_inuse++; 1874 cd->atu_tx_inuse++;
1875 if (cd->atu_tx_inuse == ATU_TX_LIST_CNT) 1875 if (cd->atu_tx_inuse == ATU_TX_LIST_CNT)
1876 ifp->if_flags |= IFF_OACTIVE; 1876 ifp->if_flags |= IFF_OACTIVE;
1877 } 1877 }
1878 splx(s); 1878 splx(s);
1879 if (c == NULL) { 1879 if (c == NULL) {
1880 DPRINTFN(10, ("%s: out of tx xfers\n", 1880 DPRINTFN(10, ("%s: out of tx xfers\n",
1881 device_xname(sc->atu_dev))); 1881 device_xname(sc->atu_dev)));
1882 ifp->if_flags |= IFF_OACTIVE; 1882 ifp->if_flags |= IFF_OACTIVE;
1883 break; 1883 break;
1884 } 1884 }
1885 1885
1886 /* 1886 /*
1887 * Poll the management queue for frames, it has priority over 1887 * Poll the management queue for frames, it has priority over
1888 * normal data frames. 1888 * normal data frames.
1889 */ 1889 */
1890 IF_DEQUEUE(&ic->ic_mgtq, m); 1890 IF_DEQUEUE(&ic->ic_mgtq, m);
1891 if (m == NULL) { 1891 if (m == NULL) {
1892 DPRINTFN(10, ("%s: atu_start: data packet\n", 1892 DPRINTFN(10, ("%s: atu_start: data packet\n",
1893 device_xname(sc->atu_dev))); 1893 device_xname(sc->atu_dev)));
1894 if (ic->ic_state != IEEE80211_S_RUN) { 1894 if (ic->ic_state != IEEE80211_S_RUN) {
1895 DPRINTFN(25, ("%s: no data till running\n", 1895 DPRINTFN(25, ("%s: no data till running\n",
1896 device_xname(sc->atu_dev))); 1896 device_xname(sc->atu_dev)));
1897 /* put the xfer back on the list */ 1897 /* put the xfer back on the list */
1898 s = splnet(); 1898 s = splnet();
1899 SLIST_INSERT_HEAD(&cd->atu_tx_free, c, 1899 SLIST_INSERT_HEAD(&cd->atu_tx_free, c,
1900 atu_list); 1900 atu_list);
1901 cd->atu_tx_inuse--; 1901 cd->atu_tx_inuse--;
1902 splx(s); 1902 splx(s);
1903 break; 1903 break;
1904 } 1904 }
1905 1905
1906 IFQ_DEQUEUE(&ifp->if_snd, m); 1906 IFQ_DEQUEUE(&ifp->if_snd, m);
1907 if (m == NULL) { 1907 if (m == NULL) {
1908 DPRINTFN(25, ("%s: nothing to send\n", 1908 DPRINTFN(25, ("%s: nothing to send\n",
1909 device_xname(sc->atu_dev))); 1909 device_xname(sc->atu_dev)));
1910 s = splnet(); 1910 s = splnet();
1911 SLIST_INSERT_HEAD(&cd->atu_tx_free, c, 1911 SLIST_INSERT_HEAD(&cd->atu_tx_free, c,
1912 atu_list); 1912 atu_list);
1913 cd->atu_tx_inuse--; 1913 cd->atu_tx_inuse--;
1914 splx(s); 1914 splx(s);
1915 break; 1915 break;
1916 } 1916 }
1917 bpf_mtap(ifp, m, BPF_D_OUT); 1917 bpf_mtap(ifp, m, BPF_D_OUT);
1918 ni = ieee80211_find_txnode(ic, 1918 ni = ieee80211_find_txnode(ic,
1919 mtod(m, struct ether_header *)->ether_dhost); 1919 mtod(m, struct ether_header *)->ether_dhost);
1920 if (ni == NULL) { 1920 if (ni == NULL) {
1921 m_freem(m); 1921 m_freem(m);
1922 goto bad; 1922 goto bad;
1923 } 1923 }
1924 m = ieee80211_encap(ic, m, ni); 1924 m = ieee80211_encap(ic, m, ni);
1925 if (m == NULL) 1925 if (m == NULL)
1926 goto bad; 1926 goto bad;
1927 } else { 1927 } else {
1928 DPRINTFN(25, ("%s: atu_start: mgmt packet\n", 1928 DPRINTFN(25, ("%s: atu_start: mgmt packet\n",
1929 device_xname(sc->atu_dev))); 1929 device_xname(sc->atu_dev)));
1930 1930
1931 /* 1931 /*
1932 * Hack! The referenced node pointer is in the 1932 * Hack! The referenced node pointer is in the
1933 * rcvif field of the packet header. This is 1933 * rcvif field of the packet header. This is
1934 * placed there by ieee80211_mgmt_output because 1934 * placed there by ieee80211_mgmt_output because
1935 * we need to hold the reference with the frame 1935 * we need to hold the reference with the frame
1936 * and there's no other way (other than packet 1936 * and there's no other way (other than packet
1937 * tags which we consider too expensive to use) 1937 * tags which we consider too expensive to use)
1938 * to pass it along. 1938 * to pass it along.
1939 */ 1939 */
1940 ni = M_GETCTX(m, struct ieee80211_node *); 1940 ni = M_GETCTX(m, struct ieee80211_node *);
1941 M_CLEARCTX(m); 1941 M_CLEARCTX(m);
1942 1942
1943 /* sc->sc_stats.ast_tx_mgmt++; */ 1943 /* sc->sc_stats.ast_tx_mgmt++; */
1944 } 1944 }
1945 1945
1946 bpf_mtap3(ic->ic_rawbpf, m, BPF_D_OUT); 1946 bpf_mtap3(ic->ic_rawbpf, m, BPF_D_OUT);
1947 1947
1948 if (atu_tx_start(sc, ni, c, m)) { 1948 if (atu_tx_start(sc, ni, c, m)) {
1949bad: 1949bad:
1950 s = splnet(); 1950 s = splnet();
1951 SLIST_INSERT_HEAD(&cd->atu_tx_free, c, 1951 SLIST_INSERT_HEAD(&cd->atu_tx_free, c,
1952 atu_list); 1952 atu_list);
1953 cd->atu_tx_inuse--; 1953 cd->atu_tx_inuse--;
1954 splx(s); 1954 splx(s);
1955 /* if_statinc(ifp, if_oerrors); */ 1955 /* if_statinc(ifp, if_oerrors); */
1956 if (ni != NULL) 1956 if (ni != NULL)
1957 ieee80211_free_node(ni); 1957 ieee80211_free_node(ni);
1958 continue; 1958 continue;
1959 } 1959 }
1960 ifp->if_timer = 5; 1960 ifp->if_timer = 5;
1961 } 1961 }
1962} 1962}
1963 1963
1964static int 1964static int
1965atu_init(struct ifnet *ifp) 1965atu_init(struct ifnet *ifp)
1966{ 1966{
1967 struct atu_softc *sc = ifp->if_softc; 1967 struct atu_softc *sc = ifp->if_softc;
1968 struct ieee80211com *ic = &sc->sc_ic; 1968 struct ieee80211com *ic = &sc->sc_ic;
1969 struct atu_chain *c; 1969 struct atu_chain *c;
1970 usbd_status err; 1970 usbd_status err;
1971 int i, s; 1971 int i, s;
1972 1972
1973 s = splnet(); 1973 s = splnet();
1974 1974
1975 DPRINTFN(10, ("%s: atu_init\n", device_xname(sc->atu_dev))); 1975 DPRINTFN(10, ("%s: atu_init\n", device_xname(sc->atu_dev)));
1976 1976
1977 if (ifp->if_flags & IFF_RUNNING) { 1977 if (ifp->if_flags & IFF_RUNNING) {
1978 splx(s); 1978 splx(s);
1979 return 0; 1979 return 0;
1980 } 1980 }
1981 1981
1982 /* Load the multicast filter. */ 1982 /* Load the multicast filter. */
1983 /*atu_setmulti(sc); */ 1983 /*atu_setmulti(sc); */
1984 1984
1985 /* Open RX and TX pipes. */ 1985 /* Open RX and TX pipes. */
1986 err = usbd_open_pipe(sc->atu_iface, sc->atu_ed[ATU_ENDPT_RX], 1986 err = usbd_open_pipe(sc->atu_iface, sc->atu_ed[ATU_ENDPT_RX],
1987 USBD_EXCLUSIVE_USE, &sc->atu_ep[ATU_ENDPT_RX]); 1987 USBD_EXCLUSIVE_USE, &sc->atu_ep[ATU_ENDPT_RX]);
1988 if (err) { 1988 if (err) {
1989 DPRINTF(("%s: open rx pipe failed: %s\n", 1989 DPRINTF(("%s: open rx pipe failed: %s\n",
1990 device_xname(sc->atu_dev), usbd_errstr(err))); 1990 device_xname(sc->atu_dev), usbd_errstr(err)));
1991 splx(s); 1991 splx(s);
1992 return EIO; 1992 return EIO;
1993 } 1993 }
1994 1994
1995 err = usbd_open_pipe(sc->atu_iface, sc->atu_ed[ATU_ENDPT_TX], 1995 err = usbd_open_pipe(sc->atu_iface, sc->atu_ed[ATU_ENDPT_TX],
1996 USBD_EXCLUSIVE_USE, &sc->atu_ep[ATU_ENDPT_TX]); 1996 USBD_EXCLUSIVE_USE, &sc->atu_ep[ATU_ENDPT_TX]);
1997 if (err) { 1997 if (err) {
1998 DPRINTF(("%s: open tx pipe failed: %s\n", 1998 DPRINTF(("%s: open tx pipe failed: %s\n",
1999 device_xname(sc->atu_dev), usbd_errstr(err))); 1999 device_xname(sc->atu_dev), usbd_errstr(err)));
2000 splx(s); 2000 splx(s);
2001 return EIO; 2001 return EIO;
2002 } 2002 }
2003 2003
2004 /* Init TX ring */ 2004 /* Init TX ring */
2005 if (atu_tx_list_init(sc)) 2005 if (atu_tx_list_init(sc))
2006 printf("%s: tx list init failed\n", device_xname(sc->atu_dev)); 2006 printf("%s: tx list init failed\n", device_xname(sc->atu_dev));
2007 2007
2008 /* Init RX ring */ 2008 /* Init RX ring */
2009 if (atu_rx_list_init(sc)) 2009 if (atu_rx_list_init(sc))
2010 printf("%s: rx list init failed\n", device_xname(sc->atu_dev)); 2010 printf("%s: rx list init failed\n", device_xname(sc->atu_dev));
2011 2011
2012 /* Start up the receive pipe. */ 2012 /* Start up the receive pipe. */
2013 for (i = 0; i < ATU_RX_LIST_CNT; i++) { 2013 for (i = 0; i < ATU_RX_LIST_CNT; i++) {
2014 c = &sc->atu_cdata.atu_rx_chain[i]; 2014 c = &sc->atu_cdata.atu_rx_chain[i];
2015 2015
2016 usbd_setup_xfer(c->atu_xfer, c, c->atu_buf, ATU_RX_BUFSZ, 2016 usbd_setup_xfer(c->atu_xfer, c, c->atu_buf, ATU_RX_BUFSZ,
2017 USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, atu_rxeof); 2017 USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, atu_rxeof);
2018 usbd_transfer(c->atu_xfer); 2018 usbd_transfer(c->atu_xfer);
2019 } 2019 }
2020 2020
2021 DPRINTFN(10, ("%s: starting up using MAC=%s\n", 2021 DPRINTFN(10, ("%s: starting up using MAC=%s\n",
2022 device_xname(sc->atu_dev), ether_sprintf(ic->ic_myaddr))); 2022 device_xname(sc->atu_dev), ether_sprintf(ic->ic_myaddr)));
2023 2023
2024 /* Do initial setup */ 2024 /* Do initial setup */
2025 err = atu_initial_config(sc); 2025 err = atu_initial_config(sc);
2026 if (err) { 2026 if (err) {
2027 DPRINTF(("%s: initial config failed!\n", 2027 DPRINTF(("%s: initial config failed!\n",
2028 device_xname(sc->atu_dev))); 2028 device_xname(sc->atu_dev)));
2029 splx(s); 2029 splx(s);
2030 return EIO; 2030 return EIO;
2031 } 2031 }
2032 DPRINTFN(10, ("%s: initialised transceiver\n", 2032 DPRINTFN(10, ("%s: initialised transceiver\n",
2033 device_xname(sc->atu_dev))); 2033 device_xname(sc->atu_dev)));
2034 2034
2035 /* sc->atu_rxfilt = ATU_RXFILT_UNICAST|ATU_RXFILT_BROADCAST; */ 2035 /* sc->atu_rxfilt = ATU_RXFILT_UNICAST|ATU_RXFILT_BROADCAST; */
2036 2036
2037 /* If we want promiscuous mode, set the allframes bit. */ 2037 /* If we want promiscuous mode, set the allframes bit. */
2038 /* 2038 /*
2039 if (ifp->if_flags & IFF_PROMISC) 2039 if (ifp->if_flags & IFF_PROMISC)
2040 sc->atu_rxfilt |= ATU_RXFILT_PROMISC; 2040 sc->atu_rxfilt |= ATU_RXFILT_PROMISC;
2041 */ 2041 */
2042 2042
2043 ifp->if_flags |= IFF_RUNNING; 2043 ifp->if_flags |= IFF_RUNNING;
2044 ifp->if_flags &= ~IFF_OACTIVE; 2044 ifp->if_flags &= ~IFF_OACTIVE;
2045 splx(s); 2045 splx(s);
2046 2046
2047 /* XXX the following HAS to be replaced */ 2047 /* XXX the following HAS to be replaced */
2048 s = splnet(); 2048 s = splnet();
2049 err = ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 2049 err = ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
2050 if (err) { 2050 if (err) {
2051 DPRINTFN(1, ("%s: atu_init: error calling " 2051 DPRINTFN(1, ("%s: atu_init: error calling "
2052 "ieee80211_net_state", device_xname(sc->atu_dev))); 2052 "ieee80211_net_state", device_xname(sc->atu_dev)));
2053 } 2053 }
2054 splx(s); 2054 splx(s);
2055 2055
2056 return 0; 2056 return 0;
2057} 2057}
2058 2058
2059#if 0 && defined(ATU_DEBUG) /* XXX XXX XXX UNUSED */ 2059#if 0 && defined(ATU_DEBUG) /* XXX XXX XXX UNUSED */
2060static void atu_debug_print(struct atu_softc *); 2060static void atu_debug_print(struct atu_softc *);
2061static void 2061static void
2062atu_debug_print(struct atu_softc *sc) 2062atu_debug_print(struct atu_softc *sc)
2063{ 2063{
2064 usbd_status err; 2064 usbd_status err;
2065 uint8_t tmp[32]; 2065 uint8_t tmp[32];
2066 2066
2067 /* DEBUG */ 2067 /* DEBUG */
2068 if ((err = atu_get_mib(sc, MIB_MAC_MGMT__CURRENT_BSSID, tmp))) 2068 if ((err = atu_get_mib(sc, MIB_MAC_MGMT__CURRENT_BSSID, tmp)))
2069 return; 2069 return;
2070 DPRINTF(("%s: DEBUG: current BSSID=%s\n", device_xname(sc->atu_dev), 2070 DPRINTF(("%s: DEBUG: current BSSID=%s\n", device_xname(sc->atu_dev),
2071 ether_sprintf(tmp))); 2071 ether_sprintf(tmp)));
2072 2072
2073 if ((err = atu_get_mib(sc, MIB_MAC_MGMT__BEACON_PERIOD, tmp))) 2073 if ((err = atu_get_mib(sc, MIB_MAC_MGMT__BEACON_PERIOD, tmp)))
2074 return; 2074 return;
2075 DPRINTF(("%s: DEBUG: beacon period=%d\n", device_xname(sc->atu_dev), 2075 DPRINTF(("%s: DEBUG: beacon period=%d\n", device_xname(sc->atu_dev),
2076 tmp[0])); 2076 tmp[0]));
2077 2077
2078 if ((err = atu_get_mib(sc, MIB_MAC_WEP__PRIVACY_INVOKED, tmp))) 2078 if ((err = atu_get_mib(sc, MIB_MAC_WEP__PRIVACY_INVOKED, tmp)))
2079 return; 2079 return;
2080 DPRINTF(("%s: DEBUG: privacy invoked=%d\n", device_xname(sc->atu_dev), 2080 DPRINTF(("%s: DEBUG: privacy invoked=%d\n", device_xname(sc->atu_dev),
2081 tmp[0])); 2081 tmp[0]));
2082 2082
2083 if ((err = atu_get_mib(sc, MIB_MAC_WEP__ENCR_LEVEL, tmp))) 2083 if ((err = atu_get_mib(sc, MIB_MAC_WEP__ENCR_LEVEL, tmp)))
2084 return; 2084 return;
2085 DPRINTF(("%s: DEBUG: encr_level=%d\n", device_xname(sc->atu_dev), 2085 DPRINTF(("%s: DEBUG: encr_level=%d\n", device_xname(sc->atu_dev),
2086 tmp[0])); 2086 tmp[0]));
2087 2087
2088 if ((err = atu_get_mib(sc, MIB_MAC_WEP__ICV_ERROR_COUNT, tmp))) 2088 if ((err = atu_get_mib(sc, MIB_MAC_WEP__ICV_ERROR_COUNT, tmp)))
2089 return; 2089 return;
2090 DPRINTF(("%s: DEBUG: icv error count=%d\n", device_xname(sc->atu_dev), 2090 DPRINTF(("%s: DEBUG: icv error count=%d\n", device_xname(sc->atu_dev),
2091 *(short *)tmp)); 2091 *(short *)tmp));
2092 2092
2093 if ((err = atu_get_mib(sc, MIB_MAC_WEP__EXCLUDED_COUNT, tmp))) 2093 if ((err = atu_get_mib(sc, MIB_MAC_WEP__EXCLUDED_COUNT, tmp)))
2094 return; 2094 return;
2095 DPRINTF(("%s: DEBUG: wep excluded count=%d\n", 2095 DPRINTF(("%s: DEBUG: wep excluded count=%d\n",
2096 device_xname(sc->atu_dev), *(short *)tmp)); 2096 device_xname(sc->atu_dev), *(short *)tmp));
2097 2097
2098 if ((err = atu_get_mib(sc, MIB_MAC_MGMT__POWER_MODE, tmp))) 2098 if ((err = atu_get_mib(sc, MIB_MAC_MGMT__POWER_MODE, tmp)))
2099 return; 2099 return;
2100 DPRINTF(("%s: DEBUG: power mode=%d\n", device_xname(sc->atu_dev), 2100 DPRINTF(("%s: DEBUG: power mode=%d\n", device_xname(sc->atu_dev),
2101 tmp[0])); 2101 tmp[0]));
2102 2102
2103 if ((err = atu_get_mib(sc, MIB_PHY__CHANNEL, tmp))) 2103 if ((err = atu_get_mib(sc, MIB_PHY__CHANNEL, tmp)))
2104 return; 2104 return;
2105 DPRINTF(("%s: DEBUG: channel=%d\n", device_xname(sc->atu_dev), tmp[0])); 2105 DPRINTF(("%s: DEBUG: channel=%d\n", device_xname(sc->atu_dev), tmp[0]));
2106 2106
2107 if ((err = atu_get_mib(sc, MIB_PHY__REG_DOMAIN, tmp))) 2107 if ((err = atu_get_mib(sc, MIB_PHY__REG_DOMAIN, tmp)))
2108 return; 2108 return;
2109 DPRINTF(("%s: DEBUG: reg domain=%d\n", device_xname(sc->atu_dev), 2109 DPRINTF(("%s: DEBUG: reg domain=%d\n", device_xname(sc->atu_dev),
2110 tmp[0])); 2110 tmp[0]));
2111 2111
2112 if ((err = atu_get_mib(sc, MIB_LOCAL__SSID_SIZE, tmp))) 2112 if ((err = atu_get_mib(sc, MIB_LOCAL__SSID_SIZE, tmp)))
2113 return; 2113 return;
2114 DPRINTF(("%s: DEBUG: ssid size=%d\n", device_xname(sc->atu_dev), 2114 DPRINTF(("%s: DEBUG: ssid size=%d\n", device_xname(sc->atu_dev),
2115 tmp[0])); 2115 tmp[0]));
2116 2116
2117 if ((err = atu_get_mib(sc, MIB_LOCAL__BEACON_ENABLE, tmp))) 2117 if ((err = atu_get_mib(sc, MIB_LOCAL__BEACON_ENABLE, tmp)))
2118 return; 2118 return;
2119 DPRINTF(("%s: DEBUG: beacon enable=%d\n", device_xname(sc->atu_dev), 2119 DPRINTF(("%s: DEBUG: beacon enable=%d\n", device_xname(sc->atu_dev),
2120 tmp[0])); 2120 tmp[0]));
2121 2121
2122 if ((err = atu_get_mib(sc, MIB_LOCAL__AUTO_RATE_FALLBACK, tmp))) 2122 if ((err = atu_get_mib(sc, MIB_LOCAL__AUTO_RATE_FALLBACK, tmp)))
2123 return; 2123 return;
2124 DPRINTF(("%s: DEBUG: auto rate fallback=%d\n", 2124 DPRINTF(("%s: DEBUG: auto rate fallback=%d\n",
2125 device_xname(sc->atu_dev), tmp[0])); 2125 device_xname(sc->atu_dev), tmp[0]));
2126 2126
2127 if ((err = atu_get_mib(sc, MIB_MAC_ADDR__ADDR, tmp))) 2127 if ((err = atu_get_mib(sc, MIB_MAC_ADDR__ADDR, tmp)))
2128 return; 2128 return;
2129 DPRINTF(("%s: DEBUG: mac addr=%s\n", device_xname(sc->atu_dev), 2129 DPRINTF(("%s: DEBUG: mac addr=%s\n", device_xname(sc->atu_dev),
2130 ether_sprintf(tmp))); 2130 ether_sprintf(tmp)));
2131 2131
2132 if ((err = atu_get_mib(sc, MIB_MAC__DESIRED_SSID, tmp))) 2132 if ((err = atu_get_mib(sc, MIB_MAC__DESIRED_SSID, tmp)))
2133 return; 2133 return;
2134 DPRINTF(("%s: DEBUG: desired ssid=%s\n", device_xname(sc->atu_dev), 2134 DPRINTF(("%s: DEBUG: desired ssid=%s\n", device_xname(sc->atu_dev),
2135 tmp)); 2135 tmp));
2136 2136
2137 if ((err = atu_get_mib(sc, MIB_MAC_MGMT__CURRENT_ESSID, tmp))) 2137 if ((err = atu_get_mib(sc, MIB_MAC_MGMT__CURRENT_ESSID, tmp)))
2138 return; 2138 return;
2139 DPRINTF(("%s: DEBUG: current ESSID=%s\n", device_xname(sc->atu_dev), 2139 DPRINTF(("%s: DEBUG: current ESSID=%s\n", device_xname(sc->atu_dev),
2140 tmp)); 2140 tmp));
2141} 2141}
2142#endif /* ATU_DEBUG */ 2142#endif /* ATU_DEBUG */
2143 2143
2144static int 2144static int
2145atu_ioctl(struct ifnet *ifp, u_long command, void *data) 2145atu_ioctl(struct ifnet *ifp, u_long command, void *data)
2146{ 2146{
2147 struct atu_softc *sc = ifp->if_softc; 2147 struct atu_softc *sc = ifp->if_softc;
2148 struct ieee80211com *ic = &sc->sc_ic; 2148 struct ieee80211com *ic = &sc->sc_ic;
2149 int err = 0, s; 2149 int err = 0, s;
2150 2150
2151 s = splnet(); 2151 s = splnet();
2152 switch (command) { 2152 switch (command) {
2153 default: 2153 default:
2154 DPRINTFN(15, ("%s: ieee80211_ioctl (%lu)\n", 2154 DPRINTFN(15, ("%s: ieee80211_ioctl (%lu)\n",
2155 device_xname(sc->atu_dev), command)); 2155 device_xname(sc->atu_dev), command));
2156 err = ieee80211_ioctl(ic, command, data); 2156 err = ieee80211_ioctl(ic, command, data);
2157 break; 2157 break;
2158 } 2158 }
2159 2159
2160 if (err == ENETRESET) { 2160 if (err == ENETRESET) {
2161 if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) == 2161 if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) ==
2162 (IFF_RUNNING|IFF_UP)) { 2162 (IFF_RUNNING|IFF_UP)) {
2163 DPRINTF(("%s: atu_ioctl(): netreset %lu\n", 2163 DPRINTF(("%s: atu_ioctl(): netreset %lu\n",
2164 device_xname(sc->atu_dev), command)); 2164 device_xname(sc->atu_dev), command));
2165 ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 2165 ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
2166 atu_initial_config(sc); 2166 atu_initial_config(sc);
2167 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); 2167 ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
2168 } 2168 }
2169 err = 0; 2169 err = 0;
2170 } 2170 }
2171 2171
2172 splx(s); 2172 splx(s);
2173 return err; 2173 return err;
2174} 2174}
2175 2175
2176static void 2176static void
2177atu_watchdog(struct ifnet *ifp) 2177atu_watchdog(struct ifnet *ifp)
2178{ 2178{
2179 struct atu_softc *sc = ifp->if_softc; 2179 struct atu_softc *sc = ifp->if_softc;
2180 struct atu_chain *c; 2180 struct atu_chain *c;
2181 usbd_status stat; 2181 usbd_status stat;
2182 int cnt, s; 2182 int cnt, s;
2183 2183
2184 DPRINTF(("%s: atu_watchdog\n", device_xname(sc->atu_dev))); 2184 DPRINTF(("%s: atu_watchdog\n", device_xname(sc->atu_dev)));
2185 2185
2186 ifp->if_timer = 0; 2186 ifp->if_timer = 0;
2187 2187
2188 if (sc->sc_state != ATU_S_OK || (ifp->if_flags & IFF_RUNNING) == 0) 2188 if (sc->sc_state != ATU_S_OK || (ifp->if_flags & IFF_RUNNING) == 0)
2189 return; 2189 return;
2190 2190
2191 sc = ifp->if_softc; 2191 sc = ifp->if_softc;
2192 s = splnet(); 2192 s = splnet();
2193 if_statinc(ifp, if_oerrors); 2193 if_statinc(ifp, if_oerrors);
2194 DPRINTF(("%s: watchdog timeout\n", device_xname(sc->atu_dev))); 2194 DPRINTF(("%s: watchdog timeout\n", device_xname(sc->atu_dev)));
2195 2195
2196 /* 2196 /*
2197 * TODO: 2197 * TODO:
2198 * we should change this since we have multiple TX tranfers... 2198 * we should change this since we have multiple TX tranfers...
2199 */ 2199 */
2200 for (cnt = 0; cnt < ATU_TX_LIST_CNT; cnt++) { 2200 for (cnt = 0; cnt < ATU_TX_LIST_CNT; cnt++) {
2201 c = &sc->atu_cdata.atu_tx_chain[cnt]; 2201 c = &sc->atu_cdata.atu_tx_chain[cnt];
2202 if (c->atu_in_xfer) { 2202 if (c->atu_in_xfer) {
2203 usbd_get_xfer_status(c->atu_xfer, NULL, NULL, NULL, 2203 usbd_get_xfer_status(c->atu_xfer, NULL, NULL, NULL,
2204 &stat); 2204 &stat);
2205 atu_txeof(c->atu_xfer, c, stat); 2205 atu_txeof(c->atu_xfer, c, stat);
2206 } 2206 }
2207 } 2207 }
2208 2208
2209 if (!IFQ_IS_EMPTY(&ifp->if_snd)) 2209 if (!IFQ_IS_EMPTY(&ifp->if_snd))
2210 atu_start(ifp); 2210 atu_start(ifp);
2211 splx(s); 2211 splx(s);
2212 2212
2213 ieee80211_watchdog(&sc->sc_ic); 2213 ieee80211_watchdog(&sc->sc_ic);
2214} 2214}
2215 2215
2216/* 2216/*
2217 * Stop the adapter and free any mbufs allocated to the 2217 * Stop the adapter and free any mbufs allocated to the
2218 * RX and TX lists. 2218 * RX and TX lists.
2219 */ 2219 */
2220static void 2220static void
2221atu_stop(struct ifnet *ifp, int disable) 2221atu_stop(struct ifnet *ifp, int disable)
2222{ 2222{
2223 struct atu_softc *sc = ifp->if_softc; 2223 struct atu_softc *sc = ifp->if_softc;
2224 struct ieee80211com *ic = &sc->sc_ic; 2224 struct ieee80211com *ic = &sc->sc_ic;
2225 struct atu_cdata *cd; 2225 struct atu_cdata *cd;
2226 usbd_status err; 2226 usbd_status err;
2227 int s; 2227 int s;
2228 2228
2229 s = splnet(); 2229 s = splnet();
2230 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 2230 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
2231 ifp->if_timer = 0; 2231 ifp->if_timer = 0;
2232 2232
2233 usb_rem_task_wait(sc->atu_udev, &sc->sc_task, USB_TASKQ_DRIVER, NULL); 2233 usb_rem_task_wait(sc->atu_udev, &sc->sc_task, USB_TASKQ_DRIVER, NULL);
2234 ieee80211_new_state(ic, IEEE80211_S_INIT, -1); 2234 ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
2235 2235
2236 /* Stop transfers. */ 2236 /* Stop transfers. */
2237 if (sc->atu_ep[ATU_ENDPT_RX] != NULL) { 2237 if (sc->atu_ep[ATU_ENDPT_RX] != NULL) {
2238 err = usbd_abort_pipe(sc->atu_ep[ATU_ENDPT_RX]); 2238 usbd_abort_pipe(sc->atu_ep[ATU_ENDPT_RX]);
2239 if (err) { 
2240 DPRINTF(("%s: abort rx pipe failed: %s\n", 
2241 device_xname(sc->atu_dev), usbd_errstr(err))); 
2242 } 
2243 } 2239 }
2244 2240
2245 if (sc->atu_ep[ATU_ENDPT_TX] != NULL) { 2241 if (sc->atu_ep[ATU_ENDPT_TX] != NULL) {
2246 err = usbd_abort_pipe(sc->atu_ep[ATU_ENDPT_TX]); 2242 usbd_abort_pipe(sc->atu_ep[ATU_ENDPT_TX]);
2247 if (err) { 
2248 DPRINTF(("%s: abort tx pipe failed: %s\n", 
2249 device_xname(sc->atu_dev), usbd_errstr(err))); 
2250 } 
2251 } 2243 }
2252 2244
2253 /* Free RX/TX/MGMT list resources. */ 2245 /* Free RX/TX/MGMT list resources. */
2254 cd = &sc->atu_cdata; 2246 cd = &sc->atu_cdata;
2255 atu_xfer_list_free(sc, cd->atu_rx_chain, ATU_RX_LIST_CNT); 2247 atu_xfer_list_free(sc, cd->atu_rx_chain, ATU_RX_LIST_CNT);
2256 atu_xfer_list_free(sc, cd->atu_tx_chain, ATU_TX_LIST_CNT); 2248 atu_xfer_list_free(sc, cd->atu_tx_chain, ATU_TX_LIST_CNT);
2257 2249
2258 /* Close pipes */ 2250 /* Close pipes */
2259 if (sc->atu_ep[ATU_ENDPT_RX] != NULL) { 2251 if (sc->atu_ep[ATU_ENDPT_RX] != NULL) {
2260 err = usbd_close_pipe(sc->atu_ep[ATU_ENDPT_RX]); 2252 err = usbd_close_pipe(sc->atu_ep[ATU_ENDPT_RX]);
2261 if (err) { 2253 if (err) {
2262 DPRINTF(("%s: close rx pipe failed: %s\n", 2254 DPRINTF(("%s: close rx pipe failed: %s\n",
2263 device_xname(sc->atu_dev), usbd_errstr(err))); 2255 device_xname(sc->atu_dev), usbd_errstr(err)));
2264 } 2256 }
2265 sc->atu_ep[ATU_ENDPT_RX] = NULL; 2257 sc->atu_ep[ATU_ENDPT_RX] = NULL;
2266 } 2258 }
2267 2259
2268 if (sc->atu_ep[ATU_ENDPT_TX] != NULL) { 2260 if (sc->atu_ep[ATU_ENDPT_TX] != NULL) {
2269 err = usbd_close_pipe(sc->atu_ep[ATU_ENDPT_TX]); 2261 err = usbd_close_pipe(sc->atu_ep[ATU_ENDPT_TX]);
2270 if (err) { 2262 if (err) {
2271 DPRINTF(("%s: close tx pipe failed: %s\n", 2263 DPRINTF(("%s: close tx pipe failed: %s\n",
2272 device_xname(sc->atu_dev), usbd_errstr(err))); 2264 device_xname(sc->atu_dev), usbd_errstr(err)));
2273 } 2265 }
2274 sc->atu_ep[ATU_ENDPT_TX] = NULL; 2266 sc->atu_ep[ATU_ENDPT_TX] = NULL;
2275 } 2267 }
2276 2268
2277 /* Let's be nice and turn off the radio before we leave */ 2269 /* Let's be nice and turn off the radio before we leave */
2278 atu_switch_radio(sc, 0); 2270 atu_switch_radio(sc, 0);
2279 2271
2280 splx(s); 2272 splx(s);
2281} 2273}

cvs diff -r1.13 -r1.14 src/sys/dev/usb/ualea.c (switch to unified diff)

--- src/sys/dev/usb/ualea.c 2021/05/29 08:45:19 1.13
+++ src/sys/dev/usb/ualea.c 2022/03/03 06:05:38 1.14
@@ -1,289 +1,289 @@ @@ -1,289 +1,289 @@
1/* $NetBSD: ualea.c,v 1.13 2021/05/29 08:45:19 riastradh Exp $ */ 1/* $NetBSD: ualea.c,v 1.14 2022/03/03 06:05:38 riastradh Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2017 The NetBSD Foundation, Inc. 4 * Copyright (c) 2017 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Taylor R. Campbell. 8 * by Taylor R. Campbell.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33__KERNEL_RCSID(0, "$NetBSD: ualea.c,v 1.13 2021/05/29 08:45:19 riastradh Exp $"); 33__KERNEL_RCSID(0, "$NetBSD: ualea.c,v 1.14 2022/03/03 06:05:38 riastradh Exp $");
34 34
35#include <sys/types.h> 35#include <sys/types.h>
36#include <sys/atomic.h> 36#include <sys/atomic.h>
37#include <sys/device_if.h> 37#include <sys/device_if.h>
38#include <sys/kmem.h> 38#include <sys/kmem.h>
39#include <sys/module.h> 39#include <sys/module.h>
40#include <sys/rndsource.h> 40#include <sys/rndsource.h>
41 41
42#include <dev/usb/usb.h> 42#include <dev/usb/usb.h>
43#include <dev/usb/usbdevs.h> 43#include <dev/usb/usbdevs.h>
44#include <dev/usb/usbdi.h> 44#include <dev/usb/usbdi.h>
45#include <dev/usb/usbdi_util.h> 45#include <dev/usb/usbdi_util.h>
46 46
47struct ualea_softc { 47struct ualea_softc {
48 device_t sc_dev; 48 device_t sc_dev;
49 kmutex_t sc_lock; 49 kmutex_t sc_lock;
50 krndsource_t sc_rnd; 50 krndsource_t sc_rnd;
51 uint16_t sc_maxpktsize; 51 uint16_t sc_maxpktsize;
52 struct usbd_pipe *sc_pipe; 52 struct usbd_pipe *sc_pipe;
53 /* 53 /*
54 * Lock covers: 54 * Lock covers:
55 * - sc_needed 55 * - sc_needed
56 * - sc_inflight 56 * - sc_inflight
57 * - usbd_transfer(sc_xfer) 57 * - usbd_transfer(sc_xfer)
58 */ 58 */
59 struct usbd_xfer *sc_xfer; 59 struct usbd_xfer *sc_xfer;
60 size_t sc_needed; 60 size_t sc_needed;
61 bool sc_attached:1; 61 bool sc_attached:1;
62 bool sc_inflight:1; 62 bool sc_inflight:1;
63}; 63};
64 64
65static int ualea_match(device_t, cfdata_t, void *); 65static int ualea_match(device_t, cfdata_t, void *);
66static void ualea_attach(device_t, device_t, void *); 66static void ualea_attach(device_t, device_t, void *);
67static int ualea_detach(device_t, int); 67static int ualea_detach(device_t, int);
68static void ualea_get(size_t, void *); 68static void ualea_get(size_t, void *);
69static void ualea_xfer_done(struct usbd_xfer *, void *, usbd_status); 69static void ualea_xfer_done(struct usbd_xfer *, void *, usbd_status);
70 70
71CFATTACH_DECL_NEW(ualea, sizeof(struct ualea_softc), 71CFATTACH_DECL_NEW(ualea, sizeof(struct ualea_softc),
72 ualea_match, ualea_attach, ualea_detach, NULL); 72 ualea_match, ualea_attach, ualea_detach, NULL);
73 73
74static const struct usb_devno ualea_devs[] = { 74static const struct usb_devno ualea_devs[] = {
75 { USB_VENDOR_ARANEUS, USB_PRODUCT_ARANEUS_ALEA }, 75 { USB_VENDOR_ARANEUS, USB_PRODUCT_ARANEUS_ALEA },
76}; 76};
77 77
78static int 78static int
79ualea_match(device_t parent, cfdata_t match, void *aux) 79ualea_match(device_t parent, cfdata_t match, void *aux)
80{ 80{
81 struct usbif_attach_arg *uiaa = aux; 81 struct usbif_attach_arg *uiaa = aux;
82 82
83 if (usb_lookup(ualea_devs, uiaa->uiaa_vendor, uiaa->uiaa_product)) 83 if (usb_lookup(ualea_devs, uiaa->uiaa_vendor, uiaa->uiaa_product))
84 return UMATCH_VENDOR_PRODUCT; 84 return UMATCH_VENDOR_PRODUCT;
85 85
86 return UMATCH_NONE; 86 return UMATCH_NONE;
87} 87}
88 88
89static void 89static void
90ualea_attach(device_t parent, device_t self, void *aux) 90ualea_attach(device_t parent, device_t self, void *aux)
91{ 91{
92 struct usbif_attach_arg *uiaa = aux; 92 struct usbif_attach_arg *uiaa = aux;
93 struct ualea_softc *sc = device_private(self); 93 struct ualea_softc *sc = device_private(self);
94 const usb_endpoint_descriptor_t *ed; 94 const usb_endpoint_descriptor_t *ed;
95 char *devinfop; 95 char *devinfop;
96 usbd_status status; 96 usbd_status status;
97 97
98 /* Print the device info. */ 98 /* Print the device info. */
99 aprint_naive("\n"); 99 aprint_naive("\n");
100 aprint_normal("\n"); 100 aprint_normal("\n");
101 devinfop = usbd_devinfo_alloc(uiaa->uiaa_device, 0); 101 devinfop = usbd_devinfo_alloc(uiaa->uiaa_device, 0);
102 aprint_normal_dev(self, "%s\n", devinfop); 102 aprint_normal_dev(self, "%s\n", devinfop);
103 usbd_devinfo_free(devinfop); 103 usbd_devinfo_free(devinfop);
104 104
105 /* Initialize the softc. */ 105 /* Initialize the softc. */
106 sc->sc_dev = self; 106 sc->sc_dev = self;
107 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB); 107 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB);
108 108
109 /* Get endpoint descriptor 0. Make sure it's bulk-in. */ 109 /* Get endpoint descriptor 0. Make sure it's bulk-in. */
110 ed = usbd_interface2endpoint_descriptor(uiaa->uiaa_iface, 0); 110 ed = usbd_interface2endpoint_descriptor(uiaa->uiaa_iface, 0);
111 if (ed == NULL) { 111 if (ed == NULL) {
112 aprint_error_dev(sc->sc_dev, "failed to read endpoint 0\n"); 112 aprint_error_dev(sc->sc_dev, "failed to read endpoint 0\n");
113 return; 113 return;
114 } 114 }
115 if (UE_GET_DIR(ed->bEndpointAddress) != UE_DIR_IN || 115 if (UE_GET_DIR(ed->bEndpointAddress) != UE_DIR_IN ||
116 UE_GET_XFERTYPE(ed->bmAttributes) != UE_BULK) { 116 UE_GET_XFERTYPE(ed->bmAttributes) != UE_BULK) {
117 aprint_error_dev(sc->sc_dev, "invalid endpoint\n"); 117 aprint_error_dev(sc->sc_dev, "invalid endpoint\n");
118 return; 118 return;
119 } 119 }
120 120
121 /* Remember the maximum packet size. */ 121 /* Remember the maximum packet size. */
122 sc->sc_maxpktsize = UGETW(ed->wMaxPacketSize); 122 sc->sc_maxpktsize = UGETW(ed->wMaxPacketSize);
123 123
124 /* Open an exclusive MP-safe pipe for endpoint 0. */ 124 /* Open an exclusive MP-safe pipe for endpoint 0. */
125 status = usbd_open_pipe(uiaa->uiaa_iface, ed->bEndpointAddress, 125 status = usbd_open_pipe(uiaa->uiaa_iface, ed->bEndpointAddress,
126 USBD_EXCLUSIVE_USE|USBD_MPSAFE, &sc->sc_pipe); 126 USBD_EXCLUSIVE_USE|USBD_MPSAFE, &sc->sc_pipe);
127 if (status) { 127 if (status) {
128 aprint_error_dev(sc->sc_dev, "failed to open pipe: %d\n", 128 aprint_error_dev(sc->sc_dev, "failed to open pipe: %d\n",
129 status); 129 status);
130 return; 130 return;
131 } 131 }
132 132
133 /* Create an xfer of maximum packet size on the pipe. */ 133 /* Create an xfer of maximum packet size on the pipe. */
134 status = usbd_create_xfer(sc->sc_pipe, sc->sc_maxpktsize, 134 status = usbd_create_xfer(sc->sc_pipe, sc->sc_maxpktsize,
135 0, 0, &sc->sc_xfer); 135 0, 0, &sc->sc_xfer);
136 if (status) { 136 if (status) {
137 aprint_error_dev(sc->sc_dev, "failed to create xfer: %d\n", 137 aprint_error_dev(sc->sc_dev, "failed to create xfer: %d\n",
138 status); 138 status);
139 return; 139 return;
140 } 140 }
141 141
142 if (!pmf_device_register(self, NULL, NULL)) 142 if (!pmf_device_register(self, NULL, NULL))
143 aprint_error_dev(sc->sc_dev, "failed to register power handler" 143 aprint_error_dev(sc->sc_dev, "failed to register power handler"
144 "\n"); 144 "\n");
145 145
146 /* Success! We are ready to run. */ 146 /* Success! We are ready to run. */
147 sc->sc_attached = true; 147 sc->sc_attached = true;
148 rndsource_setcb(&sc->sc_rnd, ualea_get, sc); 148 rndsource_setcb(&sc->sc_rnd, ualea_get, sc);
149 rnd_attach_source(&sc->sc_rnd, device_xname(self), RND_TYPE_RNG, 149 rnd_attach_source(&sc->sc_rnd, device_xname(self), RND_TYPE_RNG,
150 RND_FLAG_COLLECT_VALUE|RND_FLAG_HASCB); 150 RND_FLAG_COLLECT_VALUE|RND_FLAG_HASCB);
151} 151}
152 152
153static int 153static int
154ualea_detach(device_t self, int flags) 154ualea_detach(device_t self, int flags)
155{ 155{
156 struct ualea_softc *sc = device_private(self); 156 struct ualea_softc *sc = device_private(self);
157 157
158 /* Prevent new use of xfer. */ 158 /* Prevent new use of xfer. */
159 if (sc->sc_attached) 159 if (sc->sc_attached)
160 rnd_detach_source(&sc->sc_rnd); 160 rnd_detach_source(&sc->sc_rnd);
161 161
162 /* Cancel pending xfer. */ 162 /* Cancel pending xfer. */
163 if (sc->sc_pipe) 163 if (sc->sc_pipe)
164 (void)usbd_abort_pipe(sc->sc_pipe); 164 usbd_abort_pipe(sc->sc_pipe);
165 KASSERT(!sc->sc_inflight); 165 KASSERT(!sc->sc_inflight);
166 166
167 /* All users have drained. Tear it all down. */ 167 /* All users have drained. Tear it all down. */
168 if (sc->sc_xfer) 168 if (sc->sc_xfer)
169 usbd_destroy_xfer(sc->sc_xfer); 169 usbd_destroy_xfer(sc->sc_xfer);
170 if (sc->sc_pipe) 170 if (sc->sc_pipe)
171 (void)usbd_close_pipe(sc->sc_pipe); 171 (void)usbd_close_pipe(sc->sc_pipe);
172 mutex_destroy(&sc->sc_lock); 172 mutex_destroy(&sc->sc_lock);
173 173
174 return 0; 174 return 0;
175} 175}
176 176
177static void 177static void
178ualea_xfer(struct ualea_softc *sc) 178ualea_xfer(struct ualea_softc *sc)
179{ 179{
180 usbd_status status; 180 usbd_status status;
181 181
182 KASSERT(mutex_owned(&sc->sc_lock)); 182 KASSERT(mutex_owned(&sc->sc_lock));
183 KASSERT(sc->sc_attached); 183 KASSERT(sc->sc_attached);
184 KASSERT(!sc->sc_inflight); 184 KASSERT(!sc->sc_inflight);
185 185
186 /* Do nothing if we need nothing. */ 186 /* Do nothing if we need nothing. */
187 if (sc->sc_needed == 0) 187 if (sc->sc_needed == 0)
188 return; 188 return;
189 189
190 /* Setup the xfer to call ualea_xfer_done with sc. */ 190 /* Setup the xfer to call ualea_xfer_done with sc. */
191 usbd_setup_xfer(sc->sc_xfer, sc, usbd_get_buffer(sc->sc_xfer), 191 usbd_setup_xfer(sc->sc_xfer, sc, usbd_get_buffer(sc->sc_xfer),
192 sc->sc_maxpktsize, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, 192 sc->sc_maxpktsize, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT,
193 ualea_xfer_done); 193 ualea_xfer_done);
194 194
195 /* Issue xfer or complain if we can't. */ 195 /* Issue xfer or complain if we can't. */
196 status = usbd_transfer(sc->sc_xfer); 196 status = usbd_transfer(sc->sc_xfer);
197 KASSERT(status != USBD_NORMAL_COMPLETION); /* asynchronous xfer */ 197 KASSERT(status != USBD_NORMAL_COMPLETION); /* asynchronous xfer */
198 if (status != USBD_IN_PROGRESS) { 198 if (status != USBD_IN_PROGRESS) {
199 aprint_error_dev(sc->sc_dev, "failed to issue xfer: %d\n", 199 aprint_error_dev(sc->sc_dev, "failed to issue xfer: %d\n",
200 status); 200 status);
201 /* We failed -- let someone else have a go. */ 201 /* We failed -- let someone else have a go. */
202 return; 202 return;
203 } 203 }
204 204
205 /* Mark xfer in-flight. */ 205 /* Mark xfer in-flight. */
206 sc->sc_inflight = true; 206 sc->sc_inflight = true;
207} 207}
208 208
209static void 209static void
210ualea_get(size_t nbytes, void *cookie) 210ualea_get(size_t nbytes, void *cookie)
211{ 211{
212 struct ualea_softc *sc = cookie; 212 struct ualea_softc *sc = cookie;
213 213
214 mutex_enter(&sc->sc_lock); 214 mutex_enter(&sc->sc_lock);
215 sc->sc_needed = MAX(sc->sc_needed, nbytes); 215 sc->sc_needed = MAX(sc->sc_needed, nbytes);
216 if (!sc->sc_inflight) 216 if (!sc->sc_inflight)
217 ualea_xfer(sc); 217 ualea_xfer(sc);
218 mutex_exit(&sc->sc_lock); 218 mutex_exit(&sc->sc_lock);
219} 219}
220 220
221static void 221static void
222ualea_xfer_done(struct usbd_xfer *xfer, void *cookie, usbd_status status) 222ualea_xfer_done(struct usbd_xfer *xfer, void *cookie, usbd_status status)
223{ 223{
224 struct ualea_softc *sc = cookie; 224 struct ualea_softc *sc = cookie;
225 void *pkt; 225 void *pkt;
226 uint32_t pktsize; 226 uint32_t pktsize;
227 227
228 /* Check the transfer status. */ 228 /* Check the transfer status. */
229 if (status) { 229 if (status) {
230 aprint_error_dev(sc->sc_dev, "xfer failed: %d\n", status); 230 aprint_error_dev(sc->sc_dev, "xfer failed: %d\n", status);
231 return; 231 return;
232 } 232 }
233 233
234 /* Get and sanity-check the transferred size. */ 234 /* Get and sanity-check the transferred size. */
235 usbd_get_xfer_status(xfer, NULL, &pkt, &pktsize, NULL); 235 usbd_get_xfer_status(xfer, NULL, &pkt, &pktsize, NULL);
236 if (pktsize > sc->sc_maxpktsize) { 236 if (pktsize > sc->sc_maxpktsize) {
237 aprint_error_dev(sc->sc_dev, 237 aprint_error_dev(sc->sc_dev,
238 "bogus packet size: %"PRIu32" > %"PRIu16" (max), ignoring" 238 "bogus packet size: %"PRIu32" > %"PRIu16" (max), ignoring"
239 "\n", 239 "\n",
240 pktsize, sc->sc_maxpktsize); 240 pktsize, sc->sc_maxpktsize);
241 goto out; 241 goto out;
242 } 242 }
243 243
244 /* Add the data to the pool. */ 244 /* Add the data to the pool. */
245 rnd_add_data(&sc->sc_rnd, pkt, pktsize, NBBY*pktsize); 245 rnd_add_data(&sc->sc_rnd, pkt, pktsize, NBBY*pktsize);
246 246
247out: 247out:
248 mutex_enter(&sc->sc_lock); 248 mutex_enter(&sc->sc_lock);
249 249
250 /* Debit what we contributed from what we need. */ 250 /* Debit what we contributed from what we need. */
251 sc->sc_needed -= MIN(sc->sc_needed, pktsize); 251 sc->sc_needed -= MIN(sc->sc_needed, pktsize);
252 252
253 /* Mark xfer done. */ 253 /* Mark xfer done. */
254 sc->sc_inflight = false; 254 sc->sc_inflight = false;
255 255
256 /* Reissue xfer if we still need more. */ 256 /* Reissue xfer if we still need more. */
257 ualea_xfer(sc); 257 ualea_xfer(sc);
258 258
259 mutex_exit(&sc->sc_lock); 259 mutex_exit(&sc->sc_lock);
260} 260}
261 261
262MODULE(MODULE_CLASS_DRIVER, ualea, NULL); 262MODULE(MODULE_CLASS_DRIVER, ualea, NULL);
263 263
264#ifdef _MODULE 264#ifdef _MODULE
265#include "ioconf.c" 265#include "ioconf.c"
266#endif 266#endif
267 267
268static int 268static int
269ualea_modcmd(modcmd_t cmd, void *aux) 269ualea_modcmd(modcmd_t cmd, void *aux)
270{ 270{
271 int error = 0; 271 int error = 0;
272 272
273 switch (cmd) { 273 switch (cmd) {
274 case MODULE_CMD_INIT: 274 case MODULE_CMD_INIT:
275#ifdef _MODULE 275#ifdef _MODULE
276 error = config_init_component(cfdriver_ioconf_ualea, 276 error = config_init_component(cfdriver_ioconf_ualea,
277 cfattach_ioconf_ualea, cfdata_ioconf_ualea); 277 cfattach_ioconf_ualea, cfdata_ioconf_ualea);
278#endif 278#endif
279 return error; 279 return error;
280 case MODULE_CMD_FINI: 280 case MODULE_CMD_FINI:
281#ifdef _MODULE 281#ifdef _MODULE
282 error = config_fini_component(cfdriver_ioconf_ualea, 282 error = config_fini_component(cfdriver_ioconf_ualea,
283 cfattach_ioconf_ualea, cfdata_ioconf_ualea); 283 cfattach_ioconf_ualea, cfdata_ioconf_ualea);
284#endif 284#endif
285 return error; 285 return error;
286 default: 286 default:
287 return ENOTTY; 287 return ENOTTY;
288 } 288 }
289} 289}

cvs diff -r1.223 -r1.224 src/sys/dev/usb/usbdi.c (switch to unified diff)

--- src/sys/dev/usb/usbdi.c 2022/03/03 06:04:31 1.223
+++ src/sys/dev/usb/usbdi.c 2022/03/03 06:05:38 1.224
@@ -1,1842 +1,1839 @@ @@ -1,1842 +1,1839 @@
1/* $NetBSD: usbdi.c,v 1.223 2022/03/03 06:04:31 riastradh Exp $ */ 1/* $NetBSD: usbdi.c,v 1.224 2022/03/03 06:05:38 riastradh Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1998, 2012, 2015 The NetBSD Foundation, Inc. 4 * Copyright (c) 1998, 2012, 2015 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Lennart Augustsson (lennart@augustsson.net) at 8 * by Lennart Augustsson (lennart@augustsson.net) at
9 * Carlstedt Research & Technology, Matthew R. Green (mrg@eterna.com.au), 9 * Carlstedt Research & Technology, Matthew R. Green (mrg@eterna.com.au),
10 * and Nick Hudson. 10 * and Nick Hudson.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions 13 * modification, are permitted provided that the following conditions
14 * are met: 14 * are met:
15 * 1. Redistributions of source code must retain the above copyright 15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer. 16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright 17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the 18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution. 19 * documentation and/or other materials provided with the distribution.
20 * 20 *
21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE. 31 * POSSIBILITY OF SUCH DAMAGE.
32 */ 32 */
33 33
34#include <sys/cdefs.h> 34#include <sys/cdefs.h>
35__KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.223 2022/03/03 06:04:31 riastradh Exp $"); 35__KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.224 2022/03/03 06:05:38 riastradh Exp $");
36 36
37#ifdef _KERNEL_OPT 37#ifdef _KERNEL_OPT
38#include "opt_usb.h" 38#include "opt_usb.h"
39#include "opt_compat_netbsd.h" 39#include "opt_compat_netbsd.h"
40#include "usb_dma.h" 40#include "usb_dma.h"
41#endif 41#endif
42 42
43#include <sys/param.h> 43#include <sys/param.h>
44#include <sys/systm.h> 44#include <sys/systm.h>
45#include <sys/kernel.h> 45#include <sys/kernel.h>
46#include <sys/device.h> 46#include <sys/device.h>
47#include <sys/kmem.h> 47#include <sys/kmem.h>
48#include <sys/proc.h> 48#include <sys/proc.h>
49#include <sys/bus.h> 49#include <sys/bus.h>
50#include <sys/cpu.h> 50#include <sys/cpu.h>
51 51
52#include <dev/usb/usb.h> 52#include <dev/usb/usb.h>
53#include <dev/usb/usbdi.h> 53#include <dev/usb/usbdi.h>
54#include <dev/usb/usbdi_util.h> 54#include <dev/usb/usbdi_util.h>
55#include <dev/usb/usbdivar.h> 55#include <dev/usb/usbdivar.h>
56#include <dev/usb/usb_mem.h> 56#include <dev/usb/usb_mem.h>
57#include <dev/usb/usb_quirks.h> 57#include <dev/usb/usb_quirks.h>
58#include <dev/usb/usb_sdt.h> 58#include <dev/usb/usb_sdt.h>
59#include <dev/usb/usbhist.h> 59#include <dev/usb/usbhist.h>
60 60
61/* UTF-8 encoding stuff */ 61/* UTF-8 encoding stuff */
62#include <fs/unicode.h> 62#include <fs/unicode.h>
63 63
64SDT_PROBE_DEFINE5(usb, device, pipe, open, 64SDT_PROBE_DEFINE5(usb, device, pipe, open,
65 "struct usbd_interface *"/*iface*/, 65 "struct usbd_interface *"/*iface*/,
66 "uint8_t"/*address*/, 66 "uint8_t"/*address*/,
67 "uint8_t"/*flags*/, 67 "uint8_t"/*flags*/,
68 "int"/*ival*/, 68 "int"/*ival*/,
69 "struct usbd_pipe *"/*pipe*/); 69 "struct usbd_pipe *"/*pipe*/);
70 70
71SDT_PROBE_DEFINE7(usb, device, pipe, open__intr, 71SDT_PROBE_DEFINE7(usb, device, pipe, open__intr,
72 "struct usbd_interface *"/*iface*/, 72 "struct usbd_interface *"/*iface*/,
73 "uint8_t"/*address*/, 73 "uint8_t"/*address*/,
74 "uint8_t"/*flags*/, 74 "uint8_t"/*flags*/,
75 "int"/*ival*/, 75 "int"/*ival*/,
76 "usbd_callback"/*cb*/, 76 "usbd_callback"/*cb*/,
77 "void *"/*cookie*/, 77 "void *"/*cookie*/,
78 "struct usbd_pipe *"/*pipe*/); 78 "struct usbd_pipe *"/*pipe*/);
79 79
80SDT_PROBE_DEFINE2(usb, device, pipe, transfer__start, 80SDT_PROBE_DEFINE2(usb, device, pipe, transfer__start,
81 "struct usbd_pipe *"/*pipe*/, 81 "struct usbd_pipe *"/*pipe*/,
82 "struct usbd_xfer *"/*xfer*/); 82 "struct usbd_xfer *"/*xfer*/);
83SDT_PROBE_DEFINE3(usb, device, pipe, transfer__done, 83SDT_PROBE_DEFINE3(usb, device, pipe, transfer__done,
84 "struct usbd_pipe *"/*pipe*/, 84 "struct usbd_pipe *"/*pipe*/,
85 "struct usbd_xfer *"/*xfer*/, 85 "struct usbd_xfer *"/*xfer*/,
86 "usbd_status"/*err*/); 86 "usbd_status"/*err*/);
87SDT_PROBE_DEFINE2(usb, device, pipe, start, 87SDT_PROBE_DEFINE2(usb, device, pipe, start,
88 "struct usbd_pipe *"/*pipe*/, 88 "struct usbd_pipe *"/*pipe*/,
89 "struct usbd_xfer *"/*xfer*/); 89 "struct usbd_xfer *"/*xfer*/);
90 90
91SDT_PROBE_DEFINE1(usb, device, pipe, close, "struct usbd_pipe *"/*pipe*/); 91SDT_PROBE_DEFINE1(usb, device, pipe, close, "struct usbd_pipe *"/*pipe*/);
92SDT_PROBE_DEFINE1(usb, device, pipe, abort__start, 92SDT_PROBE_DEFINE1(usb, device, pipe, abort__start,
93 "struct usbd_pipe *"/*pipe*/); 93 "struct usbd_pipe *"/*pipe*/);
94SDT_PROBE_DEFINE1(usb, device, pipe, abort__done, 94SDT_PROBE_DEFINE1(usb, device, pipe, abort__done,
95 "struct usbd_pipe *"/*pipe*/); 95 "struct usbd_pipe *"/*pipe*/);
96SDT_PROBE_DEFINE1(usb, device, pipe, clear__endpoint__stall, 96SDT_PROBE_DEFINE1(usb, device, pipe, clear__endpoint__stall,
97 "struct usbd_pipe *"/*pipe*/); 97 "struct usbd_pipe *"/*pipe*/);
98SDT_PROBE_DEFINE1(usb, device, pipe, clear__endpoint__toggle, 98SDT_PROBE_DEFINE1(usb, device, pipe, clear__endpoint__toggle,
99 "struct usbd_pipe *"/*pipe*/); 99 "struct usbd_pipe *"/*pipe*/);
100 100
101SDT_PROBE_DEFINE5(usb, device, xfer, create, 101SDT_PROBE_DEFINE5(usb, device, xfer, create,
102 "struct usbd_xfer *"/*xfer*/, 102 "struct usbd_xfer *"/*xfer*/,
103 "struct usbd_pipe *"/*pipe*/, 103 "struct usbd_pipe *"/*pipe*/,
104 "size_t"/*len*/, 104 "size_t"/*len*/,
105 "unsigned int"/*flags*/, 105 "unsigned int"/*flags*/,
106 "unsigned int"/*nframes*/); 106 "unsigned int"/*nframes*/);
107SDT_PROBE_DEFINE1(usb, device, xfer, start, "struct usbd_xfer *"/*xfer*/); 107SDT_PROBE_DEFINE1(usb, device, xfer, start, "struct usbd_xfer *"/*xfer*/);
108SDT_PROBE_DEFINE1(usb, device, xfer, preabort, "struct usbd_xfer *"/*xfer*/); 108SDT_PROBE_DEFINE1(usb, device, xfer, preabort, "struct usbd_xfer *"/*xfer*/);
109SDT_PROBE_DEFINE1(usb, device, xfer, abort, "struct usbd_xfer *"/*xfer*/); 109SDT_PROBE_DEFINE1(usb, device, xfer, abort, "struct usbd_xfer *"/*xfer*/);
110SDT_PROBE_DEFINE1(usb, device, xfer, timeout, "struct usbd_xfer *"/*xfer*/); 110SDT_PROBE_DEFINE1(usb, device, xfer, timeout, "struct usbd_xfer *"/*xfer*/);
111SDT_PROBE_DEFINE2(usb, device, xfer, done, 111SDT_PROBE_DEFINE2(usb, device, xfer, done,
112 "struct usbd_xfer *"/*xfer*/, 112 "struct usbd_xfer *"/*xfer*/,
113 "usbd_status"/*status*/); 113 "usbd_status"/*status*/);
114SDT_PROBE_DEFINE1(usb, device, xfer, destroy, "struct usbd_xfer *"/*xfer*/); 114SDT_PROBE_DEFINE1(usb, device, xfer, destroy, "struct usbd_xfer *"/*xfer*/);
115 115
116Static usbd_status usbd_ar_pipe(struct usbd_pipe *); 116Static void usbd_ar_pipe(struct usbd_pipe *);
117static usbd_status usb_insert_transfer(struct usbd_xfer *); 117static usbd_status usb_insert_transfer(struct usbd_xfer *);
118Static void usbd_start_next(struct usbd_pipe *); 118Static void usbd_start_next(struct usbd_pipe *);
119Static usbd_status usbd_open_pipe_ival 119Static usbd_status usbd_open_pipe_ival
120 (struct usbd_interface *, uint8_t, uint8_t, struct usbd_pipe **, int); 120 (struct usbd_interface *, uint8_t, uint8_t, struct usbd_pipe **, int);
121static void *usbd_alloc_buffer(struct usbd_xfer *, uint32_t); 121static void *usbd_alloc_buffer(struct usbd_xfer *, uint32_t);
122static void usbd_free_buffer(struct usbd_xfer *); 122static void usbd_free_buffer(struct usbd_xfer *);
123static struct usbd_xfer *usbd_alloc_xfer(struct usbd_device *, unsigned int); 123static struct usbd_xfer *usbd_alloc_xfer(struct usbd_device *, unsigned int);
124static usbd_status usbd_free_xfer(struct usbd_xfer *); 124static usbd_status usbd_free_xfer(struct usbd_xfer *);
125static void usbd_request_async_cb(struct usbd_xfer *, void *, usbd_status); 125static void usbd_request_async_cb(struct usbd_xfer *, void *, usbd_status);
126static void usbd_xfer_timeout(void *); 126static void usbd_xfer_timeout(void *);
127static void usbd_xfer_timeout_task(void *); 127static void usbd_xfer_timeout_task(void *);
128static bool usbd_xfer_probe_timeout(struct usbd_xfer *); 128static bool usbd_xfer_probe_timeout(struct usbd_xfer *);
129static void usbd_xfer_cancel_timeout_async(struct usbd_xfer *); 129static void usbd_xfer_cancel_timeout_async(struct usbd_xfer *);
130 130
131#if defined(USB_DEBUG) 131#if defined(USB_DEBUG)
132void 132void
133usbd_dump_iface(struct usbd_interface *iface) 133usbd_dump_iface(struct usbd_interface *iface)
134{ 134{
135 USBHIST_FUNC(); 135 USBHIST_FUNC();
136 USBHIST_CALLARGS(usbdebug, "iface %#jx", (uintptr_t)iface, 0, 0, 0); 136 USBHIST_CALLARGS(usbdebug, "iface %#jx", (uintptr_t)iface, 0, 0, 0);
137 137
138 if (iface == NULL) 138 if (iface == NULL)
139 return; 139 return;
140 USBHIST_LOG(usbdebug, " device = %#jx idesc = %#jx index = %jd", 140 USBHIST_LOG(usbdebug, " device = %#jx idesc = %#jx index = %jd",
141 (uintptr_t)iface->ui_dev, (uintptr_t)iface->ui_idesc, 141 (uintptr_t)iface->ui_dev, (uintptr_t)iface->ui_idesc,
142 iface->ui_index, 0); 142 iface->ui_index, 0);
143 USBHIST_LOG(usbdebug, " altindex=%jd", 143 USBHIST_LOG(usbdebug, " altindex=%jd",
144 iface->ui_altindex, 0, 0, 0); 144 iface->ui_altindex, 0, 0, 0);
145} 145}
146 146
147void 147void
148usbd_dump_device(struct usbd_device *dev) 148usbd_dump_device(struct usbd_device *dev)
149{ 149{
150 USBHIST_FUNC(); 150 USBHIST_FUNC();
151 USBHIST_CALLARGS(usbdebug, "dev = %#jx", (uintptr_t)dev, 0, 0, 0); 151 USBHIST_CALLARGS(usbdebug, "dev = %#jx", (uintptr_t)dev, 0, 0, 0);
152 152
153 if (dev == NULL) 153 if (dev == NULL)
154 return; 154 return;
155 USBHIST_LOG(usbdebug, " bus = %#jx default_pipe = %#jx", 155 USBHIST_LOG(usbdebug, " bus = %#jx default_pipe = %#jx",
156 (uintptr_t)dev->ud_bus, (uintptr_t)dev->ud_pipe0, 0, 0); 156 (uintptr_t)dev->ud_bus, (uintptr_t)dev->ud_pipe0, 0, 0);
157 USBHIST_LOG(usbdebug, " address = %jd config = %jd depth = %jd ", 157 USBHIST_LOG(usbdebug, " address = %jd config = %jd depth = %jd ",
158 dev->ud_addr, dev->ud_config, dev->ud_depth, 0); 158 dev->ud_addr, dev->ud_config, dev->ud_depth, 0);
159 USBHIST_LOG(usbdebug, " speed = %jd self_powered = %jd " 159 USBHIST_LOG(usbdebug, " speed = %jd self_powered = %jd "
160 "power = %jd langid = %jd", 160 "power = %jd langid = %jd",
161 dev->ud_speed, dev->ud_selfpowered, dev->ud_power, dev->ud_langid); 161 dev->ud_speed, dev->ud_selfpowered, dev->ud_power, dev->ud_langid);
162} 162}
163 163
164void 164void
165usbd_dump_endpoint(struct usbd_endpoint *endp) 165usbd_dump_endpoint(struct usbd_endpoint *endp)
166{ 166{
167 USBHIST_FUNC(); 167 USBHIST_FUNC();
168 USBHIST_CALLARGS(usbdebug, "endp = %#jx", (uintptr_t)endp, 0, 0, 0); 168 USBHIST_CALLARGS(usbdebug, "endp = %#jx", (uintptr_t)endp, 0, 0, 0);
169 169
170 if (endp == NULL) 170 if (endp == NULL)
171 return; 171 return;
172 USBHIST_LOG(usbdebug, " edesc = %#jx refcnt = %jd", 172 USBHIST_LOG(usbdebug, " edesc = %#jx refcnt = %jd",
173 (uintptr_t)endp->ue_edesc, endp->ue_refcnt, 0, 0); 173 (uintptr_t)endp->ue_edesc, endp->ue_refcnt, 0, 0);
174 if (endp->ue_edesc) 174 if (endp->ue_edesc)
175 USBHIST_LOG(usbdebug, " bEndpointAddress=0x%02jx", 175 USBHIST_LOG(usbdebug, " bEndpointAddress=0x%02jx",
176 endp->ue_edesc->bEndpointAddress, 0, 0, 0); 176 endp->ue_edesc->bEndpointAddress, 0, 0, 0);
177} 177}
178 178
179void 179void
180usbd_dump_queue(struct usbd_pipe *pipe) 180usbd_dump_queue(struct usbd_pipe *pipe)
181{ 181{
182 struct usbd_xfer *xfer; 182 struct usbd_xfer *xfer;
183 183
184 USBHIST_FUNC(); 184 USBHIST_FUNC();
185 USBHIST_CALLARGS(usbdebug, "pipe = %#jx", (uintptr_t)pipe, 0, 0, 0); 185 USBHIST_CALLARGS(usbdebug, "pipe = %#jx", (uintptr_t)pipe, 0, 0, 0);
186 186
187 SIMPLEQ_FOREACH(xfer, &pipe->up_queue, ux_next) { 187 SIMPLEQ_FOREACH(xfer, &pipe->up_queue, ux_next) {
188 USBHIST_LOG(usbdebug, " xfer = %#jx", (uintptr_t)xfer, 188 USBHIST_LOG(usbdebug, " xfer = %#jx", (uintptr_t)xfer,
189 0, 0, 0); 189 0, 0, 0);
190 } 190 }
191} 191}
192 192
193void 193void
194usbd_dump_pipe(struct usbd_pipe *pipe) 194usbd_dump_pipe(struct usbd_pipe *pipe)
195{ 195{
196 USBHIST_FUNC(); 196 USBHIST_FUNC();
197 USBHIST_CALLARGS(usbdebug, "pipe = %#jx", (uintptr_t)pipe, 0, 0, 0); 197 USBHIST_CALLARGS(usbdebug, "pipe = %#jx", (uintptr_t)pipe, 0, 0, 0);
198 198
199 if (pipe == NULL) 199 if (pipe == NULL)
200 return; 200 return;
201 usbd_dump_iface(pipe->up_iface); 201 usbd_dump_iface(pipe->up_iface);
202 usbd_dump_device(pipe->up_dev); 202 usbd_dump_device(pipe->up_dev);
203 usbd_dump_endpoint(pipe->up_endpoint); 203 usbd_dump_endpoint(pipe->up_endpoint);
204 USBHIST_LOG(usbdebug, "(usbd_dump_pipe)", 0, 0, 0, 0); 204 USBHIST_LOG(usbdebug, "(usbd_dump_pipe)", 0, 0, 0, 0);
205 USBHIST_LOG(usbdebug, " running = %jd aborting = %jd", 205 USBHIST_LOG(usbdebug, " running = %jd aborting = %jd",
206 pipe->up_running, pipe->up_aborting, 0, 0); 206 pipe->up_running, pipe->up_aborting, 0, 0);
207 USBHIST_LOG(usbdebug, " intrxfer = %#jx, repeat = %jd, " 207 USBHIST_LOG(usbdebug, " intrxfer = %#jx, repeat = %jd, "
208 "interval = %jd", (uintptr_t)pipe->up_intrxfer, pipe->up_repeat, 208 "interval = %jd", (uintptr_t)pipe->up_intrxfer, pipe->up_repeat,
209 pipe->up_interval, 0); 209 pipe->up_interval, 0);
210} 210}
211#endif 211#endif
212 212
213usbd_status 213usbd_status
214usbd_open_pipe(struct usbd_interface *iface, uint8_t address, 214usbd_open_pipe(struct usbd_interface *iface, uint8_t address,
215 uint8_t flags, struct usbd_pipe **pipe) 215 uint8_t flags, struct usbd_pipe **pipe)
216{ 216{
217 return (usbd_open_pipe_ival(iface, address, flags, pipe, 217 return (usbd_open_pipe_ival(iface, address, flags, pipe,
218 USBD_DEFAULT_INTERVAL)); 218 USBD_DEFAULT_INTERVAL));
219} 219}
220 220
221usbd_status 221usbd_status
222usbd_open_pipe_ival(struct usbd_interface *iface, uint8_t address, 222usbd_open_pipe_ival(struct usbd_interface *iface, uint8_t address,
223 uint8_t flags, struct usbd_pipe **pipe, int ival) 223 uint8_t flags, struct usbd_pipe **pipe, int ival)
224{ 224{
225 struct usbd_pipe *p = NULL; 225 struct usbd_pipe *p = NULL;
226 struct usbd_endpoint *ep = NULL /* XXXGCC */; 226 struct usbd_endpoint *ep = NULL /* XXXGCC */;
227 bool piperef = false; 227 bool piperef = false;
228 usbd_status err; 228 usbd_status err;
229 int i; 229 int i;
230 230
231 USBHIST_FUNC(); 231 USBHIST_FUNC();
232 USBHIST_CALLARGS(usbdebug, "iface = %#jx address = %#jx flags = %#jx", 232 USBHIST_CALLARGS(usbdebug, "iface = %#jx address = %#jx flags = %#jx",
233 (uintptr_t)iface, address, flags, 0); 233 (uintptr_t)iface, address, flags, 0);
234 234
235 /* 235 /*
236 * Block usbd_set_interface so we have a snapshot of the 236 * Block usbd_set_interface so we have a snapshot of the
237 * interface endpoints. They will remain stable until we drop 237 * interface endpoints. They will remain stable until we drop
238 * the reference in usbd_close_pipe (or on failure here). 238 * the reference in usbd_close_pipe (or on failure here).
239 */ 239 */
240 err = usbd_iface_piperef(iface); 240 err = usbd_iface_piperef(iface);
241 if (err) 241 if (err)
242 goto out; 242 goto out;
243 piperef = true; 243 piperef = true;
244 244
245 /* Find the endpoint at this address. */ 245 /* Find the endpoint at this address. */
246 for (i = 0; i < iface->ui_idesc->bNumEndpoints; i++) { 246 for (i = 0; i < iface->ui_idesc->bNumEndpoints; i++) {
247 ep = &iface->ui_endpoints[i]; 247 ep = &iface->ui_endpoints[i];
248 if (ep->ue_edesc == NULL) { 248 if (ep->ue_edesc == NULL) {
249 err = USBD_IOERROR; 249 err = USBD_IOERROR;
250 goto out; 250 goto out;
251 } 251 }
252 if (ep->ue_edesc->bEndpointAddress == address) 252 if (ep->ue_edesc->bEndpointAddress == address)
253 break; 253 break;
254 } 254 }
255 if (i == iface->ui_idesc->bNumEndpoints) { 255 if (i == iface->ui_idesc->bNumEndpoints) {
256 err = USBD_BAD_ADDRESS; 256 err = USBD_BAD_ADDRESS;
257 goto out; 257 goto out;
258 } 258 }
259 259
260 /* Set up the pipe with this endpoint. */ 260 /* Set up the pipe with this endpoint. */
261 err = usbd_setup_pipe_flags(iface->ui_dev, iface, ep, ival, &p, flags); 261 err = usbd_setup_pipe_flags(iface->ui_dev, iface, ep, ival, &p, flags);
262 if (err) 262 if (err)
263 goto out; 263 goto out;
264 264
265 /* Success! */ 265 /* Success! */
266 *pipe = p; 266 *pipe = p;
267 p = NULL; /* handed off to caller */ 267 p = NULL; /* handed off to caller */
268 piperef = false; /* handed off to pipe */ 268 piperef = false; /* handed off to pipe */
269 SDT_PROBE5(usb, device, pipe, open, 269 SDT_PROBE5(usb, device, pipe, open,
270 iface, address, flags, ival, p); 270 iface, address, flags, ival, p);
271 err = USBD_NORMAL_COMPLETION; 271 err = USBD_NORMAL_COMPLETION;
272 272
273out: if (p) 273out: if (p)
274 usbd_close_pipe(p); 274 usbd_close_pipe(p);
275 if (piperef) 275 if (piperef)
276 usbd_iface_pipeunref(iface); 276 usbd_iface_pipeunref(iface);
277 return err; 277 return err;
278} 278}
279 279
280usbd_status 280usbd_status
281usbd_open_pipe_intr(struct usbd_interface *iface, uint8_t address, 281usbd_open_pipe_intr(struct usbd_interface *iface, uint8_t address,
282 uint8_t flags, struct usbd_pipe **pipe, 282 uint8_t flags, struct usbd_pipe **pipe,
283 void *priv, void *buffer, uint32_t len, 283 void *priv, void *buffer, uint32_t len,
284 usbd_callback cb, int ival) 284 usbd_callback cb, int ival)
285{ 285{
286 usbd_status err; 286 usbd_status err;
287 struct usbd_xfer *xfer; 287 struct usbd_xfer *xfer;
288 struct usbd_pipe *ipipe; 288 struct usbd_pipe *ipipe;
289 289
290 USBHIST_FUNC(); 290 USBHIST_FUNC();
291 USBHIST_CALLARGS(usbdebug, "address = %#jx flags = %#jx len = %jd", 291 USBHIST_CALLARGS(usbdebug, "address = %#jx flags = %#jx len = %jd",
292 address, flags, len, 0); 292 address, flags, len, 0);
293 293
294 err = usbd_open_pipe_ival(iface, address, 294 err = usbd_open_pipe_ival(iface, address,
295 USBD_EXCLUSIVE_USE | (flags & USBD_MPSAFE), 295 USBD_EXCLUSIVE_USE | (flags & USBD_MPSAFE),
296 &ipipe, ival); 296 &ipipe, ival);
297 if (err) 297 if (err)
298 return err; 298 return err;
299 err = usbd_create_xfer(ipipe, len, flags, 0, &xfer); 299 err = usbd_create_xfer(ipipe, len, flags, 0, &xfer);
300 if (err) 300 if (err)
301 goto bad1; 301 goto bad1;
302 302
303 usbd_setup_xfer(xfer, priv, buffer, len, flags, USBD_NO_TIMEOUT, cb); 303 usbd_setup_xfer(xfer, priv, buffer, len, flags, USBD_NO_TIMEOUT, cb);
304 ipipe->up_intrxfer = xfer; 304 ipipe->up_intrxfer = xfer;
305 ipipe->up_repeat = 1; 305 ipipe->up_repeat = 1;
306 err = usbd_transfer(xfer); 306 err = usbd_transfer(xfer);
307 *pipe = ipipe; 307 *pipe = ipipe;
308 if (err != USBD_IN_PROGRESS) 308 if (err != USBD_IN_PROGRESS)
309 goto bad3; 309 goto bad3;
310 SDT_PROBE7(usb, device, pipe, open__intr, 310 SDT_PROBE7(usb, device, pipe, open__intr,
311 iface, address, flags, ival, cb, priv, ipipe); 311 iface, address, flags, ival, cb, priv, ipipe);
312 return USBD_NORMAL_COMPLETION; 312 return USBD_NORMAL_COMPLETION;
313 313
314 bad3: 314 bad3:
315 ipipe->up_intrxfer = NULL; 315 ipipe->up_intrxfer = NULL;
316 ipipe->up_repeat = 0; 316 ipipe->up_repeat = 0;
317 317
318 usbd_destroy_xfer(xfer); 318 usbd_destroy_xfer(xfer);
319 bad1: 319 bad1:
320 usbd_close_pipe(ipipe); 320 usbd_close_pipe(ipipe);
321 return err; 321 return err;
322} 322}
323 323
324usbd_status 324usbd_status
325usbd_close_pipe(struct usbd_pipe *pipe) 325usbd_close_pipe(struct usbd_pipe *pipe)
326{ 326{
327 USBHIST_FUNC(); USBHIST_CALLED(usbdebug); 327 USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
328 328
329 KASSERT(pipe != NULL); 329 KASSERT(pipe != NULL);
330 330
331 usbd_lock_pipe(pipe); 331 usbd_lock_pipe(pipe);
332 SDT_PROBE1(usb, device, pipe, close, pipe); 332 SDT_PROBE1(usb, device, pipe, close, pipe);
333 if (!SIMPLEQ_EMPTY(&pipe->up_queue)) { 333 if (!SIMPLEQ_EMPTY(&pipe->up_queue)) {
334 printf("WARNING: pipe closed with active xfers on addr %d\n", 334 printf("WARNING: pipe closed with active xfers on addr %d\n",
335 pipe->up_dev->ud_addr); 335 pipe->up_dev->ud_addr);
336 usbd_ar_pipe(pipe); 336 usbd_ar_pipe(pipe);
337 } 337 }
338 KASSERT(SIMPLEQ_EMPTY(&pipe->up_queue)); 338 KASSERT(SIMPLEQ_EMPTY(&pipe->up_queue));
339 pipe->up_methods->upm_close(pipe); 339 pipe->up_methods->upm_close(pipe);
340 usbd_unlock_pipe(pipe); 340 usbd_unlock_pipe(pipe);
341 341
342 cv_destroy(&pipe->up_callingcv); 342 cv_destroy(&pipe->up_callingcv);
343 if (pipe->up_intrxfer) 343 if (pipe->up_intrxfer)
344 usbd_destroy_xfer(pipe->up_intrxfer); 344 usbd_destroy_xfer(pipe->up_intrxfer);
345 usb_rem_task_wait(pipe->up_dev, &pipe->up_async_task, USB_TASKQ_DRIVER, 345 usb_rem_task_wait(pipe->up_dev, &pipe->up_async_task, USB_TASKQ_DRIVER,
346 NULL); 346 NULL);
347 usbd_endpoint_release(pipe->up_dev, pipe->up_endpoint); 347 usbd_endpoint_release(pipe->up_dev, pipe->up_endpoint);
348 if (pipe->up_iface) 348 if (pipe->up_iface)
349 usbd_iface_pipeunref(pipe->up_iface); 349 usbd_iface_pipeunref(pipe->up_iface);
350 kmem_free(pipe, pipe->up_dev->ud_bus->ub_pipesize); 350 kmem_free(pipe, pipe->up_dev->ud_bus->ub_pipesize);
351 351
352 return USBD_NORMAL_COMPLETION; 352 return USBD_NORMAL_COMPLETION;
353} 353}
354 354
355usbd_status 355usbd_status
356usbd_transfer(struct usbd_xfer *xfer) 356usbd_transfer(struct usbd_xfer *xfer)
357{ 357{
358 struct usbd_pipe *pipe = xfer->ux_pipe; 358 struct usbd_pipe *pipe = xfer->ux_pipe;
359 usbd_status err; 359 usbd_status err;
360 unsigned int size, flags; 360 unsigned int size, flags;
361 361
362 USBHIST_FUNC(); USBHIST_CALLARGS(usbdebug, 362 USBHIST_FUNC(); USBHIST_CALLARGS(usbdebug,
363 "xfer = %#jx, flags = %#jx, pipe = %#jx, running = %jd", 363 "xfer = %#jx, flags = %#jx, pipe = %#jx, running = %jd",
364 (uintptr_t)xfer, xfer->ux_flags, (uintptr_t)pipe, pipe->up_running); 364 (uintptr_t)xfer, xfer->ux_flags, (uintptr_t)pipe, pipe->up_running);
365 KASSERT(xfer->ux_status == USBD_NOT_STARTED); 365 KASSERT(xfer->ux_status == USBD_NOT_STARTED);
366 SDT_PROBE1(usb, device, xfer, start, xfer); 366 SDT_PROBE1(usb, device, xfer, start, xfer);
367 367
368#ifdef USB_DEBUG 368#ifdef USB_DEBUG
369 if (usbdebug > 5) 369 if (usbdebug > 5)
370 usbd_dump_queue(pipe); 370 usbd_dump_queue(pipe);
371#endif 371#endif
372 xfer->ux_done = 0; 372 xfer->ux_done = 0;
373 373
374 if (pipe->up_aborting) { 374 if (pipe->up_aborting) {
375 USBHIST_LOG(usbdebug, "<- done xfer %#jx, aborting", 375 USBHIST_LOG(usbdebug, "<- done xfer %#jx, aborting",
376 (uintptr_t)xfer, 0, 0, 0); 376 (uintptr_t)xfer, 0, 0, 0);
377 SDT_PROBE2(usb, device, xfer, done, xfer, USBD_CANCELLED); 377 SDT_PROBE2(usb, device, xfer, done, xfer, USBD_CANCELLED);
378 return USBD_CANCELLED; 378 return USBD_CANCELLED;
379 } 379 }
380 380
381 KASSERT(xfer->ux_length == 0 || xfer->ux_buf != NULL); 381 KASSERT(xfer->ux_length == 0 || xfer->ux_buf != NULL);
382 382
383 size = xfer->ux_length; 383 size = xfer->ux_length;
384 flags = xfer->ux_flags; 384 flags = xfer->ux_flags;
385 385
386 if (size != 0) { 386 if (size != 0) {
387 /* 387 /*
388 * Use the xfer buffer if none specified in transfer setup. 388 * Use the xfer buffer if none specified in transfer setup.
389 * isoc transfers always use the xfer buffer, i.e. 389 * isoc transfers always use the xfer buffer, i.e.
390 * ux_buffer is always NULL for isoc. 390 * ux_buffer is always NULL for isoc.
391 */ 391 */
392 if (xfer->ux_buffer == NULL) { 392 if (xfer->ux_buffer == NULL) {
393 xfer->ux_buffer = xfer->ux_buf; 393 xfer->ux_buffer = xfer->ux_buf;
394 } 394 }
395 395
396 /* 396 /*
397 * If not using the xfer buffer copy data to the 397 * If not using the xfer buffer copy data to the
398 * xfer buffer for OUT transfers of >0 length 398 * xfer buffer for OUT transfers of >0 length
399 */ 399 */
400 if (xfer->ux_buffer != xfer->ux_buf) { 400 if (xfer->ux_buffer != xfer->ux_buf) {
401 KASSERT(xfer->ux_buf); 401 KASSERT(xfer->ux_buf);
402 if (!usbd_xfer_isread(xfer)) { 402 if (!usbd_xfer_isread(xfer)) {
403 memcpy(xfer->ux_buf, xfer->ux_buffer, size); 403 memcpy(xfer->ux_buf, xfer->ux_buffer, size);
404 } 404 }
405 } 405 }
406 } 406 }
407 407
408 /* xfer is not valid after the transfer method unless synchronous */ 408 /* xfer is not valid after the transfer method unless synchronous */
409 SDT_PROBE2(usb, device, pipe, transfer__start, pipe, xfer); 409 SDT_PROBE2(usb, device, pipe, transfer__start, pipe, xfer);
410 do { 410 do {
411 usbd_lock_pipe(pipe); 411 usbd_lock_pipe(pipe);
412 err = usb_insert_transfer(xfer); 412 err = usb_insert_transfer(xfer);
413 usbd_unlock_pipe(pipe); 413 usbd_unlock_pipe(pipe);
414 if (err) 414 if (err)
415 break; 415 break;
416 err = pipe->up_methods->upm_transfer(xfer); 416 err = pipe->up_methods->upm_transfer(xfer);
417 } while (0); 417 } while (0);
418 SDT_PROBE3(usb, device, pipe, transfer__done, pipe, xfer, err); 418 SDT_PROBE3(usb, device, pipe, transfer__done, pipe, xfer, err);
419 419
420 if (err != USBD_IN_PROGRESS && err) { 420 if (err != USBD_IN_PROGRESS && err) {
421 /* 421 /*
422 * The transfer made it onto the pipe queue, but didn't get 422 * The transfer made it onto the pipe queue, but didn't get
423 * accepted by the HCD for some reason. It needs removing 423 * accepted by the HCD for some reason. It needs removing
424 * from the pipe queue. 424 * from the pipe queue.
425 */ 425 */
426 USBHIST_LOG(usbdebug, "xfer failed: %jd, reinserting", 426 USBHIST_LOG(usbdebug, "xfer failed: %jd, reinserting",
427 err, 0, 0, 0); 427 err, 0, 0, 0);
428 usbd_lock_pipe(pipe); 428 usbd_lock_pipe(pipe);
429 SDT_PROBE1(usb, device, xfer, preabort, xfer); 429 SDT_PROBE1(usb, device, xfer, preabort, xfer);
430#ifdef DIAGNOSTIC 430#ifdef DIAGNOSTIC
431 xfer->ux_state = XFER_BUSY; 431 xfer->ux_state = XFER_BUSY;
432#endif 432#endif
433 SIMPLEQ_REMOVE_HEAD(&pipe->up_queue, ux_next); 433 SIMPLEQ_REMOVE_HEAD(&pipe->up_queue, ux_next);
434 if (pipe->up_serialise) 434 if (pipe->up_serialise)
435 usbd_start_next(pipe); 435 usbd_start_next(pipe);
436 usbd_unlock_pipe(pipe); 436 usbd_unlock_pipe(pipe);
437 } 437 }
438 438
439 if (!(flags & USBD_SYNCHRONOUS)) { 439 if (!(flags & USBD_SYNCHRONOUS)) {
440 USBHIST_LOG(usbdebug, "<- done xfer %#jx, not sync (err %jd)", 440 USBHIST_LOG(usbdebug, "<- done xfer %#jx, not sync (err %jd)",
441 (uintptr_t)xfer, err, 0, 0); 441 (uintptr_t)xfer, err, 0, 0);
442 if (err != USBD_IN_PROGRESS) /* XXX Possible? */ 442 if (err != USBD_IN_PROGRESS) /* XXX Possible? */
443 SDT_PROBE2(usb, device, xfer, done, xfer, err); 443 SDT_PROBE2(usb, device, xfer, done, xfer, err);
444 return err; 444 return err;
445 } 445 }
446 446
447 if (err != USBD_IN_PROGRESS) { 447 if (err != USBD_IN_PROGRESS) {
448 USBHIST_LOG(usbdebug, "<- done xfer %#jx, sync (err %jd)", 448 USBHIST_LOG(usbdebug, "<- done xfer %#jx, sync (err %jd)",
449 (uintptr_t)xfer, err, 0, 0); 449 (uintptr_t)xfer, err, 0, 0);
450 SDT_PROBE2(usb, device, xfer, done, xfer, err); 450 SDT_PROBE2(usb, device, xfer, done, xfer, err);
451 return err; 451 return err;
452 } 452 }
453 453
454 /* Sync transfer, wait for completion. */ 454 /* Sync transfer, wait for completion. */
455 usbd_lock_pipe(pipe); 455 usbd_lock_pipe(pipe);
456 while (!xfer->ux_done) { 456 while (!xfer->ux_done) {
457 if (pipe->up_dev->ud_bus->ub_usepolling) 457 if (pipe->up_dev->ud_bus->ub_usepolling)
458 panic("usbd_transfer: not done"); 458 panic("usbd_transfer: not done");
459 USBHIST_LOG(usbdebug, "<- sleeping on xfer %#jx", 459 USBHIST_LOG(usbdebug, "<- sleeping on xfer %#jx",
460 (uintptr_t)xfer, 0, 0, 0); 460 (uintptr_t)xfer, 0, 0, 0);
461 461
462 err = 0; 462 err = 0;
463 if ((flags & USBD_SYNCHRONOUS_SIG) != 0) { 463 if ((flags & USBD_SYNCHRONOUS_SIG) != 0) {
464 err = cv_wait_sig(&xfer->ux_cv, pipe->up_dev->ud_bus->ub_lock); 464 err = cv_wait_sig(&xfer->ux_cv, pipe->up_dev->ud_bus->ub_lock);
465 } else { 465 } else {
466 cv_wait(&xfer->ux_cv, pipe->up_dev->ud_bus->ub_lock); 466 cv_wait(&xfer->ux_cv, pipe->up_dev->ud_bus->ub_lock);
467 } 467 }
468 if (err) { 468 if (err) {
469 if (!xfer->ux_done) { 469 if (!xfer->ux_done) {
470 SDT_PROBE1(usb, device, xfer, abort, xfer); 470 SDT_PROBE1(usb, device, xfer, abort, xfer);
471 pipe->up_methods->upm_abort(xfer); 471 pipe->up_methods->upm_abort(xfer);
472 } 472 }
473 break; 473 break;
474 } 474 }
475 } 475 }
476 SDT_PROBE2(usb, device, xfer, done, xfer, xfer->ux_status); 476 SDT_PROBE2(usb, device, xfer, done, xfer, xfer->ux_status);
477 /* XXX Race to read xfer->ux_status? */ 477 /* XXX Race to read xfer->ux_status? */
478 usbd_unlock_pipe(pipe); 478 usbd_unlock_pipe(pipe);
479 return xfer->ux_status; 479 return xfer->ux_status;
480} 480}
481 481
482/* Like usbd_transfer(), but waits for completion. */ 482/* Like usbd_transfer(), but waits for completion. */
483usbd_status 483usbd_status
484usbd_sync_transfer(struct usbd_xfer *xfer) 484usbd_sync_transfer(struct usbd_xfer *xfer)
485{ 485{
486 xfer->ux_flags |= USBD_SYNCHRONOUS; 486 xfer->ux_flags |= USBD_SYNCHRONOUS;
487 return usbd_transfer(xfer); 487 return usbd_transfer(xfer);
488} 488}
489 489
490/* Like usbd_transfer(), but waits for completion and listens for signals. */ 490/* Like usbd_transfer(), but waits for completion and listens for signals. */
491usbd_status 491usbd_status
492usbd_sync_transfer_sig(struct usbd_xfer *xfer) 492usbd_sync_transfer_sig(struct usbd_xfer *xfer)
493{ 493{
494 xfer->ux_flags |= USBD_SYNCHRONOUS | USBD_SYNCHRONOUS_SIG; 494 xfer->ux_flags |= USBD_SYNCHRONOUS | USBD_SYNCHRONOUS_SIG;
495 return usbd_transfer(xfer); 495 return usbd_transfer(xfer);
496} 496}
497 497
498static void * 498static void *
499usbd_alloc_buffer(struct usbd_xfer *xfer, uint32_t size) 499usbd_alloc_buffer(struct usbd_xfer *xfer, uint32_t size)
500{ 500{
501 KASSERT(xfer->ux_buf == NULL); 501 KASSERT(xfer->ux_buf == NULL);
502 KASSERT(size != 0); 502 KASSERT(size != 0);
503 503
504 xfer->ux_bufsize = 0; 504 xfer->ux_bufsize = 0;
505#if NUSB_DMA > 0 505#if NUSB_DMA > 0
506 struct usbd_bus *bus = xfer->ux_bus; 506 struct usbd_bus *bus = xfer->ux_bus;
507 507
508 if (bus->ub_usedma) { 508 if (bus->ub_usedma) {
509 usb_dma_t *dmap = &xfer->ux_dmabuf; 509 usb_dma_t *dmap = &xfer->ux_dmabuf;
510 510
511 KASSERT((bus->ub_dmaflags & USBMALLOC_COHERENT) == 0); 511 KASSERT((bus->ub_dmaflags & USBMALLOC_COHERENT) == 0);
512 int err = usb_allocmem(bus->ub_dmatag, size, 0, bus->ub_dmaflags, dmap); 512 int err = usb_allocmem(bus->ub_dmatag, size, 0, bus->ub_dmaflags, dmap);
513 if (err) { 513 if (err) {
514 return NULL; 514 return NULL;
515 } 515 }
516 xfer->ux_buf = KERNADDR(&xfer->ux_dmabuf, 0); 516 xfer->ux_buf = KERNADDR(&xfer->ux_dmabuf, 0);
517 xfer->ux_bufsize = size; 517 xfer->ux_bufsize = size;
518 518
519 return xfer->ux_buf; 519 return xfer->ux_buf;
520 } 520 }
521#endif 521#endif
522 KASSERT(xfer->ux_bus->ub_usedma == false); 522 KASSERT(xfer->ux_bus->ub_usedma == false);
523 xfer->ux_buf = kmem_alloc(size, KM_SLEEP); 523 xfer->ux_buf = kmem_alloc(size, KM_SLEEP);
524 xfer->ux_bufsize = size; 524 xfer->ux_bufsize = size;
525 return xfer->ux_buf; 525 return xfer->ux_buf;
526} 526}
527 527
528static void 528static void
529usbd_free_buffer(struct usbd_xfer *xfer) 529usbd_free_buffer(struct usbd_xfer *xfer)
530{ 530{
531 KASSERT(xfer->ux_buf != NULL); 531 KASSERT(xfer->ux_buf != NULL);
532 KASSERT(xfer->ux_bufsize != 0); 532 KASSERT(xfer->ux_bufsize != 0);
533 533
534 void *buf = xfer->ux_buf; 534 void *buf = xfer->ux_buf;
535 uint32_t size = xfer->ux_bufsize; 535 uint32_t size = xfer->ux_bufsize;
536 536
537 xfer->ux_buf = NULL; 537 xfer->ux_buf = NULL;
538 xfer->ux_bufsize = 0; 538 xfer->ux_bufsize = 0;
539 539
540#if NUSB_DMA > 0 540#if NUSB_DMA > 0
541 struct usbd_bus *bus = xfer->ux_bus; 541 struct usbd_bus *bus = xfer->ux_bus;
542 542
543 if (bus->ub_usedma) { 543 if (bus->ub_usedma) {
544 usb_dma_t *dmap = &xfer->ux_dmabuf; 544 usb_dma_t *dmap = &xfer->ux_dmabuf;
545 545
546 usb_freemem(dmap); 546 usb_freemem(dmap);
547 return; 547 return;
548 } 548 }
549#endif 549#endif
550 KASSERT(xfer->ux_bus->ub_usedma == false); 550 KASSERT(xfer->ux_bus->ub_usedma == false);
551 551
552 kmem_free(buf, size); 552 kmem_free(buf, size);
553} 553}
554 554
555void * 555void *
556usbd_get_buffer(struct usbd_xfer *xfer) 556usbd_get_buffer(struct usbd_xfer *xfer)
557{ 557{
558 return xfer->ux_buf; 558 return xfer->ux_buf;
559} 559}
560 560
561struct usbd_pipe * 561struct usbd_pipe *
562usbd_get_pipe0(struct usbd_device *dev) 562usbd_get_pipe0(struct usbd_device *dev)
563{ 563{
564 564
565 return dev->ud_pipe0; 565 return dev->ud_pipe0;
566} 566}
567 567
568static struct usbd_xfer * 568static struct usbd_xfer *
569usbd_alloc_xfer(struct usbd_device *dev, unsigned int nframes) 569usbd_alloc_xfer(struct usbd_device *dev, unsigned int nframes)
570{ 570{
571 struct usbd_xfer *xfer; 571 struct usbd_xfer *xfer;
572 572
573 USBHIST_FUNC(); 573 USBHIST_FUNC();
574 574
575 ASSERT_SLEEPABLE(); 575 ASSERT_SLEEPABLE();
576 576
577 xfer = dev->ud_bus->ub_methods->ubm_allocx(dev->ud_bus, nframes); 577 xfer = dev->ud_bus->ub_methods->ubm_allocx(dev->ud_bus, nframes);
578 if (xfer == NULL) 578 if (xfer == NULL)
579 goto out; 579 goto out;
580 xfer->ux_bus = dev->ud_bus; 580 xfer->ux_bus = dev->ud_bus;
581 callout_init(&xfer->ux_callout, CALLOUT_MPSAFE); 581 callout_init(&xfer->ux_callout, CALLOUT_MPSAFE);
582 callout_setfunc(&xfer->ux_callout, usbd_xfer_timeout, xfer); 582 callout_setfunc(&xfer->ux_callout, usbd_xfer_timeout, xfer);
583 cv_init(&xfer->ux_cv, "usbxfer"); 583 cv_init(&xfer->ux_cv, "usbxfer");
584 usb_init_task(&xfer->ux_aborttask, usbd_xfer_timeout_task, xfer, 584 usb_init_task(&xfer->ux_aborttask, usbd_xfer_timeout_task, xfer,
585 USB_TASKQ_MPSAFE); 585 USB_TASKQ_MPSAFE);
586 586
587out: 587out:
588 USBHIST_CALLARGS(usbdebug, "returns %#jx", (uintptr_t)xfer, 0, 0, 0); 588 USBHIST_CALLARGS(usbdebug, "returns %#jx", (uintptr_t)xfer, 0, 0, 0);
589 589
590 return xfer; 590 return xfer;
591} 591}
592 592
593static usbd_status 593static usbd_status
594usbd_free_xfer(struct usbd_xfer *xfer) 594usbd_free_xfer(struct usbd_xfer *xfer)
595{ 595{
596 USBHIST_FUNC(); 596 USBHIST_FUNC();
597 USBHIST_CALLARGS(usbdebug, "%#jx", (uintptr_t)xfer, 0, 0, 0); 597 USBHIST_CALLARGS(usbdebug, "%#jx", (uintptr_t)xfer, 0, 0, 0);
598 598
599 if (xfer->ux_buf) { 599 if (xfer->ux_buf) {
600 usbd_free_buffer(xfer); 600 usbd_free_buffer(xfer);
601 } 601 }
602 602
603 /* Wait for any straggling timeout to complete. */ 603 /* Wait for any straggling timeout to complete. */
604 mutex_enter(xfer->ux_bus->ub_lock); 604 mutex_enter(xfer->ux_bus->ub_lock);
605 xfer->ux_timeout_reset = false; /* do not resuscitate */ 605 xfer->ux_timeout_reset = false; /* do not resuscitate */
606 callout_halt(&xfer->ux_callout, xfer->ux_bus->ub_lock); 606 callout_halt(&xfer->ux_callout, xfer->ux_bus->ub_lock);
607 usb_rem_task_wait(xfer->ux_pipe->up_dev, &xfer->ux_aborttask, 607 usb_rem_task_wait(xfer->ux_pipe->up_dev, &xfer->ux_aborttask,
608 USB_TASKQ_HC, xfer->ux_bus->ub_lock); 608 USB_TASKQ_HC, xfer->ux_bus->ub_lock);
609 mutex_exit(xfer->ux_bus->ub_lock); 609 mutex_exit(xfer->ux_bus->ub_lock);
610 610
611 cv_destroy(&xfer->ux_cv); 611 cv_destroy(&xfer->ux_cv);
612 xfer->ux_bus->ub_methods->ubm_freex(xfer->ux_bus, xfer); 612 xfer->ux_bus->ub_methods->ubm_freex(xfer->ux_bus, xfer);
613 return USBD_NORMAL_COMPLETION; 613 return USBD_NORMAL_COMPLETION;
614} 614}
615 615
616int 616int
617usbd_create_xfer(struct usbd_pipe *pipe, size_t len, unsigned int flags, 617usbd_create_xfer(struct usbd_pipe *pipe, size_t len, unsigned int flags,
618 unsigned int nframes, struct usbd_xfer **xp) 618 unsigned int nframes, struct usbd_xfer **xp)
619{ 619{
620 KASSERT(xp != NULL); 620 KASSERT(xp != NULL);
621 void *buf = NULL; 621 void *buf = NULL;
622 622
623 struct usbd_xfer *xfer = usbd_alloc_xfer(pipe->up_dev, nframes); 623 struct usbd_xfer *xfer = usbd_alloc_xfer(pipe->up_dev, nframes);
624 if (xfer == NULL) 624 if (xfer == NULL)
625 return ENOMEM; 625 return ENOMEM;
626 626
627 xfer->ux_pipe = pipe; 627 xfer->ux_pipe = pipe;
628 xfer->ux_flags = flags; 628 xfer->ux_flags = flags;
629 xfer->ux_nframes = nframes; 629 xfer->ux_nframes = nframes;
630 xfer->ux_methods = pipe->up_methods; 630 xfer->ux_methods = pipe->up_methods;
631 631
632 if (len) { 632 if (len) {
633 buf = usbd_alloc_buffer(xfer, len); 633 buf = usbd_alloc_buffer(xfer, len);
634 if (!buf) { 634 if (!buf) {
635 usbd_free_xfer(xfer); 635 usbd_free_xfer(xfer);
636 return ENOMEM; 636 return ENOMEM;
637 } 637 }
638 } 638 }
639 639
640 if (xfer->ux_methods->upm_init) { 640 if (xfer->ux_methods->upm_init) {
641 int err = xfer->ux_methods->upm_init(xfer); 641 int err = xfer->ux_methods->upm_init(xfer);
642 if (err) { 642 if (err) {
643 usbd_free_xfer(xfer); 643 usbd_free_xfer(xfer);
644 return err; 644 return err;
645 } 645 }
646 } 646 }
647 647
648 *xp = xfer; 648 *xp = xfer;
649 SDT_PROBE5(usb, device, xfer, create, 649 SDT_PROBE5(usb, device, xfer, create,
650 xfer, pipe, len, flags, nframes); 650 xfer, pipe, len, flags, nframes);
651 return 0; 651 return 0;
652} 652}
653 653
654void 654void
655usbd_destroy_xfer(struct usbd_xfer *xfer) 655usbd_destroy_xfer(struct usbd_xfer *xfer)
656{ 656{
657 657
658 SDT_PROBE1(usb, device, xfer, destroy, xfer); 658 SDT_PROBE1(usb, device, xfer, destroy, xfer);
659 if (xfer->ux_methods->upm_fini) 659 if (xfer->ux_methods->upm_fini)
660 xfer->ux_methods->upm_fini(xfer); 660 xfer->ux_methods->upm_fini(xfer);
661 661
662 usbd_free_xfer(xfer); 662 usbd_free_xfer(xfer);
663} 663}
664 664
665void 665void
666usbd_setup_xfer(struct usbd_xfer *xfer, void *priv, void *buffer, 666usbd_setup_xfer(struct usbd_xfer *xfer, void *priv, void *buffer,
667 uint32_t length, uint16_t flags, uint32_t timeout, usbd_callback callback) 667 uint32_t length, uint16_t flags, uint32_t timeout, usbd_callback callback)
668{ 668{
669 KASSERT(xfer->ux_pipe); 669 KASSERT(xfer->ux_pipe);
670 670
671 xfer->ux_priv = priv; 671 xfer->ux_priv = priv;
672 xfer->ux_buffer = buffer; 672 xfer->ux_buffer = buffer;
673 xfer->ux_length = length; 673 xfer->ux_length = length;
674 xfer->ux_actlen = 0; 674 xfer->ux_actlen = 0;
675 xfer->ux_flags = flags; 675 xfer->ux_flags = flags;
676 xfer->ux_timeout = timeout; 676 xfer->ux_timeout = timeout;
677 xfer->ux_status = USBD_NOT_STARTED; 677 xfer->ux_status = USBD_NOT_STARTED;
678 xfer->ux_callback = callback; 678 xfer->ux_callback = callback;
679 xfer->ux_rqflags &= ~URQ_REQUEST; 679 xfer->ux_rqflags &= ~URQ_REQUEST;
680 xfer->ux_nframes = 0; 680 xfer->ux_nframes = 0;
681} 681}
682 682
683void 683void
684usbd_setup_default_xfer(struct usbd_xfer *xfer, struct usbd_device *dev, 684usbd_setup_default_xfer(struct usbd_xfer *xfer, struct usbd_device *dev,
685 void *priv, uint32_t timeout, usb_device_request_t *req, void *buffer, 685 void *priv, uint32_t timeout, usb_device_request_t *req, void *buffer,
686 uint32_t length, uint16_t flags, usbd_callback callback) 686 uint32_t length, uint16_t flags, usbd_callback callback)
687{ 687{
688 KASSERT(xfer->ux_pipe == dev->ud_pipe0); 688 KASSERT(xfer->ux_pipe == dev->ud_pipe0);
689 689
690 xfer->ux_priv = priv; 690 xfer->ux_priv = priv;
691 xfer->ux_buffer = buffer; 691 xfer->ux_buffer = buffer;
692 xfer->ux_length = length; 692 xfer->ux_length = length;
693 xfer->ux_actlen = 0; 693 xfer->ux_actlen = 0;
694 xfer->ux_flags = flags; 694 xfer->ux_flags = flags;
695 xfer->ux_timeout = timeout; 695 xfer->ux_timeout = timeout;
696 xfer->ux_status = USBD_NOT_STARTED; 696 xfer->ux_status = USBD_NOT_STARTED;
697 xfer->ux_callback = callback; 697 xfer->ux_callback = callback;
698 xfer->ux_request = *req; 698 xfer->ux_request = *req;
699 xfer->ux_rqflags |= URQ_REQUEST; 699 xfer->ux_rqflags |= URQ_REQUEST;
700 xfer->ux_nframes = 0; 700 xfer->ux_nframes = 0;
701} 701}
702 702
703void 703void
704usbd_setup_isoc_xfer(struct usbd_xfer *xfer, void *priv, uint16_t *frlengths, 704usbd_setup_isoc_xfer(struct usbd_xfer *xfer, void *priv, uint16_t *frlengths,
705 uint32_t nframes, uint16_t flags, usbd_callback callback) 705 uint32_t nframes, uint16_t flags, usbd_callback callback)
706{ 706{
707 xfer->ux_priv = priv; 707 xfer->ux_priv = priv;
708 xfer->ux_buffer = NULL; 708 xfer->ux_buffer = NULL;
709 xfer->ux_length = 0; 709 xfer->ux_length = 0;
710 xfer->ux_actlen = 0; 710 xfer->ux_actlen = 0;
711 xfer->ux_flags = flags; 711 xfer->ux_flags = flags;
712 xfer->ux_timeout = USBD_NO_TIMEOUT; 712 xfer->ux_timeout = USBD_NO_TIMEOUT;
713 xfer->ux_status = USBD_NOT_STARTED; 713 xfer->ux_status = USBD_NOT_STARTED;
714 xfer->ux_callback = callback; 714 xfer->ux_callback = callback;
715 xfer->ux_rqflags &= ~URQ_REQUEST; 715 xfer->ux_rqflags &= ~URQ_REQUEST;
716 xfer->ux_frlengths = frlengths; 716 xfer->ux_frlengths = frlengths;
717 xfer->ux_nframes = nframes; 717 xfer->ux_nframes = nframes;
718 718
719 for (size_t i = 0; i < xfer->ux_nframes; i++) 719 for (size_t i = 0; i < xfer->ux_nframes; i++)
720 xfer->ux_length += xfer->ux_frlengths[i]; 720 xfer->ux_length += xfer->ux_frlengths[i];
721} 721}
722 722
723void 723void
724usbd_get_xfer_status(struct usbd_xfer *xfer, void **priv, 724usbd_get_xfer_status(struct usbd_xfer *xfer, void **priv,
725 void **buffer, uint32_t *count, usbd_status *status) 725 void **buffer, uint32_t *count, usbd_status *status)
726{ 726{
727 if (priv != NULL) 727 if (priv != NULL)
728 *priv = xfer->ux_priv; 728 *priv = xfer->ux_priv;
729 if (buffer != NULL) 729 if (buffer != NULL)
730 *buffer = xfer->ux_buffer; 730 *buffer = xfer->ux_buffer;
731 if (count != NULL) 731 if (count != NULL)
732 *count = xfer->ux_actlen; 732 *count = xfer->ux_actlen;
733 if (status != NULL) 733 if (status != NULL)
734 *status = xfer->ux_status; 734 *status = xfer->ux_status;
735} 735}
736 736
737usb_config_descriptor_t * 737usb_config_descriptor_t *
738usbd_get_config_descriptor(struct usbd_device *dev) 738usbd_get_config_descriptor(struct usbd_device *dev)
739{ 739{
740 KASSERT(dev != NULL); 740 KASSERT(dev != NULL);
741 741
742 return dev->ud_cdesc; 742 return dev->ud_cdesc;
743} 743}
744 744
745usb_interface_descriptor_t * 745usb_interface_descriptor_t *
746usbd_get_interface_descriptor(struct usbd_interface *iface) 746usbd_get_interface_descriptor(struct usbd_interface *iface)
747{ 747{
748 KASSERT(iface != NULL); 748 KASSERT(iface != NULL);
749 749
750 return iface->ui_idesc; 750 return iface->ui_idesc;
751} 751}
752 752
753usb_device_descriptor_t * 753usb_device_descriptor_t *
754usbd_get_device_descriptor(struct usbd_device *dev) 754usbd_get_device_descriptor(struct usbd_device *dev)
755{ 755{
756 KASSERT(dev != NULL); 756 KASSERT(dev != NULL);
757 757
758 return &dev->ud_ddesc; 758 return &dev->ud_ddesc;
759} 759}
760 760
761usb_endpoint_descriptor_t * 761usb_endpoint_descriptor_t *
762usbd_interface2endpoint_descriptor(struct usbd_interface *iface, uint8_t index) 762usbd_interface2endpoint_descriptor(struct usbd_interface *iface, uint8_t index)
763{ 763{
764 764
765 if (index >= iface->ui_idesc->bNumEndpoints) 765 if (index >= iface->ui_idesc->bNumEndpoints)
766 return NULL; 766 return NULL;
767 return iface->ui_endpoints[index].ue_edesc; 767 return iface->ui_endpoints[index].ue_edesc;
768} 768}
769 769
770/* Some drivers may wish to abort requests on the default pipe, * 770/* Some drivers may wish to abort requests on the default pipe, *
771 * but there is no mechanism for getting a handle on it. */ 771 * but there is no mechanism for getting a handle on it. */
772usbd_status 772void
773usbd_abort_default_pipe(struct usbd_device *device) 773usbd_abort_default_pipe(struct usbd_device *device)
774{ 774{
775 return usbd_abort_pipe(device->ud_pipe0); 775 usbd_abort_pipe(device->ud_pipe0);
776} 776}
777 777
778usbd_status 778void
779usbd_abort_pipe(struct usbd_pipe *pipe) 779usbd_abort_pipe(struct usbd_pipe *pipe)
780{ 780{
781 usbd_status err; 
782 781
783 KASSERT(pipe != NULL); 782 KASSERT(pipe != NULL);
784 783
785 usbd_lock_pipe(pipe); 784 usbd_lock_pipe(pipe);
786 err = usbd_ar_pipe(pipe); 785 usbd_ar_pipe(pipe);
787 usbd_unlock_pipe(pipe); 786 usbd_unlock_pipe(pipe);
788 return err; 
789} 787}
790 788
791usbd_status 789usbd_status
792usbd_clear_endpoint_stall(struct usbd_pipe *pipe) 790usbd_clear_endpoint_stall(struct usbd_pipe *pipe)
793{ 791{
794 struct usbd_device *dev = pipe->up_dev; 792 struct usbd_device *dev = pipe->up_dev;
795 usbd_status err; 793 usbd_status err;
796 794
797 USBHIST_FUNC(); USBHIST_CALLED(usbdebug); 795 USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
798 SDT_PROBE1(usb, device, pipe, clear__endpoint__stall, pipe); 796 SDT_PROBE1(usb, device, pipe, clear__endpoint__stall, pipe);
799 797
800 /* 798 /*
801 * Clearing en endpoint stall resets the endpoint toggle, so 799 * Clearing en endpoint stall resets the endpoint toggle, so
802 * do the same to the HC toggle. 800 * do the same to the HC toggle.
803 */ 801 */
804 SDT_PROBE1(usb, device, pipe, clear__endpoint__toggle, pipe); 802 SDT_PROBE1(usb, device, pipe, clear__endpoint__toggle, pipe);
805 pipe->up_methods->upm_cleartoggle(pipe); 803 pipe->up_methods->upm_cleartoggle(pipe);
806 804
807 err = usbd_clear_endpoint_feature(dev, 805 err = usbd_clear_endpoint_feature(dev,
808 pipe->up_endpoint->ue_edesc->bEndpointAddress, UF_ENDPOINT_HALT); 806 pipe->up_endpoint->ue_edesc->bEndpointAddress, UF_ENDPOINT_HALT);
809#if 0 807#if 0
810XXX should we do this? 808XXX should we do this?
811 if (!err) { 809 if (!err) {
812 pipe->state = USBD_PIPE_ACTIVE; 810 pipe->state = USBD_PIPE_ACTIVE;
813 /* XXX activate pipe */ 811 /* XXX activate pipe */
814 } 812 }
815#endif 813#endif
816 return err; 814 return err;
817} 815}
818 816
819void 817void
820usbd_clear_endpoint_stall_task(void *arg) 818usbd_clear_endpoint_stall_task(void *arg)
821{ 819{
822 struct usbd_pipe *pipe = arg; 820 struct usbd_pipe *pipe = arg;
823 struct usbd_device *dev = pipe->up_dev; 821 struct usbd_device *dev = pipe->up_dev;
824 822
825 SDT_PROBE1(usb, device, pipe, clear__endpoint__stall, pipe); 823 SDT_PROBE1(usb, device, pipe, clear__endpoint__stall, pipe);
826 SDT_PROBE1(usb, device, pipe, clear__endpoint__toggle, pipe); 824 SDT_PROBE1(usb, device, pipe, clear__endpoint__toggle, pipe);
827 pipe->up_methods->upm_cleartoggle(pipe); 825 pipe->up_methods->upm_cleartoggle(pipe);
828 826
829 (void)usbd_clear_endpoint_feature(dev, 827 (void)usbd_clear_endpoint_feature(dev,
830 pipe->up_endpoint->ue_edesc->bEndpointAddress, UF_ENDPOINT_HALT); 828 pipe->up_endpoint->ue_edesc->bEndpointAddress, UF_ENDPOINT_HALT);
831} 829}
832 830
833void 831void
834usbd_clear_endpoint_stall_async(struct usbd_pipe *pipe) 832usbd_clear_endpoint_stall_async(struct usbd_pipe *pipe)
835{ 833{
836 usb_add_task(pipe->up_dev, &pipe->up_async_task, USB_TASKQ_DRIVER); 834 usb_add_task(pipe->up_dev, &pipe->up_async_task, USB_TASKQ_DRIVER);
837} 835}
838 836
839void 837void
840usbd_clear_endpoint_toggle(struct usbd_pipe *pipe) 838usbd_clear_endpoint_toggle(struct usbd_pipe *pipe)
841{ 839{
842 840
843 SDT_PROBE1(usb, device, pipe, clear__endpoint__toggle, pipe); 841 SDT_PROBE1(usb, device, pipe, clear__endpoint__toggle, pipe);
844 pipe->up_methods->upm_cleartoggle(pipe); 842 pipe->up_methods->upm_cleartoggle(pipe);
845} 843}
846 844
847usbd_status 845usbd_status
848usbd_endpoint_count(struct usbd_interface *iface, uint8_t *count) 846usbd_endpoint_count(struct usbd_interface *iface, uint8_t *count)
849{ 847{
850 KASSERT(iface != NULL); 848 KASSERT(iface != NULL);
851 KASSERT(iface->ui_idesc != NULL); 849 KASSERT(iface->ui_idesc != NULL);
852 850
853 *count = iface->ui_idesc->bNumEndpoints; 851 *count = iface->ui_idesc->bNumEndpoints;
854 return USBD_NORMAL_COMPLETION; 852 return USBD_NORMAL_COMPLETION;
855} 853}
856 854
857usbd_status 855usbd_status
858usbd_interface_count(struct usbd_device *dev, uint8_t *count) 856usbd_interface_count(struct usbd_device *dev, uint8_t *count)
859{ 857{
860 858
861 if (dev->ud_cdesc == NULL) 859 if (dev->ud_cdesc == NULL)
862 return USBD_NOT_CONFIGURED; 860 return USBD_NOT_CONFIGURED;
863 *count = dev->ud_cdesc->bNumInterface; 861 *count = dev->ud_cdesc->bNumInterface;
864 return USBD_NORMAL_COMPLETION; 862 return USBD_NORMAL_COMPLETION;
865} 863}
866 864
867void 865void
868usbd_interface2device_handle(struct usbd_interface *iface, 866usbd_interface2device_handle(struct usbd_interface *iface,
869 struct usbd_device **dev) 867 struct usbd_device **dev)
870{ 868{
871 869
872 *dev = iface->ui_dev; 870 *dev = iface->ui_dev;
873} 871}
874 872
875usbd_status 873usbd_status
876usbd_device2interface_handle(struct usbd_device *dev, 874usbd_device2interface_handle(struct usbd_device *dev,
877 uint8_t ifaceno, struct usbd_interface **iface) 875 uint8_t ifaceno, struct usbd_interface **iface)
878{ 876{
879 877
880 if (dev->ud_cdesc == NULL) 878 if (dev->ud_cdesc == NULL)
881 return USBD_NOT_CONFIGURED; 879 return USBD_NOT_CONFIGURED;
882 if (ifaceno >= dev->ud_cdesc->bNumInterface) 880 if (ifaceno >= dev->ud_cdesc->bNumInterface)
883 return USBD_INVAL; 881 return USBD_INVAL;
884 *iface = &dev->ud_ifaces[ifaceno]; 882 *iface = &dev->ud_ifaces[ifaceno];
885 return USBD_NORMAL_COMPLETION; 883 return USBD_NORMAL_COMPLETION;
886} 884}
887 885
888struct usbd_device * 886struct usbd_device *
889usbd_pipe2device_handle(struct usbd_pipe *pipe) 887usbd_pipe2device_handle(struct usbd_pipe *pipe)
890{ 888{
891 KASSERT(pipe != NULL); 889 KASSERT(pipe != NULL);
892 890
893 return pipe->up_dev; 891 return pipe->up_dev;
894} 892}
895 893
896/* XXXX use altno */ 894/* XXXX use altno */
897usbd_status 895usbd_status
898usbd_set_interface(struct usbd_interface *iface, int altidx) 896usbd_set_interface(struct usbd_interface *iface, int altidx)
899{ 897{
900 bool locked = false; 898 bool locked = false;
901 usb_device_request_t req; 899 usb_device_request_t req;
902 usbd_status err; 900 usbd_status err;
903 901
904 USBHIST_FUNC(); 902 USBHIST_FUNC();
905 USBHIST_CALLARGS(usbdebug, "iface %#jx", (uintptr_t)iface, 0, 0, 0); 903 USBHIST_CALLARGS(usbdebug, "iface %#jx", (uintptr_t)iface, 0, 0, 0);
906 904
907 err = usbd_iface_lock(iface); 905 err = usbd_iface_lock(iface);
908 if (err) 906 if (err)
909 goto out; 907 goto out;
910 locked = true; 908 locked = true;
911 909
912 err = usbd_fill_iface_data(iface->ui_dev, iface->ui_index, altidx); 910 err = usbd_fill_iface_data(iface->ui_dev, iface->ui_index, altidx);
913 if (err) 911 if (err)
914 goto out; 912 goto out;
915 913
916 req.bmRequestType = UT_WRITE_INTERFACE; 914 req.bmRequestType = UT_WRITE_INTERFACE;
917 req.bRequest = UR_SET_INTERFACE; 915 req.bRequest = UR_SET_INTERFACE;
918 USETW(req.wValue, iface->ui_idesc->bAlternateSetting); 916 USETW(req.wValue, iface->ui_idesc->bAlternateSetting);
919 USETW(req.wIndex, iface->ui_idesc->bInterfaceNumber); 917 USETW(req.wIndex, iface->ui_idesc->bInterfaceNumber);
920 USETW(req.wLength, 0); 918 USETW(req.wLength, 0);
921 err = usbd_do_request(iface->ui_dev, &req, 0); 919 err = usbd_do_request(iface->ui_dev, &req, 0);
922 920
923out: /* XXX back out iface data? */ 921out: /* XXX back out iface data? */
924 if (locked) 922 if (locked)
925 usbd_iface_unlock(iface); 923 usbd_iface_unlock(iface);
926 return err; 924 return err;
927} 925}
928 926
929int 927int
930usbd_get_no_alts(usb_config_descriptor_t *cdesc, int ifaceno) 928usbd_get_no_alts(usb_config_descriptor_t *cdesc, int ifaceno)
931{ 929{
932 char *p = (char *)cdesc; 930 char *p = (char *)cdesc;
933 char *end = p + UGETW(cdesc->wTotalLength); 931 char *end = p + UGETW(cdesc->wTotalLength);
934 usb_interface_descriptor_t *d; 932 usb_interface_descriptor_t *d;
935 int n; 933 int n;
936 934
937 for (n = 0; p < end; p += d->bLength) { 935 for (n = 0; p < end; p += d->bLength) {
938 d = (usb_interface_descriptor_t *)p; 936 d = (usb_interface_descriptor_t *)p;
939 if (p + d->bLength <= end && 937 if (p + d->bLength <= end &&
940 d->bDescriptorType == UDESC_INTERFACE && 938 d->bDescriptorType == UDESC_INTERFACE &&
941 d->bInterfaceNumber == ifaceno) 939 d->bInterfaceNumber == ifaceno)
942 n++; 940 n++;
943 } 941 }
944 return n; 942 return n;
945} 943}
946 944
947int 945int
948usbd_get_interface_altindex(struct usbd_interface *iface) 946usbd_get_interface_altindex(struct usbd_interface *iface)
949{ 947{
950 return iface->ui_altindex; 948 return iface->ui_altindex;
951} 949}
952 950
953usbd_status 951usbd_status
954usbd_get_interface(struct usbd_interface *iface, uint8_t *aiface) 952usbd_get_interface(struct usbd_interface *iface, uint8_t *aiface)
955{ 953{
956 usb_device_request_t req; 954 usb_device_request_t req;
957 955
958 req.bmRequestType = UT_READ_INTERFACE; 956 req.bmRequestType = UT_READ_INTERFACE;
959 req.bRequest = UR_GET_INTERFACE; 957 req.bRequest = UR_GET_INTERFACE;
960 USETW(req.wValue, 0); 958 USETW(req.wValue, 0);
961 USETW(req.wIndex, iface->ui_idesc->bInterfaceNumber); 959 USETW(req.wIndex, iface->ui_idesc->bInterfaceNumber);
962 USETW(req.wLength, 1); 960 USETW(req.wLength, 1);
963 return usbd_do_request(iface->ui_dev, &req, aiface); 961 return usbd_do_request(iface->ui_dev, &req, aiface);
964} 962}
965 963
966/*** Internal routines ***/ 964/*** Internal routines ***/
967 965
968/* Dequeue all pipe operations, called with bus lock held. */ 966/* Dequeue all pipe operations, called with bus lock held. */
969Static usbd_status 967Static void
970usbd_ar_pipe(struct usbd_pipe *pipe) 968usbd_ar_pipe(struct usbd_pipe *pipe)
971{ 969{
972 struct usbd_xfer *xfer; 970 struct usbd_xfer *xfer;
973 971
974 USBHIST_FUNC(); 972 USBHIST_FUNC();
975 USBHIST_CALLARGS(usbdebug, "pipe = %#jx", (uintptr_t)pipe, 0, 0, 0); 973 USBHIST_CALLARGS(usbdebug, "pipe = %#jx", (uintptr_t)pipe, 0, 0, 0);
976 SDT_PROBE1(usb, device, pipe, abort__start, pipe); 974 SDT_PROBE1(usb, device, pipe, abort__start, pipe);
977 975
978 KASSERT(mutex_owned(pipe->up_dev->ud_bus->ub_lock)); 976 KASSERT(mutex_owned(pipe->up_dev->ud_bus->ub_lock));
979 977
980#ifdef USB_DEBUG 978#ifdef USB_DEBUG
981 if (usbdebug > 5) 979 if (usbdebug > 5)
982 usbd_dump_queue(pipe); 980 usbd_dump_queue(pipe);
983#endif 981#endif
984 pipe->up_repeat = 0; 982 pipe->up_repeat = 0;
985 pipe->up_running = 0; 983 pipe->up_running = 0;
986 pipe->up_aborting = 1; 984 pipe->up_aborting = 1;
987 while ((xfer = SIMPLEQ_FIRST(&pipe->up_queue)) != NULL) { 985 while ((xfer = SIMPLEQ_FIRST(&pipe->up_queue)) != NULL) {
988 USBHIST_LOG(usbdebug, "pipe = %#jx xfer = %#jx " 986 USBHIST_LOG(usbdebug, "pipe = %#jx xfer = %#jx "
989 "(methods = %#jx)", (uintptr_t)pipe, (uintptr_t)xfer, 987 "(methods = %#jx)", (uintptr_t)pipe, (uintptr_t)xfer,
990 (uintptr_t)pipe->up_methods, 0); 988 (uintptr_t)pipe->up_methods, 0);
991 if (xfer->ux_status == USBD_NOT_STARTED) { 989 if (xfer->ux_status == USBD_NOT_STARTED) {
992 SDT_PROBE1(usb, device, xfer, preabort, xfer); 990 SDT_PROBE1(usb, device, xfer, preabort, xfer);
993#ifdef DIAGNOSTIC 991#ifdef DIAGNOSTIC
994 xfer->ux_state = XFER_BUSY; 992 xfer->ux_state = XFER_BUSY;
995#endif 993#endif
996 SIMPLEQ_REMOVE_HEAD(&pipe->up_queue, ux_next); 994 SIMPLEQ_REMOVE_HEAD(&pipe->up_queue, ux_next);
997 } else { 995 } else {
998 /* Make the HC abort it (and invoke the callback). */ 996 /* Make the HC abort it (and invoke the callback). */
999 SDT_PROBE1(usb, device, xfer, abort, xfer); 997 SDT_PROBE1(usb, device, xfer, abort, xfer);
1000 pipe->up_methods->upm_abort(xfer); 998 pipe->up_methods->upm_abort(xfer);
1001 while (pipe->up_callingxfer == xfer) { 999 while (pipe->up_callingxfer == xfer) {
1002 USBHIST_LOG(usbdebug, "wait for callback" 1000 USBHIST_LOG(usbdebug, "wait for callback"
1003 "pipe = %#jx xfer = %#jx", 1001 "pipe = %#jx xfer = %#jx",
1004 (uintptr_t)pipe, (uintptr_t)xfer, 0, 0); 1002 (uintptr_t)pipe, (uintptr_t)xfer, 0, 0);
1005 cv_wait(&pipe->up_callingcv, 1003 cv_wait(&pipe->up_callingcv,
1006 pipe->up_dev->ud_bus->ub_lock); 1004 pipe->up_dev->ud_bus->ub_lock);
1007 } 1005 }
1008 /* XXX only for non-0 usbd_clear_endpoint_stall(pipe); */ 1006 /* XXX only for non-0 usbd_clear_endpoint_stall(pipe); */
1009 } 1007 }
1010 } 1008 }
1011 pipe->up_aborting = 0; 1009 pipe->up_aborting = 0;
1012 SDT_PROBE1(usb, device, pipe, abort__done, pipe); 1010 SDT_PROBE1(usb, device, pipe, abort__done, pipe);
1013 return USBD_NORMAL_COMPLETION; 
1014} 1011}
1015 1012
1016/* Called with USB lock held. */ 1013/* Called with USB lock held. */
1017void 1014void
1018usb_transfer_complete(struct usbd_xfer *xfer) 1015usb_transfer_complete(struct usbd_xfer *xfer)
1019{ 1016{
1020 struct usbd_pipe *pipe = xfer->ux_pipe; 1017 struct usbd_pipe *pipe = xfer->ux_pipe;
1021 struct usbd_bus *bus = pipe->up_dev->ud_bus; 1018 struct usbd_bus *bus = pipe->up_dev->ud_bus;
1022 int sync = xfer->ux_flags & USBD_SYNCHRONOUS; 1019 int sync = xfer->ux_flags & USBD_SYNCHRONOUS;
1023 int erred; 1020 int erred;
1024 int polling = bus->ub_usepolling; 1021 int polling = bus->ub_usepolling;
1025 int repeat = pipe->up_repeat; 1022 int repeat = pipe->up_repeat;
1026 1023
1027 USBHIST_FUNC(); 1024 USBHIST_FUNC();
1028 USBHIST_CALLARGS(usbdebug, "pipe = %#jx xfer = %#jx status = %jd " 1025 USBHIST_CALLARGS(usbdebug, "pipe = %#jx xfer = %#jx status = %jd "
1029 "actlen = %jd", (uintptr_t)pipe, (uintptr_t)xfer, xfer->ux_status, 1026 "actlen = %jd", (uintptr_t)pipe, (uintptr_t)xfer, xfer->ux_status,
1030 xfer->ux_actlen); 1027 xfer->ux_actlen);
1031 1028
1032 KASSERT(polling || mutex_owned(pipe->up_dev->ud_bus->ub_lock)); 1029 KASSERT(polling || mutex_owned(pipe->up_dev->ud_bus->ub_lock));
1033 KASSERTMSG(xfer->ux_state == XFER_ONQU, "xfer %p state is %x", xfer, 1030 KASSERTMSG(xfer->ux_state == XFER_ONQU, "xfer %p state is %x", xfer,
1034 xfer->ux_state); 1031 xfer->ux_state);
1035 KASSERT(pipe != NULL); 1032 KASSERT(pipe != NULL);
1036 1033
1037 /* 1034 /*
1038 * If device is known to miss out ack, then pretend that 1035 * If device is known to miss out ack, then pretend that
1039 * output timeout is a success. Userland should handle 1036 * output timeout is a success. Userland should handle
1040 * the logic to verify that the operation succeeded. 1037 * the logic to verify that the operation succeeded.
1041 */ 1038 */
1042 if (pipe->up_dev->ud_quirks && 1039 if (pipe->up_dev->ud_quirks &&
1043 pipe->up_dev->ud_quirks->uq_flags & UQ_MISS_OUT_ACK && 1040 pipe->up_dev->ud_quirks->uq_flags & UQ_MISS_OUT_ACK &&
1044 xfer->ux_status == USBD_TIMEOUT && 1041 xfer->ux_status == USBD_TIMEOUT &&
1045 !usbd_xfer_isread(xfer)) { 1042 !usbd_xfer_isread(xfer)) {
1046 USBHIST_LOG(usbdebug, "Possible output ack miss for xfer %#jx: " 1043 USBHIST_LOG(usbdebug, "Possible output ack miss for xfer %#jx: "
1047 "hiding write timeout to %jd.%jd for %ju bytes written", 1044 "hiding write timeout to %jd.%jd for %ju bytes written",
1048 (uintptr_t)xfer, curlwp->l_proc->p_pid, curlwp->l_lid, 1045 (uintptr_t)xfer, curlwp->l_proc->p_pid, curlwp->l_lid,
1049 xfer->ux_length); 1046 xfer->ux_length);
1050 1047
1051 xfer->ux_status = USBD_NORMAL_COMPLETION; 1048 xfer->ux_status = USBD_NORMAL_COMPLETION;
1052 xfer->ux_actlen = xfer->ux_length; 1049 xfer->ux_actlen = xfer->ux_length;
1053 } 1050 }
1054 1051
1055 erred = xfer->ux_status == USBD_CANCELLED || 1052 erred = xfer->ux_status == USBD_CANCELLED ||
1056 xfer->ux_status == USBD_TIMEOUT; 1053 xfer->ux_status == USBD_TIMEOUT;
1057 1054
1058 if (!repeat) { 1055 if (!repeat) {
1059 /* Remove request from queue. */ 1056 /* Remove request from queue. */
1060 1057
1061 KASSERTMSG(!SIMPLEQ_EMPTY(&pipe->up_queue), 1058 KASSERTMSG(!SIMPLEQ_EMPTY(&pipe->up_queue),
1062 "pipe %p is empty, but xfer %p wants to complete", pipe, 1059 "pipe %p is empty, but xfer %p wants to complete", pipe,
1063 xfer); 1060 xfer);
1064 KASSERTMSG(xfer == SIMPLEQ_FIRST(&pipe->up_queue), 1061 KASSERTMSG(xfer == SIMPLEQ_FIRST(&pipe->up_queue),
1065 "xfer %p is not start of queue (%p is at start)", xfer, 1062 "xfer %p is not start of queue (%p is at start)", xfer,
1066 SIMPLEQ_FIRST(&pipe->up_queue)); 1063 SIMPLEQ_FIRST(&pipe->up_queue));
1067 1064
1068#ifdef DIAGNOSTIC 1065#ifdef DIAGNOSTIC
1069 xfer->ux_state = XFER_BUSY; 1066 xfer->ux_state = XFER_BUSY;
1070#endif 1067#endif
1071 SIMPLEQ_REMOVE_HEAD(&pipe->up_queue, ux_next); 1068 SIMPLEQ_REMOVE_HEAD(&pipe->up_queue, ux_next);
1072 } 1069 }
1073 USBHIST_LOG(usbdebug, "xfer %#jx: repeat %jd new head = %#jx", 1070 USBHIST_LOG(usbdebug, "xfer %#jx: repeat %jd new head = %#jx",
1074 (uintptr_t)xfer, repeat, (uintptr_t)SIMPLEQ_FIRST(&pipe->up_queue), 1071 (uintptr_t)xfer, repeat, (uintptr_t)SIMPLEQ_FIRST(&pipe->up_queue),
1075 0); 1072 0);
1076 1073
1077 /* Count completed transfers. */ 1074 /* Count completed transfers. */
1078 ++pipe->up_dev->ud_bus->ub_stats.uds_requests 1075 ++pipe->up_dev->ud_bus->ub_stats.uds_requests
1079 [pipe->up_endpoint->ue_edesc->bmAttributes & UE_XFERTYPE]; 1076 [pipe->up_endpoint->ue_edesc->bmAttributes & UE_XFERTYPE];
1080 1077
1081 xfer->ux_done = 1; 1078 xfer->ux_done = 1;
1082 if (!xfer->ux_status && xfer->ux_actlen < xfer->ux_length && 1079 if (!xfer->ux_status && xfer->ux_actlen < xfer->ux_length &&
1083 !(xfer->ux_flags & USBD_SHORT_XFER_OK)) { 1080 !(xfer->ux_flags & USBD_SHORT_XFER_OK)) {
1084 USBHIST_LOG(usbdebug, "short transfer %jd < %jd", 1081 USBHIST_LOG(usbdebug, "short transfer %jd < %jd",
1085 xfer->ux_actlen, xfer->ux_length, 0, 0); 1082 xfer->ux_actlen, xfer->ux_length, 0, 0);
1086 xfer->ux_status = USBD_SHORT_XFER; 1083 xfer->ux_status = USBD_SHORT_XFER;
1087 } 1084 }
1088 1085
1089 USBHIST_LOG(usbdebug, "xfer %#jx doing done %#jx", (uintptr_t)xfer, 1086 USBHIST_LOG(usbdebug, "xfer %#jx doing done %#jx", (uintptr_t)xfer,
1090 (uintptr_t)pipe->up_methods->upm_done, 0, 0); 1087 (uintptr_t)pipe->up_methods->upm_done, 0, 0);
1091 SDT_PROBE2(usb, device, xfer, done, xfer, xfer->ux_status); 1088 SDT_PROBE2(usb, device, xfer, done, xfer, xfer->ux_status);
1092 pipe->up_methods->upm_done(xfer); 1089 pipe->up_methods->upm_done(xfer);
1093 1090
1094 if (xfer->ux_length != 0 && xfer->ux_buffer != xfer->ux_buf) { 1091 if (xfer->ux_length != 0 && xfer->ux_buffer != xfer->ux_buf) {
1095 KDASSERTMSG(xfer->ux_actlen <= xfer->ux_length, 1092 KDASSERTMSG(xfer->ux_actlen <= xfer->ux_length,
1096 "actlen %d length %d",xfer->ux_actlen, xfer->ux_length); 1093 "actlen %d length %d",xfer->ux_actlen, xfer->ux_length);
1097 1094
1098 /* Only if IN transfer */ 1095 /* Only if IN transfer */
1099 if (usbd_xfer_isread(xfer)) { 1096 if (usbd_xfer_isread(xfer)) {
1100 memcpy(xfer->ux_buffer, xfer->ux_buf, xfer->ux_actlen); 1097 memcpy(xfer->ux_buffer, xfer->ux_buf, xfer->ux_actlen);
1101 } 1098 }
1102 } 1099 }
1103 1100
1104 USBHIST_LOG(usbdebug, "xfer %#jx doing callback %#jx status %jd", 1101 USBHIST_LOG(usbdebug, "xfer %#jx doing callback %#jx status %jd",
1105 (uintptr_t)xfer, (uintptr_t)xfer->ux_callback, xfer->ux_status, 0); 1102 (uintptr_t)xfer, (uintptr_t)xfer->ux_callback, xfer->ux_status, 0);
1106 1103
1107 if (xfer->ux_callback) { 1104 if (xfer->ux_callback) {
1108 if (!polling) { 1105 if (!polling) {
1109 KASSERT(pipe->up_callingxfer == NULL); 1106 KASSERT(pipe->up_callingxfer == NULL);
1110 pipe->up_callingxfer = xfer; 1107 pipe->up_callingxfer = xfer;
1111 mutex_exit(pipe->up_dev->ud_bus->ub_lock); 1108 mutex_exit(pipe->up_dev->ud_bus->ub_lock);
1112 if (!(pipe->up_flags & USBD_MPSAFE)) 1109 if (!(pipe->up_flags & USBD_MPSAFE))
1113 KERNEL_LOCK(1, curlwp); 1110 KERNEL_LOCK(1, curlwp);
1114 } 1111 }
1115 1112
1116 xfer->ux_callback(xfer, xfer->ux_priv, xfer->ux_status); 1113 xfer->ux_callback(xfer, xfer->ux_priv, xfer->ux_status);
1117 1114
1118 if (!polling) { 1115 if (!polling) {
1119 if (!(pipe->up_flags & USBD_MPSAFE)) 1116 if (!(pipe->up_flags & USBD_MPSAFE))
1120 KERNEL_UNLOCK_ONE(curlwp); 1117 KERNEL_UNLOCK_ONE(curlwp);
1121 mutex_enter(pipe->up_dev->ud_bus->ub_lock); 1118 mutex_enter(pipe->up_dev->ud_bus->ub_lock);
1122 KASSERT(pipe->up_callingxfer == xfer); 1119 KASSERT(pipe->up_callingxfer == xfer);
1123 pipe->up_callingxfer = NULL; 1120 pipe->up_callingxfer = NULL;
1124 cv_broadcast(&pipe->up_callingcv); 1121 cv_broadcast(&pipe->up_callingcv);
1125 } 1122 }
1126 } 1123 }
1127 1124
1128 if (sync && !polling) { 1125 if (sync && !polling) {
1129 USBHIST_LOG(usbdebug, "<- done xfer %#jx, wakeup", 1126 USBHIST_LOG(usbdebug, "<- done xfer %#jx, wakeup",
1130 (uintptr_t)xfer, 0, 0, 0); 1127 (uintptr_t)xfer, 0, 0, 0);
1131 cv_broadcast(&xfer->ux_cv); 1128 cv_broadcast(&xfer->ux_cv);
1132 } 1129 }
1133 1130
1134 if (repeat) { 1131 if (repeat) {
1135 xfer->ux_actlen = 0; 1132 xfer->ux_actlen = 0;
1136 xfer->ux_status = USBD_NOT_STARTED; 1133 xfer->ux_status = USBD_NOT_STARTED;
1137 } else { 1134 } else {
1138 /* XXX should we stop the queue on all errors? */ 1135 /* XXX should we stop the queue on all errors? */
1139 if (erred && pipe->up_iface != NULL) /* not control pipe */ 1136 if (erred && pipe->up_iface != NULL) /* not control pipe */
1140 pipe->up_running = 0; 1137 pipe->up_running = 0;
1141 } 1138 }
1142 if (pipe->up_running && pipe->up_serialise) 1139 if (pipe->up_running && pipe->up_serialise)
1143 usbd_start_next(pipe); 1140 usbd_start_next(pipe);
1144} 1141}
1145 1142
1146/* Called with USB lock held. */ 1143/* Called with USB lock held. */
1147static usbd_status 1144static usbd_status
1148usb_insert_transfer(struct usbd_xfer *xfer) 1145usb_insert_transfer(struct usbd_xfer *xfer)
1149{ 1146{
1150 struct usbd_pipe *pipe = xfer->ux_pipe; 1147 struct usbd_pipe *pipe = xfer->ux_pipe;
1151 usbd_status err; 1148 usbd_status err;
1152 1149
1153 USBHIST_FUNC(); USBHIST_CALLARGS(usbdebug, 1150 USBHIST_FUNC(); USBHIST_CALLARGS(usbdebug,
1154 "xfer = %#jx pipe = %#jx running = %jd timeout = %jd", 1151 "xfer = %#jx pipe = %#jx running = %jd timeout = %jd",
1155 (uintptr_t)xfer, (uintptr_t)pipe, 1152 (uintptr_t)xfer, (uintptr_t)pipe,
1156 pipe->up_running, xfer->ux_timeout); 1153 pipe->up_running, xfer->ux_timeout);
1157 1154
1158 KASSERT(mutex_owned(pipe->up_dev->ud_bus->ub_lock)); 1155 KASSERT(mutex_owned(pipe->up_dev->ud_bus->ub_lock));
1159 KASSERTMSG(xfer->ux_state == XFER_BUSY, "xfer %p state is %x", xfer, 1156 KASSERTMSG(xfer->ux_state == XFER_BUSY, "xfer %p state is %x", xfer,
1160 xfer->ux_state); 1157 xfer->ux_state);
1161 1158
1162#ifdef DIAGNOSTIC 1159#ifdef DIAGNOSTIC
1163 xfer->ux_state = XFER_ONQU; 1160 xfer->ux_state = XFER_ONQU;
1164#endif 1161#endif
1165 SIMPLEQ_INSERT_TAIL(&pipe->up_queue, xfer, ux_next); 1162 SIMPLEQ_INSERT_TAIL(&pipe->up_queue, xfer, ux_next);
1166 if (pipe->up_running && pipe->up_serialise) 1163 if (pipe->up_running && pipe->up_serialise)
1167 err = USBD_IN_PROGRESS; 1164 err = USBD_IN_PROGRESS;
1168 else { 1165 else {
1169 pipe->up_running = 1; 1166 pipe->up_running = 1;
1170 err = USBD_NORMAL_COMPLETION; 1167 err = USBD_NORMAL_COMPLETION;
1171 } 1168 }
1172 USBHIST_LOG(usbdebug, "<- done xfer %#jx, err %jd", (uintptr_t)xfer, 1169 USBHIST_LOG(usbdebug, "<- done xfer %#jx, err %jd", (uintptr_t)xfer,
1173 err, 0, 0); 1170 err, 0, 0);
1174 return err; 1171 return err;
1175} 1172}
1176 1173
1177/* Called with USB lock held. */ 1174/* Called with USB lock held. */
1178void 1175void
1179usbd_start_next(struct usbd_pipe *pipe) 1176usbd_start_next(struct usbd_pipe *pipe)
1180{ 1177{
1181 struct usbd_xfer *xfer; 1178 struct usbd_xfer *xfer;
1182 usbd_status err; 1179 usbd_status err;
1183 1180
1184 USBHIST_FUNC(); 1181 USBHIST_FUNC();
1185 1182
1186 KASSERT(pipe != NULL); 1183 KASSERT(pipe != NULL);
1187 KASSERT(pipe->up_methods != NULL); 1184 KASSERT(pipe->up_methods != NULL);
1188 KASSERT(pipe->up_methods->upm_start != NULL); 1185 KASSERT(pipe->up_methods->upm_start != NULL);
1189 KASSERT(pipe->up_serialise == true); 1186 KASSERT(pipe->up_serialise == true);
1190 1187
1191 int polling = pipe->up_dev->ud_bus->ub_usepolling; 1188 int polling = pipe->up_dev->ud_bus->ub_usepolling;
1192 KASSERT(polling || mutex_owned(pipe->up_dev->ud_bus->ub_lock)); 1189 KASSERT(polling || mutex_owned(pipe->up_dev->ud_bus->ub_lock));
1193 1190
1194 /* Get next request in queue. */ 1191 /* Get next request in queue. */
1195 xfer = SIMPLEQ_FIRST(&pipe->up_queue); 1192 xfer = SIMPLEQ_FIRST(&pipe->up_queue);
1196 USBHIST_CALLARGS(usbdebug, "pipe = %#jx, xfer = %#jx", (uintptr_t)pipe, 1193 USBHIST_CALLARGS(usbdebug, "pipe = %#jx, xfer = %#jx", (uintptr_t)pipe,
1197 (uintptr_t)xfer, 0, 0); 1194 (uintptr_t)xfer, 0, 0);
1198 if (xfer == NULL) { 1195 if (xfer == NULL) {
1199 pipe->up_running = 0; 1196 pipe->up_running = 0;
1200 } else { 1197 } else {
1201 if (!polling) 1198 if (!polling)
1202 mutex_exit(pipe->up_dev->ud_bus->ub_lock); 1199 mutex_exit(pipe->up_dev->ud_bus->ub_lock);
1203 SDT_PROBE2(usb, device, pipe, start, pipe, xfer); 1200 SDT_PROBE2(usb, device, pipe, start, pipe, xfer);
1204 err = pipe->up_methods->upm_start(xfer); 1201 err = pipe->up_methods->upm_start(xfer);
1205 if (!polling) 1202 if (!polling)
1206 mutex_enter(pipe->up_dev->ud_bus->ub_lock); 1203 mutex_enter(pipe->up_dev->ud_bus->ub_lock);
1207 1204
1208 if (err != USBD_IN_PROGRESS) { 1205 if (err != USBD_IN_PROGRESS) {
1209 USBHIST_LOG(usbdebug, "error = %jd", err, 0, 0, 0); 1206 USBHIST_LOG(usbdebug, "error = %jd", err, 0, 0, 0);
1210 pipe->up_running = 0; 1207 pipe->up_running = 0;
1211 /* XXX do what? */ 1208 /* XXX do what? */
1212 } 1209 }
1213 } 1210 }
1214 1211
1215 KASSERT(polling || mutex_owned(pipe->up_dev->ud_bus->ub_lock)); 1212 KASSERT(polling || mutex_owned(pipe->up_dev->ud_bus->ub_lock));
1216} 1213}
1217 1214
1218usbd_status 1215usbd_status
1219usbd_do_request(struct usbd_device *dev, usb_device_request_t *req, void *data) 1216usbd_do_request(struct usbd_device *dev, usb_device_request_t *req, void *data)
1220{ 1217{
1221 1218
1222 return usbd_do_request_flags(dev, req, data, 0, 0, 1219 return usbd_do_request_flags(dev, req, data, 0, 0,
1223 USBD_DEFAULT_TIMEOUT); 1220 USBD_DEFAULT_TIMEOUT);
1224} 1221}
1225 1222
1226usbd_status 1223usbd_status
1227usbd_do_request_flags(struct usbd_device *dev, usb_device_request_t *req, 1224usbd_do_request_flags(struct usbd_device *dev, usb_device_request_t *req,
1228 void *data, uint16_t flags, int *actlen, uint32_t timeout) 1225 void *data, uint16_t flags, int *actlen, uint32_t timeout)
1229{ 1226{
1230 size_t len = UGETW(req->wLength); 1227 size_t len = UGETW(req->wLength);
1231 1228
1232 return usbd_do_request_len(dev, req, len, data, flags, actlen, timeout); 1229 return usbd_do_request_len(dev, req, len, data, flags, actlen, timeout);
1233} 1230}
1234 1231
1235usbd_status 1232usbd_status
1236usbd_do_request_len(struct usbd_device *dev, usb_device_request_t *req, 1233usbd_do_request_len(struct usbd_device *dev, usb_device_request_t *req,
1237 size_t len, void *data, uint16_t flags, int *actlen, uint32_t timeout) 1234 size_t len, void *data, uint16_t flags, int *actlen, uint32_t timeout)
1238{ 1235{
1239 struct usbd_xfer *xfer; 1236 struct usbd_xfer *xfer;
1240 usbd_status err; 1237 usbd_status err;
1241 1238
1242 KASSERT(len >= UGETW(req->wLength)); 1239 KASSERT(len >= UGETW(req->wLength));
1243 1240
1244 USBHIST_FUNC(); 1241 USBHIST_FUNC();
1245 USBHIST_CALLARGS(usbdebug, "dev=%#jx req=%jx flags=%jx len=%jx", 1242 USBHIST_CALLARGS(usbdebug, "dev=%#jx req=%jx flags=%jx len=%jx",
1246 (uintptr_t)dev, (uintptr_t)req, flags, len); 1243 (uintptr_t)dev, (uintptr_t)req, flags, len);
1247 1244
1248 ASSERT_SLEEPABLE(); 1245 ASSERT_SLEEPABLE();
1249 1246
1250 int error = usbd_create_xfer(dev->ud_pipe0, len, 0, 0, &xfer); 1247 int error = usbd_create_xfer(dev->ud_pipe0, len, 0, 0, &xfer);
1251 if (error) 1248 if (error)
1252 return USBD_NOMEM; 1249 return USBD_NOMEM;
1253 1250
1254 usbd_setup_default_xfer(xfer, dev, 0, timeout, req, data, 1251 usbd_setup_default_xfer(xfer, dev, 0, timeout, req, data,
1255 UGETW(req->wLength), flags, NULL); 1252 UGETW(req->wLength), flags, NULL);
1256 KASSERT(xfer->ux_pipe == dev->ud_pipe0); 1253 KASSERT(xfer->ux_pipe == dev->ud_pipe0);
1257 err = usbd_sync_transfer(xfer); 1254 err = usbd_sync_transfer(xfer);
1258#if defined(USB_DEBUG) || defined(DIAGNOSTIC) 1255#if defined(USB_DEBUG) || defined(DIAGNOSTIC)
1259 if (xfer->ux_actlen > xfer->ux_length) { 1256 if (xfer->ux_actlen > xfer->ux_length) {
1260 USBHIST_LOG(usbdebug, "overrun addr = %jd type = 0x%02jx", 1257 USBHIST_LOG(usbdebug, "overrun addr = %jd type = 0x%02jx",
1261 dev->ud_addr, xfer->ux_request.bmRequestType, 0, 0); 1258 dev->ud_addr, xfer->ux_request.bmRequestType, 0, 0);
1262 USBHIST_LOG(usbdebug, " req = 0x%02jx val = %jd " 1259 USBHIST_LOG(usbdebug, " req = 0x%02jx val = %jd "
1263 "index = %jd", 1260 "index = %jd",
1264 xfer->ux_request.bRequest, UGETW(xfer->ux_request.wValue), 1261 xfer->ux_request.bRequest, UGETW(xfer->ux_request.wValue),
1265 UGETW(xfer->ux_request.wIndex), 0); 1262 UGETW(xfer->ux_request.wIndex), 0);
1266 USBHIST_LOG(usbdebug, " rlen = %jd length = %jd " 1263 USBHIST_LOG(usbdebug, " rlen = %jd length = %jd "
1267 "actlen = %jd", 1264 "actlen = %jd",
1268 UGETW(xfer->ux_request.wLength), 1265 UGETW(xfer->ux_request.wLength),
1269 xfer->ux_length, xfer->ux_actlen, 0); 1266 xfer->ux_length, xfer->ux_actlen, 0);
1270 } 1267 }
1271#endif 1268#endif
1272 if (actlen != NULL) 1269 if (actlen != NULL)
1273 *actlen = xfer->ux_actlen; 1270 *actlen = xfer->ux_actlen;
1274 1271
1275 usbd_destroy_xfer(xfer); 1272 usbd_destroy_xfer(xfer);
1276 1273
1277 if (err) { 1274 if (err) {
1278 USBHIST_LOG(usbdebug, "returning err = %jd", err, 0, 0, 0); 1275 USBHIST_LOG(usbdebug, "returning err = %jd", err, 0, 0, 0);
1279 } 1276 }
1280 return err; 1277 return err;
1281} 1278}
1282 1279
1283static void 1280static void
1284usbd_request_async_cb(struct usbd_xfer *xfer, void *priv, usbd_status status) 1281usbd_request_async_cb(struct usbd_xfer *xfer, void *priv, usbd_status status)
1285{ 1282{
1286 usbd_destroy_xfer(xfer); 1283 usbd_destroy_xfer(xfer);
1287} 1284}
1288 1285
1289/* 1286/*
1290 * Execute a request without waiting for completion. 1287 * Execute a request without waiting for completion.
1291 * Can be used from interrupt context. 1288 * Can be used from interrupt context.
1292 */ 1289 */
1293usbd_status 1290usbd_status
1294usbd_request_async(struct usbd_device *dev, struct usbd_xfer *xfer, 1291usbd_request_async(struct usbd_device *dev, struct usbd_xfer *xfer,
1295 usb_device_request_t *req, void *priv, usbd_callback callback) 1292 usb_device_request_t *req, void *priv, usbd_callback callback)
1296{ 1293{
1297 usbd_status err; 1294 usbd_status err;
1298 1295
1299 if (callback == NULL) 1296 if (callback == NULL)
1300 callback = usbd_request_async_cb; 1297 callback = usbd_request_async_cb;
1301 1298
1302 usbd_setup_default_xfer(xfer, dev, priv, 1299 usbd_setup_default_xfer(xfer, dev, priv,
1303 USBD_DEFAULT_TIMEOUT, req, NULL, UGETW(req->wLength), 0, 1300 USBD_DEFAULT_TIMEOUT, req, NULL, UGETW(req->wLength), 0,
1304 callback); 1301 callback);
1305 err = usbd_transfer(xfer); 1302 err = usbd_transfer(xfer);
1306 if (err != USBD_IN_PROGRESS) { 1303 if (err != USBD_IN_PROGRESS) {
1307 usbd_destroy_xfer(xfer); 1304 usbd_destroy_xfer(xfer);
1308 return (err); 1305 return (err);
1309 } 1306 }
1310 return (USBD_NORMAL_COMPLETION); 1307 return (USBD_NORMAL_COMPLETION);
1311} 1308}
1312 1309
1313const struct usbd_quirks * 1310const struct usbd_quirks *
1314usbd_get_quirks(struct usbd_device *dev) 1311usbd_get_quirks(struct usbd_device *dev)
1315{ 1312{
1316#ifdef DIAGNOSTIC 1313#ifdef DIAGNOSTIC
1317 if (dev == NULL) { 1314 if (dev == NULL) {
1318 printf("usbd_get_quirks: dev == NULL\n"); 1315 printf("usbd_get_quirks: dev == NULL\n");
1319 return 0; 1316 return 0;
1320 } 1317 }
1321#endif 1318#endif
1322 return dev->ud_quirks; 1319 return dev->ud_quirks;
1323} 1320}
1324 1321
1325/* XXX do periodic free() of free list */ 1322/* XXX do periodic free() of free list */
1326 1323
1327/* 1324/*
1328 * Called from keyboard driver when in polling mode. 1325 * Called from keyboard driver when in polling mode.
1329 */ 1326 */
1330void 1327void
1331usbd_dopoll(struct usbd_interface *iface) 1328usbd_dopoll(struct usbd_interface *iface)
1332{ 1329{
1333 iface->ui_dev->ud_bus->ub_methods->ubm_dopoll(iface->ui_dev->ud_bus); 1330 iface->ui_dev->ud_bus->ub_methods->ubm_dopoll(iface->ui_dev->ud_bus);
1334} 1331}
1335 1332
1336/* 1333/*
1337 * This is for keyboard driver as well, which only operates in polling 1334 * This is for keyboard driver as well, which only operates in polling
1338 * mode from the ask root, etc., prompt and from DDB. 1335 * mode from the ask root, etc., prompt and from DDB.
1339 */ 1336 */
1340void 1337void
1341usbd_set_polling(struct usbd_device *dev, int on) 1338usbd_set_polling(struct usbd_device *dev, int on)
1342{ 1339{
1343 if (on) 1340 if (on)
1344 dev->ud_bus->ub_usepolling++; 1341 dev->ud_bus->ub_usepolling++;
1345 else 1342 else
1346 dev->ud_bus->ub_usepolling--; 1343 dev->ud_bus->ub_usepolling--;
1347 1344
1348 /* Kick the host controller when switching modes */ 1345 /* Kick the host controller when switching modes */
1349 mutex_enter(dev->ud_bus->ub_lock); 1346 mutex_enter(dev->ud_bus->ub_lock);
1350 dev->ud_bus->ub_methods->ubm_softint(dev->ud_bus); 1347 dev->ud_bus->ub_methods->ubm_softint(dev->ud_bus);
1351 mutex_exit(dev->ud_bus->ub_lock); 1348 mutex_exit(dev->ud_bus->ub_lock);
1352} 1349}
1353 1350
1354 1351
1355usb_endpoint_descriptor_t * 1352usb_endpoint_descriptor_t *
1356usbd_get_endpoint_descriptor(struct usbd_interface *iface, uint8_t address) 1353usbd_get_endpoint_descriptor(struct usbd_interface *iface, uint8_t address)
1357{ 1354{
1358 struct usbd_endpoint *ep; 1355 struct usbd_endpoint *ep;
1359 int i; 1356 int i;
1360 1357
1361 for (i = 0; i < iface->ui_idesc->bNumEndpoints; i++) { 1358 for (i = 0; i < iface->ui_idesc->bNumEndpoints; i++) {
1362 ep = &iface->ui_endpoints[i]; 1359 ep = &iface->ui_endpoints[i];
1363 if (ep->ue_edesc->bEndpointAddress == address) 1360 if (ep->ue_edesc->bEndpointAddress == address)
1364 return iface->ui_endpoints[i].ue_edesc; 1361 return iface->ui_endpoints[i].ue_edesc;
1365 } 1362 }
1366 return NULL; 1363 return NULL;
1367} 1364}
1368 1365
1369/* 1366/*
1370 * usbd_ratecheck() can limit the number of error messages that occurs. 1367 * usbd_ratecheck() can limit the number of error messages that occurs.
1371 * When a device is unplugged it may take up to 0.25s for the hub driver 1368 * When a device is unplugged it may take up to 0.25s for the hub driver
1372 * to notice it. If the driver continuously tries to do I/O operations 1369 * to notice it. If the driver continuously tries to do I/O operations
1373 * this can generate a large number of messages. 1370 * this can generate a large number of messages.
1374 */ 1371 */
1375int 1372int
1376usbd_ratecheck(struct timeval *last) 1373usbd_ratecheck(struct timeval *last)
1377{ 1374{
1378 static struct timeval errinterval = { 0, 250000 }; /* 0.25 s*/ 1375 static struct timeval errinterval = { 0, 250000 }; /* 0.25 s*/
1379 1376
1380 return ratecheck(last, &errinterval); 1377 return ratecheck(last, &errinterval);
1381} 1378}
1382 1379
1383/* 1380/*
1384 * Search for a vendor/product pair in an array. The item size is 1381 * Search for a vendor/product pair in an array. The item size is
1385 * given as an argument. 1382 * given as an argument.
1386 */ 1383 */
1387const struct usb_devno * 1384const struct usb_devno *
1388usb_match_device(const struct usb_devno *tbl, u_int nentries, u_int sz, 1385usb_match_device(const struct usb_devno *tbl, u_int nentries, u_int sz,
1389 uint16_t vendor, uint16_t product) 1386 uint16_t vendor, uint16_t product)
1390{ 1387{
1391 while (nentries-- > 0) { 1388 while (nentries-- > 0) {
1392 uint16_t tproduct = tbl->ud_product; 1389 uint16_t tproduct = tbl->ud_product;
1393 if (tbl->ud_vendor == vendor && 1390 if (tbl->ud_vendor == vendor &&
1394 (tproduct == product || tproduct == USB_PRODUCT_ANY)) 1391 (tproduct == product || tproduct == USB_PRODUCT_ANY))
1395 return tbl; 1392 return tbl;
1396 tbl = (const struct usb_devno *)((const char *)tbl + sz); 1393 tbl = (const struct usb_devno *)((const char *)tbl + sz);
1397 } 1394 }
1398 return NULL; 1395 return NULL;
1399} 1396}
1400 1397
1401usbd_status 1398usbd_status
1402usbd_get_string(struct usbd_device *dev, int si, char *buf) 1399usbd_get_string(struct usbd_device *dev, int si, char *buf)
1403{ 1400{
1404 return usbd_get_string0(dev, si, buf, 1); 1401 return usbd_get_string0(dev, si, buf, 1);
1405} 1402}
1406 1403
1407usbd_status 1404usbd_status
1408usbd_get_string0(struct usbd_device *dev, int si, char *buf, int unicode) 1405usbd_get_string0(struct usbd_device *dev, int si, char *buf, int unicode)
1409{ 1406{
1410 int swap = dev->ud_quirks->uq_flags & UQ_SWAP_UNICODE; 1407 int swap = dev->ud_quirks->uq_flags & UQ_SWAP_UNICODE;
1411 usb_string_descriptor_t us; 1408 usb_string_descriptor_t us;
1412 char *s; 1409 char *s;
1413 int i, n; 1410 int i, n;
1414 uint16_t c; 1411 uint16_t c;
1415 usbd_status err; 1412 usbd_status err;
1416 int size; 1413 int size;
1417 1414
1418 USBHIST_FUNC(); USBHIST_CALLED(usbdebug); 1415 USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
1419 1416
1420 buf[0] = '\0'; 1417 buf[0] = '\0';
1421 if (si == 0) 1418 if (si == 0)
1422 return USBD_INVAL; 1419 return USBD_INVAL;
1423 if (dev->ud_quirks->uq_flags & UQ_NO_STRINGS) 1420 if (dev->ud_quirks->uq_flags & UQ_NO_STRINGS)
1424 return USBD_STALLED; 1421 return USBD_STALLED;
1425 if (dev->ud_langid == USBD_NOLANG) { 1422 if (dev->ud_langid == USBD_NOLANG) {
1426 /* Set up default language */ 1423 /* Set up default language */
1427 err = usbd_get_string_desc(dev, USB_LANGUAGE_TABLE, 0, &us, 1424 err = usbd_get_string_desc(dev, USB_LANGUAGE_TABLE, 0, &us,
1428 &size); 1425 &size);
1429 if (err || size < 4) { 1426 if (err || size < 4) {
1430 USBHIST_LOG(usbdebug, "getting lang failed, using 0", 1427 USBHIST_LOG(usbdebug, "getting lang failed, using 0",
1431 0, 0, 0, 0); 1428 0, 0, 0, 0);
1432 dev->ud_langid = 0; /* Well, just pick something then */ 1429 dev->ud_langid = 0; /* Well, just pick something then */
1433 } else { 1430 } else {
1434 /* Pick the first language as the default. */ 1431 /* Pick the first language as the default. */
1435 dev->ud_langid = UGETW(us.bString[0]); 1432 dev->ud_langid = UGETW(us.bString[0]);
1436 } 1433 }
1437 } 1434 }
1438 err = usbd_get_string_desc(dev, si, dev->ud_langid, &us, &size); 1435 err = usbd_get_string_desc(dev, si, dev->ud_langid, &us, &size);
1439 if (err) 1436 if (err)
1440 return err; 1437 return err;
1441 s = buf; 1438 s = buf;
1442 n = size / 2 - 1; 1439 n = size / 2 - 1;
1443 if (unicode) { 1440 if (unicode) {
1444 for (i = 0; i < n; i++) { 1441 for (i = 0; i < n; i++) {
1445 c = UGETW(us.bString[i]); 1442 c = UGETW(us.bString[i]);
1446 if (swap) 1443 if (swap)
1447 c = (c >> 8) | (c << 8); 1444 c = (c >> 8) | (c << 8);
1448 s += wput_utf8(s, 3, c); 1445 s += wput_utf8(s, 3, c);
1449 } 1446 }
1450 *s++ = 0; 1447 *s++ = 0;
1451 } 1448 }
1452#ifdef COMPAT_30 1449#ifdef COMPAT_30
1453 else { 1450 else {
1454 for (i = 0; i < n; i++) { 1451 for (i = 0; i < n; i++) {
1455 c = UGETW(us.bString[i]); 1452 c = UGETW(us.bString[i]);
1456 if (swap) 1453 if (swap)
1457 c = (c >> 8) | (c << 8); 1454 c = (c >> 8) | (c << 8);
1458 *s++ = (c < 0x80) ? c : '?'; 1455 *s++ = (c < 0x80) ? c : '?';
1459 } 1456 }
1460 *s++ = 0; 1457 *s++ = 0;
1461 } 1458 }
1462#endif 1459#endif
1463 return USBD_NORMAL_COMPLETION; 1460 return USBD_NORMAL_COMPLETION;
1464} 1461}
1465 1462
1466/* 1463/*
1467 * usbd_xfer_trycomplete(xfer) 1464 * usbd_xfer_trycomplete(xfer)
1468 * 1465 *
1469 * Try to claim xfer for completion. Return true if successful, 1466 * Try to claim xfer for completion. Return true if successful,
1470 * false if the xfer has been synchronously aborted or has timed 1467 * false if the xfer has been synchronously aborted or has timed
1471 * out. 1468 * out.
1472 * 1469 *
1473 * If this returns true, caller is responsible for setting 1470 * If this returns true, caller is responsible for setting
1474 * xfer->ux_status and calling usb_transfer_complete. To be used 1471 * xfer->ux_status and calling usb_transfer_complete. To be used
1475 * in a host controller interrupt handler. 1472 * in a host controller interrupt handler.
1476 * 1473 *
1477 * Caller must either hold the bus lock or have the bus in polling 1474 * Caller must either hold the bus lock or have the bus in polling
1478 * mode. 1475 * mode.
1479 */ 1476 */
1480bool 1477bool
1481usbd_xfer_trycomplete(struct usbd_xfer *xfer) 1478usbd_xfer_trycomplete(struct usbd_xfer *xfer)
1482{ 1479{
1483 struct usbd_bus *bus __diagused = xfer->ux_bus; 1480 struct usbd_bus *bus __diagused = xfer->ux_bus;
1484 1481
1485 KASSERT(bus->ub_usepolling || mutex_owned(bus->ub_lock)); 1482 KASSERT(bus->ub_usepolling || mutex_owned(bus->ub_lock));
1486 1483
1487 /* 1484 /*
1488 * If software has completed it, either by synchronous abort or 1485 * If software has completed it, either by synchronous abort or
1489 * by timeout, too late. 1486 * by timeout, too late.
1490 */ 1487 */
1491 if (xfer->ux_status != USBD_IN_PROGRESS) 1488 if (xfer->ux_status != USBD_IN_PROGRESS)
1492 return false; 1489 return false;
1493 1490
1494 /* 1491 /*
1495 * We are completing the xfer. Cancel the timeout if we can, 1492 * We are completing the xfer. Cancel the timeout if we can,
1496 * but only asynchronously. See usbd_xfer_cancel_timeout_async 1493 * but only asynchronously. See usbd_xfer_cancel_timeout_async
1497 * for why we need not wait for the callout or task here. 1494 * for why we need not wait for the callout or task here.
1498 */ 1495 */
1499 usbd_xfer_cancel_timeout_async(xfer); 1496 usbd_xfer_cancel_timeout_async(xfer);
1500 1497
1501 /* Success! Note: Caller must set xfer->ux_status afterwar. */ 1498 /* Success! Note: Caller must set xfer->ux_status afterwar. */
1502 return true; 1499 return true;
1503} 1500}
1504 1501
1505/* 1502/*
1506 * usbd_xfer_abort(xfer) 1503 * usbd_xfer_abort(xfer)
1507 * 1504 *
1508 * Try to claim xfer to abort. If successful, mark it completed 1505 * Try to claim xfer to abort. If successful, mark it completed
1509 * with USBD_CANCELLED and call the bus-specific method to abort 1506 * with USBD_CANCELLED and call the bus-specific method to abort
1510 * at the hardware level. 1507 * at the hardware level.
1511 * 1508 *
1512 * To be called in thread context from struct 1509 * To be called in thread context from struct
1513 * usbd_pipe_methods::upm_abort. 1510 * usbd_pipe_methods::upm_abort.
1514 * 1511 *
1515 * Caller must hold the bus lock. 1512 * Caller must hold the bus lock.
1516 */ 1513 */
1517void 1514void
1518usbd_xfer_abort(struct usbd_xfer *xfer) 1515usbd_xfer_abort(struct usbd_xfer *xfer)
1519{ 1516{
1520 struct usbd_bus *bus = xfer->ux_bus; 1517 struct usbd_bus *bus = xfer->ux_bus;
1521 1518
1522 KASSERT(mutex_owned(bus->ub_lock)); 1519 KASSERT(mutex_owned(bus->ub_lock));
1523 1520
1524 /* 1521 /*
1525 * If host controller interrupt or timer interrupt has 1522 * If host controller interrupt or timer interrupt has
1526 * completed it, too late. But the xfer cannot be 1523 * completed it, too late. But the xfer cannot be
1527 * cancelled already -- only one caller can synchronously 1524 * cancelled already -- only one caller can synchronously
1528 * abort. 1525 * abort.
1529 */ 1526 */
1530 KASSERT(xfer->ux_status != USBD_CANCELLED); 1527 KASSERT(xfer->ux_status != USBD_CANCELLED);
1531 if (xfer->ux_status != USBD_IN_PROGRESS) 1528 if (xfer->ux_status != USBD_IN_PROGRESS)
1532 return; 1529 return;
1533 1530
1534 /* 1531 /*
1535 * Cancel the timeout if we can, but only asynchronously; see 1532 * Cancel the timeout if we can, but only asynchronously; see
1536 * usbd_xfer_cancel_timeout_async for why we need not wait for 1533 * usbd_xfer_cancel_timeout_async for why we need not wait for
1537 * the callout or task here. 1534 * the callout or task here.
1538 */ 1535 */
1539 usbd_xfer_cancel_timeout_async(xfer); 1536 usbd_xfer_cancel_timeout_async(xfer);
1540 1537
1541 /* 1538 /*
1542 * We beat everyone else. Claim the status as cancelled and do 1539 * We beat everyone else. Claim the status as cancelled and do
1543 * the bus-specific dance to abort the hardware. 1540 * the bus-specific dance to abort the hardware.
1544 */ 1541 */
1545 xfer->ux_status = USBD_CANCELLED; 1542 xfer->ux_status = USBD_CANCELLED;
1546 bus->ub_methods->ubm_abortx(xfer); 1543 bus->ub_methods->ubm_abortx(xfer);
1547} 1544}
1548 1545
1549/* 1546/*
1550 * usbd_xfer_timeout(xfer) 1547 * usbd_xfer_timeout(xfer)
1551 * 1548 *
1552 * Called at IPL_SOFTCLOCK when too much time has elapsed waiting 1549 * Called at IPL_SOFTCLOCK when too much time has elapsed waiting
1553 * for xfer to complete. Since we can't abort the xfer at 1550 * for xfer to complete. Since we can't abort the xfer at
1554 * IPL_SOFTCLOCK, defer to a usb_task to run it in thread context, 1551 * IPL_SOFTCLOCK, defer to a usb_task to run it in thread context,
1555 * unless the xfer has completed or aborted concurrently -- and if 1552 * unless the xfer has completed or aborted concurrently -- and if
1556 * the xfer has also been resubmitted, take care of rescheduling 1553 * the xfer has also been resubmitted, take care of rescheduling
1557 * the callout. 1554 * the callout.
1558 */ 1555 */
1559static void 1556static void
1560usbd_xfer_timeout(void *cookie) 1557usbd_xfer_timeout(void *cookie)
1561{ 1558{
1562 struct usbd_xfer *xfer = cookie; 1559 struct usbd_xfer *xfer = cookie;
1563 struct usbd_bus *bus = xfer->ux_bus; 1560 struct usbd_bus *bus = xfer->ux_bus;
1564 struct usbd_device *dev = xfer->ux_pipe->up_dev; 1561 struct usbd_device *dev = xfer->ux_pipe->up_dev;
1565 1562
1566 /* Acquire the lock so we can transition the timeout state. */ 1563 /* Acquire the lock so we can transition the timeout state. */
1567 mutex_enter(bus->ub_lock); 1564 mutex_enter(bus->ub_lock);
1568 1565
1569 /* 1566 /*
1570 * Use usbd_xfer_probe_timeout to check whether the timeout is 1567 * Use usbd_xfer_probe_timeout to check whether the timeout is
1571 * still valid, or to reschedule the callout if necessary. If 1568 * still valid, or to reschedule the callout if necessary. If
1572 * it is still valid, schedule the task. 1569 * it is still valid, schedule the task.
1573 */ 1570 */
1574 if (usbd_xfer_probe_timeout(xfer)) 1571 if (usbd_xfer_probe_timeout(xfer))
1575 usb_add_task(dev, &xfer->ux_aborttask, USB_TASKQ_HC); 1572 usb_add_task(dev, &xfer->ux_aborttask, USB_TASKQ_HC);
1576 1573
1577 /* 1574 /*
1578 * Notify usbd_xfer_cancel_timeout_async that we may have 1575 * Notify usbd_xfer_cancel_timeout_async that we may have
1579 * scheduled the task. This causes callout_invoking to return 1576 * scheduled the task. This causes callout_invoking to return
1580 * false in usbd_xfer_cancel_timeout_async so that it can tell 1577 * false in usbd_xfer_cancel_timeout_async so that it can tell
1581 * which stage in the callout->task->abort process we're at. 1578 * which stage in the callout->task->abort process we're at.
1582 */ 1579 */
1583 callout_ack(&xfer->ux_callout); 1580 callout_ack(&xfer->ux_callout);
1584 1581
1585 /* All done -- release the lock. */ 1582 /* All done -- release the lock. */
1586 mutex_exit(bus->ub_lock); 1583 mutex_exit(bus->ub_lock);
1587} 1584}
1588 1585
1589/* 1586/*
1590 * usbd_xfer_timeout_task(xfer) 1587 * usbd_xfer_timeout_task(xfer)
1591 * 1588 *
1592 * Called in thread context when too much time has elapsed waiting 1589 * Called in thread context when too much time has elapsed waiting
1593 * for xfer to complete. Abort the xfer with USBD_TIMEOUT, unless 1590 * for xfer to complete. Abort the xfer with USBD_TIMEOUT, unless
1594 * it has completed or aborted concurrently -- and if the xfer has 1591 * it has completed or aborted concurrently -- and if the xfer has
1595 * also been resubmitted, take care of rescheduling the callout. 1592 * also been resubmitted, take care of rescheduling the callout.
1596 */ 1593 */
1597static void 1594static void
1598usbd_xfer_timeout_task(void *cookie) 1595usbd_xfer_timeout_task(void *cookie)
1599{ 1596{
1600 struct usbd_xfer *xfer = cookie; 1597 struct usbd_xfer *xfer = cookie;
1601 struct usbd_bus *bus = xfer->ux_bus; 1598 struct usbd_bus *bus = xfer->ux_bus;
1602 1599
1603 /* Acquire the lock so we can transition the timeout state. */ 1600 /* Acquire the lock so we can transition the timeout state. */
1604 mutex_enter(bus->ub_lock); 1601 mutex_enter(bus->ub_lock);
1605 1602
1606 /* 1603 /*
1607 * Use usbd_xfer_probe_timeout to check whether the timeout is 1604 * Use usbd_xfer_probe_timeout to check whether the timeout is
1608 * still valid, or to reschedule the callout if necessary. If 1605 * still valid, or to reschedule the callout if necessary. If
1609 * it is not valid -- the timeout has been asynchronously 1606 * it is not valid -- the timeout has been asynchronously
1610 * cancelled, or the xfer has already been resubmitted -- then 1607 * cancelled, or the xfer has already been resubmitted -- then
1611 * we're done here. 1608 * we're done here.
1612 */ 1609 */
1613 if (!usbd_xfer_probe_timeout(xfer)) 1610 if (!usbd_xfer_probe_timeout(xfer))
1614 goto out; 1611 goto out;
1615 1612
1616 /* 1613 /*
1617 * May have completed or been aborted, but we're the only one 1614 * May have completed or been aborted, but we're the only one
1618 * who can time it out. If it has completed or been aborted, 1615 * who can time it out. If it has completed or been aborted,
1619 * no need to timeout. 1616 * no need to timeout.
1620 */ 1617 */
1621 KASSERT(xfer->ux_status != USBD_TIMEOUT); 1618 KASSERT(xfer->ux_status != USBD_TIMEOUT);
1622 if (xfer->ux_status != USBD_IN_PROGRESS) 1619 if (xfer->ux_status != USBD_IN_PROGRESS)
1623 goto out; 1620 goto out;
1624 1621
1625 /* 1622 /*
1626 * We beat everyone else. Claim the status as timed out and do 1623 * We beat everyone else. Claim the status as timed out and do
1627 * the bus-specific dance to abort the hardware. 1624 * the bus-specific dance to abort the hardware.
1628 */ 1625 */
1629 xfer->ux_status = USBD_TIMEOUT; 1626 xfer->ux_status = USBD_TIMEOUT;
1630 bus->ub_methods->ubm_abortx(xfer); 1627 bus->ub_methods->ubm_abortx(xfer);
1631 1628
1632out: /* All done -- release the lock. */ 1629out: /* All done -- release the lock. */
1633 mutex_exit(bus->ub_lock); 1630 mutex_exit(bus->ub_lock);
1634} 1631}
1635 1632
1636/* 1633/*
1637 * usbd_xfer_probe_timeout(xfer) 1634 * usbd_xfer_probe_timeout(xfer)
1638 * 1635 *
1639 * Probe the status of xfer's timeout. Acknowledge and process a 1636 * Probe the status of xfer's timeout. Acknowledge and process a
1640 * request to reschedule. Return true if the timeout is still 1637 * request to reschedule. Return true if the timeout is still
1641 * valid and the caller should take further action (queueing a 1638 * valid and the caller should take further action (queueing a
1642 * task or aborting the xfer), false if it must stop here. 1639 * task or aborting the xfer), false if it must stop here.
1643 */ 1640 */
1644static bool 1641static bool
1645usbd_xfer_probe_timeout(struct usbd_xfer *xfer) 1642usbd_xfer_probe_timeout(struct usbd_xfer *xfer)
1646{ 1643{
1647 struct usbd_bus *bus = xfer->ux_bus; 1644 struct usbd_bus *bus = xfer->ux_bus;
1648 bool valid; 1645 bool valid;
1649 1646
1650 KASSERT(bus->ub_usepolling || mutex_owned(bus->ub_lock)); 1647 KASSERT(bus->ub_usepolling || mutex_owned(bus->ub_lock));
1651 1648
1652 /* The timeout must be set. */ 1649 /* The timeout must be set. */
1653 KASSERT(xfer->ux_timeout_set); 1650 KASSERT(xfer->ux_timeout_set);
1654 1651
1655 /* 1652 /*
1656 * Neither callout nor task may be pending; they execute 1653 * Neither callout nor task may be pending; they execute
1657 * alternately in lock step. 1654 * alternately in lock step.
1658 */ 1655 */
1659 KASSERT(!callout_pending(&xfer->ux_callout)); 1656 KASSERT(!callout_pending(&xfer->ux_callout));
1660 KASSERT(!usb_task_pending(xfer->ux_pipe->up_dev, &xfer->ux_aborttask)); 1657 KASSERT(!usb_task_pending(xfer->ux_pipe->up_dev, &xfer->ux_aborttask));
1661 1658
1662 /* There are a few cases... */ 1659 /* There are a few cases... */
1663 if (bus->ub_methods->ubm_dying(bus)) { 1660 if (bus->ub_methods->ubm_dying(bus)) {
1664 /* Host controller dying. Drop it all on the floor. */ 1661 /* Host controller dying. Drop it all on the floor. */
1665 xfer->ux_timeout_set = false; 1662 xfer->ux_timeout_set = false;
1666 xfer->ux_timeout_reset = false; 1663 xfer->ux_timeout_reset = false;
1667 valid = false; 1664 valid = false;
1668 } else if (xfer->ux_timeout_reset) { 1665 } else if (xfer->ux_timeout_reset) {
1669 /* 1666 /*
1670 * The xfer completed _and_ got resubmitted while we 1667 * The xfer completed _and_ got resubmitted while we
1671 * waited for the lock. Acknowledge the request to 1668 * waited for the lock. Acknowledge the request to
1672 * reschedule, and reschedule it if there is a timeout 1669 * reschedule, and reschedule it if there is a timeout
1673 * and the bus is not polling. 1670 * and the bus is not polling.
1674 */ 1671 */
1675 xfer->ux_timeout_reset = false; 1672 xfer->ux_timeout_reset = false;
1676 if (xfer->ux_timeout && !bus->ub_usepolling) { 1673 if (xfer->ux_timeout && !bus->ub_usepolling) {
1677 KASSERT(xfer->ux_timeout_set); 1674 KASSERT(xfer->ux_timeout_set);
1678 callout_schedule(&xfer->ux_callout, 1675 callout_schedule(&xfer->ux_callout,
1679 mstohz(xfer->ux_timeout)); 1676 mstohz(xfer->ux_timeout));
1680 } else { 1677 } else {
1681 /* No more callout or task scheduled. */ 1678 /* No more callout or task scheduled. */
1682 xfer->ux_timeout_set = false; 1679 xfer->ux_timeout_set = false;
1683 } 1680 }
1684 valid = false; 1681 valid = false;
1685 } else if (xfer->ux_status != USBD_IN_PROGRESS) { 1682 } else if (xfer->ux_status != USBD_IN_PROGRESS) {
1686 /* 1683 /*
1687 * The xfer has completed by hardware completion or by 1684 * The xfer has completed by hardware completion or by
1688 * software abort, and has not been resubmitted, so the 1685 * software abort, and has not been resubmitted, so the
1689 * timeout must be unset, and is no longer valid for 1686 * timeout must be unset, and is no longer valid for
1690 * the caller. 1687 * the caller.
1691 */ 1688 */
1692 xfer->ux_timeout_set = false; 1689 xfer->ux_timeout_set = false;
1693 valid = false; 1690 valid = false;
1694 } else { 1691 } else {
1695 /* 1692 /*
1696 * The xfer has not yet completed, so the timeout is 1693 * The xfer has not yet completed, so the timeout is
1697 * valid. 1694 * valid.
1698 */ 1695 */
1699 valid = true; 1696 valid = true;
1700 } 1697 }
1701 1698
1702 /* Any reset must have been processed. */ 1699 /* Any reset must have been processed. */
1703 KASSERT(!xfer->ux_timeout_reset); 1700 KASSERT(!xfer->ux_timeout_reset);
1704 1701
1705 /* 1702 /*
1706 * Either we claim the timeout is set, or the callout is idle. 1703 * Either we claim the timeout is set, or the callout is idle.
1707 * If the timeout is still set, we may be handing off to the 1704 * If the timeout is still set, we may be handing off to the
1708 * task instead, so this is an if but not an iff. 1705 * task instead, so this is an if but not an iff.
1709 */ 1706 */
1710 KASSERT(xfer->ux_timeout_set || !callout_pending(&xfer->ux_callout)); 1707 KASSERT(xfer->ux_timeout_set || !callout_pending(&xfer->ux_callout));
1711 1708
1712 /* 1709 /*
1713 * The task must be idle now. 1710 * The task must be idle now.
1714 * 1711 *
1715 * - If the caller is the callout, _and_ the timeout is still 1712 * - If the caller is the callout, _and_ the timeout is still
1716 * valid, the caller will schedule it, but it hasn't been 1713 * valid, the caller will schedule it, but it hasn't been
1717 * scheduled yet. (If the timeout is not valid, the task 1714 * scheduled yet. (If the timeout is not valid, the task
1718 * should not be scheduled.) 1715 * should not be scheduled.)
1719 * 1716 *
1720 * - If the caller is the task, it cannot be scheduled again 1717 * - If the caller is the task, it cannot be scheduled again
1721 * until the callout runs again, which won't happen until we 1718 * until the callout runs again, which won't happen until we
1722 * next release the lock. 1719 * next release the lock.
1723 */ 1720 */
1724 KASSERT(!usb_task_pending(xfer->ux_pipe->up_dev, &xfer->ux_aborttask)); 1721 KASSERT(!usb_task_pending(xfer->ux_pipe->up_dev, &xfer->ux_aborttask));
1725 1722
1726 KASSERT(bus->ub_usepolling || mutex_owned(bus->ub_lock)); 1723 KASSERT(bus->ub_usepolling || mutex_owned(bus->ub_lock));
1727 1724
1728 return valid; 1725 return valid;
1729} 1726}
1730 1727
1731/* 1728/*
1732 * usbd_xfer_schedule_timeout(xfer) 1729 * usbd_xfer_schedule_timeout(xfer)
1733 * 1730 *
1734 * Ensure that xfer has a timeout. If the callout is already 1731 * Ensure that xfer has a timeout. If the callout is already
1735 * queued or the task is already running, request that they 1732 * queued or the task is already running, request that they
1736 * reschedule the callout. If not, and if we're not polling, 1733 * reschedule the callout. If not, and if we're not polling,
1737 * schedule the callout anew. 1734 * schedule the callout anew.
1738 * 1735 *
1739 * To be called in thread context from struct 1736 * To be called in thread context from struct
1740 * usbd_pipe_methods::upm_start. 1737 * usbd_pipe_methods::upm_start.
1741 */ 1738 */
1742void 1739void
1743usbd_xfer_schedule_timeout(struct usbd_xfer *xfer) 1740usbd_xfer_schedule_timeout(struct usbd_xfer *xfer)
1744{ 1741{
1745 struct usbd_bus *bus = xfer->ux_bus; 1742 struct usbd_bus *bus = xfer->ux_bus;
1746 1743
1747 KASSERT(bus->ub_usepolling || mutex_owned(bus->ub_lock)); 1744 KASSERT(bus->ub_usepolling || mutex_owned(bus->ub_lock));
1748 1745
1749 if (xfer->ux_timeout_set) { 1746 if (xfer->ux_timeout_set) {
1750 /* 1747 /*
1751 * Callout or task has fired from a prior completed 1748 * Callout or task has fired from a prior completed
1752 * xfer but has not yet noticed that the xfer is done. 1749 * xfer but has not yet noticed that the xfer is done.
1753 * Ask it to reschedule itself to ux_timeout. 1750 * Ask it to reschedule itself to ux_timeout.
1754 */ 1751 */
1755 xfer->ux_timeout_reset = true; 1752 xfer->ux_timeout_reset = true;
1756 } else if (xfer->ux_timeout && !bus->ub_usepolling) { 1753 } else if (xfer->ux_timeout && !bus->ub_usepolling) {
1757 /* Callout is not scheduled. Schedule it. */ 1754 /* Callout is not scheduled. Schedule it. */
1758 KASSERT(!callout_pending(&xfer->ux_callout)); 1755 KASSERT(!callout_pending(&xfer->ux_callout));
1759 callout_schedule(&xfer->ux_callout, mstohz(xfer->ux_timeout)); 1756 callout_schedule(&xfer->ux_callout, mstohz(xfer->ux_timeout));
1760 xfer->ux_timeout_set = true; 1757 xfer->ux_timeout_set = true;
1761 } 1758 }
1762 1759
1763 KASSERT(bus->ub_usepolling || mutex_owned(bus->ub_lock)); 1760 KASSERT(bus->ub_usepolling || mutex_owned(bus->ub_lock));
1764} 1761}
1765 1762
1766/* 1763/*
1767 * usbd_xfer_cancel_timeout_async(xfer) 1764 * usbd_xfer_cancel_timeout_async(xfer)
1768 * 1765 *
1769 * Cancel the callout and the task of xfer, which have not yet run 1766 * Cancel the callout and the task of xfer, which have not yet run
1770 * to completion, but don't wait for the callout or task to finish 1767 * to completion, but don't wait for the callout or task to finish
1771 * running. 1768 * running.
1772 * 1769 *
1773 * If they have already fired, at worst they are waiting for the 1770 * If they have already fired, at worst they are waiting for the
1774 * bus lock. They will see that the xfer is no longer in progress 1771 * bus lock. They will see that the xfer is no longer in progress
1775 * and give up, or they will see that the xfer has been 1772 * and give up, or they will see that the xfer has been
1776 * resubmitted with a new timeout and reschedule the callout. 1773 * resubmitted with a new timeout and reschedule the callout.
1777 * 1774 *
1778 * If a resubmitted request completed so fast that the callout 1775 * If a resubmitted request completed so fast that the callout
1779 * didn't have time to process a timer reset, just cancel the 1776 * didn't have time to process a timer reset, just cancel the
1780 * timer reset. 1777 * timer reset.
1781 */ 1778 */
1782static void 1779static void
1783usbd_xfer_cancel_timeout_async(struct usbd_xfer *xfer) 1780usbd_xfer_cancel_timeout_async(struct usbd_xfer *xfer)
1784{ 1781{
1785 struct usbd_bus *bus __diagused = xfer->ux_bus; 1782 struct usbd_bus *bus __diagused = xfer->ux_bus;
1786 1783
1787 KASSERT(bus->ub_usepolling || mutex_owned(bus->ub_lock)); 1784 KASSERT(bus->ub_usepolling || mutex_owned(bus->ub_lock));
1788 1785
1789 /* 1786 /*
1790 * If the timer wasn't running anyway, forget about it. This 1787 * If the timer wasn't running anyway, forget about it. This
1791 * can happen if we are completing an isochronous transfer 1788 * can happen if we are completing an isochronous transfer
1792 * which doesn't use the same timeout logic. 1789 * which doesn't use the same timeout logic.
1793 */ 1790 */
1794 if (!xfer->ux_timeout_set) 1791 if (!xfer->ux_timeout_set)
1795 return; 1792 return;
1796 1793
1797 xfer->ux_timeout_reset = false; 1794 xfer->ux_timeout_reset = false;
1798 if (!callout_stop(&xfer->ux_callout)) { 1795 if (!callout_stop(&xfer->ux_callout)) {
1799 /* 1796 /*
1800 * We stopped the callout before it ran. The timeout 1797 * We stopped the callout before it ran. The timeout
1801 * is no longer set. 1798 * is no longer set.
1802 */ 1799 */
1803 xfer->ux_timeout_set = false; 1800 xfer->ux_timeout_set = false;
1804 } else if (callout_invoking(&xfer->ux_callout)) { 1801 } else if (callout_invoking(&xfer->ux_callout)) {
1805 /* 1802 /*
1806 * The callout has begun to run but it has not yet 1803 * The callout has begun to run but it has not yet
1807 * acquired the lock and called callout_ack. The task 1804 * acquired the lock and called callout_ack. The task
1808 * cannot be queued yet, and the callout cannot have 1805 * cannot be queued yet, and the callout cannot have
1809 * been rescheduled yet. 1806 * been rescheduled yet.
1810 * 1807 *
1811 * By the time the callout acquires the lock, we will 1808 * By the time the callout acquires the lock, we will
1812 * have transitioned from USBD_IN_PROGRESS to a 1809 * have transitioned from USBD_IN_PROGRESS to a
1813 * completed status, and possibly also resubmitted the 1810 * completed status, and possibly also resubmitted the
1814 * xfer and set xfer->ux_timeout_reset = true. In both 1811 * xfer and set xfer->ux_timeout_reset = true. In both
1815 * cases, the callout will DTRT, so no further action 1812 * cases, the callout will DTRT, so no further action
1816 * is needed here. 1813 * is needed here.
1817 */ 1814 */
1818 } else if (usb_rem_task(xfer->ux_pipe->up_dev, &xfer->ux_aborttask)) { 1815 } else if (usb_rem_task(xfer->ux_pipe->up_dev, &xfer->ux_aborttask)) {
1819 /* 1816 /*
1820 * The callout had fired and scheduled the task, but we 1817 * The callout had fired and scheduled the task, but we
1821 * stopped the task before it could run. The timeout 1818 * stopped the task before it could run. The timeout
1822 * is therefore no longer set -- the next resubmission 1819 * is therefore no longer set -- the next resubmission
1823 * of the xfer must schedule a new timeout. 1820 * of the xfer must schedule a new timeout.
1824 * 1821 *
1825 * The callout should not be pending at this point: 1822 * The callout should not be pending at this point:
1826 * it is scheduled only under the lock, and only when 1823 * it is scheduled only under the lock, and only when
1827 * xfer->ux_timeout_set is false, or by the callout or 1824 * xfer->ux_timeout_set is false, or by the callout or
1828 * task itself when xfer->ux_timeout_reset is true. 1825 * task itself when xfer->ux_timeout_reset is true.
1829 */ 1826 */
1830 xfer->ux_timeout_set = false; 1827 xfer->ux_timeout_set = false;
1831 } 1828 }
1832 1829
1833 /* 1830 /*
1834 * The callout cannot be scheduled and the task cannot be 1831 * The callout cannot be scheduled and the task cannot be
1835 * queued at this point. Either we cancelled them, or they are 1832 * queued at this point. Either we cancelled them, or they are
1836 * already running and waiting for the bus lock. 1833 * already running and waiting for the bus lock.
1837 */ 1834 */
1838 KASSERT(!callout_pending(&xfer->ux_callout)); 1835 KASSERT(!callout_pending(&xfer->ux_callout));
1839 KASSERT(!usb_task_pending(xfer->ux_pipe->up_dev, &xfer->ux_aborttask)); 1836 KASSERT(!usb_task_pending(xfer->ux_pipe->up_dev, &xfer->ux_aborttask));
1840 1837
1841 KASSERT(bus->ub_usepolling || mutex_owned(bus->ub_lock)); 1838 KASSERT(bus->ub_usepolling || mutex_owned(bus->ub_lock));
1842} 1839}

cvs diff -r1.104 -r1.105 src/sys/dev/usb/usbdi.h (switch to unified diff)

--- src/sys/dev/usb/usbdi.h 2022/02/14 09:22:30 1.104
+++ src/sys/dev/usb/usbdi.h 2022/03/03 06:05:38 1.105
@@ -1,318 +1,318 @@ @@ -1,318 +1,318 @@
1/* $NetBSD: usbdi.h,v 1.104 2022/02/14 09:22:30 riastradh Exp $ */ 1/* $NetBSD: usbdi.h,v 1.105 2022/03/03 06:05:38 riastradh Exp $ */
2/* $FreeBSD: src/sys/dev/usb/usbdi.h,v 1.18 1999/11/17 22:33:49 n_hibma Exp $ */ 2/* $FreeBSD: src/sys/dev/usb/usbdi.h,v 1.18 1999/11/17 22:33:49 n_hibma Exp $ */
3 3
4/* 4/*
5 * Copyright (c) 1998 The NetBSD Foundation, Inc. 5 * Copyright (c) 1998 The NetBSD Foundation, Inc.
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * This code is derived from software contributed to The NetBSD Foundation 8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Lennart Augustsson (lennart@augustsson.net) at 9 * by Lennart Augustsson (lennart@augustsson.net) at
10 * Carlstedt Research & Technology. 10 * Carlstedt Research & Technology.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions 13 * modification, are permitted provided that the following conditions
14 * are met: 14 * are met:
15 * 1. Redistributions of source code must retain the above copyright 15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer. 16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright 17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the 18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution. 19 * documentation and/or other materials provided with the distribution.
20 * 20 *
21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE. 31 * POSSIBILITY OF SUCH DAMAGE.
32 */ 32 */
33 33
34#ifndef _USBDI_H_ 34#ifndef _USBDI_H_
35#define _USBDI_H_ 35#define _USBDI_H_
36 36
37#include <sys/types.h> 37#include <sys/types.h>
38 38
39#include <dev/usb/usb.h> 39#include <dev/usb/usb.h>
40 40
41struct usbd_bus; 41struct usbd_bus;
42struct usbd_device; 42struct usbd_device;
43struct usbd_interface; 43struct usbd_interface;
44struct usbd_pipe; 44struct usbd_pipe;
45struct usbd_xfer; 45struct usbd_xfer;
46 46
47typedef enum { /* keep in sync with usbd_error_strs */ 47typedef enum { /* keep in sync with usbd_error_strs */
48 USBD_NORMAL_COMPLETION = 0, /* must be 0 */ 48 USBD_NORMAL_COMPLETION = 0, /* must be 0 */
49 USBD_IN_PROGRESS, /* 1 */ 49 USBD_IN_PROGRESS, /* 1 */
50 /* errors */ 50 /* errors */
51 USBD_PENDING_REQUESTS, /* 2 */ 51 USBD_PENDING_REQUESTS, /* 2 */
52 USBD_NOT_STARTED, /* 3 */ 52 USBD_NOT_STARTED, /* 3 */
53 USBD_INVAL, /* 4 */ 53 USBD_INVAL, /* 4 */
54 USBD_NOMEM, /* 5 */ 54 USBD_NOMEM, /* 5 */
55 USBD_CANCELLED, /* 6 */ 55 USBD_CANCELLED, /* 6 */
56 USBD_BAD_ADDRESS, /* 7 */ 56 USBD_BAD_ADDRESS, /* 7 */
57 USBD_IN_USE, /* 8 */ 57 USBD_IN_USE, /* 8 */
58 USBD_NO_ADDR, /* 9 */ 58 USBD_NO_ADDR, /* 9 */
59 USBD_SET_ADDR_FAILED, /* 10 */ 59 USBD_SET_ADDR_FAILED, /* 10 */
60 USBD_NO_POWER, /* 11 */ 60 USBD_NO_POWER, /* 11 */
61 USBD_TOO_DEEP, /* 12 */ 61 USBD_TOO_DEEP, /* 12 */
62 USBD_IOERROR, /* 13 */ 62 USBD_IOERROR, /* 13 */
63 USBD_NOT_CONFIGURED, /* 14 */ 63 USBD_NOT_CONFIGURED, /* 14 */
64 USBD_TIMEOUT, /* 15 */ 64 USBD_TIMEOUT, /* 15 */
65 USBD_SHORT_XFER, /* 16 */ 65 USBD_SHORT_XFER, /* 16 */
66 USBD_STALLED, /* 17 */ 66 USBD_STALLED, /* 17 */
67 USBD_INTERRUPTED, /* 18 */ 67 USBD_INTERRUPTED, /* 18 */
68 68
69 USBD_ERROR_MAX /* must be last */ 69 USBD_ERROR_MAX /* must be last */
70} usbd_status; 70} usbd_status;
71 71
72typedef void (*usbd_callback)(struct usbd_xfer *, void *, usbd_status); 72typedef void (*usbd_callback)(struct usbd_xfer *, void *, usbd_status);
73 73
74/* Use default (specified by ep. desc.) interval on interrupt pipe */ 74/* Use default (specified by ep. desc.) interval on interrupt pipe */
75#define USBD_DEFAULT_INTERVAL (-1) 75#define USBD_DEFAULT_INTERVAL (-1)
76 76
77/* Open flags */ 77/* Open flags */
78#define USBD_EXCLUSIVE_USE 0x01 78#define USBD_EXCLUSIVE_USE 0x01
79#define USBD_MPSAFE 0x80 79#define USBD_MPSAFE 0x80
80 80
81/* Request flags */ 81/* Request flags */
82#define USBD_SYNCHRONOUS 0x02 /* wait for completion */ 82#define USBD_SYNCHRONOUS 0x02 /* wait for completion */
83/* in usb.h #define USBD_SHORT_XFER_OK 0x04*/ /* allow short reads */ 83/* in usb.h #define USBD_SHORT_XFER_OK 0x04*/ /* allow short reads */
84#define USBD_FORCE_SHORT_XFER 0x08 /* force last short packet on write */ 84#define USBD_FORCE_SHORT_XFER 0x08 /* force last short packet on write */
85#define USBD_SYNCHRONOUS_SIG 0x10 /* if waiting for completion, 85#define USBD_SYNCHRONOUS_SIG 0x10 /* if waiting for completion,
86 * also take signals */ 86 * also take signals */
87 87
88#define USBD_NO_TIMEOUT 0 88#define USBD_NO_TIMEOUT 0
89#define USBD_DEFAULT_TIMEOUT 5000 /* ms = 5 s */ 89#define USBD_DEFAULT_TIMEOUT 5000 /* ms = 5 s */
90#define USBD_CONFIG_TIMEOUT (3*USBD_DEFAULT_TIMEOUT) 90#define USBD_CONFIG_TIMEOUT (3*USBD_DEFAULT_TIMEOUT)
91 91
92#define DEVINFOSIZE 1024 92#define DEVINFOSIZE 1024
93 93
94usbd_status usbd_open_pipe_intr(struct usbd_interface *, uint8_t, uint8_t, 94usbd_status usbd_open_pipe_intr(struct usbd_interface *, uint8_t, uint8_t,
95 struct usbd_pipe **, void *, void *, uint32_t, usbd_callback, int); 95 struct usbd_pipe **, void *, void *, uint32_t, usbd_callback, int);
96usbd_status usbd_open_pipe(struct usbd_interface *, uint8_t, uint8_t, 96usbd_status usbd_open_pipe(struct usbd_interface *, uint8_t, uint8_t,
97 struct usbd_pipe **); 97 struct usbd_pipe **);
98usbd_status usbd_close_pipe(struct usbd_pipe *); 98usbd_status usbd_close_pipe(struct usbd_pipe *);
99 99
100usbd_status usbd_transfer(struct usbd_xfer *); 100usbd_status usbd_transfer(struct usbd_xfer *);
101 101
102void *usbd_get_buffer(struct usbd_xfer *); 102void *usbd_get_buffer(struct usbd_xfer *);
103struct usbd_pipe *usbd_get_pipe0(struct usbd_device *); 103struct usbd_pipe *usbd_get_pipe0(struct usbd_device *);
104 104
105int usbd_create_xfer(struct usbd_pipe *, size_t, unsigned int, unsigned int, 105int usbd_create_xfer(struct usbd_pipe *, size_t, unsigned int, unsigned int,
106 struct usbd_xfer **); 106 struct usbd_xfer **);
107void usbd_destroy_xfer(struct usbd_xfer *); 107void usbd_destroy_xfer(struct usbd_xfer *);
108 108
109void usbd_setup_xfer(struct usbd_xfer *, void *, void *, 109void usbd_setup_xfer(struct usbd_xfer *, void *, void *,
110 uint32_t, uint16_t, uint32_t, usbd_callback); 110 uint32_t, uint16_t, uint32_t, usbd_callback);
111 111
112void usbd_setup_default_xfer(struct usbd_xfer *, struct usbd_device *, 112void usbd_setup_default_xfer(struct usbd_xfer *, struct usbd_device *,
113 void *, uint32_t, usb_device_request_t *, void *, 113 void *, uint32_t, usb_device_request_t *, void *,
114 uint32_t, uint16_t, usbd_callback); 114 uint32_t, uint16_t, usbd_callback);
115 115
116void usbd_setup_isoc_xfer(struct usbd_xfer *, void *, uint16_t *, 116void usbd_setup_isoc_xfer(struct usbd_xfer *, void *, uint16_t *,
117 uint32_t, uint16_t, usbd_callback); 117 uint32_t, uint16_t, usbd_callback);
118 118
119void usbd_get_xfer_status(struct usbd_xfer *, void **, 119void usbd_get_xfer_status(struct usbd_xfer *, void **,
120 void **, uint32_t *, usbd_status *); 120 void **, uint32_t *, usbd_status *);
121 121
122usb_endpoint_descriptor_t *usbd_interface2endpoint_descriptor 122usb_endpoint_descriptor_t *usbd_interface2endpoint_descriptor
123 (struct usbd_interface *, uint8_t); 123 (struct usbd_interface *, uint8_t);
124 124
125usbd_status usbd_abort_pipe(struct usbd_pipe *); 125void usbd_abort_pipe(struct usbd_pipe *);
126usbd_status usbd_abort_default_pipe(struct usbd_device *); 126void usbd_abort_default_pipe(struct usbd_device *);
127 127
128usbd_status usbd_clear_endpoint_stall(struct usbd_pipe *); 128usbd_status usbd_clear_endpoint_stall(struct usbd_pipe *);
129void usbd_clear_endpoint_stall_async(struct usbd_pipe *); 129void usbd_clear_endpoint_stall_async(struct usbd_pipe *);
130 130
131void usbd_clear_endpoint_toggle(struct usbd_pipe *); 131void usbd_clear_endpoint_toggle(struct usbd_pipe *);
132usbd_status usbd_endpoint_count(struct usbd_interface *, uint8_t *); 132usbd_status usbd_endpoint_count(struct usbd_interface *, uint8_t *);
133 133
134usbd_status usbd_interface_count(struct usbd_device *, uint8_t *); 134usbd_status usbd_interface_count(struct usbd_device *, uint8_t *);
135 135
136void usbd_interface2device_handle(struct usbd_interface *, struct usbd_device **); 136void usbd_interface2device_handle(struct usbd_interface *, struct usbd_device **);
137usbd_status usbd_device2interface_handle(struct usbd_device *, 137usbd_status usbd_device2interface_handle(struct usbd_device *,
138 uint8_t, struct usbd_interface **); 138 uint8_t, struct usbd_interface **);
139 139
140struct usbd_device *usbd_pipe2device_handle(struct usbd_pipe *); 140struct usbd_device *usbd_pipe2device_handle(struct usbd_pipe *);
141 141
142usbd_status usbd_sync_transfer(struct usbd_xfer *); 142usbd_status usbd_sync_transfer(struct usbd_xfer *);
143usbd_status usbd_sync_transfer_sig(struct usbd_xfer *); 143usbd_status usbd_sync_transfer_sig(struct usbd_xfer *);
144 144
145usbd_status usbd_do_request(struct usbd_device *, usb_device_request_t *, void *); 145usbd_status usbd_do_request(struct usbd_device *, usb_device_request_t *, void *);
146usbd_status usbd_request_async(struct usbd_device *, struct usbd_xfer *, 146usbd_status usbd_request_async(struct usbd_device *, struct usbd_xfer *,
147 usb_device_request_t *, void *, usbd_callback); 147 usb_device_request_t *, void *, usbd_callback);
148usbd_status usbd_do_request_flags(struct usbd_device *, usb_device_request_t *, 148usbd_status usbd_do_request_flags(struct usbd_device *, usb_device_request_t *,
149 void *, uint16_t, int *, uint32_t); 149 void *, uint16_t, int *, uint32_t);
150usbd_status usbd_do_request_len(struct usbd_device *dev, 150usbd_status usbd_do_request_len(struct usbd_device *dev,
151 usb_device_request_t *req, size_t len, void *data, uint16_t flags, 151 usb_device_request_t *req, size_t len, void *data, uint16_t flags,
152 int *actlen, uint32_t timeout); 152 int *actlen, uint32_t timeout);
153 153
154usb_interface_descriptor_t * 154usb_interface_descriptor_t *
155 usbd_get_interface_descriptor(struct usbd_interface *); 155 usbd_get_interface_descriptor(struct usbd_interface *);
156usb_endpoint_descriptor_t * 156usb_endpoint_descriptor_t *
157 usbd_get_endpoint_descriptor(struct usbd_interface *, uint8_t); 157 usbd_get_endpoint_descriptor(struct usbd_interface *, uint8_t);
158 158
159usb_config_descriptor_t *usbd_get_config_descriptor(struct usbd_device *); 159usb_config_descriptor_t *usbd_get_config_descriptor(struct usbd_device *);
160usb_device_descriptor_t *usbd_get_device_descriptor(struct usbd_device *); 160usb_device_descriptor_t *usbd_get_device_descriptor(struct usbd_device *);
161 161
162usbd_status usbd_set_interface(struct usbd_interface *, int); 162usbd_status usbd_set_interface(struct usbd_interface *, int);
163usbd_status usbd_get_interface(struct usbd_interface *, uint8_t *); 163usbd_status usbd_get_interface(struct usbd_interface *, uint8_t *);
164 164
165int usbd_get_no_alts(usb_config_descriptor_t *, int); 165int usbd_get_no_alts(usb_config_descriptor_t *, int);
166 166
167void usbd_fill_deviceinfo(struct usbd_device *, struct usb_device_info *, int); 167void usbd_fill_deviceinfo(struct usbd_device *, struct usb_device_info *, int);
168int usbd_get_interface_altindex(struct usbd_interface *); 168int usbd_get_interface_altindex(struct usbd_interface *);
169 169
170usb_interface_descriptor_t *usbd_find_idesc(usb_config_descriptor_t *, 170usb_interface_descriptor_t *usbd_find_idesc(usb_config_descriptor_t *,
171 int, int); 171 int, int);
172usb_endpoint_descriptor_t *usbd_find_edesc(usb_config_descriptor_t *, 172usb_endpoint_descriptor_t *usbd_find_edesc(usb_config_descriptor_t *,
173 int, int, int); 173 int, int, int);
174 174
175void usbd_dopoll(struct usbd_interface *); 175void usbd_dopoll(struct usbd_interface *);
176void usbd_set_polling(struct usbd_device *, int); 176void usbd_set_polling(struct usbd_device *, int);
177 177
178const char *usbd_errstr(usbd_status); 178const char *usbd_errstr(usbd_status);
179 179
180void usbd_add_dev_event(int, struct usbd_device *); 180void usbd_add_dev_event(int, struct usbd_device *);
181void usbd_add_drv_event(int, struct usbd_device *, device_t); 181void usbd_add_drv_event(int, struct usbd_device *, device_t);
182 182
183char *usbd_devinfo_alloc(struct usbd_device *, int); 183char *usbd_devinfo_alloc(struct usbd_device *, int);
184void usbd_devinfo_free(char *); 184void usbd_devinfo_free(char *);
185 185
186const struct usbd_quirks *usbd_get_quirks(struct usbd_device *); 186const struct usbd_quirks *usbd_get_quirks(struct usbd_device *);
187 187
188usbd_status usbd_reload_device_desc(struct usbd_device *); 188usbd_status usbd_reload_device_desc(struct usbd_device *);
189 189
190int usbd_ratecheck(struct timeval *); 190int usbd_ratecheck(struct timeval *);
191 191
192usbd_status usbd_get_string(struct usbd_device *, int, char *); 192usbd_status usbd_get_string(struct usbd_device *, int, char *);
193usbd_status usbd_get_string0(struct usbd_device *, int, char *, int); 193usbd_status usbd_get_string0(struct usbd_device *, int, char *, int);
194 194
195/* For use by HCI drivers, not USB device drivers */ 195/* For use by HCI drivers, not USB device drivers */
196void usbd_xfer_schedule_timeout(struct usbd_xfer *); 196void usbd_xfer_schedule_timeout(struct usbd_xfer *);
197bool usbd_xfer_trycomplete(struct usbd_xfer *); 197bool usbd_xfer_trycomplete(struct usbd_xfer *);
198void usbd_xfer_abort(struct usbd_xfer *); 198void usbd_xfer_abort(struct usbd_xfer *);
199 199
200/* Used to clear endpoint stalls from the softint */ 200/* Used to clear endpoint stalls from the softint */
201void usbd_clear_endpoint_stall_task(void *); 201void usbd_clear_endpoint_stall_task(void *);
202 202
203/* 203/*
204 * The usb_task structs form a queue of things to run in the USB event 204 * The usb_task structs form a queue of things to run in the USB event
205 * thread. Normally this is just device discovery when a connect/disconnect 205 * thread. Normally this is just device discovery when a connect/disconnect
206 * has been detected. But it may also be used by drivers that need to 206 * has been detected. But it may also be used by drivers that need to
207 * perform (short) tasks that must have a process context. 207 * perform (short) tasks that must have a process context.
208 */ 208 */
209struct usb_task { 209struct usb_task {
210 TAILQ_ENTRY(usb_task) next; 210 TAILQ_ENTRY(usb_task) next;
211 void (*fun)(void *); 211 void (*fun)(void *);
212 void *arg; 212 void *arg;
213 volatile unsigned queue; 213 volatile unsigned queue;
214 int flags; 214 int flags;
215}; 215};
216#define USB_TASKQ_HC 0 216#define USB_TASKQ_HC 0
217#define USB_TASKQ_DRIVER 1 217#define USB_TASKQ_DRIVER 1
218#define USB_NUM_TASKQS 2 218#define USB_NUM_TASKQS 2
219#define USB_TASKQ_NAMES {"usbtask-hc", "usbtask-dr"} 219#define USB_TASKQ_NAMES {"usbtask-hc", "usbtask-dr"}
220#define USB_TASKQ_MPSAFE 0x80 220#define USB_TASKQ_MPSAFE 0x80
221 221
222void usb_add_task(struct usbd_device *, struct usb_task *, int); 222void usb_add_task(struct usbd_device *, struct usb_task *, int);
223bool usb_rem_task(struct usbd_device *, struct usb_task *); 223bool usb_rem_task(struct usbd_device *, struct usb_task *);
224bool usb_rem_task_wait(struct usbd_device *, struct usb_task *, int, 224bool usb_rem_task_wait(struct usbd_device *, struct usb_task *, int,
225 kmutex_t *); 225 kmutex_t *);
226bool usb_task_pending(struct usbd_device *, struct usb_task *); 226bool usb_task_pending(struct usbd_device *, struct usb_task *);
227#define usb_init_task(t, f, a, fl) ((t)->fun = (f), (t)->arg = (a), (t)->queue = USB_NUM_TASKQS, (t)->flags = (fl)) 227#define usb_init_task(t, f, a, fl) ((t)->fun = (f), (t)->arg = (a), (t)->queue = USB_NUM_TASKQS, (t)->flags = (fl))
228 228
229bool usb_in_event_thread(device_t); 229bool usb_in_event_thread(device_t);
230 230
231struct usb_devno { 231struct usb_devno {
232 uint16_t ud_vendor; 232 uint16_t ud_vendor;
233 uint16_t ud_product; 233 uint16_t ud_product;
234}; 234};
235const struct usb_devno *usb_match_device(const struct usb_devno *, 235const struct usb_devno *usb_match_device(const struct usb_devno *,
236 u_int, u_int, uint16_t, uint16_t); 236 u_int, u_int, uint16_t, uint16_t);
237#define usb_lookup(tbl, vendor, product) \ 237#define usb_lookup(tbl, vendor, product) \
238 usb_match_device((const struct usb_devno *)(tbl), sizeof(tbl) / sizeof((tbl)[0]), sizeof((tbl)[0]), (vendor), (product)) 238 usb_match_device((const struct usb_devno *)(tbl), sizeof(tbl) / sizeof((tbl)[0]), sizeof((tbl)[0]), (vendor), (product))
239#define USB_PRODUCT_ANY 0xffff 239#define USB_PRODUCT_ANY 0xffff
240 240
241/* compat callbacks */ 241/* compat callbacks */
242void usbd_devinfo_vp(struct usbd_device *, char *, size_t, char *, size_t, 242void usbd_devinfo_vp(struct usbd_device *, char *, size_t, char *, size_t,
243 int, int); 243 int, int);
244int usbd_printBCD(char *, size_t, int); 244int usbd_printBCD(char *, size_t, int);
245 245
246 246
247/* NetBSD attachment information */ 247/* NetBSD attachment information */
248 248
249/* Attach data */ 249/* Attach data */
250struct usb_attach_arg { 250struct usb_attach_arg {
251 int uaa_port; 251 int uaa_port;
252 int uaa_vendor; 252 int uaa_vendor;
253 int uaa_product; 253 int uaa_product;
254 int uaa_release; 254 int uaa_release;
255 struct usbd_device * uaa_device; /* current device */ 255 struct usbd_device * uaa_device; /* current device */
256 int uaa_class; 256 int uaa_class;
257 int uaa_subclass; 257 int uaa_subclass;
258 int uaa_proto; 258 int uaa_proto;
259 int uaa_usegeneric; 259 int uaa_usegeneric;
260}; 260};
261 261
262struct usbif_attach_arg { 262struct usbif_attach_arg {
263 int uiaa_port; 263 int uiaa_port;
264 int uiaa_configno; 264 int uiaa_configno;
265 int uiaa_ifaceno; 265 int uiaa_ifaceno;
266 int uiaa_vendor; 266 int uiaa_vendor;
267 int uiaa_product; 267 int uiaa_product;
268 int uiaa_release; 268 int uiaa_release;
269 struct usbd_device * uiaa_device; /* current device */ 269 struct usbd_device * uiaa_device; /* current device */
270 270
271 struct usbd_interface * uiaa_iface; /* current interface */ 271 struct usbd_interface * uiaa_iface; /* current interface */
272 int uiaa_class; 272 int uiaa_class;
273 int uiaa_subclass; 273 int uiaa_subclass;
274 int uiaa_proto; 274 int uiaa_proto;
275 275
276 /* XXX need accounting for interfaces not matched to */ 276 /* XXX need accounting for interfaces not matched to */
277 277
278 struct usbd_interface **uiaa_ifaces; /* all interfaces */ 278 struct usbd_interface **uiaa_ifaces; /* all interfaces */
279 int uiaa_nifaces; /* number of interfaces */ 279 int uiaa_nifaces; /* number of interfaces */
280}; 280};
281 281
282/* Match codes. */ 282/* Match codes. */
283#define UMATCH_HIGHEST 15 283#define UMATCH_HIGHEST 15
284/* First five codes is for a whole device. */ 284/* First five codes is for a whole device. */
285#define UMATCH_VENDOR_PRODUCT_REV 14 285#define UMATCH_VENDOR_PRODUCT_REV 14
286#define UMATCH_VENDOR_PRODUCT 13 286#define UMATCH_VENDOR_PRODUCT 13
287#define UMATCH_VENDOR_DEVCLASS_DEVPROTO 12 287#define UMATCH_VENDOR_DEVCLASS_DEVPROTO 12
288#define UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO 11 288#define UMATCH_DEVCLASS_DEVSUBCLASS_DEVPROTO 11
289#define UMATCH_DEVCLASS_DEVSUBCLASS 10 289#define UMATCH_DEVCLASS_DEVSUBCLASS 10
290/* Next six codes are for interfaces. */ 290/* Next six codes are for interfaces. */
291#define UMATCH_VENDOR_PRODUCT_REV_CONF_IFACE 9 291#define UMATCH_VENDOR_PRODUCT_REV_CONF_IFACE 9
292#define UMATCH_VENDOR_PRODUCT_CONF_IFACE 8 292#define UMATCH_VENDOR_PRODUCT_CONF_IFACE 8
293#define UMATCH_VENDOR_IFACESUBCLASS_IFACEPROTO 7 293#define UMATCH_VENDOR_IFACESUBCLASS_IFACEPROTO 7
294#define UMATCH_VENDOR_IFACESUBCLASS 6 294#define UMATCH_VENDOR_IFACESUBCLASS 6
295#define UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO 5 295#define UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO 5
296#define UMATCH_IFACECLASS_IFACESUBCLASS 4 296#define UMATCH_IFACECLASS_IFACESUBCLASS 4
297#define UMATCH_IFACECLASS 3 297#define UMATCH_IFACECLASS 3
298#define UMATCH_IFACECLASS_GENERIC 2 298#define UMATCH_IFACECLASS_GENERIC 2
299/* Generic driver */ 299/* Generic driver */
300#define UMATCH_GENERIC 1 300#define UMATCH_GENERIC 1
301/* No match */ 301/* No match */
302#define UMATCH_NONE 0 302#define UMATCH_NONE 0
303 303
304 304
305/* 305/*
306 * IPL_USB is defined as IPL_VM for drivers that have not been made MP safe. 306 * IPL_USB is defined as IPL_VM for drivers that have not been made MP safe.
307 * IPL_VM (currently) takes the kernel lock. 307 * IPL_VM (currently) takes the kernel lock.
308 * 308 *
309 * Eventually, IPL_USB can/should be changed 309 * Eventually, IPL_USB can/should be changed
310 */ 310 */
311#define IPL_USB IPL_VM 311#define IPL_USB IPL_VM
312#define splhardusb splvm 312#define splhardusb splvm
313 313
314#define SOFTINT_USB SOFTINT_SERIAL 314#define SOFTINT_USB SOFTINT_SERIAL
315#define IPL_SOFTUSB IPL_SOFTSERIAL 315#define IPL_SOFTUSB IPL_SOFTSERIAL
316#define splusb splsoftserial 316#define splusb splsoftserial
317 317
318#endif /* _USBDI_H_ */ 318#endif /* _USBDI_H_ */

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

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

cvs diff -r1.35 -r1.36 src/sys/dev/usb/utoppy.c (switch to unified diff)

--- src/sys/dev/usb/utoppy.c 2020/03/14 02:35:34 1.35
+++ src/sys/dev/usb/utoppy.c 2022/03/03 06:05:38 1.36
@@ -1,1865 +1,1862 @@ @@ -1,1865 +1,1862 @@
1/* $NetBSD: utoppy.c,v 1.35 2020/03/14 02:35:34 christos Exp $ */ 1/* $NetBSD: utoppy.c,v 1.36 2022/03/03 06:05:38 riastradh Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2006 The NetBSD Foundation, Inc. 4 * Copyright (c) 2006 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Steve C. Woodford. 8 * by Steve C. Woodford.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33__KERNEL_RCSID(0, "$NetBSD: utoppy.c,v 1.35 2020/03/14 02:35:34 christos Exp $"); 33__KERNEL_RCSID(0, "$NetBSD: utoppy.c,v 1.36 2022/03/03 06:05:38 riastradh Exp $");
34 34
35#ifdef _KERNEL_OPT 35#ifdef _KERNEL_OPT
36#include "opt_usb.h" 36#include "opt_usb.h"
37#endif 37#endif
38 38
39#include <sys/param.h> 39#include <sys/param.h>
40#include <sys/systm.h> 40#include <sys/systm.h>
41#include <sys/proc.h> 41#include <sys/proc.h>
42#include <sys/kernel.h> 42#include <sys/kernel.h>
43#include <sys/fcntl.h> 43#include <sys/fcntl.h>
44#include <sys/device.h> 44#include <sys/device.h>
45#include <sys/ioctl.h> 45#include <sys/ioctl.h>
46#include <sys/uio.h> 46#include <sys/uio.h>
47#include <sys/conf.h> 47#include <sys/conf.h>
48#include <sys/vnode.h> 48#include <sys/vnode.h>
49#include <sys/bus.h> 49#include <sys/bus.h>
50 50
51#include <lib/libkern/crc16.h> 51#include <lib/libkern/crc16.h>
52 52
53#include <dev/usb/usb.h> 53#include <dev/usb/usb.h>
54#include <dev/usb/usbdi.h> 54#include <dev/usb/usbdi.h>
55#include <dev/usb/usbdivar.h> 55#include <dev/usb/usbdivar.h>
56#include <dev/usb/usbdi_util.h> 56#include <dev/usb/usbdi_util.h>
57#include <dev/usb/usbdevs.h> 57#include <dev/usb/usbdevs.h>
58#include <dev/usb/usb_quirks.h> 58#include <dev/usb/usb_quirks.h>
59#include <dev/usb/utoppy.h> 59#include <dev/usb/utoppy.h>
60 60
61#include "ioconf.h" 61#include "ioconf.h"
62 62
63#undef UTOPPY_DEBUG 63#undef UTOPPY_DEBUG
64#ifdef UTOPPY_DEBUG 64#ifdef UTOPPY_DEBUG
65#define UTOPPY_DBG_OPEN 0x0001 65#define UTOPPY_DBG_OPEN 0x0001
66#define UTOPPY_DBG_CLOSE 0x0002 66#define UTOPPY_DBG_CLOSE 0x0002
67#define UTOPPY_DBG_READ 0x0004 67#define UTOPPY_DBG_READ 0x0004
68#define UTOPPY_DBG_WRITE 0x0008 68#define UTOPPY_DBG_WRITE 0x0008
69#define UTOPPY_DBG_IOCTL 0x0010 69#define UTOPPY_DBG_IOCTL 0x0010
70#define UTOPPY_DBG_SEND_PACKET 0x0020 70#define UTOPPY_DBG_SEND_PACKET 0x0020
71#define UTOPPY_DBG_RECV_PACKET 0x0040 71#define UTOPPY_DBG_RECV_PACKET 0x0040
72#define UTOPPY_DBG_ADDPATH 0x0080 72#define UTOPPY_DBG_ADDPATH 0x0080
73#define UTOPPY_DBG_READDIR 0x0100 73#define UTOPPY_DBG_READDIR 0x0100
74#define UTOPPY_DBG_DUMP 0x0200 74#define UTOPPY_DBG_DUMP 0x0200
75#define DPRINTF(l, m) \ 75#define DPRINTF(l, m) \
76 do { \ 76 do { \
77 if (utoppy_debug & l) \ 77 if (utoppy_debug & l) \
78 printf m; \ 78 printf m; \
79 } while (/*CONSTCOND*/0) 79 } while (/*CONSTCOND*/0)
80static int utoppy_debug = 0; 80static int utoppy_debug = 0;
81static void utoppy_dump_packet(const void *, size_t); 81static void utoppy_dump_packet(const void *, size_t);
82#define DDUMP_PACKET(p, l) \ 82#define DDUMP_PACKET(p, l) \
83 do { \ 83 do { \
84 if (utoppy_debug & UTOPPY_DBG_DUMP) \ 84 if (utoppy_debug & UTOPPY_DBG_DUMP) \
85 utoppy_dump_packet((p), (l)); \ 85 utoppy_dump_packet((p), (l)); \
86 } while (/*CONSTCOND*/0) 86 } while (/*CONSTCOND*/0)
87#else 87#else
88#define DPRINTF(l, m) /* nothing */ 88#define DPRINTF(l, m) /* nothing */
89#define DDUMP_PACKET(p, l) /* nothing */ 89#define DDUMP_PACKET(p, l) /* nothing */
90#endif 90#endif
91 91
92 92
93#define UTOPPY_CONFIG_NO 1 93#define UTOPPY_CONFIG_NO 1
94#define UTOPPY_NUMENDPOINTS 2 94#define UTOPPY_NUMENDPOINTS 2
95 95
96#define UTOPPY_BSIZE 0xffff 96#define UTOPPY_BSIZE 0xffff
97#define UTOPPY_FRAG_SIZE 0x1000 97#define UTOPPY_FRAG_SIZE 0x1000
98#define UTOPPY_HEADER_SIZE 8 98#define UTOPPY_HEADER_SIZE 8
99#define UTOPPY_SHORT_TIMEOUT (500) /* 0.5 seconds */ 99#define UTOPPY_SHORT_TIMEOUT (500) /* 0.5 seconds */
100#define UTOPPY_LONG_TIMEOUT (10 * 1000) /* 10 seconds */ 100#define UTOPPY_LONG_TIMEOUT (10 * 1000) /* 10 seconds */
101 101
102/* Protocol Commands and Responses */ 102/* Protocol Commands and Responses */
103#define UTOPPY_RESP_ERROR 0x0001 103#define UTOPPY_RESP_ERROR 0x0001
104#define UTOPPY_CMD_ACK 0x0002 104#define UTOPPY_CMD_ACK 0x0002
105#define UTOPPY_RESP_SUCCESS UTOPPY_CMD_ACK 105#define UTOPPY_RESP_SUCCESS UTOPPY_CMD_ACK
106#define UTOPPY_CMD_CANCEL 0x0003 106#define UTOPPY_CMD_CANCEL 0x0003
107#define UTOPPY_CMD_READY 0x0100 107#define UTOPPY_CMD_READY 0x0100
108#define UTOPPY_CMD_RESET 0x0101 108#define UTOPPY_CMD_RESET 0x0101
109#define UTOPPY_CMD_TURBO 0x0102 109#define UTOPPY_CMD_TURBO 0x0102
110#define UTOPPY_CMD_STATS 0x1000 110#define UTOPPY_CMD_STATS 0x1000
111#define UTOPPY_RESP_STATS_DATA 0x1001 111#define UTOPPY_RESP_STATS_DATA 0x1001
112#define UTOPPY_CMD_READDIR 0x1002 112#define UTOPPY_CMD_READDIR 0x1002
113#define UTOPPY_RESP_READDIR_DATA 0x1003 113#define UTOPPY_RESP_READDIR_DATA 0x1003
114#define UTOPPY_RESP_READDIR_END 0x1004 114#define UTOPPY_RESP_READDIR_END 0x1004
115#define UTOPPY_CMD_DELETE 0x1005 115#define UTOPPY_CMD_DELETE 0x1005
116#define UTOPPY_CMD_RENAME 0x1006 116#define UTOPPY_CMD_RENAME 0x1006
117#define UTOPPY_CMD_MKDIR 0x1007 117#define UTOPPY_CMD_MKDIR 0x1007
118#define UTOPPY_CMD_FILE 0x1008 118#define UTOPPY_CMD_FILE 0x1008
119#define UTOPPY_FILE_WRITE 0 119#define UTOPPY_FILE_WRITE 0
120#define UTOPPY_FILE_READ 1 120#define UTOPPY_FILE_READ 1
121#define UTOPPY_RESP_FILE_HEADER 0x1009 121#define UTOPPY_RESP_FILE_HEADER 0x1009
122#define UTOPPY_RESP_FILE_DATA 0x100a 122#define UTOPPY_RESP_FILE_DATA 0x100a
123#define UTOPPY_RESP_FILE_END 0x100b 123#define UTOPPY_RESP_FILE_END 0x100b
124 124
125enum utoppy_state { 125enum utoppy_state {
126 UTOPPY_STATE_CLOSED, 126 UTOPPY_STATE_CLOSED,
127 UTOPPY_STATE_OPENING, 127 UTOPPY_STATE_OPENING,
128 UTOPPY_STATE_IDLE, 128 UTOPPY_STATE_IDLE,
129 UTOPPY_STATE_READDIR, 129 UTOPPY_STATE_READDIR,
130 UTOPPY_STATE_READFILE, 130 UTOPPY_STATE_READFILE,
131 UTOPPY_STATE_WRITEFILE 131 UTOPPY_STATE_WRITEFILE
132}; 132};
133 133
134struct utoppy_softc { 134struct utoppy_softc {
135 device_t sc_dev; 135 device_t sc_dev;
136 struct usbd_device *sc_udev; /* device */ 136 struct usbd_device *sc_udev; /* device */
137 struct usbd_interface *sc_iface; /* interface */ 137 struct usbd_interface *sc_iface; /* interface */
138 int sc_dying; 138 int sc_dying;
139 int sc_refcnt; 139 int sc_refcnt;
140 140
141 enum utoppy_state sc_state; 141 enum utoppy_state sc_state;
142 u_int sc_turbo_mode; 142 u_int sc_turbo_mode;
143 143
144 int sc_out; 144 int sc_out;
145 struct usbd_pipe *sc_out_pipe; /* bulk out pipe */ 145 struct usbd_pipe *sc_out_pipe; /* bulk out pipe */
146 struct usbd_xfer *sc_out_xfer; 146 struct usbd_xfer *sc_out_xfer;
147 void *sc_out_buf; 147 void *sc_out_buf;
148 void *sc_out_data; 148 void *sc_out_data;
149 uint64_t sc_wr_offset; 149 uint64_t sc_wr_offset;
150 uint64_t sc_wr_size; 150 uint64_t sc_wr_size;
151 151
152 int sc_in; 152 int sc_in;
153 struct usbd_pipe *sc_in_pipe; /* bulk in pipe */ 153 struct usbd_pipe *sc_in_pipe; /* bulk in pipe */
154 struct usbd_xfer *sc_in_xfer; 154 struct usbd_xfer *sc_in_xfer;
155 void *sc_in_buf; 155 void *sc_in_buf;
156 void *sc_in_data; 156 void *sc_in_data;
157 size_t sc_in_len; 157 size_t sc_in_len;
158 u_int sc_in_offset; 158 u_int sc_in_offset;
159}; 159};
160 160
161struct utoppy_header { 161struct utoppy_header {
162 uint16_t h_len; 162 uint16_t h_len;
163 uint16_t h_crc; 163 uint16_t h_crc;
164 uint16_t h_cmd2; 164 uint16_t h_cmd2;
165 uint16_t h_cmd; 165 uint16_t h_cmd;
166 uint8_t h_data[0]; 166 uint8_t h_data[0];
167}; 167};
168#define UTOPPY_OUT_INIT(sc) \ 168#define UTOPPY_OUT_INIT(sc) \
169 do { \ 169 do { \
170 struct utoppy_header *_h = sc->sc_out_data; \ 170 struct utoppy_header *_h = sc->sc_out_data; \
171 _h->h_len = 0; \ 171 _h->h_len = 0; \
172 } while (/*CONSTCOND*/0) 172 } while (/*CONSTCOND*/0)
173 173
174#define UTOPPY_MJD_1970 40587u /* MJD value for Jan 1 00:00:00 1970 */ 174#define UTOPPY_MJD_1970 40587u /* MJD value for Jan 1 00:00:00 1970 */
175 175
176#define UTOPPY_FTYPE_DIR 1 176#define UTOPPY_FTYPE_DIR 1
177#define UTOPPY_FTYPE_FILE 2 177#define UTOPPY_FTYPE_FILE 2
178 178
179#define UTOPPY_IN_DATA(sc) \ 179#define UTOPPY_IN_DATA(sc) \
180 ((void*)&(((uint8_t*)(sc)->sc_in_data)[(sc)->sc_in_offset+UTOPPY_HEADER_SIZE])) 180 ((void*)&(((uint8_t*)(sc)->sc_in_data)[(sc)->sc_in_offset+UTOPPY_HEADER_SIZE]))
181 181
182static dev_type_open(utoppyopen); 182static dev_type_open(utoppyopen);
183static dev_type_close(utoppyclose); 183static dev_type_close(utoppyclose);
184static dev_type_read(utoppyread); 184static dev_type_read(utoppyread);
185static dev_type_write(utoppywrite); 185static dev_type_write(utoppywrite);
186static dev_type_ioctl(utoppyioctl); 186static dev_type_ioctl(utoppyioctl);
187 187
188const struct cdevsw utoppy_cdevsw = { 188const struct cdevsw utoppy_cdevsw = {
189 .d_open = utoppyopen, 189 .d_open = utoppyopen,
190 .d_close = utoppyclose, 190 .d_close = utoppyclose,
191 .d_read = utoppyread, 191 .d_read = utoppyread,
192 .d_write = utoppywrite, 192 .d_write = utoppywrite,
193 .d_ioctl = utoppyioctl, 193 .d_ioctl = utoppyioctl,
194 .d_stop = nostop, 194 .d_stop = nostop,
195 .d_tty = notty, 195 .d_tty = notty,
196 .d_poll = nopoll, 196 .d_poll = nopoll,
197 .d_mmap = nommap, 197 .d_mmap = nommap,
198 .d_kqfilter = nokqfilter, 198 .d_kqfilter = nokqfilter,
199 .d_discard = nodiscard, 199 .d_discard = nodiscard,
200 .d_flag = D_OTHER 200 .d_flag = D_OTHER
201}; 201};
202 202
203#define UTOPPYUNIT(n) (minor(n)) 203#define UTOPPYUNIT(n) (minor(n))
204 204
205static int utoppy_match(device_t, cfdata_t, void *); 205static int utoppy_match(device_t, cfdata_t, void *);
206static void utoppy_attach(device_t, device_t, void *); 206static void utoppy_attach(device_t, device_t, void *);
207static int utoppy_detach(device_t, int); 207static int utoppy_detach(device_t, int);
208static int utoppy_activate(device_t, enum devact); 208static int utoppy_activate(device_t, enum devact);
209 209
210CFATTACH_DECL_NEW(utoppy, sizeof(struct utoppy_softc), utoppy_match, 210CFATTACH_DECL_NEW(utoppy, sizeof(struct utoppy_softc), utoppy_match,
211 utoppy_attach, utoppy_detach, utoppy_activate); 211 utoppy_attach, utoppy_detach, utoppy_activate);
212 212
213static int 213static int
214utoppy_match(device_t parent, cfdata_t match, void *aux) 214utoppy_match(device_t parent, cfdata_t match, void *aux)
215{ 215{
216 struct usb_attach_arg *uaa = aux; 216 struct usb_attach_arg *uaa = aux;
217 217
218 if (uaa->uaa_vendor == USB_VENDOR_TOPFIELD && 218 if (uaa->uaa_vendor == USB_VENDOR_TOPFIELD &&
219 uaa->uaa_product == USB_PRODUCT_TOPFIELD_TF5000PVR) 219 uaa->uaa_product == USB_PRODUCT_TOPFIELD_TF5000PVR)
220 return UMATCH_VENDOR_PRODUCT; 220 return UMATCH_VENDOR_PRODUCT;
221 221
222 return UMATCH_NONE; 222 return UMATCH_NONE;
223} 223}
224 224
225static void 225static void
226utoppy_attach(device_t parent, device_t self, void *aux) 226utoppy_attach(device_t parent, device_t self, void *aux)
227{ 227{
228 struct utoppy_softc *sc = device_private(self); 228 struct utoppy_softc *sc = device_private(self);
229 struct usb_attach_arg *uaa = aux; 229 struct usb_attach_arg *uaa = aux;
230 struct usbd_device *dev = uaa->uaa_device; 230 struct usbd_device *dev = uaa->uaa_device;
231 struct usbd_interface *iface; 231 struct usbd_interface *iface;
232 usb_endpoint_descriptor_t *ed; 232 usb_endpoint_descriptor_t *ed;
233 char *devinfop; 233 char *devinfop;
234 uint8_t epcount; 234 uint8_t epcount;
235 int i; 235 int i;
236 236
237 sc->sc_dev = self; 237 sc->sc_dev = self;
238 238
239 aprint_naive("\n"); 239 aprint_naive("\n");
240 aprint_normal("\n"); 240 aprint_normal("\n");
241 241
242 devinfop = usbd_devinfo_alloc(dev, 0); 242 devinfop = usbd_devinfo_alloc(dev, 0);
243 aprint_normal_dev(self, "%s\n", devinfop); 243 aprint_normal_dev(self, "%s\n", devinfop);
244 usbd_devinfo_free(devinfop); 244 usbd_devinfo_free(devinfop);
245 245
246 sc->sc_dying = 0; 246 sc->sc_dying = 0;
247 sc->sc_refcnt = 0; 247 sc->sc_refcnt = 0;
248 sc->sc_udev = dev; 248 sc->sc_udev = dev;
249 249
250 if (usbd_set_config_index(dev, 0, 1) 250 if (usbd_set_config_index(dev, 0, 1)
251 || usbd_device2interface_handle(dev, 0, &iface)) { 251 || usbd_device2interface_handle(dev, 0, &iface)) {
252 aprint_error_dev(self, "Configuration failed\n"); 252 aprint_error_dev(self, "Configuration failed\n");
253 return; 253 return;
254 } 254 }
255 255
256 epcount = 0; 256 epcount = 0;
257 (void) usbd_endpoint_count(iface, &epcount); 257 (void) usbd_endpoint_count(iface, &epcount);
258 if (epcount != UTOPPY_NUMENDPOINTS) { 258 if (epcount != UTOPPY_NUMENDPOINTS) {
259 aprint_error_dev(self, "Expected %d endpoints, got %d\n", 259 aprint_error_dev(self, "Expected %d endpoints, got %d\n",
260 UTOPPY_NUMENDPOINTS, epcount); 260 UTOPPY_NUMENDPOINTS, epcount);
261 return; 261 return;
262 } 262 }
263 263
264 sc->sc_in = -1; 264 sc->sc_in = -1;
265 sc->sc_out = -1; 265 sc->sc_out = -1;
266 266
267 for (i = 0; i < epcount; i++) { 267 for (i = 0; i < epcount; i++) {
268 ed = usbd_interface2endpoint_descriptor(iface, i); 268 ed = usbd_interface2endpoint_descriptor(iface, i);
269 if (ed == NULL) { 269 if (ed == NULL) {
270 aprint_error_dev(self, "couldn't get ep %d\n", i); 270 aprint_error_dev(self, "couldn't get ep %d\n", i);
271 return; 271 return;
272 } 272 }
273 273
274 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && 274 if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
275 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 275 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
276 sc->sc_in = ed->bEndpointAddress; 276 sc->sc_in = ed->bEndpointAddress;
277 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && 277 } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
278 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { 278 UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
279 sc->sc_out = ed->bEndpointAddress; 279 sc->sc_out = ed->bEndpointAddress;
280 } 280 }
281 } 281 }
282 282
283 if (sc->sc_out == -1 || sc->sc_in == -1) { 283 if (sc->sc_out == -1 || sc->sc_in == -1) {
284 aprint_error_dev(self, 284 aprint_error_dev(self,
285 "could not find bulk in/out endpoints\n"); 285 "could not find bulk in/out endpoints\n");
286 sc->sc_dying = 1; 286 sc->sc_dying = 1;
287 return; 287 return;
288 } 288 }
289 289
290 sc->sc_iface = iface; 290 sc->sc_iface = iface;
291 sc->sc_udev = dev; 291 sc->sc_udev = dev;
292 292
293 sc->sc_out_pipe = NULL; 293 sc->sc_out_pipe = NULL;
294 sc->sc_in_pipe = NULL; 294 sc->sc_in_pipe = NULL;
295 295
296 if (usbd_open_pipe(sc->sc_iface, sc->sc_out, 0, &sc->sc_out_pipe)) { 296 if (usbd_open_pipe(sc->sc_iface, sc->sc_out, 0, &sc->sc_out_pipe)) {
297 DPRINTF(UTOPPY_DBG_OPEN, ("%s: usbd_open_pipe(OUT) failed\n", 297 DPRINTF(UTOPPY_DBG_OPEN, ("%s: usbd_open_pipe(OUT) failed\n",
298 device_xname(sc->sc_dev))); 298 device_xname(sc->sc_dev)));
299 aprint_error_dev(self, "could not open OUT pipe\n"); 299 aprint_error_dev(self, "could not open OUT pipe\n");
300 sc->sc_dying = 1; 300 sc->sc_dying = 1;
301 return; 301 return;
302 } 302 }
303 303
304 if (usbd_open_pipe(sc->sc_iface, sc->sc_in, 0, &sc->sc_in_pipe)) { 304 if (usbd_open_pipe(sc->sc_iface, sc->sc_in, 0, &sc->sc_in_pipe)) {
305 DPRINTF(UTOPPY_DBG_OPEN, ("%s: usbd_open_pipe(IN) failed\n", 305 DPRINTF(UTOPPY_DBG_OPEN, ("%s: usbd_open_pipe(IN) failed\n",
306 device_xname(sc->sc_dev))); 306 device_xname(sc->sc_dev)));
307 aprint_error_dev(self, "could not open IN pipe\n"); 307 aprint_error_dev(self, "could not open IN pipe\n");
308 308
309 usbd_close_pipe(sc->sc_out_pipe); 309 usbd_close_pipe(sc->sc_out_pipe);
310 sc->sc_out_pipe = NULL; 310 sc->sc_out_pipe = NULL;
311 sc->sc_dying = 1; 311 sc->sc_dying = 1;
312 return; 312 return;
313 } 313 }
314 314
315 int error; 315 int error;
316 error = usbd_create_xfer(sc->sc_out_pipe, UTOPPY_FRAG_SIZE, 0, 0, 316 error = usbd_create_xfer(sc->sc_out_pipe, UTOPPY_FRAG_SIZE, 0, 0,
317 &sc->sc_out_xfer); 317 &sc->sc_out_xfer);
318 if (error) { 318 if (error) {
319 aprint_error_dev(self, "could not allocate bulk out xfer\n"); 319 aprint_error_dev(self, "could not allocate bulk out xfer\n");
320 goto fail0; 320 goto fail0;
321 } 321 }
322 322
323 error = usbd_create_xfer(sc->sc_in_pipe, UTOPPY_FRAG_SIZE, 323 error = usbd_create_xfer(sc->sc_in_pipe, UTOPPY_FRAG_SIZE,
324 0, 0, &sc->sc_in_xfer); 324 0, 0, &sc->sc_in_xfer);
325 if (error) { 325 if (error) {
326 aprint_error_dev(self, "could not allocate bulk in xfer\n"); 326 aprint_error_dev(self, "could not allocate bulk in xfer\n");
327 goto fail1; 327 goto fail1;
328 } 328 }
329 329
330 sc->sc_out_buf = usbd_get_buffer(sc->sc_out_xfer); 330 sc->sc_out_buf = usbd_get_buffer(sc->sc_out_xfer);
331 sc->sc_in_buf = usbd_get_buffer(sc->sc_in_xfer); 331 sc->sc_in_buf = usbd_get_buffer(sc->sc_in_xfer);
332 332
333 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev); 333 usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev);
334 334
335 return; 335 return;
336 336
337 fail1: usbd_destroy_xfer(sc->sc_out_xfer); 337 fail1: usbd_destroy_xfer(sc->sc_out_xfer);
338 sc->sc_out_xfer = NULL; 338 sc->sc_out_xfer = NULL;
339 339
340 fail0: sc->sc_dying = 1; 340 fail0: sc->sc_dying = 1;
341 return; 341 return;
342} 342}
343 343
344static int 344static int
345utoppy_activate(device_t self, enum devact act) 345utoppy_activate(device_t self, enum devact act)
346{ 346{
347 struct utoppy_softc *sc = device_private(self); 347 struct utoppy_softc *sc = device_private(self);
348 348
349 switch (act) { 349 switch (act) {
350 case DVACT_DEACTIVATE: 350 case DVACT_DEACTIVATE:
351 sc->sc_dying = 1; 351 sc->sc_dying = 1;
352 return 0; 352 return 0;
353 default: 353 default:
354 return EOPNOTSUPP; 354 return EOPNOTSUPP;
355 } 355 }
356} 356}
357 357
358static int 358static int
359utoppy_detach(device_t self, int flags) 359utoppy_detach(device_t self, int flags)
360{ 360{
361 struct utoppy_softc *sc = device_private(self); 361 struct utoppy_softc *sc = device_private(self);
362 int maj, mn; 362 int maj, mn;
363 int s; 363 int s;
364 364
365 sc->sc_dying = 1; 365 sc->sc_dying = 1;
366 if (sc->sc_out_pipe != NULL) 366 if (sc->sc_out_pipe != NULL)
367 usbd_abort_pipe(sc->sc_out_pipe); 367 usbd_abort_pipe(sc->sc_out_pipe);
368 if (sc->sc_in_pipe != NULL) 368 if (sc->sc_in_pipe != NULL)
369 usbd_abort_pipe(sc->sc_in_pipe); 369 usbd_abort_pipe(sc->sc_in_pipe);
370 370
371 if (sc->sc_in_xfer != NULL) 371 if (sc->sc_in_xfer != NULL)
372 usbd_destroy_xfer(sc->sc_in_xfer); 372 usbd_destroy_xfer(sc->sc_in_xfer);
373 if (sc->sc_out_xfer != NULL) 373 if (sc->sc_out_xfer != NULL)
374 usbd_destroy_xfer(sc->sc_out_xfer); 374 usbd_destroy_xfer(sc->sc_out_xfer);
375 375
376 if (sc->sc_out_pipe != NULL) 376 if (sc->sc_out_pipe != NULL)
377 usbd_close_pipe(sc->sc_out_pipe); 377 usbd_close_pipe(sc->sc_out_pipe);
378 if (sc->sc_in_pipe != NULL) 378 if (sc->sc_in_pipe != NULL)
379 usbd_close_pipe(sc->sc_in_pipe); 379 usbd_close_pipe(sc->sc_in_pipe);
380 380
381 s = splusb(); 381 s = splusb();
382 if (--sc->sc_refcnt >= 0) 382 if (--sc->sc_refcnt >= 0)
383 usb_detach_waitold(sc->sc_dev); 383 usb_detach_waitold(sc->sc_dev);
384 splx(s); 384 splx(s);
385 385
386 /* locate the major number */ 386 /* locate the major number */
387 maj = cdevsw_lookup_major(&utoppy_cdevsw); 387 maj = cdevsw_lookup_major(&utoppy_cdevsw);
388 388
389 /* Nuke the vnodes for any open instances (calls close). */ 389 /* Nuke the vnodes for any open instances (calls close). */
390 mn = device_unit(self); 390 mn = device_unit(self);
391 vdevgone(maj, mn, mn, VCHR); 391 vdevgone(maj, mn, mn, VCHR);
392 392
393 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev); 393 usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev);
394 394
395 return 0; 395 return 0;
396} 396}
397 397
398#define UTOPPY_CRC16(ccrc,b) crc16_byte((ccrc), (b)) /* from crc16.h */ 398#define UTOPPY_CRC16(ccrc,b) crc16_byte((ccrc), (b)) /* from crc16.h */
399 399
400static const int utoppy_usbdstatus_lookup[] = { 400static const int utoppy_usbdstatus_lookup[] = {
401 0, /* USBD_NORMAL_COMPLETION */ 401 0, /* USBD_NORMAL_COMPLETION */
402 EINPROGRESS, /* USBD_IN_PROGRESS */ 402 EINPROGRESS, /* USBD_IN_PROGRESS */
403 EALREADY, /* USBD_PENDING_REQUESTS */ 403 EALREADY, /* USBD_PENDING_REQUESTS */
404 EAGAIN, /* USBD_NOT_STARTED */ 404 EAGAIN, /* USBD_NOT_STARTED */
405 EINVAL, /* USBD_INVAL */ 405 EINVAL, /* USBD_INVAL */
406 ENOMEM, /* USBD_NOMEM */ 406 ENOMEM, /* USBD_NOMEM */
407 ECONNRESET, /* USBD_CANCELLED */ 407 ECONNRESET, /* USBD_CANCELLED */
408 EFAULT, /* USBD_BAD_ADDRESS */ 408 EFAULT, /* USBD_BAD_ADDRESS */
409 EBUSY, /* USBD_IN_USE */ 409 EBUSY, /* USBD_IN_USE */
410 EADDRNOTAVAIL, /* USBD_NO_ADDR */ 410 EADDRNOTAVAIL, /* USBD_NO_ADDR */
411 ENETDOWN, /* USBD_SET_ADDR_FAILED */ 411 ENETDOWN, /* USBD_SET_ADDR_FAILED */
412 EIO, /* USBD_NO_POWER */ 412 EIO, /* USBD_NO_POWER */
413 EMLINK, /* USBD_TOO_DEEP */ 413 EMLINK, /* USBD_TOO_DEEP */
414 EIO, /* USBD_IOERROR */ 414 EIO, /* USBD_IOERROR */
415 ENXIO, /* USBD_NOT_CONFIGURED */ 415 ENXIO, /* USBD_NOT_CONFIGURED */
416 ETIMEDOUT, /* USBD_TIMEOUT */ 416 ETIMEDOUT, /* USBD_TIMEOUT */
417 EBADMSG, /* USBD_SHORT_XFER */ 417 EBADMSG, /* USBD_SHORT_XFER */
418 EHOSTDOWN, /* USBD_STALLED */ 418 EHOSTDOWN, /* USBD_STALLED */
419 EINTR /* USBD_INTERRUPTED */ 419 EINTR /* USBD_INTERRUPTED */
420}; 420};
421 421
422static __inline int 422static __inline int
423utoppy_usbd_status2errno(usbd_status err) 423utoppy_usbd_status2errno(usbd_status err)
424{ 424{
425 425
426 if (err >= USBD_ERROR_MAX) 426 if (err >= USBD_ERROR_MAX)
427 return EFAULT; 427 return EFAULT;
428 return utoppy_usbdstatus_lookup[err]; 428 return utoppy_usbdstatus_lookup[err];
429} 429}
430 430
431#ifdef UTOPPY_DEBUG 431#ifdef UTOPPY_DEBUG
432static const char * 432static const char *
433utoppy_state_string(enum utoppy_state state) 433utoppy_state_string(enum utoppy_state state)
434{ 434{
435 const char *str; 435 const char *str;
436 436
437 switch (state) { 437 switch (state) {
438 case UTOPPY_STATE_CLOSED: 438 case UTOPPY_STATE_CLOSED:
439 str = "CLOSED"; 439 str = "CLOSED";
440 break; 440 break;
441 case UTOPPY_STATE_OPENING: 441 case UTOPPY_STATE_OPENING:
442 str = "OPENING"; 442 str = "OPENING";
443 break; 443 break;
444 case UTOPPY_STATE_IDLE: 444 case UTOPPY_STATE_IDLE:
445 str = "IDLE"; 445 str = "IDLE";
446 break; 446 break;
447 case UTOPPY_STATE_READDIR: 447 case UTOPPY_STATE_READDIR:
448 str = "READ DIRECTORY"; 448 str = "READ DIRECTORY";
449 break; 449 break;
450 case UTOPPY_STATE_READFILE: 450 case UTOPPY_STATE_READFILE:
451 str = "READ FILE"; 451 str = "READ FILE";
452 break; 452 break;
453 case UTOPPY_STATE_WRITEFILE: 453 case UTOPPY_STATE_WRITEFILE:
454 str = "WRITE FILE"; 454 str = "WRITE FILE";
455 break; 455 break;
456 default: 456 default:
457 str = "INVALID!"; 457 str = "INVALID!";
458 break; 458 break;
459 } 459 }
460 460
461 return str; 461 return str;
462} 462}
463 463
464static void 464static void
465utoppy_dump_packet(const void *b, size_t len) 465utoppy_dump_packet(const void *b, size_t len)
466{ 466{
467 const uint8_t *buf = b, *l; 467 const uint8_t *buf = b, *l;
468 uint8_t c; 468 uint8_t c;
469 size_t i, j; 469 size_t i, j;
470 470
471 if (len == 0) 471 if (len == 0)
472 return; 472 return;
473 473
474 len = uimin(len, 256); 474 len = uimin(len, 256);
475 475
476 printf("00: "); 476 printf("00: ");
477 477
478 for (i = 0, l = buf; i < len; i++) { 478 for (i = 0, l = buf; i < len; i++) {
479 printf("%02x ", *buf++); 479 printf("%02x ", *buf++);
480 480
481 if ((i % 16) == 15) { 481 if ((i % 16) == 15) {
482 for (j = 0; j < 16; j++) { 482 for (j = 0; j < 16; j++) {
483 c = *l++; 483 c = *l++;
484 if (c < ' ' || c > 0x7e) 484 if (c < ' ' || c > 0x7e)
485 c = '.'; 485 c = '.';
486 printf("%c", c); 486 printf("%c", c);
487 } 487 }
488 488
489 printf("\n"); 489 printf("\n");
490 l = buf; 490 l = buf;
491 491
492 if ((i + 1) < len) 492 if ((i + 1) < len)
493 printf("%02x: ", (u_int)i + 1); 493 printf("%02x: ", (u_int)i + 1);
494 } 494 }
495 } 495 }
496 496
497 while ((i++ % 16) != 0) 497 while ((i++ % 16) != 0)
498 printf(" "); 498 printf(" ");
499 499
500 if (l < buf) { 500 if (l < buf) {
501 while (l < buf) { 501 while (l < buf) {
502 c = *l++; 502 c = *l++;
503 if (c < ' ' || c > 0x7e) 503 if (c < ' ' || c > 0x7e)
504 c = '.'; 504 c = '.';
505 printf("%c", c); 505 printf("%c", c);
506 } 506 }
507 507
508 printf("\n"); 508 printf("\n");
509 } 509 }
510} 510}
511#endif 511#endif
512 512
513static usbd_status 513static usbd_status
514utoppy_bulk_transfer(struct usbd_xfer *xfer, struct usbd_pipe *pipe, 514utoppy_bulk_transfer(struct usbd_xfer *xfer, struct usbd_pipe *pipe,
515 uint16_t flags, uint32_t timeout, void *buf, uint32_t *size) 515 uint16_t flags, uint32_t timeout, void *buf, uint32_t *size)
516{ 516{
517 usbd_status err; 517 usbd_status err;
518 518
519 usbd_setup_xfer(xfer, 0, buf, *size, flags, timeout, NULL); 519 usbd_setup_xfer(xfer, 0, buf, *size, flags, timeout, NULL);
520 520
521 err = usbd_sync_transfer_sig(xfer); 521 err = usbd_sync_transfer_sig(xfer);
522 522
523 usbd_get_xfer_status(xfer, NULL, NULL, size, NULL); 523 usbd_get_xfer_status(xfer, NULL, NULL, size, NULL);
524 return err; 524 return err;
525} 525}
526 526
527static int 527static int
528utoppy_send_packet(struct utoppy_softc *sc, uint16_t cmd, uint32_t timeout) 528utoppy_send_packet(struct utoppy_softc *sc, uint16_t cmd, uint32_t timeout)
529{ 529{
530 struct utoppy_header *h; 530 struct utoppy_header *h;
531 usbd_status err; 531 usbd_status err;
532 uint32_t len; 532 uint32_t len;
533 uint16_t dlen, crc; 533 uint16_t dlen, crc;
534 uint8_t *data, *e, t1, t2; 534 uint8_t *data, *e, t1, t2;
535 535
536 h = sc->sc_out_data; 536 h = sc->sc_out_data;
537 537
538 DPRINTF(UTOPPY_DBG_SEND_PACKET, ("%s: utoppy_send_packet: cmd 0x%04x, " 538 DPRINTF(UTOPPY_DBG_SEND_PACKET, ("%s: utoppy_send_packet: cmd 0x%04x, "
539 "len %d\n", device_xname(sc->sc_dev), (u_int)cmd, h->h_len)); 539 "len %d\n", device_xname(sc->sc_dev), (u_int)cmd, h->h_len));
540 540
541 dlen = h->h_len; 541 dlen = h->h_len;
542 len = dlen + UTOPPY_HEADER_SIZE; 542 len = dlen + UTOPPY_HEADER_SIZE;
543 543
544 if (len & 1) 544 if (len & 1)
545 len++; 545 len++;
546 if ((len % 64) == 0) 546 if ((len % 64) == 0)
547 len += 2; 547 len += 2;
548 548
549 if (len >= UTOPPY_BSIZE) { 549 if (len >= UTOPPY_BSIZE) {
550 DPRINTF(UTOPPY_DBG_SEND_PACKET, ("%s: utoppy_send_packet: " 550 DPRINTF(UTOPPY_DBG_SEND_PACKET, ("%s: utoppy_send_packet: "
551 "packet too big (%d)\n", device_xname(sc->sc_dev), 551 "packet too big (%d)\n", device_xname(sc->sc_dev),
552 (int)len)); 552 (int)len));
553 return EINVAL; 553 return EINVAL;
554 } 554 }
555 555
556 h->h_len = htole16(dlen + UTOPPY_HEADER_SIZE); 556 h->h_len = htole16(dlen + UTOPPY_HEADER_SIZE);
557 h->h_cmd2 = 0; 557 h->h_cmd2 = 0;
558 h->h_cmd = htole16(cmd); 558 h->h_cmd = htole16(cmd);
559 559
560 /* The command word is part of the CRC */ 560 /* The command word is part of the CRC */
561 crc = UTOPPY_CRC16(0, 0); 561 crc = UTOPPY_CRC16(0, 0);
562 crc = UTOPPY_CRC16(crc, 0); 562 crc = UTOPPY_CRC16(crc, 0);
563 crc = UTOPPY_CRC16(crc, cmd >> 8); 563 crc = UTOPPY_CRC16(crc, cmd >> 8);
564 crc = UTOPPY_CRC16(crc, cmd); 564 crc = UTOPPY_CRC16(crc, cmd);
565 565
566 /* 566 /*
567 * If there is data following the header, calculate the CRC and 567 * If there is data following the header, calculate the CRC and
568 * byte-swap as we go. 568 * byte-swap as we go.
569 */ 569 */
570 if (dlen) { 570 if (dlen) {
571 data = h->h_data; 571 data = h->h_data;
572 e = data + (dlen & ~1); 572 e = data + (dlen & ~1);
573 573
574 do { 574 do {
575 t1 = data[0]; 575 t1 = data[0];
576 t2 = data[1]; 576 t2 = data[1];
577 crc = UTOPPY_CRC16(crc, t1); 577 crc = UTOPPY_CRC16(crc, t1);
578 crc = UTOPPY_CRC16(crc, t2); 578 crc = UTOPPY_CRC16(crc, t2);
579 *data++ = t2; 579 *data++ = t2;
580 *data++ = t1; 580 *data++ = t1;
581 } while (data < e); 581 } while (data < e);
582 582
583 if (dlen & 1) { 583 if (dlen & 1) {
584 t1 = data[0]; 584 t1 = data[0];
585 crc = UTOPPY_CRC16(crc, t1); 585 crc = UTOPPY_CRC16(crc, t1);
586 data[1] = t1; 586 data[1] = t1;
587 } 587 }
588 } 588 }
589 589
590 h->h_crc = htole16(crc); 590 h->h_crc = htole16(crc);
591 data = sc->sc_out_data; 591 data = sc->sc_out_data;
592 592
593 DPRINTF(UTOPPY_DBG_SEND_PACKET, ("%s: utoppy_send_packet: total len " 593 DPRINTF(UTOPPY_DBG_SEND_PACKET, ("%s: utoppy_send_packet: total len "
594 "%d...\n", device_xname(sc->sc_dev), (int)len)); 594 "%d...\n", device_xname(sc->sc_dev), (int)len));
595 DDUMP_PACKET(data, len); 595 DDUMP_PACKET(data, len);
596 596
597 do { 597 do {
598 uint32_t thislen; 598 uint32_t thislen;
599 599
600 thislen = uimin(len, UTOPPY_FRAG_SIZE); 600 thislen = uimin(len, UTOPPY_FRAG_SIZE);
601 601
602 memcpy(sc->sc_out_buf, data, thislen); 602 memcpy(sc->sc_out_buf, data, thislen);
603 603
604 err = utoppy_bulk_transfer(sc->sc_out_xfer, sc->sc_out_pipe, 604 err = utoppy_bulk_transfer(sc->sc_out_xfer, sc->sc_out_pipe,
605 0, timeout, sc->sc_out_buf, &thislen); 605 0, timeout, sc->sc_out_buf, &thislen);
606 606
607 if (thislen != uimin(len, UTOPPY_FRAG_SIZE)) { 607 if (thislen != uimin(len, UTOPPY_FRAG_SIZE)) {
608 DPRINTF(UTOPPY_DBG_SEND_PACKET, ("%s: " 608 DPRINTF(UTOPPY_DBG_SEND_PACKET, ("%s: "
609 "utoppy_send_packet: sent %ld, err %d\n", 609 "utoppy_send_packet: sent %ld, err %d\n",
610 device_xname(sc->sc_dev), (u_long)thislen, err)); 610 device_xname(sc->sc_dev), (u_long)thislen, err));
611 } 611 }
612 612
613 if (err == 0) { 613 if (err == 0) {
614 len -= thislen; 614 len -= thislen;
615 data += thislen; 615 data += thislen;
616 } 616 }
617 } while (err == 0 && len); 617 } while (err == 0 && len);
618 618
619 DPRINTF(UTOPPY_DBG_SEND_PACKET, ("%s: utoppy_send_packet: " 619 DPRINTF(UTOPPY_DBG_SEND_PACKET, ("%s: utoppy_send_packet: "
620 "usbd_bulk_transfer() returned %d.\n", 620 "usbd_bulk_transfer() returned %d.\n",
621 device_xname(sc->sc_dev),err)); 621 device_xname(sc->sc_dev),err));
622 622
623 return err ? utoppy_usbd_status2errno(err) : 0; 623 return err ? utoppy_usbd_status2errno(err) : 0;
624} 624}
625 625
626static int 626static int
627utoppy_recv_packet(struct utoppy_softc *sc, uint16_t *respp, uint32_t timeout) 627utoppy_recv_packet(struct utoppy_softc *sc, uint16_t *respp, uint32_t timeout)
628{ 628{
629 struct utoppy_header *h; 629 struct utoppy_header *h;
630 usbd_status err; 630 usbd_status err;
631 uint32_t len, thislen, requested, bytesleft; 631 uint32_t len, thislen, requested, bytesleft;
632 uint16_t crc; 632 uint16_t crc;
633 uint8_t *data, *e, t1, t2; 633 uint8_t *data, *e, t1, t2;
634 634
635 data = sc->sc_in_data; 635 data = sc->sc_in_data;
636 len = 0; 636 len = 0;
637 bytesleft = UTOPPY_BSIZE; 637 bytesleft = UTOPPY_BSIZE;
638 638
639 DPRINTF(UTOPPY_DBG_RECV_PACKET, ("%s: utoppy_recv_packet: ...\n", 639 DPRINTF(UTOPPY_DBG_RECV_PACKET, ("%s: utoppy_recv_packet: ...\n",
640 device_xname(sc->sc_dev))); 640 device_xname(sc->sc_dev)));
641 641
642 do { 642 do {
643 requested = thislen = uimin(bytesleft, UTOPPY_FRAG_SIZE); 643 requested = thislen = uimin(bytesleft, UTOPPY_FRAG_SIZE);
644 644
645 err = utoppy_bulk_transfer(sc->sc_in_xfer, sc->sc_in_pipe, 645 err = utoppy_bulk_transfer(sc->sc_in_xfer, sc->sc_in_pipe,
646 USBD_SHORT_XFER_OK, timeout, sc->sc_in_buf, 646 USBD_SHORT_XFER_OK, timeout, sc->sc_in_buf,
647 &thislen); 647 &thislen);
648 648
649 DPRINTF(UTOPPY_DBG_RECV_PACKET, ("%s: utoppy_recv_packet: " 649 DPRINTF(UTOPPY_DBG_RECV_PACKET, ("%s: utoppy_recv_packet: "
650 "usbd_bulk_transfer() returned %d, thislen %d, data %p\n", 650 "usbd_bulk_transfer() returned %d, thislen %d, data %p\n",
651 device_xname(sc->sc_dev), err, (u_int)thislen, data)); 651 device_xname(sc->sc_dev), err, (u_int)thislen, data));
652 652
653 if (err == 0) { 653 if (err == 0) {
654 memcpy(data, sc->sc_in_buf, thislen); 654 memcpy(data, sc->sc_in_buf, thislen);
655 DDUMP_PACKET(data, thislen); 655 DDUMP_PACKET(data, thislen);
656 len += thislen; 656 len += thislen;
657 bytesleft -= thislen; 657 bytesleft -= thislen;
658 data += thislen; 658 data += thislen;
659 } 659 }
660 } while (err == 0 && bytesleft && thislen == requested); 660 } while (err == 0 && bytesleft && thislen == requested);
661 661
662 if (err) 662 if (err)
663 return utoppy_usbd_status2errno(err); 663 return utoppy_usbd_status2errno(err);
664 664
665 h = sc->sc_in_data; 665 h = sc->sc_in_data;
666 666
667 DPRINTF(UTOPPY_DBG_RECV_PACKET, ("%s: utoppy_recv_packet: received %d " 667 DPRINTF(UTOPPY_DBG_RECV_PACKET, ("%s: utoppy_recv_packet: received %d "
668 "bytes in total to %p\n", device_xname(sc->sc_dev), (u_int)len, h)); 668 "bytes in total to %p\n", device_xname(sc->sc_dev), (u_int)len, h));
669 DDUMP_PACKET(h, len); 669 DDUMP_PACKET(h, len);
670 670
671 if (len < UTOPPY_HEADER_SIZE || len < (uint32_t)le16toh(h->h_len)) { 671 if (len < UTOPPY_HEADER_SIZE || len < (uint32_t)le16toh(h->h_len)) {
672 DPRINTF(UTOPPY_DBG_RECV_PACKET, ("%s: utoppy_recv_packet: bad " 672 DPRINTF(UTOPPY_DBG_RECV_PACKET, ("%s: utoppy_recv_packet: bad "
673 " length (len %d, h_len %d)\n", device_xname(sc->sc_dev), 673 " length (len %d, h_len %d)\n", device_xname(sc->sc_dev),
674 (int)len, le16toh(h->h_len))); 674 (int)len, le16toh(h->h_len)));
675 return EIO; 675 return EIO;
676 } 676 }
677 677
678 len = h->h_len = le16toh(h->h_len); 678 len = h->h_len = le16toh(h->h_len);
679 h->h_crc = le16toh(h->h_crc); 679 h->h_crc = le16toh(h->h_crc);
680 *respp = h->h_cmd = le16toh(h->h_cmd); 680 *respp = h->h_cmd = le16toh(h->h_cmd);
681 h->h_cmd2 = le16toh(h->h_cmd2); 681 h->h_cmd2 = le16toh(h->h_cmd2);
682 682
683 /* 683 /*
684 * To maximise data throughput when transferring files, acknowledge 684 * To maximise data throughput when transferring files, acknowledge
685 * data blocks as soon as we receive them. If we detect an error 685 * data blocks as soon as we receive them. If we detect an error
686 * later on, we can always cancel. 686 * later on, we can always cancel.
687 */ 687 */
688 if (*respp == UTOPPY_RESP_FILE_DATA) { 688 if (*respp == UTOPPY_RESP_FILE_DATA) {
689 DPRINTF(UTOPPY_DBG_RECV_PACKET, ("%s: utoppy_recv_packet: " 689 DPRINTF(UTOPPY_DBG_RECV_PACKET, ("%s: utoppy_recv_packet: "
690 "ACKing file data\n", device_xname(sc->sc_dev))); 690 "ACKing file data\n", device_xname(sc->sc_dev)));
691 691
692 UTOPPY_OUT_INIT(sc); 692 UTOPPY_OUT_INIT(sc);
693 err = utoppy_send_packet(sc, UTOPPY_CMD_ACK, 693 err = utoppy_send_packet(sc, UTOPPY_CMD_ACK,
694 UTOPPY_SHORT_TIMEOUT); 694 UTOPPY_SHORT_TIMEOUT);
695 if (err) { 695 if (err) {
696 DPRINTF(UTOPPY_DBG_RECV_PACKET, ("%s: " 696 DPRINTF(UTOPPY_DBG_RECV_PACKET, ("%s: "
697 "utoppy_recv_packet: failed to ACK file data: %d\n", 697 "utoppy_recv_packet: failed to ACK file data: %d\n",
698 device_xname(sc->sc_dev), err)); 698 device_xname(sc->sc_dev), err));
699 return err; 699 return err;
700 } 700 }
701 } 701 }
702 702
703 /* The command word is part of the CRC */ 703 /* The command word is part of the CRC */
704 crc = UTOPPY_CRC16(0, h->h_cmd2 >> 8); 704 crc = UTOPPY_CRC16(0, h->h_cmd2 >> 8);
705 crc = UTOPPY_CRC16(crc, h->h_cmd2); 705 crc = UTOPPY_CRC16(crc, h->h_cmd2);
706 crc = UTOPPY_CRC16(crc, h->h_cmd >> 8); 706 crc = UTOPPY_CRC16(crc, h->h_cmd >> 8);
707 crc = UTOPPY_CRC16(crc, h->h_cmd); 707 crc = UTOPPY_CRC16(crc, h->h_cmd);
708 708
709 /* 709 /*
710 * Extract any payload, byte-swapping and calculating the CRC16 710 * Extract any payload, byte-swapping and calculating the CRC16
711 * as we go. 711 * as we go.
712 */ 712 */
713 if (len > UTOPPY_HEADER_SIZE) { 713 if (len > UTOPPY_HEADER_SIZE) {
714 data = h->h_data; 714 data = h->h_data;
715 e = data + ((len & ~1) - UTOPPY_HEADER_SIZE); 715 e = data + ((len & ~1) - UTOPPY_HEADER_SIZE);
716 716
717 while (data < e) { 717 while (data < e) {
718 t1 = data[0]; 718 t1 = data[0];
719 t2 = data[1]; 719 t2 = data[1];
720 crc = UTOPPY_CRC16(crc, t2); 720 crc = UTOPPY_CRC16(crc, t2);
721 crc = UTOPPY_CRC16(crc, t1); 721 crc = UTOPPY_CRC16(crc, t1);
722 *data++ = t2; 722 *data++ = t2;
723 *data++ = t1; 723 *data++ = t1;
724 } 724 }
725 725
726 if (len & 1) { 726 if (len & 1) {
727 t1 = data[1]; 727 t1 = data[1];
728 crc = UTOPPY_CRC16(crc, t1); 728 crc = UTOPPY_CRC16(crc, t1);
729 *data = t1; 729 *data = t1;
730 } 730 }
731 } 731 }
732 732
733 sc->sc_in_len = (size_t) len - UTOPPY_HEADER_SIZE; 733 sc->sc_in_len = (size_t) len - UTOPPY_HEADER_SIZE;
734 sc->sc_in_offset = 0; 734 sc->sc_in_offset = 0;
735 735
736 DPRINTF(UTOPPY_DBG_RECV_PACKET, ("%s: utoppy_recv_packet: len %d, " 736 DPRINTF(UTOPPY_DBG_RECV_PACKET, ("%s: utoppy_recv_packet: len %d, "
737 "crc 0x%04x, hdrcrc 0x%04x\n", device_xname(sc->sc_dev), 737 "crc 0x%04x, hdrcrc 0x%04x\n", device_xname(sc->sc_dev),
738 (int)len, crc, h->h_crc)); 738 (int)len, crc, h->h_crc));
739 DDUMP_PACKET(h, len); 739 DDUMP_PACKET(h, len);
740 740
741 return (crc == h->h_crc) ? 0 : EBADMSG; 741 return (crc == h->h_crc) ? 0 : EBADMSG;
742} 742}
743 743
744static __inline void * 744static __inline void *
745utoppy_current_ptr(void *b) 745utoppy_current_ptr(void *b)
746{ 746{
747 struct utoppy_header *h = b; 747 struct utoppy_header *h = b;
748 748
749 return &h->h_data[h->h_len]; 749 return &h->h_data[h->h_len];
750} 750}
751 751
752static __inline void 752static __inline void
753utoppy_advance_ptr(void *b, size_t len) 753utoppy_advance_ptr(void *b, size_t len)
754{ 754{
755 struct utoppy_header *h = b; 755 struct utoppy_header *h = b;
756 756
757 h->h_len += len; 757 h->h_len += len;
758} 758}
759 759
760static __inline void 760static __inline void
761utoppy_add_8(struct utoppy_softc *sc, uint8_t v) 761utoppy_add_8(struct utoppy_softc *sc, uint8_t v)
762{ 762{
763 struct utoppy_header *h = sc->sc_out_data; 763 struct utoppy_header *h = sc->sc_out_data;
764 uint8_t *p; 764 uint8_t *p;
765 765
766 p = utoppy_current_ptr(h); 766 p = utoppy_current_ptr(h);
767 *p = v; 767 *p = v;
768 utoppy_advance_ptr(h, sizeof(v)); 768 utoppy_advance_ptr(h, sizeof(v));
769} 769}
770 770
771static __inline void 771static __inline void
772utoppy_add_16(struct utoppy_softc *sc, uint16_t v) 772utoppy_add_16(struct utoppy_softc *sc, uint16_t v)
773{ 773{
774 struct utoppy_header *h = sc->sc_out_data; 774 struct utoppy_header *h = sc->sc_out_data;
775 uint8_t *p; 775 uint8_t *p;
776 776
777 p = utoppy_current_ptr(h); 777 p = utoppy_current_ptr(h);
778 *p++ = (uint8_t)(v >> 8); 778 *p++ = (uint8_t)(v >> 8);
779 *p = (uint8_t)v; 779 *p = (uint8_t)v;
780 utoppy_advance_ptr(h, sizeof(v)); 780 utoppy_advance_ptr(h, sizeof(v));
781} 781}
782 782
783static __inline void 783static __inline void
784utoppy_add_32(struct utoppy_softc *sc, uint32_t v) 784utoppy_add_32(struct utoppy_softc *sc, uint32_t v)
785{ 785{
786 struct utoppy_header *h = sc->sc_out_data; 786 struct utoppy_header *h = sc->sc_out_data;
787 uint8_t *p; 787 uint8_t *p;
788 788
789 p = utoppy_current_ptr(h); 789 p = utoppy_current_ptr(h);
790 *p++ = (uint8_t)(v >> 24); 790 *p++ = (uint8_t)(v >> 24);
791 *p++ = (uint8_t)(v >> 16); 791 *p++ = (uint8_t)(v >> 16);
792 *p++ = (uint8_t)(v >> 8); 792 *p++ = (uint8_t)(v >> 8);
793 *p = (uint8_t)v; 793 *p = (uint8_t)v;
794 utoppy_advance_ptr(h, sizeof(v)); 794 utoppy_advance_ptr(h, sizeof(v));
795} 795}
796 796
797static __inline void 797static __inline void
798utoppy_add_64(struct utoppy_softc *sc, uint64_t v) 798utoppy_add_64(struct utoppy_softc *sc, uint64_t v)
799{ 799{
800 struct utoppy_header *h = sc->sc_out_data; 800 struct utoppy_header *h = sc->sc_out_data;
801 uint8_t *p; 801 uint8_t *p;
802 802
803 p = utoppy_current_ptr(h); 803 p = utoppy_current_ptr(h);
804 *p++ = (uint8_t)(v >> 56); 804 *p++ = (uint8_t)(v >> 56);
805 *p++ = (uint8_t)(v >> 48); 805 *p++ = (uint8_t)(v >> 48);
806 *p++ = (uint8_t)(v >> 40); 806 *p++ = (uint8_t)(v >> 40);
807 *p++ = (uint8_t)(v >> 32); 807 *p++ = (uint8_t)(v >> 32);
808 *p++ = (uint8_t)(v >> 24); 808 *p++ = (uint8_t)(v >> 24);
809 *p++ = (uint8_t)(v >> 16); 809 *p++ = (uint8_t)(v >> 16);
810 *p++ = (uint8_t)(v >> 8); 810 *p++ = (uint8_t)(v >> 8);
811 *p = (uint8_t)v; 811 *p = (uint8_t)v;
812 utoppy_advance_ptr(h, sizeof(v)); 812 utoppy_advance_ptr(h, sizeof(v));
813} 813}
814 814
815static __inline void 815static __inline void
816utoppy_add_string(struct utoppy_softc *sc, const char *str, size_t len) 816utoppy_add_string(struct utoppy_softc *sc, const char *str, size_t len)
817{ 817{
818 struct utoppy_header *h = sc->sc_out_data; 818 struct utoppy_header *h = sc->sc_out_data;
819 char *p; 819 char *p;
820 820
821 p = utoppy_current_ptr(h); 821 p = utoppy_current_ptr(h);
822 memset(p, 0, len); 822 memset(p, 0, len);
823 strncpy(p, str, len); 823 strncpy(p, str, len);
824 utoppy_advance_ptr(h, len); 824 utoppy_advance_ptr(h, len);
825} 825}
826 826
827static int 827static int
828utoppy_add_path(struct utoppy_softc *sc, const char *path, int putlen) 828utoppy_add_path(struct utoppy_softc *sc, const char *path, int putlen)
829{ 829{
830 struct utoppy_header *h = sc->sc_out_data; 830 struct utoppy_header *h = sc->sc_out_data;
831 uint8_t *p, *str, *s; 831 uint8_t *p, *str, *s;
832 size_t len; 832 size_t len;
833 int err; 833 int err;
834 834
835 p = utoppy_current_ptr(h); 835 p = utoppy_current_ptr(h);
836 836
837 str = putlen ? (p + sizeof(uint16_t)) : p; 837 str = putlen ? (p + sizeof(uint16_t)) : p;
838 838
839 err = copyinstr(path, str, UTOPPY_MAX_FILENAME_LEN, &len); 839 err = copyinstr(path, str, UTOPPY_MAX_FILENAME_LEN, &len);
840 840
841 DPRINTF(UTOPPY_DBG_ADDPATH, ("utoppy_add_path: err %d, len %d\n", 841 DPRINTF(UTOPPY_DBG_ADDPATH, ("utoppy_add_path: err %d, len %d\n",
842 err, (int)len)); 842 err, (int)len));
843 843
844 if (err) 844 if (err)
845 return err; 845 return err;
846 846
847 if (len < 2) 847 if (len < 2)
848 return EINVAL; 848 return EINVAL;
849 849
850 /* 850 /*
851 * copyinstr(9) has already copied the terminating NUL character, 851 * copyinstr(9) has already copied the terminating NUL character,
852 * but we append another one in case we have to pad the length 852 * but we append another one in case we have to pad the length
853 * later on. 853 * later on.
854 */ 854 */
855 str[len] = '\0'; 855 str[len] = '\0';
856 856
857 /* 857 /*
858 * The Toppy uses backslash as the directory separator, so convert 858 * The Toppy uses backslash as the directory separator, so convert
859 * all forward slashes. 859 * all forward slashes.
860 */ 860 */
861 for (s = &str[len - 2]; s >= str; s--) 861 for (s = &str[len - 2]; s >= str; s--)
862 if (*s == '/') 862 if (*s == '/')
863 *s = '\\'; 863 *s = '\\';
864 864
865 if ((len + h->h_len) & 1) 865 if ((len + h->h_len) & 1)
866 len++; 866 len++;
867 867
868 if (putlen) 868 if (putlen)
869 utoppy_add_16(sc, len); 869 utoppy_add_16(sc, len);
870 870
871 utoppy_advance_ptr(h, len); 871 utoppy_advance_ptr(h, len);
872 872
873 DPRINTF(UTOPPY_DBG_ADDPATH, ("utoppy_add_path: final len %d\n", 873 DPRINTF(UTOPPY_DBG_ADDPATH, ("utoppy_add_path: final len %d\n",
874 (u_int)len)); 874 (u_int)len));
875 875
876 return 0; 876 return 0;
877} 877}
878 878
879static __inline int 879static __inline int
880utoppy_get_8(struct utoppy_softc *sc, uint8_t *vp) 880utoppy_get_8(struct utoppy_softc *sc, uint8_t *vp)
881{ 881{
882 uint8_t *p; 882 uint8_t *p;
883 883
884 if (sc->sc_in_len < sizeof(*vp)) 884 if (sc->sc_in_len < sizeof(*vp))
885 return 1; 885 return 1;
886 886
887 p = UTOPPY_IN_DATA(sc); 887 p = UTOPPY_IN_DATA(sc);
888 *vp = *p; 888 *vp = *p;
889 sc->sc_in_offset += sizeof(*vp); 889 sc->sc_in_offset += sizeof(*vp);
890 sc->sc_in_len -= sizeof(*vp); 890 sc->sc_in_len -= sizeof(*vp);
891 return 0; 891 return 0;
892} 892}
893 893
894static __inline int 894static __inline int
895utoppy_get_16(struct utoppy_softc *sc, uint16_t *vp) 895utoppy_get_16(struct utoppy_softc *sc, uint16_t *vp)
896{ 896{
897 uint16_t v; 897 uint16_t v;
898 uint8_t *p; 898 uint8_t *p;
899 899
900 if (sc->sc_in_len < sizeof(v)) 900 if (sc->sc_in_len < sizeof(v))
901 return 1; 901 return 1;
902 902
903 p = UTOPPY_IN_DATA(sc); 903 p = UTOPPY_IN_DATA(sc);
904 v = *p++; 904 v = *p++;
905 v = (v << 8) | *p; 905 v = (v << 8) | *p;
906 *vp = v; 906 *vp = v;
907 sc->sc_in_offset += sizeof(v); 907 sc->sc_in_offset += sizeof(v);
908 sc->sc_in_len -= sizeof(v); 908 sc->sc_in_len -= sizeof(v);
909 return 0; 909 return 0;
910} 910}
911 911
912static __inline int 912static __inline int
913utoppy_get_32(struct utoppy_softc *sc, uint32_t *vp) 913utoppy_get_32(struct utoppy_softc *sc, uint32_t *vp)
914{ 914{
915 uint32_t v; 915 uint32_t v;
916 uint8_t *p; 916 uint8_t *p;
917 917
918 if (sc->sc_in_len < sizeof(v)) 918 if (sc->sc_in_len < sizeof(v))
919 return 1; 919 return 1;
920 920
921 p = UTOPPY_IN_DATA(sc); 921 p = UTOPPY_IN_DATA(sc);
922 v = *p++; 922 v = *p++;
923 v = (v << 8) | *p++; 923 v = (v << 8) | *p++;
924 v = (v << 8) | *p++; 924 v = (v << 8) | *p++;
925 v = (v << 8) | *p; 925 v = (v << 8) | *p;
926 *vp = v; 926 *vp = v;
927 sc->sc_in_offset += sizeof(v); 927 sc->sc_in_offset += sizeof(v);
928 sc->sc_in_len -= sizeof(v); 928 sc->sc_in_len -= sizeof(v);
929 return 0; 929 return 0;
930} 930}
931 931
932static __inline int 932static __inline int
933utoppy_get_64(struct utoppy_softc *sc, uint64_t *vp) 933utoppy_get_64(struct utoppy_softc *sc, uint64_t *vp)
934{ 934{
935 uint64_t v; 935 uint64_t v;
936 uint8_t *p; 936 uint8_t *p;
937 937
938 if (sc->sc_in_len < sizeof(v)) 938 if (sc->sc_in_len < sizeof(v))
939 return 1; 939 return 1;
940 940
941 p = UTOPPY_IN_DATA(sc); 941 p = UTOPPY_IN_DATA(sc);
942 v = *p++; 942 v = *p++;
943 v = (v << 8) | *p++; 943 v = (v << 8) | *p++;
944 v = (v << 8) | *p++; 944 v = (v << 8) | *p++;
945 v = (v << 8) | *p++; 945 v = (v << 8) | *p++;
946 v = (v << 8) | *p++; 946 v = (v << 8) | *p++;
947 v = (v << 8) | *p++; 947 v = (v << 8) | *p++;
948 v = (v << 8) | *p++; 948 v = (v << 8) | *p++;
949 v = (v << 8) | *p; 949 v = (v << 8) | *p;
950 *vp = v; 950 *vp = v;
951 sc->sc_in_offset += sizeof(v); 951 sc->sc_in_offset += sizeof(v);
952 sc->sc_in_len -= sizeof(v); 952 sc->sc_in_len -= sizeof(v);
953 return 0; 953 return 0;
954} 954}
955 955
956static __inline int 956static __inline int
957utoppy_get_string(struct utoppy_softc *sc, char *str, size_t len) 957utoppy_get_string(struct utoppy_softc *sc, char *str, size_t len)
958{ 958{
959 char *p; 959 char *p;
960 960
961 if (sc->sc_in_len < len) 961 if (sc->sc_in_len < len)
962 return 1; 962 return 1;
963 963
964 memset(str, 0, len); 964 memset(str, 0, len);
965 p = UTOPPY_IN_DATA(sc); 965 p = UTOPPY_IN_DATA(sc);
966 strncpy(str, p, len); 966 strncpy(str, p, len);
967 sc->sc_in_offset += len; 967 sc->sc_in_offset += len;
968 sc->sc_in_len -= len; 968 sc->sc_in_len -= len;
969 return 0; 969 return 0;
970} 970}
971 971
972static int 972static int
973utoppy_command(struct utoppy_softc *sc, uint16_t cmd, int timeout, 973utoppy_command(struct utoppy_softc *sc, uint16_t cmd, int timeout,
974 uint16_t *presp) 974 uint16_t *presp)
975{ 975{
976 int err; 976 int err;
977 977
978 err = utoppy_send_packet(sc, cmd, timeout); 978 err = utoppy_send_packet(sc, cmd, timeout);
979 if (err) 979 if (err)
980 return err; 980 return err;
981 981
982 err = utoppy_recv_packet(sc, presp, timeout); 982 err = utoppy_recv_packet(sc, presp, timeout);
983 if (err == EBADMSG) { 983 if (err == EBADMSG) {
984 UTOPPY_OUT_INIT(sc); 984 UTOPPY_OUT_INIT(sc);
985 utoppy_send_packet(sc, UTOPPY_RESP_ERROR, timeout); 985 utoppy_send_packet(sc, UTOPPY_RESP_ERROR, timeout);
986 } 986 }
987 987
988 return err; 988 return err;
989} 989}
990 990
991static int 991static int
992utoppy_timestamp_decode(struct utoppy_softc *sc, time_t *tp) 992utoppy_timestamp_decode(struct utoppy_softc *sc, time_t *tp)
993{ 993{
994 uint16_t mjd; 994 uint16_t mjd;
995 uint8_t hour, minute, sec; 995 uint8_t hour, minute, sec;
996 uint32_t rv; 996 uint32_t rv;
997 997
998 if (utoppy_get_16(sc, &mjd) || utoppy_get_8(sc, &hour) || 998 if (utoppy_get_16(sc, &mjd) || utoppy_get_8(sc, &hour) ||
999 utoppy_get_8(sc, &minute) || utoppy_get_8(sc, &sec)) 999 utoppy_get_8(sc, &minute) || utoppy_get_8(sc, &sec))
1000 return 1; 1000 return 1;
1001 1001
1002 if (mjd == 0xffffu && hour == 0xffu && minute == 0xffu && sec == 0xffu){ 1002 if (mjd == 0xffffu && hour == 0xffu && minute == 0xffu && sec == 0xffu){
1003 *tp = 0; 1003 *tp = 0;
1004 return 0; 1004 return 0;
1005 } 1005 }
1006 1006
1007 rv = (mjd < UTOPPY_MJD_1970) ? UTOPPY_MJD_1970 : (uint32_t) mjd; 1007 rv = (mjd < UTOPPY_MJD_1970) ? UTOPPY_MJD_1970 : (uint32_t) mjd;
1008 1008
1009 /* Calculate seconds since 1970 */ 1009 /* Calculate seconds since 1970 */
1010 rv = (rv - UTOPPY_MJD_1970) * 60 * 60 * 24; 1010 rv = (rv - UTOPPY_MJD_1970) * 60 * 60 * 24;
1011 1011
1012 /* Add in the hours, minutes, and seconds */ 1012 /* Add in the hours, minutes, and seconds */
1013 rv += (uint32_t)hour * 60 * 60; 1013 rv += (uint32_t)hour * 60 * 60;
1014 rv += (uint32_t)minute * 60; 1014 rv += (uint32_t)minute * 60;
1015 rv += sec; 1015 rv += sec;
1016 *tp = (time_t)rv; 1016 *tp = (time_t)rv;
1017 1017
1018 return 0; 1018 return 0;
1019} 1019}
1020 1020
1021static void 1021static void
1022utoppy_timestamp_encode(struct utoppy_softc *sc, time_t t) 1022utoppy_timestamp_encode(struct utoppy_softc *sc, time_t t)
1023{ 1023{
1024 u_int mjd, hour, minute; 1024 u_int mjd, hour, minute;
1025 1025
1026 mjd = t / (60 * 60 * 24); 1026 mjd = t / (60 * 60 * 24);
1027 t -= mjd * 60 * 60 * 24; 1027 t -= mjd * 60 * 60 * 24;
1028 1028
1029 hour = t / (60 * 60); 1029 hour = t / (60 * 60);
1030 t -= hour * 60 * 60; 1030 t -= hour * 60 * 60;
1031 1031
1032 minute = t / 60; 1032 minute = t / 60;
1033 t -= minute * 60; 1033 t -= minute * 60;
1034 1034
1035 utoppy_add_16(sc, mjd + UTOPPY_MJD_1970); 1035 utoppy_add_16(sc, mjd + UTOPPY_MJD_1970);
1036 utoppy_add_8(sc, hour); 1036 utoppy_add_8(sc, hour);
1037 utoppy_add_8(sc, minute); 1037 utoppy_add_8(sc, minute);
1038 utoppy_add_8(sc, t); 1038 utoppy_add_8(sc, t);
1039} 1039}
1040 1040
1041static int 1041static int
1042utoppy_turbo_mode(struct utoppy_softc *sc, int state) 1042utoppy_turbo_mode(struct utoppy_softc *sc, int state)
1043{ 1043{
1044 uint16_t r; 1044 uint16_t r;
1045 int err; 1045 int err;
1046 1046
1047 UTOPPY_OUT_INIT(sc); 1047 UTOPPY_OUT_INIT(sc);
1048 utoppy_add_32(sc, state); 1048 utoppy_add_32(sc, state);
1049 1049
1050 err = utoppy_command(sc, UTOPPY_CMD_TURBO, UTOPPY_SHORT_TIMEOUT, &r); 1050 err = utoppy_command(sc, UTOPPY_CMD_TURBO, UTOPPY_SHORT_TIMEOUT, &r);
1051 if (err) 1051 if (err)
1052 return err; 1052 return err;
1053 1053
1054 return (r == UTOPPY_RESP_SUCCESS) ? 0 : EIO; 1054 return (r == UTOPPY_RESP_SUCCESS) ? 0 : EIO;
1055} 1055}
1056 1056
1057static int 1057static int
1058utoppy_check_ready(struct utoppy_softc *sc) 1058utoppy_check_ready(struct utoppy_softc *sc)
1059{ 1059{
1060 uint16_t r; 1060 uint16_t r;
1061 int err; 1061 int err;
1062 1062
1063 UTOPPY_OUT_INIT(sc); 1063 UTOPPY_OUT_INIT(sc);
1064 1064
1065 err = utoppy_command(sc, UTOPPY_CMD_READY, UTOPPY_LONG_TIMEOUT, &r); 1065 err = utoppy_command(sc, UTOPPY_CMD_READY, UTOPPY_LONG_TIMEOUT, &r);
1066 if (err) 1066 if (err)
1067 return err; 1067 return err;
1068 1068
1069 return (r == UTOPPY_RESP_SUCCESS) ? 0 : EIO; 1069 return (r == UTOPPY_RESP_SUCCESS) ? 0 : EIO;
1070} 1070}
1071 1071
1072static int 1072static int
1073utoppy_cancel(struct utoppy_softc *sc) 1073utoppy_cancel(struct utoppy_softc *sc)
1074{ 1074{
1075 uint16_t r; 1075 uint16_t r;
1076 int err, i; 1076 int err, i;
1077 1077
1078 /* 1078 /*
1079 * Issue the cancel command serveral times. the Toppy doesn't 1079 * Issue the cancel command serveral times. the Toppy doesn't
1080 * always respond to the first. 1080 * always respond to the first.
1081 */ 1081 */
1082 for (i = 0; i < 3; i++) { 1082 for (i = 0; i < 3; i++) {
1083 UTOPPY_OUT_INIT(sc); 1083 UTOPPY_OUT_INIT(sc);
1084 err = utoppy_command(sc, UTOPPY_CMD_CANCEL, 1084 err = utoppy_command(sc, UTOPPY_CMD_CANCEL,
1085 UTOPPY_SHORT_TIMEOUT, &r); 1085 UTOPPY_SHORT_TIMEOUT, &r);
1086 if (err == 0 && r == UTOPPY_RESP_SUCCESS) 1086 if (err == 0 && r == UTOPPY_RESP_SUCCESS)
1087 break; 1087 break;
1088 err = ETIMEDOUT; 1088 err = ETIMEDOUT;
1089 } 1089 }
1090 1090
1091 if (err) 1091 if (err)
1092 return err; 1092 return err;
1093 1093
1094 /* 1094 /*
1095 * Make sure turbo mode is off, otherwise the Toppy will not 1095 * Make sure turbo mode is off, otherwise the Toppy will not
1096 * respond to remote control input. 1096 * respond to remote control input.
1097 */ 1097 */
1098 (void) utoppy_turbo_mode(sc, 0); 1098 (void) utoppy_turbo_mode(sc, 0);
1099 1099
1100 sc->sc_state = UTOPPY_STATE_IDLE; 1100 sc->sc_state = UTOPPY_STATE_IDLE;
1101 return 0; 1101 return 0;
1102} 1102}
1103 1103
1104static int 1104static int
1105utoppy_stats(struct utoppy_softc *sc, struct utoppy_stats *us) 1105utoppy_stats(struct utoppy_softc *sc, struct utoppy_stats *us)
1106{ 1106{
1107 uint32_t hsize, hfree; 1107 uint32_t hsize, hfree;
1108 uint16_t r; 1108 uint16_t r;
1109 int err; 1109 int err;
1110 1110
1111 UTOPPY_OUT_INIT(sc); 1111 UTOPPY_OUT_INIT(sc);
1112 err = utoppy_command(sc, UTOPPY_CMD_STATS, UTOPPY_LONG_TIMEOUT, &r); 1112 err = utoppy_command(sc, UTOPPY_CMD_STATS, UTOPPY_LONG_TIMEOUT, &r);
1113 if (err) 1113 if (err)
1114 return err; 1114 return err;
1115 1115
1116 if (r != UTOPPY_RESP_STATS_DATA) 1116 if (r != UTOPPY_RESP_STATS_DATA)
1117 return EIO; 1117 return EIO;
1118 1118
1119 if (utoppy_get_32(sc, &hsize) || utoppy_get_32(sc, &hfree)) 1119 if (utoppy_get_32(sc, &hsize) || utoppy_get_32(sc, &hfree))
1120 return EIO; 1120 return EIO;
1121 1121
1122 us->us_hdd_size = hsize; 1122 us->us_hdd_size = hsize;
1123 us->us_hdd_size *= 1024; 1123 us->us_hdd_size *= 1024;
1124 us->us_hdd_free = hfree; 1124 us->us_hdd_free = hfree;
1125 us->us_hdd_free *= 1024; 1125 us->us_hdd_free *= 1024;
1126 1126
1127 return 0; 1127 return 0;
1128} 1128}
1129 1129
1130static int 1130static int
1131utoppy_readdir_next(struct utoppy_softc *sc) 1131utoppy_readdir_next(struct utoppy_softc *sc)
1132{ 1132{
1133 uint16_t resp; 1133 uint16_t resp;
1134 int err; 1134 int err;
1135 1135
1136 DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppy_readdir_next: running...\n", 1136 DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppy_readdir_next: running...\n",
1137 device_xname(sc->sc_dev))); 1137 device_xname(sc->sc_dev)));
1138 1138
1139 /* 1139 /*
1140 * Fetch the next READDIR response 1140 * Fetch the next READDIR response
1141 */ 1141 */
1142 err = utoppy_recv_packet(sc, &resp, UTOPPY_LONG_TIMEOUT); 1142 err = utoppy_recv_packet(sc, &resp, UTOPPY_LONG_TIMEOUT);
1143 if (err) { 1143 if (err) {
1144 DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppy_readdir_next: " 1144 DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppy_readdir_next: "
1145 "utoppy_recv_packet() returned %d\n", 1145 "utoppy_recv_packet() returned %d\n",
1146 device_xname(sc->sc_dev), err)); 1146 device_xname(sc->sc_dev), err));
1147 if (err == EBADMSG) { 1147 if (err == EBADMSG) {
1148 UTOPPY_OUT_INIT(sc); 1148 UTOPPY_OUT_INIT(sc);
1149 utoppy_send_packet(sc, UTOPPY_RESP_ERROR, 1149 utoppy_send_packet(sc, UTOPPY_RESP_ERROR,
1150 UTOPPY_LONG_TIMEOUT); 1150 UTOPPY_LONG_TIMEOUT);
1151 } 1151 }
1152 utoppy_cancel(sc); 1152 utoppy_cancel(sc);
1153 return err; 1153 return err;
1154 } 1154 }
1155 1155
1156 DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppy_readdir_next: " 1156 DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppy_readdir_next: "
1157 "utoppy_recv_packet() returned %d, len %ld\n", 1157 "utoppy_recv_packet() returned %d, len %ld\n",
1158 device_xname(sc->sc_dev), err, (u_long)sc->sc_in_len)); 1158 device_xname(sc->sc_dev), err, (u_long)sc->sc_in_len));
1159 1159
1160 switch (resp) { 1160 switch (resp) {
1161 case UTOPPY_RESP_READDIR_DATA: 1161 case UTOPPY_RESP_READDIR_DATA:
1162 DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppy_readdir_next: " 1162 DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppy_readdir_next: "
1163 "UTOPPY_RESP_READDIR_DATA\n", device_xname(sc->sc_dev))); 1163 "UTOPPY_RESP_READDIR_DATA\n", device_xname(sc->sc_dev)));
1164 1164
1165 UTOPPY_OUT_INIT(sc); 1165 UTOPPY_OUT_INIT(sc);
1166 err = utoppy_send_packet(sc, UTOPPY_CMD_ACK, 1166 err = utoppy_send_packet(sc, UTOPPY_CMD_ACK,
1167 UTOPPY_LONG_TIMEOUT); 1167 UTOPPY_LONG_TIMEOUT);
1168 if (err) { 1168 if (err) {
1169 DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppy_readdir_next: " 1169 DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppy_readdir_next: "
1170 "utoppy_send_packet(ACK) returned %d\n", 1170 "utoppy_send_packet(ACK) returned %d\n",
1171 device_xname(sc->sc_dev), err)); 1171 device_xname(sc->sc_dev), err));
1172 utoppy_cancel(sc); 1172 utoppy_cancel(sc);
1173 return err; 1173 return err;
1174 } 1174 }
1175 sc->sc_state = UTOPPY_STATE_READDIR; 1175 sc->sc_state = UTOPPY_STATE_READDIR;
1176 sc->sc_in_offset = 0; 1176 sc->sc_in_offset = 0;
1177 break; 1177 break;
1178 1178
1179 case UTOPPY_RESP_READDIR_END: 1179 case UTOPPY_RESP_READDIR_END:
1180 DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppy_readdir_next: " 1180 DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppy_readdir_next: "
1181 "UTOPPY_RESP_READDIR_END\n", device_xname(sc->sc_dev))); 1181 "UTOPPY_RESP_READDIR_END\n", device_xname(sc->sc_dev)));
1182 1182
1183 UTOPPY_OUT_INIT(sc); 1183 UTOPPY_OUT_INIT(sc);
1184 utoppy_send_packet(sc, UTOPPY_CMD_ACK, UTOPPY_SHORT_TIMEOUT); 1184 utoppy_send_packet(sc, UTOPPY_CMD_ACK, UTOPPY_SHORT_TIMEOUT);
1185 sc->sc_state = UTOPPY_STATE_IDLE; 1185 sc->sc_state = UTOPPY_STATE_IDLE;
1186 sc->sc_in_len = 0; 1186 sc->sc_in_len = 0;
1187 break; 1187 break;
1188 1188
1189 default: 1189 default:
1190 DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppy_readdir_next: " 1190 DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppy_readdir_next: "
1191 "bad response: %#x\n", device_xname(sc->sc_dev), resp)); 1191 "bad response: %#x\n", device_xname(sc->sc_dev), resp));
1192 sc->sc_state = UTOPPY_STATE_IDLE; 1192 sc->sc_state = UTOPPY_STATE_IDLE;
1193 sc->sc_in_len = 0; 1193 sc->sc_in_len = 0;
1194 return EIO; 1194 return EIO;
1195 } 1195 }
1196 1196
1197 return 0; 1197 return 0;
1198} 1198}
1199 1199
1200static size_t 1200static size_t
1201utoppy_readdir_decode(struct utoppy_softc *sc, struct utoppy_dirent *ud) 1201utoppy_readdir_decode(struct utoppy_softc *sc, struct utoppy_dirent *ud)
1202{ 1202{
1203 uint8_t ftype; 1203 uint8_t ftype;
1204 1204
1205 DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppy_readdir_decode: bytes left" 1205 DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppy_readdir_decode: bytes left"
1206 " %d\n", device_xname(sc->sc_dev), (int)sc->sc_in_len)); 1206 " %d\n", device_xname(sc->sc_dev), (int)sc->sc_in_len));
1207 1207
1208 if (utoppy_timestamp_decode(sc, &ud->ud_mtime) || 1208 if (utoppy_timestamp_decode(sc, &ud->ud_mtime) ||
1209 utoppy_get_8(sc, &ftype) || utoppy_get_64(sc, &ud->ud_size) || 1209 utoppy_get_8(sc, &ftype) || utoppy_get_64(sc, &ud->ud_size) ||
1210 utoppy_get_string(sc, ud->ud_path, UTOPPY_MAX_FILENAME_LEN + 1) || 1210 utoppy_get_string(sc, ud->ud_path, UTOPPY_MAX_FILENAME_LEN + 1) ||
1211 utoppy_get_32(sc, &ud->ud_attributes)) { 1211 utoppy_get_32(sc, &ud->ud_attributes)) {
1212 DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppy_readdir_decode: no " 1212 DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppy_readdir_decode: no "
1213 "more to decode\n", device_xname(sc->sc_dev))); 1213 "more to decode\n", device_xname(sc->sc_dev)));
1214 return 0; 1214 return 0;
1215 } 1215 }
1216 1216
1217 switch (ftype) { 1217 switch (ftype) {
1218 case UTOPPY_FTYPE_DIR: 1218 case UTOPPY_FTYPE_DIR:
1219 ud->ud_type = UTOPPY_DIRENT_DIRECTORY; 1219 ud->ud_type = UTOPPY_DIRENT_DIRECTORY;
1220 break; 1220 break;
1221 case UTOPPY_FTYPE_FILE: 1221 case UTOPPY_FTYPE_FILE:
1222 ud->ud_type = UTOPPY_DIRENT_FILE; 1222 ud->ud_type = UTOPPY_DIRENT_FILE;
1223 break; 1223 break;
1224 default: 1224 default:
1225 ud->ud_type = UTOPPY_DIRENT_UNKNOWN; 1225 ud->ud_type = UTOPPY_DIRENT_UNKNOWN;
1226 break; 1226 break;
1227 } 1227 }
1228 1228
1229 DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppy_readdir_decode: %s '%s', " 1229 DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppy_readdir_decode: %s '%s', "
1230 "size %lld, time 0x%08lx, attr 0x%08x\n", device_xname(sc->sc_dev), 1230 "size %lld, time 0x%08lx, attr 0x%08x\n", device_xname(sc->sc_dev),
1231 (ftype == UTOPPY_FTYPE_DIR) ? "DIR" : 1231 (ftype == UTOPPY_FTYPE_DIR) ? "DIR" :
1232 ((ftype == UTOPPY_FTYPE_FILE) ? "FILE" : "UNKNOWN"), ud->ud_path, 1232 ((ftype == UTOPPY_FTYPE_FILE) ? "FILE" : "UNKNOWN"), ud->ud_path,
1233 ud->ud_size, (u_long)ud->ud_mtime, ud->ud_attributes)); 1233 ud->ud_size, (u_long)ud->ud_mtime, ud->ud_attributes));
1234 1234
1235 return 1; 1235 return 1;
1236} 1236}
1237 1237
1238static int 1238static int
1239utoppy_readfile_next(struct utoppy_softc *sc) 1239utoppy_readfile_next(struct utoppy_softc *sc)
1240{ 1240{
1241 uint64_t off; 1241 uint64_t off;
1242 uint16_t resp; 1242 uint16_t resp;
1243 int err; 1243 int err;
1244 1244
1245 err = utoppy_recv_packet(sc, &resp, UTOPPY_LONG_TIMEOUT); 1245 err = utoppy_recv_packet(sc, &resp, UTOPPY_LONG_TIMEOUT);
1246 if (err) { 1246 if (err) {
1247 DPRINTF(UTOPPY_DBG_READ, ("%s: utoppy_readfile_next: " 1247 DPRINTF(UTOPPY_DBG_READ, ("%s: utoppy_readfile_next: "
1248 "utoppy_recv_packet() returned %d\n", 1248 "utoppy_recv_packet() returned %d\n",
1249 device_xname(sc->sc_dev), err)); 1249 device_xname(sc->sc_dev), err));
1250 utoppy_cancel(sc); 1250 utoppy_cancel(sc);
1251 return err; 1251 return err;
1252 } 1252 }
1253 1253
1254 switch (resp) { 1254 switch (resp) {
1255 case UTOPPY_RESP_FILE_HEADER: 1255 case UTOPPY_RESP_FILE_HEADER:
1256 /* ACK it */ 1256 /* ACK it */
1257 UTOPPY_OUT_INIT(sc); 1257 UTOPPY_OUT_INIT(sc);
1258 err = utoppy_send_packet(sc, UTOPPY_CMD_ACK, 1258 err = utoppy_send_packet(sc, UTOPPY_CMD_ACK,
1259 UTOPPY_LONG_TIMEOUT); 1259 UTOPPY_LONG_TIMEOUT);
1260 if (err) { 1260 if (err) {
1261 DPRINTF(UTOPPY_DBG_READ, ("%s: utoppy_readfile_next: " 1261 DPRINTF(UTOPPY_DBG_READ, ("%s: utoppy_readfile_next: "
1262 "utoppy_send_packet(UTOPPY_CMD_ACK) returned %d\n", 1262 "utoppy_send_packet(UTOPPY_CMD_ACK) returned %d\n",
1263 device_xname(sc->sc_dev), err)); 1263 device_xname(sc->sc_dev), err));
1264 utoppy_cancel(sc); 1264 utoppy_cancel(sc);
1265 return err; 1265 return err;
1266 } 1266 }
1267 1267
1268 sc->sc_in_len = 0; 1268 sc->sc_in_len = 0;
1269 DPRINTF(UTOPPY_DBG_READ, ("%s: utoppy_readfile_next: " 1269 DPRINTF(UTOPPY_DBG_READ, ("%s: utoppy_readfile_next: "
1270 "FILE_HEADER done\n", device_xname(sc->sc_dev))); 1270 "FILE_HEADER done\n", device_xname(sc->sc_dev)));
1271 break; 1271 break;
1272 1272
1273 case UTOPPY_RESP_FILE_DATA: 1273 case UTOPPY_RESP_FILE_DATA:
1274 /* Already ACK'd */ 1274 /* Already ACK'd */
1275 if (utoppy_get_64(sc, &off)) { 1275 if (utoppy_get_64(sc, &off)) {
1276 DPRINTF(UTOPPY_DBG_READ, ("%s: utoppy_readfile_next: " 1276 DPRINTF(UTOPPY_DBG_READ, ("%s: utoppy_readfile_next: "
1277 "UTOPPY_RESP_FILE_DATA did not provide offset\n", 1277 "UTOPPY_RESP_FILE_DATA did not provide offset\n",
1278 device_xname(sc->sc_dev))); 1278 device_xname(sc->sc_dev)));
1279 utoppy_cancel(sc); 1279 utoppy_cancel(sc);
1280 return EBADMSG; 1280 return EBADMSG;
1281 } 1281 }
1282 1282
1283 DPRINTF(UTOPPY_DBG_READ, ("%s: utoppy_readfile_next: " 1283 DPRINTF(UTOPPY_DBG_READ, ("%s: utoppy_readfile_next: "
1284 "UTOPPY_RESP_FILE_DATA: offset %lld, bytes left %ld\n", 1284 "UTOPPY_RESP_FILE_DATA: offset %lld, bytes left %ld\n",
1285 device_xname(sc->sc_dev), off, (u_long)sc->sc_in_len)); 1285 device_xname(sc->sc_dev), off, (u_long)sc->sc_in_len));
1286 break; 1286 break;
1287 1287
1288 case UTOPPY_RESP_FILE_END: 1288 case UTOPPY_RESP_FILE_END:
1289 DPRINTF(UTOPPY_DBG_READ, ("%s: utoppy_readfile_next: " 1289 DPRINTF(UTOPPY_DBG_READ, ("%s: utoppy_readfile_next: "
1290 "UTOPPY_RESP_FILE_END: sending ACK\n", 1290 "UTOPPY_RESP_FILE_END: sending ACK\n",
1291 device_xname(sc->sc_dev))); 1291 device_xname(sc->sc_dev)));
1292 UTOPPY_OUT_INIT(sc); 1292 UTOPPY_OUT_INIT(sc);
1293 utoppy_send_packet(sc, UTOPPY_CMD_ACK, UTOPPY_SHORT_TIMEOUT); 1293 utoppy_send_packet(sc, UTOPPY_CMD_ACK, UTOPPY_SHORT_TIMEOUT);
1294 /*FALLTHROUGH*/ 1294 /*FALLTHROUGH*/
1295 1295
1296 case UTOPPY_RESP_SUCCESS: 1296 case UTOPPY_RESP_SUCCESS:
1297 sc->sc_state = UTOPPY_STATE_IDLE; 1297 sc->sc_state = UTOPPY_STATE_IDLE;
1298 (void) utoppy_turbo_mode(sc, 0); 1298 (void) utoppy_turbo_mode(sc, 0);
1299 DPRINTF(UTOPPY_DBG_READ, ("%s: utoppy_readfile_next: all " 1299 DPRINTF(UTOPPY_DBG_READ, ("%s: utoppy_readfile_next: all "
1300 "done\n", device_xname(sc->sc_dev))); 1300 "done\n", device_xname(sc->sc_dev)));
1301 break; 1301 break;
1302 1302
1303 case UTOPPY_RESP_ERROR: 1303 case UTOPPY_RESP_ERROR:
1304 default: 1304 default:
1305 DPRINTF(UTOPPY_DBG_READ, ("%s: utoppy_readfile_next: bad " 1305 DPRINTF(UTOPPY_DBG_READ, ("%s: utoppy_readfile_next: bad "
1306 "response code 0x%0x\n", device_xname(sc->sc_dev), resp)); 1306 "response code 0x%0x\n", device_xname(sc->sc_dev), resp));
1307 utoppy_cancel(sc); 1307 utoppy_cancel(sc);
1308 return EIO; 1308 return EIO;
1309 } 1309 }
1310 1310
1311 return 0; 1311 return 0;
1312} 1312}
1313 1313
1314static int 1314static int
1315utoppyopen(dev_t dev, int flag, int mode, 1315utoppyopen(dev_t dev, int flag, int mode,
1316 struct lwp *l) 1316 struct lwp *l)
1317{ 1317{
1318 struct utoppy_softc *sc; 1318 struct utoppy_softc *sc;
1319 int error = 0; 1319 int error = 0;
1320 1320
1321 sc = device_lookup_private(&utoppy_cd, UTOPPYUNIT(dev)); 1321 sc = device_lookup_private(&utoppy_cd, UTOPPYUNIT(dev));
1322 if (sc == NULL) 1322 if (sc == NULL)
1323 return ENXIO; 1323 return ENXIO;
1324 1324
1325 if (sc == NULL || sc->sc_iface == NULL || sc->sc_dying) 1325 if (sc == NULL || sc->sc_iface == NULL || sc->sc_dying)
1326 return ENXIO; 1326 return ENXIO;
1327 1327
1328 if (sc->sc_state != UTOPPY_STATE_CLOSED) { 1328 if (sc->sc_state != UTOPPY_STATE_CLOSED) {
1329 DPRINTF(UTOPPY_DBG_OPEN, ("%s: utoppyopen: already open\n", 1329 DPRINTF(UTOPPY_DBG_OPEN, ("%s: utoppyopen: already open\n",
1330 device_xname(sc->sc_dev))); 1330 device_xname(sc->sc_dev)));
1331 return EBUSY; 1331 return EBUSY;
1332 } 1332 }
1333 1333
1334 DPRINTF(UTOPPY_DBG_OPEN, ("%s: utoppyopen: opening...\n", 1334 DPRINTF(UTOPPY_DBG_OPEN, ("%s: utoppyopen: opening...\n",
1335 device_xname(sc->sc_dev))); 1335 device_xname(sc->sc_dev)));
1336 1336
1337 sc->sc_refcnt++; 1337 sc->sc_refcnt++;
1338 sc->sc_state = UTOPPY_STATE_OPENING; 1338 sc->sc_state = UTOPPY_STATE_OPENING;
1339 sc->sc_turbo_mode = 0; 1339 sc->sc_turbo_mode = 0;
1340 sc->sc_out_data = kmem_alloc(UTOPPY_BSIZE + 1, KM_SLEEP); 1340 sc->sc_out_data = kmem_alloc(UTOPPY_BSIZE + 1, KM_SLEEP);
1341 sc->sc_in_data = kmem_alloc(UTOPPY_BSIZE + 1, KM_SLEEP); 1341 sc->sc_in_data = kmem_alloc(UTOPPY_BSIZE + 1, KM_SLEEP);
1342 1342
1343 if ((error = utoppy_cancel(sc)) != 0) 1343 if ((error = utoppy_cancel(sc)) != 0)
1344 goto error; 1344 goto error;
1345 1345
1346 if ((error = utoppy_check_ready(sc)) != 0) { 1346 if ((error = utoppy_check_ready(sc)) != 0) {
1347 DPRINTF(UTOPPY_DBG_OPEN, ("%s: utoppyopen: utoppy_check_ready()" 1347 DPRINTF(UTOPPY_DBG_OPEN, ("%s: utoppyopen: utoppy_check_ready()"
1348 " returned %d\n", device_xname(sc->sc_dev), error)); 1348 " returned %d\n", device_xname(sc->sc_dev), error));
1349 } 1349 }
1350 1350
1351 error: 1351 error:
1352 sc->sc_state = error ? UTOPPY_STATE_CLOSED : UTOPPY_STATE_IDLE; 1352 sc->sc_state = error ? UTOPPY_STATE_CLOSED : UTOPPY_STATE_IDLE;
1353 1353
1354 DPRINTF(UTOPPY_DBG_OPEN, ("%s: utoppyopen: done. error %d, new state " 1354 DPRINTF(UTOPPY_DBG_OPEN, ("%s: utoppyopen: done. error %d, new state "
1355 "'%s'\n", device_xname(sc->sc_dev), error, 1355 "'%s'\n", device_xname(sc->sc_dev), error,
1356 utoppy_state_string(sc->sc_state))); 1356 utoppy_state_string(sc->sc_state)));
1357 1357
1358 if (--sc->sc_refcnt < 0) 1358 if (--sc->sc_refcnt < 0)
1359 usb_detach_wakeupold(sc->sc_dev); 1359 usb_detach_wakeupold(sc->sc_dev);
1360 1360
1361 return error; 1361 return error;
1362} 1362}
1363 1363
1364static int 1364static int
1365utoppyclose(dev_t dev, int flag, int mode, struct lwp *l) 1365utoppyclose(dev_t dev, int flag, int mode, struct lwp *l)
1366{ 1366{
1367 struct utoppy_softc *sc; 1367 struct utoppy_softc *sc;
1368 usbd_status err; 
1369 1368
1370 sc = device_lookup_private(&utoppy_cd, UTOPPYUNIT(dev)); 1369 sc = device_lookup_private(&utoppy_cd, UTOPPYUNIT(dev));
1371 1370
1372 DPRINTF(UTOPPY_DBG_CLOSE, ("%s: utoppyclose: closing...\n", 1371 DPRINTF(UTOPPY_DBG_CLOSE, ("%s: utoppyclose: closing...\n",
1373 device_xname(sc->sc_dev))); 1372 device_xname(sc->sc_dev)));
1374 1373
1375 if (sc->sc_state < UTOPPY_STATE_IDLE) { 1374 if (sc->sc_state < UTOPPY_STATE_IDLE) {
1376 /* We are being forced to close before the open completed. */ 1375 /* We are being forced to close before the open completed. */
1377 DPRINTF(UTOPPY_DBG_CLOSE, ("%s: utoppyclose: not properly " 1376 DPRINTF(UTOPPY_DBG_CLOSE, ("%s: utoppyclose: not properly "
1378 "open: %s\n", device_xname(sc->sc_dev), 1377 "open: %s\n", device_xname(sc->sc_dev),
1379 utoppy_state_string(sc->sc_state))); 1378 utoppy_state_string(sc->sc_state)));
1380 return 0; 1379 return 0;
1381 } 1380 }
1382 1381
1383 if (sc->sc_out_data) 1382 if (sc->sc_out_data)
1384 (void) utoppy_cancel(sc); 1383 (void) utoppy_cancel(sc);
1385 1384
1386 if (sc->sc_out_pipe != NULL) { 1385 if (sc->sc_out_pipe != NULL) {
1387 if ((err = usbd_abort_pipe(sc->sc_out_pipe)) != 0) 1386 usbd_abort_pipe(sc->sc_out_pipe);
1388 printf("usbd_abort_pipe(OUT) returned %d\n", err); 
1389 sc->sc_out_pipe = NULL; 1387 sc->sc_out_pipe = NULL;
1390 } 1388 }
1391 1389
1392 if (sc->sc_in_pipe != NULL) { 1390 if (sc->sc_in_pipe != NULL) {
1393 if ((err = usbd_abort_pipe(sc->sc_in_pipe)) != 0) 1391 usbd_abort_pipe(sc->sc_in_pipe);
1394 printf("usbd_abort_pipe(IN) returned %d\n", err); 
1395 sc->sc_in_pipe = NULL; 1392 sc->sc_in_pipe = NULL;
1396 } 1393 }
1397 1394
1398 if (sc->sc_out_data) { 1395 if (sc->sc_out_data) {
1399 kmem_free(sc->sc_out_data, UTOPPY_BSIZE + 1); 1396 kmem_free(sc->sc_out_data, UTOPPY_BSIZE + 1);
1400 sc->sc_out_data = NULL; 1397 sc->sc_out_data = NULL;
1401 } 1398 }
1402 1399
1403 if (sc->sc_in_data) { 1400 if (sc->sc_in_data) {
1404 kmem_free(sc->sc_in_data, UTOPPY_BSIZE + 1); 1401 kmem_free(sc->sc_in_data, UTOPPY_BSIZE + 1);
1405 sc->sc_in_data = NULL; 1402 sc->sc_in_data = NULL;
1406 } 1403 }
1407 1404
1408 sc->sc_state = UTOPPY_STATE_CLOSED; 1405 sc->sc_state = UTOPPY_STATE_CLOSED;
1409 1406
1410 DPRINTF(UTOPPY_DBG_CLOSE, ("%s: utoppyclose: done.\n", 1407 DPRINTF(UTOPPY_DBG_CLOSE, ("%s: utoppyclose: done.\n",
1411 device_xname(sc->sc_dev))); 1408 device_xname(sc->sc_dev)));
1412 1409
1413 return 0; 1410 return 0;
1414} 1411}
1415 1412
1416static int 1413static int
1417utoppyread(dev_t dev, struct uio *uio, int flags) 1414utoppyread(dev_t dev, struct uio *uio, int flags)
1418{ 1415{
1419 struct utoppy_softc *sc; 1416 struct utoppy_softc *sc;
1420 struct utoppy_dirent ud; 1417 struct utoppy_dirent ud;
1421 size_t len; 1418 size_t len;
1422 int err; 1419 int err;
1423 1420
1424 sc = device_lookup_private(&utoppy_cd, UTOPPYUNIT(dev)); 1421 sc = device_lookup_private(&utoppy_cd, UTOPPYUNIT(dev));
1425 1422
1426 if (sc->sc_dying) 1423 if (sc->sc_dying)
1427 return EIO; 1424 return EIO;
1428 1425
1429 sc->sc_refcnt++; 1426 sc->sc_refcnt++;
1430 1427
1431 DPRINTF(UTOPPY_DBG_READ, ("%s: utoppyread: reading: state '%s'\n", 1428 DPRINTF(UTOPPY_DBG_READ, ("%s: utoppyread: reading: state '%s'\n",
1432 device_xname(sc->sc_dev), utoppy_state_string(sc->sc_state))); 1429 device_xname(sc->sc_dev), utoppy_state_string(sc->sc_state)));
1433 1430
1434 switch (sc->sc_state) { 1431 switch (sc->sc_state) {
1435 case UTOPPY_STATE_READDIR: 1432 case UTOPPY_STATE_READDIR:
1436 err = 0; 1433 err = 0;
1437 while (err == 0 && uio->uio_resid >= sizeof(ud) && 1434 while (err == 0 && uio->uio_resid >= sizeof(ud) &&
1438 sc->sc_state != UTOPPY_STATE_IDLE) { 1435 sc->sc_state != UTOPPY_STATE_IDLE) {
1439 if (utoppy_readdir_decode(sc, &ud) == 0) 1436 if (utoppy_readdir_decode(sc, &ud) == 0)
1440 err = utoppy_readdir_next(sc); 1437 err = utoppy_readdir_next(sc);
1441 else 1438 else
1442 if ((err = uiomove(&ud, sizeof(ud), uio)) != 0) 1439 if ((err = uiomove(&ud, sizeof(ud), uio)) != 0)
1443 utoppy_cancel(sc); 1440 utoppy_cancel(sc);
1444 } 1441 }
1445 break; 1442 break;
1446 1443
1447 case UTOPPY_STATE_READFILE: 1444 case UTOPPY_STATE_READFILE:
1448 err = 0; 1445 err = 0;
1449 while (err == 0 && uio->uio_resid > 0 && 1446 while (err == 0 && uio->uio_resid > 0 &&
1450 sc->sc_state != UTOPPY_STATE_IDLE) { 1447 sc->sc_state != UTOPPY_STATE_IDLE) {
1451 DPRINTF(UTOPPY_DBG_READ, ("%s: utoppyread: READFILE: " 1448 DPRINTF(UTOPPY_DBG_READ, ("%s: utoppyread: READFILE: "
1452 "resid %ld, bytes_left %ld\n", 1449 "resid %ld, bytes_left %ld\n",
1453 device_xname(sc->sc_dev), (u_long)uio->uio_resid, 1450 device_xname(sc->sc_dev), (u_long)uio->uio_resid,
1454 (u_long)sc->sc_in_len)); 1451 (u_long)sc->sc_in_len));
1455 1452
1456 if (sc->sc_in_len == 0 && 1453 if (sc->sc_in_len == 0 &&
1457 (err = utoppy_readfile_next(sc)) != 0) { 1454 (err = utoppy_readfile_next(sc)) != 0) {
1458 DPRINTF(UTOPPY_DBG_READ, ("%s: utoppyread: " 1455 DPRINTF(UTOPPY_DBG_READ, ("%s: utoppyread: "
1459 "READFILE: utoppy_readfile_next returned " 1456 "READFILE: utoppy_readfile_next returned "
1460 "%d\n", device_xname(sc->sc_dev), err)); 1457 "%d\n", device_xname(sc->sc_dev), err));
1461 break; 1458 break;
1462 } 1459 }
1463 1460
1464 len = uimin(uio->uio_resid, sc->sc_in_len); 1461 len = uimin(uio->uio_resid, sc->sc_in_len);
1465 if (len) { 1462 if (len) {
1466 err = uiomove(UTOPPY_IN_DATA(sc), len, uio); 1463 err = uiomove(UTOPPY_IN_DATA(sc), len, uio);
1467 if (err == 0) { 1464 if (err == 0) {
1468 sc->sc_in_offset += len; 1465 sc->sc_in_offset += len;
1469 sc->sc_in_len -= len; 1466 sc->sc_in_len -= len;
1470 } 1467 }
1471 } 1468 }
1472 } 1469 }
1473 break; 1470 break;
1474 1471
1475 case UTOPPY_STATE_IDLE: 1472 case UTOPPY_STATE_IDLE:
1476 err = 0; 1473 err = 0;
1477 break; 1474 break;
1478 1475
1479 case UTOPPY_STATE_WRITEFILE: 1476 case UTOPPY_STATE_WRITEFILE:
1480 err = EBUSY; 1477 err = EBUSY;
1481 break; 1478 break;
1482 1479
1483 default: 1480 default:
1484 err = EIO; 1481 err = EIO;
1485 break; 1482 break;
1486 } 1483 }
1487 1484
1488 DPRINTF(UTOPPY_DBG_READ, ("%s: utoppyread: done. err %d, state '%s'\n", 1485 DPRINTF(UTOPPY_DBG_READ, ("%s: utoppyread: done. err %d, state '%s'\n",
1489 device_xname(sc->sc_dev), err, utoppy_state_string(sc->sc_state))); 1486 device_xname(sc->sc_dev), err, utoppy_state_string(sc->sc_state)));
1490 1487
1491 if (--sc->sc_refcnt < 0) 1488 if (--sc->sc_refcnt < 0)
1492 usb_detach_wakeupold(sc->sc_dev); 1489 usb_detach_wakeupold(sc->sc_dev);
1493 1490
1494 return err; 1491 return err;
1495} 1492}
1496 1493
1497static int 1494static int
1498utoppywrite(dev_t dev, struct uio *uio, int flags) 1495utoppywrite(dev_t dev, struct uio *uio, int flags)
1499{ 1496{
1500 struct utoppy_softc *sc; 1497 struct utoppy_softc *sc;
1501 uint16_t resp; 1498 uint16_t resp;
1502 size_t len; 1499 size_t len;
1503 int err; 1500 int err;
1504 1501
1505 sc = device_lookup_private(&utoppy_cd, UTOPPYUNIT(dev)); 1502 sc = device_lookup_private(&utoppy_cd, UTOPPYUNIT(dev));
1506 1503
1507 if (sc->sc_dying) 1504 if (sc->sc_dying)
1508 return EIO; 1505 return EIO;
1509 1506
1510 switch(sc->sc_state) { 1507 switch(sc->sc_state) {
1511 case UTOPPY_STATE_WRITEFILE: 1508 case UTOPPY_STATE_WRITEFILE:
1512 break; 1509 break;
1513 1510
1514 case UTOPPY_STATE_IDLE: 1511 case UTOPPY_STATE_IDLE:
1515 return 0; 1512 return 0;
1516 1513
1517 default: 1514 default:
1518 return EIO; 1515 return EIO;
1519 } 1516 }
1520 1517
1521 sc->sc_refcnt++; 1518 sc->sc_refcnt++;
1522 err = 0; 1519 err = 0;
1523 1520
1524 DPRINTF(UTOPPY_DBG_WRITE, ("%s: utoppywrite: PRE-WRITEFILE: resid " 1521 DPRINTF(UTOPPY_DBG_WRITE, ("%s: utoppywrite: PRE-WRITEFILE: resid "
1525 "%ld, wr_size %lld, wr_offset %lld\n", device_xname(sc->sc_dev), 1522 "%ld, wr_size %lld, wr_offset %lld\n", device_xname(sc->sc_dev),
1526 (u_long)uio->uio_resid, sc->sc_wr_size, sc->sc_wr_offset)); 1523 (u_long)uio->uio_resid, sc->sc_wr_size, sc->sc_wr_offset));
1527 1524
1528 while (sc->sc_state == UTOPPY_STATE_WRITEFILE && 1525 while (sc->sc_state == UTOPPY_STATE_WRITEFILE &&
1529 (len = uimin(uio->uio_resid, sc->sc_wr_size)) != 0) { 1526 (len = uimin(uio->uio_resid, sc->sc_wr_size)) != 0) {
1530 1527
1531 len = uimin(len, UTOPPY_BSIZE - (UTOPPY_HEADER_SIZE + 1528 len = uimin(len, UTOPPY_BSIZE - (UTOPPY_HEADER_SIZE +
1532 sizeof(uint64_t) + 3)); 1529 sizeof(uint64_t) + 3));
1533 1530
1534 DPRINTF(UTOPPY_DBG_WRITE, ("%s: utoppywrite: uiomove(%ld)\n", 1531 DPRINTF(UTOPPY_DBG_WRITE, ("%s: utoppywrite: uiomove(%ld)\n",
1535 device_xname(sc->sc_dev), (u_long)len)); 1532 device_xname(sc->sc_dev), (u_long)len));
1536 1533
1537 UTOPPY_OUT_INIT(sc); 1534 UTOPPY_OUT_INIT(sc);
1538 utoppy_add_64(sc, sc->sc_wr_offset); 1535 utoppy_add_64(sc, sc->sc_wr_offset);
1539 1536
1540 err = uiomove(utoppy_current_ptr(sc->sc_out_data), len, uio); 1537 err = uiomove(utoppy_current_ptr(sc->sc_out_data), len, uio);
1541 if (err) { 1538 if (err) {
1542 DPRINTF(UTOPPY_DBG_WRITE, ("%s: utoppywrite: uiomove()" 1539 DPRINTF(UTOPPY_DBG_WRITE, ("%s: utoppywrite: uiomove()"
1543 " returned %d\n", device_xname(sc->sc_dev), err)); 1540 " returned %d\n", device_xname(sc->sc_dev), err));
1544 break; 1541 break;
1545 } 1542 }
1546 1543
1547 utoppy_advance_ptr(sc->sc_out_data, len); 1544 utoppy_advance_ptr(sc->sc_out_data, len);
1548 1545
1549 err = utoppy_command(sc, UTOPPY_RESP_FILE_DATA, 1546 err = utoppy_command(sc, UTOPPY_RESP_FILE_DATA,
1550 UTOPPY_LONG_TIMEOUT, &resp); 1547 UTOPPY_LONG_TIMEOUT, &resp);
1551 if (err) { 1548 if (err) {
1552 DPRINTF(UTOPPY_DBG_WRITE, ("%s: utoppywrite: " 1549 DPRINTF(UTOPPY_DBG_WRITE, ("%s: utoppywrite: "
1553 "utoppy_command(UTOPPY_RESP_FILE_DATA) " 1550 "utoppy_command(UTOPPY_RESP_FILE_DATA) "
1554 "returned %d\n", device_xname(sc->sc_dev), err)); 1551 "returned %d\n", device_xname(sc->sc_dev), err));
1555 break; 1552 break;
1556 } 1553 }
1557 if (resp != UTOPPY_RESP_SUCCESS) { 1554 if (resp != UTOPPY_RESP_SUCCESS) {
1558 DPRINTF(UTOPPY_DBG_WRITE, ("%s: utoppywrite: " 1555 DPRINTF(UTOPPY_DBG_WRITE, ("%s: utoppywrite: "
1559 "utoppy_command(UTOPPY_RESP_FILE_DATA) returned " 1556 "utoppy_command(UTOPPY_RESP_FILE_DATA) returned "
1560 "bad response %#x\n", device_xname(sc->sc_dev), 1557 "bad response %#x\n", device_xname(sc->sc_dev),
1561 resp)); 1558 resp));
1562 utoppy_cancel(sc); 1559 utoppy_cancel(sc);
1563 err = EIO; 1560 err = EIO;
1564 break; 1561 break;
1565 } 1562 }
1566 1563
1567 sc->sc_wr_offset += len; 1564 sc->sc_wr_offset += len;
1568 sc->sc_wr_size -= len; 1565 sc->sc_wr_size -= len;
1569 } 1566 }
1570 1567
1571 DPRINTF(UTOPPY_DBG_WRITE, ("%s: utoppywrite: POST-WRITEFILE: resid " 1568 DPRINTF(UTOPPY_DBG_WRITE, ("%s: utoppywrite: POST-WRITEFILE: resid "
1572 "%ld, wr_size %lld, wr_offset %lld, err %d\n", 1569 "%ld, wr_size %lld, wr_offset %lld, err %d\n",
1573 device_xname(sc->sc_dev), (u_long)uio->uio_resid, sc->sc_wr_size, 1570 device_xname(sc->sc_dev), (u_long)uio->uio_resid, sc->sc_wr_size,
1574 sc->sc_wr_offset, err)); 1571 sc->sc_wr_offset, err));
1575 1572
1576 if (err == 0 && sc->sc_wr_size == 0) { 1573 if (err == 0 && sc->sc_wr_size == 0) {
1577 DPRINTF(UTOPPY_DBG_WRITE, ("%s: utoppywrite: sending " 1574 DPRINTF(UTOPPY_DBG_WRITE, ("%s: utoppywrite: sending "
1578 "FILE_END...\n", device_xname(sc->sc_dev))); 1575 "FILE_END...\n", device_xname(sc->sc_dev)));
1579 UTOPPY_OUT_INIT(sc); 1576 UTOPPY_OUT_INIT(sc);
1580 err = utoppy_command(sc, UTOPPY_RESP_FILE_END, 1577 err = utoppy_command(sc, UTOPPY_RESP_FILE_END,
1581 UTOPPY_LONG_TIMEOUT, &resp); 1578 UTOPPY_LONG_TIMEOUT, &resp);
1582 if (err) { 1579 if (err) {
1583 DPRINTF(UTOPPY_DBG_WRITE, ("%s: utoppywrite: " 1580 DPRINTF(UTOPPY_DBG_WRITE, ("%s: utoppywrite: "
1584 "utoppy_command(UTOPPY_RESP_FILE_END) returned " 1581 "utoppy_command(UTOPPY_RESP_FILE_END) returned "
1585 "%d\n", device_xname(sc->sc_dev), err)); 1582 "%d\n", device_xname(sc->sc_dev), err));
1586 1583
1587 utoppy_cancel(sc); 1584 utoppy_cancel(sc);
1588 } 1585 }
1589 1586
1590 sc->sc_state = UTOPPY_STATE_IDLE; 1587 sc->sc_state = UTOPPY_STATE_IDLE;
1591 DPRINTF(UTOPPY_DBG_WRITE, ("%s: utoppywrite: state %s\n", 1588 DPRINTF(UTOPPY_DBG_WRITE, ("%s: utoppywrite: state %s\n",
1592 device_xname(sc->sc_dev), 1589 device_xname(sc->sc_dev),
1593 utoppy_state_string(sc->sc_state))); 1590 utoppy_state_string(sc->sc_state)));
1594 } 1591 }
1595 1592
1596 if (--sc->sc_refcnt < 0) 1593 if (--sc->sc_refcnt < 0)
1597 usb_detach_wakeupold(sc->sc_dev); 1594 usb_detach_wakeupold(sc->sc_dev);
1598 1595
1599 return err; 1596 return err;
1600} 1597}
1601 1598
1602static int 1599static int
1603utoppyioctl(dev_t dev, u_long cmd, void *data, int flag, 1600utoppyioctl(dev_t dev, u_long cmd, void *data, int flag,
1604 struct lwp *l) 1601 struct lwp *l)
1605{ 1602{
1606 struct utoppy_softc *sc; 1603 struct utoppy_softc *sc;
1607 struct utoppy_rename *ur; 1604 struct utoppy_rename *ur;
1608 struct utoppy_readfile *urf; 1605 struct utoppy_readfile *urf;
1609 struct utoppy_writefile *uw; 1606 struct utoppy_writefile *uw;
1610 char uwf[UTOPPY_MAX_FILENAME_LEN + 1], *uwfp; 1607 char uwf[UTOPPY_MAX_FILENAME_LEN + 1], *uwfp;
1611 uint16_t resp; 1608 uint16_t resp;
1612 int err; 1609 int err;
1613 1610
1614 sc = device_lookup_private(&utoppy_cd, UTOPPYUNIT(dev)); 1611 sc = device_lookup_private(&utoppy_cd, UTOPPYUNIT(dev));
1615 1612
1616 if (sc->sc_dying) 1613 if (sc->sc_dying)
1617 return EIO; 1614 return EIO;
1618 1615
1619 DPRINTF(UTOPPY_DBG_IOCTL, ("%s: utoppyioctl: cmd 0x%08lx, state '%s'\n", 1616 DPRINTF(UTOPPY_DBG_IOCTL, ("%s: utoppyioctl: cmd 0x%08lx, state '%s'\n",
1620 device_xname(sc->sc_dev), cmd, utoppy_state_string(sc->sc_state))); 1617 device_xname(sc->sc_dev), cmd, utoppy_state_string(sc->sc_state)));
1621 1618
1622 if (sc->sc_state != UTOPPY_STATE_IDLE && cmd != UTOPPYIOCANCEL) { 1619 if (sc->sc_state != UTOPPY_STATE_IDLE && cmd != UTOPPYIOCANCEL) {
1623 DPRINTF(UTOPPY_DBG_IOCTL, ("%s: utoppyioctl: still busy.\n", 1620 DPRINTF(UTOPPY_DBG_IOCTL, ("%s: utoppyioctl: still busy.\n",
1624 device_xname(sc->sc_dev))); 1621 device_xname(sc->sc_dev)));
1625 return EBUSY; 1622 return EBUSY;
1626 } 1623 }
1627 1624
1628 sc->sc_refcnt++; 1625 sc->sc_refcnt++;
1629 1626
1630 switch (cmd) { 1627 switch (cmd) {
1631 case UTOPPYIOTURBO: 1628 case UTOPPYIOTURBO:
1632 err = 0; 1629 err = 0;
1633 sc->sc_turbo_mode = *((int *)data) ? 1 : 0; 1630 sc->sc_turbo_mode = *((int *)data) ? 1 : 0;
1634 DPRINTF(UTOPPY_DBG_IOCTL, ("%s: utoppyioctl: UTOPPYIOTURBO: " 1631 DPRINTF(UTOPPY_DBG_IOCTL, ("%s: utoppyioctl: UTOPPYIOTURBO: "
1635 "%s\n", device_xname(sc->sc_dev), 1632 "%s\n", device_xname(sc->sc_dev),
1636 sc->sc_turbo_mode ? "On" : "Off")); 1633 sc->sc_turbo_mode ? "On" : "Off"));
1637 break; 1634 break;
1638 1635
1639 case UTOPPYIOCANCEL: 1636 case UTOPPYIOCANCEL:
1640 DPRINTF(UTOPPY_DBG_IOCTL, ("%s: utoppyioctl: UTOPPYIOCANCEL\n", 1637 DPRINTF(UTOPPY_DBG_IOCTL, ("%s: utoppyioctl: UTOPPYIOCANCEL\n",
1641 device_xname(sc->sc_dev))); 1638 device_xname(sc->sc_dev)));
1642 err = utoppy_cancel(sc); 1639 err = utoppy_cancel(sc);
1643 break; 1640 break;
1644 1641
1645 case UTOPPYIOREBOOT: 1642 case UTOPPYIOREBOOT:
1646 DPRINTF(UTOPPY_DBG_IOCTL, ("%s: utoppyioctl: UTOPPYIOREBOOT\n", 1643 DPRINTF(UTOPPY_DBG_IOCTL, ("%s: utoppyioctl: UTOPPYIOREBOOT\n",
1647 device_xname(sc->sc_dev))); 1644 device_xname(sc->sc_dev)));
1648 UTOPPY_OUT_INIT(sc); 1645 UTOPPY_OUT_INIT(sc);
1649 err = utoppy_command(sc, UTOPPY_CMD_RESET, UTOPPY_LONG_TIMEOUT, 1646 err = utoppy_command(sc, UTOPPY_CMD_RESET, UTOPPY_LONG_TIMEOUT,
1650 &resp); 1647 &resp);
1651 if (err) 1648 if (err)
1652 break; 1649 break;
1653 1650
1654 if (resp != UTOPPY_RESP_SUCCESS) 1651 if (resp != UTOPPY_RESP_SUCCESS)
1655 err = EIO; 1652 err = EIO;
1656 break; 1653 break;
1657 1654
1658 case UTOPPYIOSTATS: 1655 case UTOPPYIOSTATS:
1659 DPRINTF(UTOPPY_DBG_IOCTL, ("%s: utoppyioctl: UTOPPYIOSTATS\n", 1656 DPRINTF(UTOPPY_DBG_IOCTL, ("%s: utoppyioctl: UTOPPYIOSTATS\n",
1660 device_xname(sc->sc_dev))); 1657 device_xname(sc->sc_dev)));
1661 err = utoppy_stats(sc, (struct utoppy_stats *)data); 1658 err = utoppy_stats(sc, (struct utoppy_stats *)data);
1662 break; 1659 break;
1663 1660
1664 case UTOPPYIORENAME: 1661 case UTOPPYIORENAME:
1665 DPRINTF(UTOPPY_DBG_IOCTL, ("%s: utoppyioctl: UTOPPYIORENAME\n", 1662 DPRINTF(UTOPPY_DBG_IOCTL, ("%s: utoppyioctl: UTOPPYIORENAME\n",
1666 device_xname(sc->sc_dev))); 1663 device_xname(sc->sc_dev)));
1667 ur = (struct utoppy_rename *)data; 1664 ur = (struct utoppy_rename *)data;
1668 UTOPPY_OUT_INIT(sc); 1665 UTOPPY_OUT_INIT(sc);
1669 1666
1670 if ((err = utoppy_add_path(sc, ur->ur_old_path, 1)) != 0) 1667 if ((err = utoppy_add_path(sc, ur->ur_old_path, 1)) != 0)
1671 break; 1668 break;
1672 if ((err = utoppy_add_path(sc, ur->ur_new_path, 1)) != 0) 1669 if ((err = utoppy_add_path(sc, ur->ur_new_path, 1)) != 0)
1673 break; 1670 break;
1674 1671
1675 err = utoppy_command(sc, UTOPPY_CMD_RENAME, 1672 err = utoppy_command(sc, UTOPPY_CMD_RENAME,
1676 UTOPPY_LONG_TIMEOUT, &resp); 1673 UTOPPY_LONG_TIMEOUT, &resp);
1677 if (err) 1674 if (err)
1678 break; 1675 break;
1679 1676
1680 if (resp != UTOPPY_RESP_SUCCESS) 1677 if (resp != UTOPPY_RESP_SUCCESS)
1681 err = EIO; 1678 err = EIO;
1682 break; 1679 break;
1683 1680
1684 case UTOPPYIOMKDIR: 1681 case UTOPPYIOMKDIR:
1685 DPRINTF(UTOPPY_DBG_IOCTL, ("%s: utoppyioctl: UTOPPYIOMKDIR\n", 1682 DPRINTF(UTOPPY_DBG_IOCTL, ("%s: utoppyioctl: UTOPPYIOMKDIR\n",
1686 device_xname(sc->sc_dev))); 1683 device_xname(sc->sc_dev)));
1687 UTOPPY_OUT_INIT(sc); 1684 UTOPPY_OUT_INIT(sc);
1688 err = utoppy_add_path(sc, *((const char **)data), 1); 1685 err = utoppy_add_path(sc, *((const char **)data), 1);
1689 if (err) 1686 if (err)
1690 break; 1687 break;
1691 1688
1692 err = utoppy_command(sc, UTOPPY_CMD_MKDIR, UTOPPY_LONG_TIMEOUT, 1689 err = utoppy_command(sc, UTOPPY_CMD_MKDIR, UTOPPY_LONG_TIMEOUT,
1693 &resp); 1690 &resp);
1694 if (err) 1691 if (err)
1695 break; 1692 break;
1696 1693
1697 if (resp != UTOPPY_RESP_SUCCESS) 1694 if (resp != UTOPPY_RESP_SUCCESS)
1698 err = EIO; 1695 err = EIO;
1699 break; 1696 break;
1700 1697
1701 case UTOPPYIODELETE: 1698 case UTOPPYIODELETE:
1702 DPRINTF(UTOPPY_DBG_IOCTL, ("%s: utoppyioctl: UTOPPYIODELETE\n", 1699 DPRINTF(UTOPPY_DBG_IOCTL, ("%s: utoppyioctl: UTOPPYIODELETE\n",
1703 device_xname(sc->sc_dev))); 1700 device_xname(sc->sc_dev)));
1704 UTOPPY_OUT_INIT(sc); 1701 UTOPPY_OUT_INIT(sc);
1705 err = utoppy_add_path(sc, *((const char **)data), 0); 1702 err = utoppy_add_path(sc, *((const char **)data), 0);
1706 if (err) 1703 if (err)
1707 break; 1704 break;
1708 1705
1709 err = utoppy_command(sc, UTOPPY_CMD_DELETE, UTOPPY_LONG_TIMEOUT, 1706 err = utoppy_command(sc, UTOPPY_CMD_DELETE, UTOPPY_LONG_TIMEOUT,
1710 &resp); 1707 &resp);
1711 if (err) 1708 if (err)
1712 break; 1709 break;
1713 1710
1714 if (resp != UTOPPY_RESP_SUCCESS) 1711 if (resp != UTOPPY_RESP_SUCCESS)
1715 err = EIO; 1712 err = EIO;
1716 break; 1713 break;
1717 1714
1718 case UTOPPYIOREADDIR: 1715 case UTOPPYIOREADDIR:
1719 DPRINTF(UTOPPY_DBG_IOCTL, ("%s: utoppyioctl: UTOPPYIOREADDIR\n", 1716 DPRINTF(UTOPPY_DBG_IOCTL, ("%s: utoppyioctl: UTOPPYIOREADDIR\n",
1720 device_xname(sc->sc_dev))); 1717 device_xname(sc->sc_dev)));
1721 UTOPPY_OUT_INIT(sc); 1718 UTOPPY_OUT_INIT(sc);
1722 err = utoppy_add_path(sc, *((const char **)data), 0); 1719 err = utoppy_add_path(sc, *((const char **)data), 0);
1723 if (err) { 1720 if (err) {
1724 DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppyioctl: " 1721 DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppyioctl: "
1725 "utoppy_add_path() returned %d\n", 1722 "utoppy_add_path() returned %d\n",
1726 device_xname(sc->sc_dev), err)); 1723 device_xname(sc->sc_dev), err));
1727 break; 1724 break;
1728 } 1725 }
1729 1726
1730 err = utoppy_send_packet(sc, UTOPPY_CMD_READDIR, 1727 err = utoppy_send_packet(sc, UTOPPY_CMD_READDIR,
1731 UTOPPY_LONG_TIMEOUT); 1728 UTOPPY_LONG_TIMEOUT);
1732 if (err != 0) { 1729 if (err != 0) {
1733 DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppyioctl: " 1730 DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppyioctl: "
1734 "UTOPPY_CMD_READDIR returned %d\n", 1731 "UTOPPY_CMD_READDIR returned %d\n",
1735 device_xname(sc->sc_dev), err)); 1732 device_xname(sc->sc_dev), err));
1736 break; 1733 break;
1737 } 1734 }
1738 1735
1739 err = utoppy_readdir_next(sc); 1736 err = utoppy_readdir_next(sc);
1740 if (err) { 1737 if (err) {
1741 DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppyioctl: " 1738 DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppyioctl: "
1742 "utoppy_readdir_next() returned %d\n", 1739 "utoppy_readdir_next() returned %d\n",
1743 device_xname(sc->sc_dev), err)); 1740 device_xname(sc->sc_dev), err));
1744 } 1741 }
1745 break; 1742 break;
1746 1743
1747 case UTOPPYIOREADFILE: 1744 case UTOPPYIOREADFILE:
1748 urf = (struct utoppy_readfile *)data; 1745 urf = (struct utoppy_readfile *)data;
1749 1746
1750 DPRINTF(UTOPPY_DBG_IOCTL,("%s: utoppyioctl: UTOPPYIOREADFILE " 1747 DPRINTF(UTOPPY_DBG_IOCTL,("%s: utoppyioctl: UTOPPYIOREADFILE "
1751 "%s, offset %lld\n", device_xname(sc->sc_dev), 1748 "%s, offset %lld\n", device_xname(sc->sc_dev),
1752 urf->ur_path, urf->ur_offset)); 1749 urf->ur_path, urf->ur_offset));
1753 1750
1754 if ((err = utoppy_turbo_mode(sc, sc->sc_turbo_mode)) != 0) 1751 if ((err = utoppy_turbo_mode(sc, sc->sc_turbo_mode)) != 0)
1755 break; 1752 break;
1756 1753
1757 UTOPPY_OUT_INIT(sc); 1754 UTOPPY_OUT_INIT(sc);
1758 utoppy_add_8(sc, UTOPPY_FILE_READ); 1755 utoppy_add_8(sc, UTOPPY_FILE_READ);
1759 1756
1760 if ((err = utoppy_add_path(sc, urf->ur_path, 1)) != 0) 1757 if ((err = utoppy_add_path(sc, urf->ur_path, 1)) != 0)
1761 break; 1758 break;
1762 1759
1763 utoppy_add_64(sc, urf->ur_offset); 1760 utoppy_add_64(sc, urf->ur_offset);
1764 1761
1765 sc->sc_state = UTOPPY_STATE_READFILE; 1762 sc->sc_state = UTOPPY_STATE_READFILE;
1766 sc->sc_in_offset = 0; 1763 sc->sc_in_offset = 0;
1767 1764
1768 err = utoppy_send_packet(sc, UTOPPY_CMD_FILE, 1765 err = utoppy_send_packet(sc, UTOPPY_CMD_FILE,
1769 UTOPPY_LONG_TIMEOUT); 1766 UTOPPY_LONG_TIMEOUT);
1770 if (err == 0) 1767 if (err == 0)
1771 err = utoppy_readfile_next(sc); 1768 err = utoppy_readfile_next(sc);
1772 break; 1769 break;
1773 1770
1774 case UTOPPYIOWRITEFILE: 1771 case UTOPPYIOWRITEFILE:
1775 uw = (struct utoppy_writefile *)data; 1772 uw = (struct utoppy_writefile *)data;
1776 1773
1777 DPRINTF(UTOPPY_DBG_IOCTL,("%s: utoppyioctl: UTOPPYIOWRITEFILE " 1774 DPRINTF(UTOPPY_DBG_IOCTL,("%s: utoppyioctl: UTOPPYIOWRITEFILE "
1778 "%s, size %lld, offset %lld\n", device_xname(sc->sc_dev), 1775 "%s, size %lld, offset %lld\n", device_xname(sc->sc_dev),
1779 uw->uw_path, uw->uw_size, uw->uw_offset)); 1776 uw->uw_path, uw->uw_size, uw->uw_offset));
1780 1777
1781 if ((err = utoppy_turbo_mode(sc, sc->sc_turbo_mode)) != 0) 1778 if ((err = utoppy_turbo_mode(sc, sc->sc_turbo_mode)) != 0)
1782 break; 1779 break;
1783 1780
1784 UTOPPY_OUT_INIT(sc); 1781 UTOPPY_OUT_INIT(sc);
1785 utoppy_add_8(sc, UTOPPY_FILE_WRITE); 1782 utoppy_add_8(sc, UTOPPY_FILE_WRITE);
1786 uwfp = utoppy_current_ptr(sc->sc_out_data); 1783 uwfp = utoppy_current_ptr(sc->sc_out_data);
1787 1784
1788 if ((err = utoppy_add_path(sc, uw->uw_path, 1)) != 0) { 1785 if ((err = utoppy_add_path(sc, uw->uw_path, 1)) != 0) {
1789 DPRINTF(UTOPPY_DBG_WRITE,("%s: utoppyioctl: add_path()" 1786 DPRINTF(UTOPPY_DBG_WRITE,("%s: utoppyioctl: add_path()"
1790 " returned %d\n", device_xname(sc->sc_dev), err)); 1787 " returned %d\n", device_xname(sc->sc_dev), err));
1791 break; 1788 break;
1792 } 1789 }
1793 1790
1794 strncpy(uwf, &uwfp[2], sizeof(uwf)); 1791 strncpy(uwf, &uwfp[2], sizeof(uwf));
1795 utoppy_add_64(sc, uw->uw_offset); 1792 utoppy_add_64(sc, uw->uw_offset);
1796 1793
1797 err = utoppy_command(sc, UTOPPY_CMD_FILE, UTOPPY_LONG_TIMEOUT, 1794 err = utoppy_command(sc, UTOPPY_CMD_FILE, UTOPPY_LONG_TIMEOUT,
1798 &resp); 1795 &resp);
1799 if (err) { 1796 if (err) {
1800 DPRINTF(UTOPPY_DBG_WRITE,("%s: utoppyioctl: " 1797 DPRINTF(UTOPPY_DBG_WRITE,("%s: utoppyioctl: "
1801 "utoppy_command(UTOPPY_CMD_FILE) returned " 1798 "utoppy_command(UTOPPY_CMD_FILE) returned "
1802 "%d\n", device_xname(sc->sc_dev), err)); 1799 "%d\n", device_xname(sc->sc_dev), err));
1803 break; 1800 break;
1804 } 1801 }
1805 if (resp != UTOPPY_RESP_SUCCESS) { 1802 if (resp != UTOPPY_RESP_SUCCESS) {
1806 DPRINTF(UTOPPY_DBG_WRITE,("%s: utoppyioctl: " 1803 DPRINTF(UTOPPY_DBG_WRITE,("%s: utoppyioctl: "
1807 "utoppy_command(UTOPPY_CMD_FILE) returned " 1804 "utoppy_command(UTOPPY_CMD_FILE) returned "
1808 "bad response %#x\n", device_xname(sc->sc_dev), 1805 "bad response %#x\n", device_xname(sc->sc_dev),
1809 resp)); 1806 resp));
1810 err = EIO; 1807 err = EIO;
1811 break; 1808 break;
1812 } 1809 }
1813 1810
1814 UTOPPY_OUT_INIT(sc); 1811 UTOPPY_OUT_INIT(sc);
1815 utoppy_timestamp_encode(sc, uw->uw_mtime); 1812 utoppy_timestamp_encode(sc, uw->uw_mtime);
1816 utoppy_add_8(sc, UTOPPY_FTYPE_FILE); 1813 utoppy_add_8(sc, UTOPPY_FTYPE_FILE);
1817 utoppy_add_64(sc, uw->uw_size); 1814 utoppy_add_64(sc, uw->uw_size);
1818 utoppy_add_string(sc, uwf, sizeof(uwf)); 1815 utoppy_add_string(sc, uwf, sizeof(uwf));
1819 utoppy_add_32(sc, 0); 1816 utoppy_add_32(sc, 0);
1820 1817
1821 err = utoppy_command(sc, UTOPPY_RESP_FILE_HEADER, 1818 err = utoppy_command(sc, UTOPPY_RESP_FILE_HEADER,
1822 UTOPPY_LONG_TIMEOUT, &resp); 1819 UTOPPY_LONG_TIMEOUT, &resp);
1823 if (err) { 1820 if (err) {
1824 DPRINTF(UTOPPY_DBG_WRITE,("%s: utoppyioctl: " 1821 DPRINTF(UTOPPY_DBG_WRITE,("%s: utoppyioctl: "
1825 "utoppy_command(UTOPPY_RESP_FILE_HEADER) " 1822 "utoppy_command(UTOPPY_RESP_FILE_HEADER) "
1826 "returned %d\n", device_xname(sc->sc_dev), err)); 1823 "returned %d\n", device_xname(sc->sc_dev), err));
1827 break; 1824 break;
1828 } 1825 }
1829 if (resp != UTOPPY_RESP_SUCCESS) { 1826 if (resp != UTOPPY_RESP_SUCCESS) {
1830 DPRINTF(UTOPPY_DBG_WRITE,("%s: utoppyioctl: " 1827 DPRINTF(UTOPPY_DBG_WRITE,("%s: utoppyioctl: "
1831 "utoppy_command(UTOPPY_RESP_FILE_HEADER) " 1828 "utoppy_command(UTOPPY_RESP_FILE_HEADER) "
1832 "returned bad response %#x\n", 1829 "returned bad response %#x\n",
1833 device_xname(sc->sc_dev), resp)); 1830 device_xname(sc->sc_dev), resp));
1834 err = EIO; 1831 err = EIO;
1835 break; 1832 break;
1836 } 1833 }
1837 1834
1838 sc->sc_wr_offset = uw->uw_offset; 1835 sc->sc_wr_offset = uw->uw_offset;
1839 sc->sc_wr_size = uw->uw_size; 1836 sc->sc_wr_size = uw->uw_size;
1840 sc->sc_state = UTOPPY_STATE_WRITEFILE; 1837 sc->sc_state = UTOPPY_STATE_WRITEFILE;
1841 1838
1842 DPRINTF(UTOPPY_DBG_WRITE,("%s: utoppyioctl: Changing state to " 1839 DPRINTF(UTOPPY_DBG_WRITE,("%s: utoppyioctl: Changing state to "
1843 "%s. wr_offset %lld, wr_size %lld\n", 1840 "%s. wr_offset %lld, wr_size %lld\n",
1844 device_xname(sc->sc_dev), utoppy_state_string(sc->sc_state), 1841 device_xname(sc->sc_dev), utoppy_state_string(sc->sc_state),
1845 sc->sc_wr_offset, sc->sc_wr_size)); 1842 sc->sc_wr_offset, sc->sc_wr_size));
1846 break; 1843 break;
1847 1844
1848 default: 1845 default:
1849 DPRINTF(UTOPPY_DBG_IOCTL,("%s: utoppyioctl: Invalid cmd\n", 1846 DPRINTF(UTOPPY_DBG_IOCTL,("%s: utoppyioctl: Invalid cmd\n",
1850 device_xname(sc->sc_dev))); 1847 device_xname(sc->sc_dev)));
1851 err = ENODEV; 1848 err = ENODEV;
1852 break; 1849 break;
1853 } 1850 }
1854 1851
1855 DPRINTF(UTOPPY_DBG_IOCTL,("%s: utoppyioctl: done. err %d, state '%s'\n", 1852 DPRINTF(UTOPPY_DBG_IOCTL,("%s: utoppyioctl: done. err %d, state '%s'\n",
1856 device_xname(sc->sc_dev), err, utoppy_state_string(sc->sc_state))); 1853 device_xname(sc->sc_dev), err, utoppy_state_string(sc->sc_state)));
1857 1854
1858 if (err) 1855 if (err)
1859 utoppy_cancel(sc); 1856 utoppy_cancel(sc);
1860 1857
1861 if (--sc->sc_refcnt < 0) 1858 if (--sc->sc_refcnt < 0)
1862 usb_detach_wakeupold(sc->sc_dev); 1859 usb_detach_wakeupold(sc->sc_dev);
1863 1860
1864 return err; 1861 return err;
1865} 1862}