Sat Oct 1 13:46:52 2016 UTC ()
remove unused variable.


(christos)
diff -r1.96 -r1.97 src/sys/dev/ic/sl811hs.c

cvs diff -r1.96 -r1.97 src/sys/dev/ic/sl811hs.c (switch to unified diff)

--- src/sys/dev/ic/sl811hs.c 2016/09/24 15:06:29 1.96
+++ src/sys/dev/ic/sl811hs.c 2016/10/01 13:46:52 1.97
@@ -1,1192 +1,1186 @@ @@ -1,1192 +1,1186 @@
1/* $NetBSD: sl811hs.c,v 1.96 2016/09/24 15:06:29 skrll Exp $ */ 1/* $NetBSD: sl811hs.c,v 1.97 2016/10/01 13:46:52 christos Exp $ */
2 2
3/* 3/*
4 * Not (c) 2007 Matthew Orgass 4 * Not (c) 2007 Matthew Orgass
5 * This file is public domain, meaning anyone can make any use of part or all 5 * This file is public domain, meaning anyone can make any use of part or all
6 * of this file including copying into other works without credit. Any use, 6 * of this file including copying into other works without credit. Any use,
7 * modified or not, is solely the responsibility of the user. If this file is 7 * modified or not, is solely the responsibility of the user. If this file is
8 * part of a collection then use in the collection is governed by the terms of 8 * part of a collection then use in the collection is governed by the terms of
9 * the collection. 9 * the collection.
10 */ 10 */
11 11
12/* 12/*
13 * Cypress/ScanLogic SL811HS/T USB Host Controller 13 * Cypress/ScanLogic SL811HS/T USB Host Controller
14 * Datasheet, Errata, and App Note available at www.cypress.com 14 * Datasheet, Errata, and App Note available at www.cypress.com
15 * 15 *
16 * Uses: Ratoc CFU1U PCMCIA USB Host Controller, Nereid X68k USB HC, ISA 16 * Uses: Ratoc CFU1U PCMCIA USB Host Controller, Nereid X68k USB HC, ISA
17 * HCs. The Ratoc CFU2 uses a different chip. 17 * HCs. The Ratoc CFU2 uses a different chip.
18 * 18 *
19 * This chip puts the serial in USB. It implements USB by means of an eight 19 * This chip puts the serial in USB. It implements USB by means of an eight
20 * bit I/O interface. It can be used for ISA, PCMCIA/CF, parallel port, 20 * bit I/O interface. It can be used for ISA, PCMCIA/CF, parallel port,
21 * serial port, or any eight bit interface. It has 256 bytes of memory, the 21 * serial port, or any eight bit interface. It has 256 bytes of memory, the
22 * first 16 of which are used for register access. There are two sets of 22 * first 16 of which are used for register access. There are two sets of
23 * registers for sending individual bus transactions. Because USB is polled, 23 * registers for sending individual bus transactions. Because USB is polled,
24 * this organization means that some amount of card access must often be made 24 * this organization means that some amount of card access must often be made
25 * when devices are attached, even if when they are not directly being used. 25 * when devices are attached, even if when they are not directly being used.
26 * A per-ms frame interrupt is necessary and many devices will poll with a 26 * A per-ms frame interrupt is necessary and many devices will poll with a
27 * per-frame bulk transfer. 27 * per-frame bulk transfer.
28 * 28 *
29 * It is possible to write a little over two bytes to the chip (auto 29 * It is possible to write a little over two bytes to the chip (auto
30 * incremented) per full speed byte time on the USB. Unfortunately, 30 * incremented) per full speed byte time on the USB. Unfortunately,
31 * auto-increment does not work reliably so write and bus speed is 31 * auto-increment does not work reliably so write and bus speed is
32 * approximately the same for full speed devices. 32 * approximately the same for full speed devices.
33 * 33 *
34 * In addition to the 240 byte packet size limit for isochronous transfers, 34 * In addition to the 240 byte packet size limit for isochronous transfers,
35 * this chip has no means of determining the current frame number other than 35 * this chip has no means of determining the current frame number other than
36 * getting all 1ms SOF interrupts, which is not always possible even on a fast 36 * getting all 1ms SOF interrupts, which is not always possible even on a fast
37 * system. Isochronous transfers guarantee that transfers will never be 37 * system. Isochronous transfers guarantee that transfers will never be
38 * retried in a later frame, so this can cause problems with devices beyond 38 * retried in a later frame, so this can cause problems with devices beyond
39 * the difficulty in actually performing the transfer most frames. I tried 39 * the difficulty in actually performing the transfer most frames. I tried
40 * implementing isoc transfers and was able to play CD-derrived audio via an 40 * implementing isoc transfers and was able to play CD-derrived audio via an
41 * iMic on a 2GHz PC, however it would still be interrupted at times and 41 * iMic on a 2GHz PC, however it would still be interrupted at times and
42 * once interrupted, would stay out of sync. All isoc support has been 42 * once interrupted, would stay out of sync. All isoc support has been
43 * removed. 43 * removed.
44 * 44 *
45 * BUGS: all chip revisions have problems with low speed devices through hubs. 45 * BUGS: all chip revisions have problems with low speed devices through hubs.
46 * The chip stops generating SOF with hubs that send SE0 during SOF. See 46 * The chip stops generating SOF with hubs that send SE0 during SOF. See
47 * comment in dointr(). All performance enhancing features of this chip seem 47 * comment in dointr(). All performance enhancing features of this chip seem
48 * not to work properly, most confirmed buggy in errata doc. 48 * not to work properly, most confirmed buggy in errata doc.
49 * 49 *
50 */ 50 */
51 51
52/* 52/*
53 * The hard interrupt is the main entry point. Start, callbacks, and repeat 53 * The hard interrupt is the main entry point. Start, callbacks, and repeat
54 * are the only others called frequently. 54 * are the only others called frequently.
55 * 55 *
56 * Since this driver attaches to pcmcia, card removal at any point should be 56 * Since this driver attaches to pcmcia, card removal at any point should be
57 * expected and not cause panics or infinite loops. 57 * expected and not cause panics or infinite loops.
58 */ 58 */
59 59
60/* 60/*
61 * XXX TODO: 61 * XXX TODO:
62 * copy next output packet while transfering 62 * copy next output packet while transfering
63 * usb suspend 63 * usb suspend
64 * could keep track of known values of all buffer space? 64 * could keep track of known values of all buffer space?
65 * combined print/log function for errors 65 * combined print/log function for errors
66 * 66 *
67 * ub_usepolling support is untested and may not work 67 * ub_usepolling support is untested and may not work
68 */ 68 */
69 69
70#include <sys/cdefs.h> 70#include <sys/cdefs.h>
71__KERNEL_RCSID(0, "$NetBSD: sl811hs.c,v 1.96 2016/09/24 15:06:29 skrll Exp $"); 71__KERNEL_RCSID(0, "$NetBSD: sl811hs.c,v 1.97 2016/10/01 13:46:52 christos Exp $");
72 72
73#ifdef _KERNEL_OPT 73#ifdef _KERNEL_OPT
74#include "opt_slhci.h" 74#include "opt_slhci.h"
75#include "opt_usb.h" 75#include "opt_usb.h"
76#endif 76#endif
77 77
78#include <sys/param.h> 78#include <sys/param.h>
79 79
80#include <sys/bus.h> 80#include <sys/bus.h>
81#include <sys/cpu.h> 81#include <sys/cpu.h>
82#include <sys/device.h> 82#include <sys/device.h>
83#include <sys/gcq.h> 83#include <sys/gcq.h>
84#include <sys/intr.h> 84#include <sys/intr.h>
85#include <sys/kernel.h> 85#include <sys/kernel.h>
86#include <sys/kmem.h> 86#include <sys/kmem.h>
87#include <sys/proc.h> 87#include <sys/proc.h>
88#include <sys/queue.h> 88#include <sys/queue.h>
89#include <sys/sysctl.h> 89#include <sys/sysctl.h>
90#include <sys/systm.h> 90#include <sys/systm.h>
91 91
92#include <dev/usb/usb.h> 92#include <dev/usb/usb.h>
93#include <dev/usb/usbdi.h> 93#include <dev/usb/usbdi.h>
94#include <dev/usb/usbdivar.h> 94#include <dev/usb/usbdivar.h>
95#include <dev/usb/usbhist.h> 95#include <dev/usb/usbhist.h>
96#include <dev/usb/usb_mem.h> 96#include <dev/usb/usb_mem.h>
97#include <dev/usb/usbdevs.h> 97#include <dev/usb/usbdevs.h>
98#include <dev/usb/usbroothub.h> 98#include <dev/usb/usbroothub.h>
99 99
100#include <dev/ic/sl811hsreg.h> 100#include <dev/ic/sl811hsreg.h>
101#include <dev/ic/sl811hsvar.h> 101#include <dev/ic/sl811hsvar.h>
102 102
103#define Q_CB 0 /* Control/Bulk */ 103#define Q_CB 0 /* Control/Bulk */
104#define Q_NEXT_CB 1 104#define Q_NEXT_CB 1
105#define Q_MAX_XFER Q_CB 105#define Q_MAX_XFER Q_CB
106#define Q_CALLBACKS 2 106#define Q_CALLBACKS 2
107#define Q_MAX Q_CALLBACKS 107#define Q_MAX Q_CALLBACKS
108 108
109#define F_AREADY (0x00000001) 109#define F_AREADY (0x00000001)
110#define F_BREADY (0x00000002) 110#define F_BREADY (0x00000002)
111#define F_AINPROG (0x00000004) 111#define F_AINPROG (0x00000004)
112#define F_BINPROG (0x00000008) 112#define F_BINPROG (0x00000008)
113#define F_LOWSPEED (0x00000010) 113#define F_LOWSPEED (0x00000010)
114#define F_UDISABLED (0x00000020) /* Consider disabled for USB */ 114#define F_UDISABLED (0x00000020) /* Consider disabled for USB */
115#define F_NODEV (0x00000040) 115#define F_NODEV (0x00000040)
116#define F_ROOTINTR (0x00000080) 116#define F_ROOTINTR (0x00000080)
117#define F_REALPOWER (0x00000100) /* Actual power state */ 117#define F_REALPOWER (0x00000100) /* Actual power state */
118#define F_POWER (0x00000200) /* USB reported power state */ 118#define F_POWER (0x00000200) /* USB reported power state */
119#define F_ACTIVE (0x00000400) 119#define F_ACTIVE (0x00000400)
120#define F_CALLBACK (0x00000800) /* Callback scheduled */ 120#define F_CALLBACK (0x00000800) /* Callback scheduled */
121#define F_SOFCHECK1 (0x00001000) 121#define F_SOFCHECK1 (0x00001000)
122#define F_SOFCHECK2 (0x00002000) 122#define F_SOFCHECK2 (0x00002000)
123#define F_CRESET (0x00004000) /* Reset done not reported */ 123#define F_CRESET (0x00004000) /* Reset done not reported */
124#define F_CCONNECT (0x00008000) /* Connect change not reported */ 124#define F_CCONNECT (0x00008000) /* Connect change not reported */
125#define F_RESET (0x00010000) 125#define F_RESET (0x00010000)
126#define F_ISOC_WARNED (0x00020000) 126#define F_ISOC_WARNED (0x00020000)
127#define F_LSVH_WARNED (0x00040000) 127#define F_LSVH_WARNED (0x00040000)
128 128
129#define F_DISABLED (F_NODEV|F_UDISABLED) 129#define F_DISABLED (F_NODEV|F_UDISABLED)
130#define F_CHANGE (F_CRESET|F_CCONNECT) 130#define F_CHANGE (F_CRESET|F_CCONNECT)
131 131
132#ifdef SLHCI_TRY_LSVH 132#ifdef SLHCI_TRY_LSVH
133unsigned int slhci_try_lsvh = 1; 133unsigned int slhci_try_lsvh = 1;
134#else 134#else
135unsigned int slhci_try_lsvh = 0; 135unsigned int slhci_try_lsvh = 0;
136#endif 136#endif
137 137
138#define ADR 0 138#define ADR 0
139#define LEN 1 139#define LEN 1
140#define PID 2 140#define PID 2
141#define DEV 3 141#define DEV 3
142#define STAT 2 142#define STAT 2
143#define CONT 3 143#define CONT 3
144 144
145#define A 0 145#define A 0
146#define B 1 146#define B 1
147 147
148static const uint8_t slhci_tregs[2][4] = 148static const uint8_t slhci_tregs[2][4] =
149{{SL11_E0ADDR, SL11_E0LEN, SL11_E0PID, SL11_E0DEV }, 149{{SL11_E0ADDR, SL11_E0LEN, SL11_E0PID, SL11_E0DEV },
150 {SL11_E1ADDR, SL11_E1LEN, SL11_E1PID, SL11_E1DEV }}; 150 {SL11_E1ADDR, SL11_E1LEN, SL11_E1PID, SL11_E1DEV }};
151 151
152#define PT_ROOT_CTRL 0 152#define PT_ROOT_CTRL 0
153#define PT_ROOT_INTR 1 153#define PT_ROOT_INTR 1
154#define PT_CTRL_SETUP 2 154#define PT_CTRL_SETUP 2
155#define PT_CTRL_DATA 3 155#define PT_CTRL_DATA 3
156#define PT_CTRL_STATUS 4 156#define PT_CTRL_STATUS 4
157#define PT_INTR 5 157#define PT_INTR 5
158#define PT_BULK 6 158#define PT_BULK 6
159#define PT_MAX 6 159#define PT_MAX 6
160 160
161#ifdef SLHCI_DEBUG 161#ifdef SLHCI_DEBUG
162#define SLHCI_MEM_ACCOUNTING 162#define SLHCI_MEM_ACCOUNTING
163#endif 163#endif
164 164
165/* 165/*
166 * Maximum allowable reserved bus time. Since intr/isoc transfers have 166 * Maximum allowable reserved bus time. Since intr/isoc transfers have
167 * unconditional priority, this is all that ensures control and bulk transfers 167 * unconditional priority, this is all that ensures control and bulk transfers
168 * get a chance. It is a single value for all frames since all transfers can 168 * get a chance. It is a single value for all frames since all transfers can
169 * use multiple consecutive frames if an error is encountered. Note that it 169 * use multiple consecutive frames if an error is encountered. Note that it
170 * is not really possible to fill the bus with transfers, so this value should 170 * is not really possible to fill the bus with transfers, so this value should
171 * be on the low side. Defaults to giving a warning unless SLHCI_NO_OVERTIME 171 * be on the low side. Defaults to giving a warning unless SLHCI_NO_OVERTIME
172 * is defined. Full time is 12000 - END_BUSTIME. 172 * is defined. Full time is 12000 - END_BUSTIME.
173 */ 173 */
174#ifndef SLHCI_RESERVED_BUSTIME 174#ifndef SLHCI_RESERVED_BUSTIME
175#define SLHCI_RESERVED_BUSTIME 5000 175#define SLHCI_RESERVED_BUSTIME 5000
176#endif 176#endif
177 177
178/* 178/*
179 * Rate for "exceeds reserved bus time" warnings (default) or errors. 179 * Rate for "exceeds reserved bus time" warnings (default) or errors.
180 * Warnings only happen when an endpoint open causes the time to go above 180 * Warnings only happen when an endpoint open causes the time to go above
181 * SLHCI_RESERVED_BUSTIME, not if it is already above. 181 * SLHCI_RESERVED_BUSTIME, not if it is already above.
182 */ 182 */
183#ifndef SLHCI_OVERTIME_WARNING_RATE 183#ifndef SLHCI_OVERTIME_WARNING_RATE
184#define SLHCI_OVERTIME_WARNING_RATE { 60, 0 } /* 60 seconds */ 184#define SLHCI_OVERTIME_WARNING_RATE { 60, 0 } /* 60 seconds */
185#endif 185#endif
186static const struct timeval reserved_warn_rate = SLHCI_OVERTIME_WARNING_RATE; 186static const struct timeval reserved_warn_rate = SLHCI_OVERTIME_WARNING_RATE;
187 187
188/* Rate for overflow warnings */ 
189#ifndef SLHCI_OVERFLOW_WARNING_RATE 
190#define SLHCI_OVERFLOW_WARNING_RATE { 60, 0 } /* 60 seconds */ 
191#endif 
192static const struct timeval overflow_warn_rate = SLHCI_OVERFLOW_WARNING_RATE; 
193 
194/* 188/*
195 * For EOF, the spec says 42 bit times, plus (I think) a possible hub skew of 189 * For EOF, the spec says 42 bit times, plus (I think) a possible hub skew of
196 * 20 bit times. By default leave 66 bit times to start the transfer beyond 190 * 20 bit times. By default leave 66 bit times to start the transfer beyond
197 * the required time. Units are full-speed bit times (a bit over 5us per 64). 191 * the required time. Units are full-speed bit times (a bit over 5us per 64).
198 * Only multiples of 64 are significant. 192 * Only multiples of 64 are significant.
199 */ 193 */
200#define SLHCI_STANDARD_END_BUSTIME 128 194#define SLHCI_STANDARD_END_BUSTIME 128
201#ifndef SLHCI_EXTRA_END_BUSTIME 195#ifndef SLHCI_EXTRA_END_BUSTIME
202#define SLHCI_EXTRA_END_BUSTIME 0 196#define SLHCI_EXTRA_END_BUSTIME 0
203#endif 197#endif
204 198
205#define SLHCI_END_BUSTIME (SLHCI_STANDARD_END_BUSTIME+SLHCI_EXTRA_END_BUSTIME) 199#define SLHCI_END_BUSTIME (SLHCI_STANDARD_END_BUSTIME+SLHCI_EXTRA_END_BUSTIME)
206 200
207/* 201/*
208 * This is an approximation of the USB worst-case timings presented on p. 54 of 202 * This is an approximation of the USB worst-case timings presented on p. 54 of
209 * the USB 1.1 spec translated to full speed bit times. 203 * the USB 1.1 spec translated to full speed bit times.
210 * FS = full speed with handshake, FSII = isoc in, FSIO = isoc out, 204 * FS = full speed with handshake, FSII = isoc in, FSIO = isoc out,
211 * FSI = isoc (worst case), LS = low speed 205 * FSI = isoc (worst case), LS = low speed
212 */ 206 */
213#define SLHCI_FS_CONST 114 207#define SLHCI_FS_CONST 114
214#define SLHCI_FSII_CONST 92 208#define SLHCI_FSII_CONST 92
215#define SLHCI_FSIO_CONST 80 209#define SLHCI_FSIO_CONST 80
216#define SLHCI_FSI_CONST 92 210#define SLHCI_FSI_CONST 92
217#define SLHCI_LS_CONST 804 211#define SLHCI_LS_CONST 804
218#ifndef SLHCI_PRECICE_BUSTIME 212#ifndef SLHCI_PRECICE_BUSTIME
219/* 213/*
220 * These values are < 3% too high (compared to the multiply and divide) for 214 * These values are < 3% too high (compared to the multiply and divide) for
221 * max sized packets. 215 * max sized packets.
222 */ 216 */
223#define SLHCI_FS_DATA_TIME(len) (((u_int)(len)<<3)+(len)+((len)>>1)) 217#define SLHCI_FS_DATA_TIME(len) (((u_int)(len)<<3)+(len)+((len)>>1))
224#define SLHCI_LS_DATA_TIME(len) (((u_int)(len)<<6)+((u_int)(len)<<4)) 218#define SLHCI_LS_DATA_TIME(len) (((u_int)(len)<<6)+((u_int)(len)<<4))
225#else 219#else
226#define SLHCI_FS_DATA_TIME(len) (56*(len)/6) 220#define SLHCI_FS_DATA_TIME(len) (56*(len)/6)
227#define SLHCI_LS_DATA_TIME(len) (449*(len)/6) 221#define SLHCI_LS_DATA_TIME(len) (449*(len)/6)
228#endif 222#endif
229 223
230/* 224/*
231 * Set SLHCI_WAIT_SIZE to the desired maximum size of single FS transfer 225 * Set SLHCI_WAIT_SIZE to the desired maximum size of single FS transfer
232 * to poll for after starting a transfer. 64 gets all full speed transfers. 226 * to poll for after starting a transfer. 64 gets all full speed transfers.
233 * Note that even if 0 polling will occur if data equal or greater than the 227 * Note that even if 0 polling will occur if data equal or greater than the
234 * transfer size is copied to the chip while the transfer is in progress. 228 * transfer size is copied to the chip while the transfer is in progress.
235 * Setting SLHCI_WAIT_TIME to -12000 will disable polling. 229 * Setting SLHCI_WAIT_TIME to -12000 will disable polling.
236 */ 230 */
237#ifndef SLHCI_WAIT_SIZE 231#ifndef SLHCI_WAIT_SIZE
238#define SLHCI_WAIT_SIZE 8 232#define SLHCI_WAIT_SIZE 8
239#endif 233#endif
240#ifndef SLHCI_WAIT_TIME 234#ifndef SLHCI_WAIT_TIME
241#define SLHCI_WAIT_TIME (SLHCI_FS_CONST + \ 235#define SLHCI_WAIT_TIME (SLHCI_FS_CONST + \
242 SLHCI_FS_DATA_TIME(SLHCI_WAIT_SIZE)) 236 SLHCI_FS_DATA_TIME(SLHCI_WAIT_SIZE))
243#endif 237#endif
244const int slhci_wait_time = SLHCI_WAIT_TIME; 238const int slhci_wait_time = SLHCI_WAIT_TIME;
245 239
246#ifndef SLHCI_MAX_RETRIES 240#ifndef SLHCI_MAX_RETRIES
247#define SLHCI_MAX_RETRIES 3 241#define SLHCI_MAX_RETRIES 3
248#endif 242#endif
249 243
250/* Check IER values for corruption after this many unrecognized interrupts. */ 244/* Check IER values for corruption after this many unrecognized interrupts. */
251#ifndef SLHCI_IER_CHECK_FREQUENCY 245#ifndef SLHCI_IER_CHECK_FREQUENCY
252#ifdef SLHCI_DEBUG 246#ifdef SLHCI_DEBUG
253#define SLHCI_IER_CHECK_FREQUENCY 1 247#define SLHCI_IER_CHECK_FREQUENCY 1
254#else 248#else
255#define SLHCI_IER_CHECK_FREQUENCY 100 249#define SLHCI_IER_CHECK_FREQUENCY 100
256#endif 250#endif
257#endif 251#endif
258 252
259/* Note that buffer points to the start of the buffer for this transfer. */ 253/* Note that buffer points to the start of the buffer for this transfer. */
260struct slhci_pipe { 254struct slhci_pipe {
261 struct usbd_pipe pipe; 255 struct usbd_pipe pipe;
262 struct usbd_xfer *xfer; /* xfer in progress */ 256 struct usbd_xfer *xfer; /* xfer in progress */
263 uint8_t *buffer; /* I/O buffer (if needed) */ 257 uint8_t *buffer; /* I/O buffer (if needed) */
264 struct gcq ap; /* All pipes */ 258 struct gcq ap; /* All pipes */
265 struct gcq to; /* Timeout list */ 259 struct gcq to; /* Timeout list */
266 struct gcq xq; /* Xfer queues */ 260 struct gcq xq; /* Xfer queues */
267 unsigned int pflags; /* Pipe flags */ 261 unsigned int pflags; /* Pipe flags */
268#define PF_GONE (0x01) /* Pipe is on disabled device */ 262#define PF_GONE (0x01) /* Pipe is on disabled device */
269#define PF_TOGGLE (0x02) /* Data toggle status */ 263#define PF_TOGGLE (0x02) /* Data toggle status */
270#define PF_LS (0x04) /* Pipe is low speed */ 264#define PF_LS (0x04) /* Pipe is low speed */
271#define PF_PREAMBLE (0x08) /* Needs preamble */ 265#define PF_PREAMBLE (0x08) /* Needs preamble */
272 Frame to_frame; /* Frame number for timeout */ 266 Frame to_frame; /* Frame number for timeout */
273 Frame frame; /* Frame number for intr xfer */ 267 Frame frame; /* Frame number for intr xfer */
274 Frame lastframe; /* Previous frame number for intr */ 268 Frame lastframe; /* Previous frame number for intr */
275 uint16_t bustime; /* Worst case bus time usage */ 269 uint16_t bustime; /* Worst case bus time usage */
276 uint16_t newbustime[2]; /* new bustimes (see index below) */ 270 uint16_t newbustime[2]; /* new bustimes (see index below) */
277 uint8_t tregs[4]; /* ADR, LEN, PID, DEV */ 271 uint8_t tregs[4]; /* ADR, LEN, PID, DEV */
278 uint8_t newlen[2]; /* 0 = short data, 1 = ctrl data */ 272 uint8_t newlen[2]; /* 0 = short data, 1 = ctrl data */
279 uint8_t newpid; /* for ctrl */ 273 uint8_t newpid; /* for ctrl */
280 uint8_t wantshort; /* last xfer must be short */ 274 uint8_t wantshort; /* last xfer must be short */
281 uint8_t control; /* Host control register settings */ 275 uint8_t control; /* Host control register settings */
282 uint8_t nerrs; /* Current number of errors */ 276 uint8_t nerrs; /* Current number of errors */
283 uint8_t ptype; /* Pipe type */ 277 uint8_t ptype; /* Pipe type */
284}; 278};
285 279
286#define SLHCI_BUS2SC(bus) ((bus)->ub_hcpriv) 280#define SLHCI_BUS2SC(bus) ((bus)->ub_hcpriv)
287#define SLHCI_PIPE2SC(pipe) SLHCI_BUS2SC((pipe)->up_dev->ud_bus) 281#define SLHCI_PIPE2SC(pipe) SLHCI_BUS2SC((pipe)->up_dev->ud_bus)
288#define SLHCI_XFER2SC(xfer) SLHCI_BUS2SC((xfer)->ux_bus) 282#define SLHCI_XFER2SC(xfer) SLHCI_BUS2SC((xfer)->ux_bus)
289 283
290#define SLHCI_PIPE2SPIPE(pipe) ((struct slhci_pipe *)(pipe)) 284#define SLHCI_PIPE2SPIPE(pipe) ((struct slhci_pipe *)(pipe))
291#define SLHCI_XFER2SPIPE(xfer) SLHCI_PIPE2SPIPE((xfer)->ux_pipe) 285#define SLHCI_XFER2SPIPE(xfer) SLHCI_PIPE2SPIPE((xfer)->ux_pipe)
292 286
293#define SLHCI_XFER_TYPE(x) (SLHCI_XFER2SPIPE(xfer)->ptype) 287#define SLHCI_XFER_TYPE(x) (SLHCI_XFER2SPIPE(xfer)->ptype)
294 288
295#ifdef SLHCI_PROFILE_TRANSFER 289#ifdef SLHCI_PROFILE_TRANSFER
296#if defined(__mips__) 290#if defined(__mips__)
297/* 291/*
298 * MIPS cycle counter does not directly count cpu cycles but is a different 292 * MIPS cycle counter does not directly count cpu cycles but is a different
299 * fraction of cpu cycles depending on the cpu. 293 * fraction of cpu cycles depending on the cpu.
300 */ 294 */
301typedef uint32_t cc_type; 295typedef uint32_t cc_type;
302#define CC_TYPE_FMT "%u" 296#define CC_TYPE_FMT "%u"
303#define slhci_cc_set(x) __asm volatile ("mfc0 %[cc], $9\n\tnop\n\tnop\n\tnop" \ 297#define slhci_cc_set(x) __asm volatile ("mfc0 %[cc], $9\n\tnop\n\tnop\n\tnop" \
304 : [cc] "=r"(x)) 298 : [cc] "=r"(x))
305#elif defined(__i386__) 299#elif defined(__i386__)
306typedef uint64_t cc_type; 300typedef uint64_t cc_type;
307#define CC_TYPE_FMT "%llu" 301#define CC_TYPE_FMT "%llu"
308#define slhci_cc_set(x) __asm volatile ("rdtsc" : "=A"(x)) 302#define slhci_cc_set(x) __asm volatile ("rdtsc" : "=A"(x))
309#else 303#else
310#error "SLHCI_PROFILE_TRANSFER not implemented on this MACHINE_ARCH (see sys/dev/ic/sl811hs.c)" 304#error "SLHCI_PROFILE_TRANSFER not implemented on this MACHINE_ARCH (see sys/dev/ic/sl811hs.c)"
311#endif 305#endif
312struct slhci_cc_time { 306struct slhci_cc_time {
313 cc_type start; 307 cc_type start;
314 cc_type stop; 308 cc_type stop;
315 unsigned int miscdata; 309 unsigned int miscdata;
316}; 310};
317#ifndef SLHCI_N_TIMES 311#ifndef SLHCI_N_TIMES
318#define SLHCI_N_TIMES 200 312#define SLHCI_N_TIMES 200
319#endif 313#endif
320struct slhci_cc_times { 314struct slhci_cc_times {
321 struct slhci_cc_time times[SLHCI_N_TIMES]; 315 struct slhci_cc_time times[SLHCI_N_TIMES];
322 int current; 316 int current;
323 int wraparound; 317 int wraparound;
324}; 318};
325 319
326static struct slhci_cc_times t_ab[2]; 320static struct slhci_cc_times t_ab[2];
327static struct slhci_cc_times t_abdone; 321static struct slhci_cc_times t_abdone;
328static struct slhci_cc_times t_copy_to_dev; 322static struct slhci_cc_times t_copy_to_dev;
329static struct slhci_cc_times t_copy_from_dev; 323static struct slhci_cc_times t_copy_from_dev;
330static struct slhci_cc_times t_intr; 324static struct slhci_cc_times t_intr;
331static struct slhci_cc_times t_lock; 325static struct slhci_cc_times t_lock;
332static struct slhci_cc_times t_delay; 326static struct slhci_cc_times t_delay;
333static struct slhci_cc_times t_hard_int; 327static struct slhci_cc_times t_hard_int;
334static struct slhci_cc_times t_callback; 328static struct slhci_cc_times t_callback;
335 329
336static inline void 330static inline void
337start_cc_time(struct slhci_cc_times *times, unsigned int misc) { 331start_cc_time(struct slhci_cc_times *times, unsigned int misc) {
338 times->times[times->current].miscdata = misc; 332 times->times[times->current].miscdata = misc;
339 slhci_cc_set(times->times[times->current].start); 333 slhci_cc_set(times->times[times->current].start);
340} 334}
341static inline void 335static inline void
342stop_cc_time(struct slhci_cc_times *times) { 336stop_cc_time(struct slhci_cc_times *times) {
343 slhci_cc_set(times->times[times->current].stop); 337 slhci_cc_set(times->times[times->current].stop);
344 if (++times->current >= SLHCI_N_TIMES) { 338 if (++times->current >= SLHCI_N_TIMES) {
345 times->current = 0; 339 times->current = 0;
346 times->wraparound = 1; 340 times->wraparound = 1;
347 } 341 }
348} 342}
349 343
350void slhci_dump_cc_times(int); 344void slhci_dump_cc_times(int);
351 345
352void 346void
353slhci_dump_cc_times(int n) { 347slhci_dump_cc_times(int n) {
354 struct slhci_cc_times *times; 348 struct slhci_cc_times *times;
355 int i; 349 int i;
356 350
357 switch (n) { 351 switch (n) {
358 default: 352 default:
359 case 0: 353 case 0:
360 printf("USBA start transfer to intr:\n"); 354 printf("USBA start transfer to intr:\n");
361 times = &t_ab[A]; 355 times = &t_ab[A];
362 break; 356 break;
363 case 1: 357 case 1:
364 printf("USBB start transfer to intr:\n"); 358 printf("USBB start transfer to intr:\n");
365 times = &t_ab[B]; 359 times = &t_ab[B];
366 break; 360 break;
367 case 2: 361 case 2:
368 printf("abdone:\n"); 362 printf("abdone:\n");
369 times = &t_abdone; 363 times = &t_abdone;
370 break; 364 break;
371 case 3: 365 case 3:
372 printf("copy to device:\n"); 366 printf("copy to device:\n");
373 times = &t_copy_to_dev; 367 times = &t_copy_to_dev;
374 break; 368 break;
375 case 4: 369 case 4:
376 printf("copy from device:\n"); 370 printf("copy from device:\n");
377 times = &t_copy_from_dev; 371 times = &t_copy_from_dev;
378 break; 372 break;
379 case 5: 373 case 5:
380 printf("intr to intr:\n"); 374 printf("intr to intr:\n");
381 times = &t_intr; 375 times = &t_intr;
382 break; 376 break;
383 case 6: 377 case 6:
384 printf("lock to release:\n"); 378 printf("lock to release:\n");
385 times = &t_lock; 379 times = &t_lock;
386 break; 380 break;
387 case 7: 381 case 7:
388 printf("delay time:\n"); 382 printf("delay time:\n");
389 times = &t_delay; 383 times = &t_delay;
390 break; 384 break;
391 case 8: 385 case 8:
392 printf("hard interrupt enter to exit:\n"); 386 printf("hard interrupt enter to exit:\n");
393 times = &t_hard_int; 387 times = &t_hard_int;
394 break; 388 break;
395 case 9: 389 case 9:
396 printf("callback:\n"); 390 printf("callback:\n");
397 times = &t_callback; 391 times = &t_callback;
398 break; 392 break;
399 } 393 }
400 394
401 if (times->wraparound) 395 if (times->wraparound)
402 for (i = times->current + 1; i < SLHCI_N_TIMES; i++) 396 for (i = times->current + 1; i < SLHCI_N_TIMES; i++)
403 printf("start " CC_TYPE_FMT " stop " CC_TYPE_FMT 397 printf("start " CC_TYPE_FMT " stop " CC_TYPE_FMT
404 " difference %8i miscdata %#x\n", 398 " difference %8i miscdata %#x\n",
405 times->times[i].start, times->times[i].stop, 399 times->times[i].start, times->times[i].stop,
406 (int)(times->times[i].stop - 400 (int)(times->times[i].stop -
407 times->times[i].start), times->times[i].miscdata); 401 times->times[i].start), times->times[i].miscdata);
408 402
409 for (i = 0; i < times->current; i++) 403 for (i = 0; i < times->current; i++)
410 printf("start " CC_TYPE_FMT " stop " CC_TYPE_FMT 404 printf("start " CC_TYPE_FMT " stop " CC_TYPE_FMT
411 " difference %8i miscdata %#x\n", times->times[i].start, 405 " difference %8i miscdata %#x\n", times->times[i].start,
412 times->times[i].stop, (int)(times->times[i].stop - 406 times->times[i].stop, (int)(times->times[i].stop -
413 times->times[i].start), times->times[i].miscdata); 407 times->times[i].start), times->times[i].miscdata);
414} 408}
415#else 409#else
416#define start_cc_time(x, y) 410#define start_cc_time(x, y)
417#define stop_cc_time(x) 411#define stop_cc_time(x)
418#endif /* SLHCI_PROFILE_TRANSFER */ 412#endif /* SLHCI_PROFILE_TRANSFER */
419 413
420typedef usbd_status (*LockCallFunc)(struct slhci_softc *, struct slhci_pipe 414typedef usbd_status (*LockCallFunc)(struct slhci_softc *, struct slhci_pipe
421 *, struct usbd_xfer *); 415 *, struct usbd_xfer *);
422 416
423struct usbd_xfer * slhci_allocx(struct usbd_bus *, unsigned int); 417struct usbd_xfer * slhci_allocx(struct usbd_bus *, unsigned int);
424void slhci_freex(struct usbd_bus *, struct usbd_xfer *); 418void slhci_freex(struct usbd_bus *, struct usbd_xfer *);
425static void slhci_get_lock(struct usbd_bus *, kmutex_t **); 419static void slhci_get_lock(struct usbd_bus *, kmutex_t **);
426 420
427usbd_status slhci_transfer(struct usbd_xfer *); 421usbd_status slhci_transfer(struct usbd_xfer *);
428usbd_status slhci_start(struct usbd_xfer *); 422usbd_status slhci_start(struct usbd_xfer *);
429usbd_status slhci_root_start(struct usbd_xfer *); 423usbd_status slhci_root_start(struct usbd_xfer *);
430usbd_status slhci_open(struct usbd_pipe *); 424usbd_status slhci_open(struct usbd_pipe *);
431 425
432static int slhci_roothub_ctrl(struct usbd_bus *, usb_device_request_t *, 426static int slhci_roothub_ctrl(struct usbd_bus *, usb_device_request_t *,
433 void *, int); 427 void *, int);
434 428
435/* 429/*
436 * slhci_supported_rev, slhci_preinit, slhci_attach, slhci_detach, 430 * slhci_supported_rev, slhci_preinit, slhci_attach, slhci_detach,
437 * slhci_activate 431 * slhci_activate
438 */ 432 */
439 433
440void slhci_abort(struct usbd_xfer *); 434void slhci_abort(struct usbd_xfer *);
441void slhci_close(struct usbd_pipe *); 435void slhci_close(struct usbd_pipe *);
442void slhci_clear_toggle(struct usbd_pipe *); 436void slhci_clear_toggle(struct usbd_pipe *);
443void slhci_poll(struct usbd_bus *); 437void slhci_poll(struct usbd_bus *);
444void slhci_done(struct usbd_xfer *); 438void slhci_done(struct usbd_xfer *);
445void slhci_void(void *); 439void slhci_void(void *);
446 440
447/* lock entry functions */ 441/* lock entry functions */
448 442
449#ifdef SLHCI_MEM_ACCOUNTING 443#ifdef SLHCI_MEM_ACCOUNTING
450void slhci_mem_use(struct usbd_bus *, int); 444void slhci_mem_use(struct usbd_bus *, int);
451#endif 445#endif
452 446
453void slhci_reset_entry(void *); 447void slhci_reset_entry(void *);
454usbd_status slhci_lock_call(struct slhci_softc *, LockCallFunc, 448usbd_status slhci_lock_call(struct slhci_softc *, LockCallFunc,
455 struct slhci_pipe *, struct usbd_xfer *); 449 struct slhci_pipe *, struct usbd_xfer *);
456void slhci_start_entry(struct slhci_softc *, struct slhci_pipe *); 450void slhci_start_entry(struct slhci_softc *, struct slhci_pipe *);
457void slhci_callback_entry(void *arg); 451void slhci_callback_entry(void *arg);
458void slhci_do_callback(struct slhci_softc *, struct usbd_xfer *); 452void slhci_do_callback(struct slhci_softc *, struct usbd_xfer *);
459 453
460/* slhci_intr */ 454/* slhci_intr */
461 455
462void slhci_main(struct slhci_softc *); 456void slhci_main(struct slhci_softc *);
463 457
464/* in lock functions */ 458/* in lock functions */
465 459
466static void slhci_write(struct slhci_softc *, uint8_t, uint8_t); 460static void slhci_write(struct slhci_softc *, uint8_t, uint8_t);
467static uint8_t slhci_read(struct slhci_softc *, uint8_t); 461static uint8_t slhci_read(struct slhci_softc *, uint8_t);
468static void slhci_write_multi(struct slhci_softc *, uint8_t, uint8_t *, int); 462static void slhci_write_multi(struct slhci_softc *, uint8_t, uint8_t *, int);
469static void slhci_read_multi(struct slhci_softc *, uint8_t, uint8_t *, int); 463static void slhci_read_multi(struct slhci_softc *, uint8_t, uint8_t *, int);
470 464
471static void slhci_waitintr(struct slhci_softc *, int); 465static void slhci_waitintr(struct slhci_softc *, int);
472static int slhci_dointr(struct slhci_softc *); 466static int slhci_dointr(struct slhci_softc *);
473static void slhci_abdone(struct slhci_softc *, int); 467static void slhci_abdone(struct slhci_softc *, int);
474static void slhci_tstart(struct slhci_softc *); 468static void slhci_tstart(struct slhci_softc *);
475static void slhci_dotransfer(struct slhci_softc *); 469static void slhci_dotransfer(struct slhci_softc *);
476 470
477static void slhci_callback(struct slhci_softc *); 471static void slhci_callback(struct slhci_softc *);
478static void slhci_enter_xfer(struct slhci_softc *, struct slhci_pipe *); 472static void slhci_enter_xfer(struct slhci_softc *, struct slhci_pipe *);
479static void slhci_enter_xfers(struct slhci_softc *); 473static void slhci_enter_xfers(struct slhci_softc *);
480static void slhci_queue_timed(struct slhci_softc *, struct slhci_pipe *); 474static void slhci_queue_timed(struct slhci_softc *, struct slhci_pipe *);
481static void slhci_xfer_timer(struct slhci_softc *, struct slhci_pipe *); 475static void slhci_xfer_timer(struct slhci_softc *, struct slhci_pipe *);
482 476
483static void slhci_callback_schedule(struct slhci_softc *); 477static void slhci_callback_schedule(struct slhci_softc *);
484static void slhci_do_callback_schedule(struct slhci_softc *); 478static void slhci_do_callback_schedule(struct slhci_softc *);
485#if 0 479#if 0
486void slhci_pollxfer(struct slhci_softc *, struct usbd_xfer *); /* XXX */ 480void slhci_pollxfer(struct slhci_softc *, struct usbd_xfer *); /* XXX */
487#endif 481#endif
488 482
489static usbd_status slhci_do_poll(struct slhci_softc *, struct slhci_pipe *, 483static usbd_status slhci_do_poll(struct slhci_softc *, struct slhci_pipe *,
490 struct usbd_xfer *); 484 struct usbd_xfer *);
491static usbd_status slhci_lsvh_warn(struct slhci_softc *, struct slhci_pipe *, 485static usbd_status slhci_lsvh_warn(struct slhci_softc *, struct slhci_pipe *,
492 struct usbd_xfer *); 486 struct usbd_xfer *);
493static usbd_status slhci_isoc_warn(struct slhci_softc *, struct slhci_pipe *, 487static usbd_status slhci_isoc_warn(struct slhci_softc *, struct slhci_pipe *,
494 struct usbd_xfer *); 488 struct usbd_xfer *);
495static usbd_status slhci_open_pipe(struct slhci_softc *, struct slhci_pipe *, 489static usbd_status slhci_open_pipe(struct slhci_softc *, struct slhci_pipe *,
496 struct usbd_xfer *); 490 struct usbd_xfer *);
497static usbd_status slhci_close_pipe(struct slhci_softc *, struct slhci_pipe *, 491static usbd_status slhci_close_pipe(struct slhci_softc *, struct slhci_pipe *,
498 struct usbd_xfer *); 492 struct usbd_xfer *);
499static usbd_status slhci_do_abort(struct slhci_softc *, struct slhci_pipe *, 493static usbd_status slhci_do_abort(struct slhci_softc *, struct slhci_pipe *,
500 struct usbd_xfer *); 494 struct usbd_xfer *);
501static usbd_status slhci_halt(struct slhci_softc *, struct slhci_pipe *, 495static usbd_status slhci_halt(struct slhci_softc *, struct slhci_pipe *,
502 struct usbd_xfer *); 496 struct usbd_xfer *);
503 497
504static void slhci_intrchange(struct slhci_softc *, uint8_t); 498static void slhci_intrchange(struct slhci_softc *, uint8_t);
505static void slhci_drain(struct slhci_softc *); 499static void slhci_drain(struct slhci_softc *);
506static void slhci_reset(struct slhci_softc *); 500static void slhci_reset(struct slhci_softc *);
507static int slhci_reserve_bustime(struct slhci_softc *, struct slhci_pipe *, 501static int slhci_reserve_bustime(struct slhci_softc *, struct slhci_pipe *,
508 int); 502 int);
509static void slhci_insert(struct slhci_softc *); 503static void slhci_insert(struct slhci_softc *);
510 504
511static usbd_status slhci_clear_feature(struct slhci_softc *, unsigned int); 505static usbd_status slhci_clear_feature(struct slhci_softc *, unsigned int);
512static usbd_status slhci_set_feature(struct slhci_softc *, unsigned int); 506static usbd_status slhci_set_feature(struct slhci_softc *, unsigned int);
513static void slhci_get_status(struct slhci_softc *, usb_port_status_t *); 507static void slhci_get_status(struct slhci_softc *, usb_port_status_t *);
514 508
515#define SLHCIHIST_FUNC() USBHIST_FUNC() 509#define SLHCIHIST_FUNC() USBHIST_FUNC()
516#define SLHCIHIST_CALLED() USBHIST_CALLED(slhcidebug) 510#define SLHCIHIST_CALLED() USBHIST_CALLED(slhcidebug)
517 511
518#ifdef SLHCI_DEBUG 512#ifdef SLHCI_DEBUG
519static int slhci_memtest(struct slhci_softc *); 513static int slhci_memtest(struct slhci_softc *);
520 514
521void slhci_log_buffer(struct usbd_xfer *); 515void slhci_log_buffer(struct usbd_xfer *);
522void slhci_log_req(usb_device_request_t *); 516void slhci_log_req(usb_device_request_t *);
523void slhci_log_dumpreg(void); 517void slhci_log_dumpreg(void);
524void slhci_log_xfer(struct usbd_xfer *); 518void slhci_log_xfer(struct usbd_xfer *);
525void slhci_log_spipe(struct slhci_pipe *); 519void slhci_log_spipe(struct slhci_pipe *);
526void slhci_print_intr(void); 520void slhci_print_intr(void);
527void slhci_log_sc(void); 521void slhci_log_sc(void);
528void slhci_log_slreq(struct slhci_pipe *); 522void slhci_log_slreq(struct slhci_pipe *);
529 523
530/* Constified so you can read the values from ddb */ 524/* Constified so you can read the values from ddb */
531const int SLHCI_D_TRACE = 0x0001; 525const int SLHCI_D_TRACE = 0x0001;
532const int SLHCI_D_MSG = 0x0002; 526const int SLHCI_D_MSG = 0x0002;
533const int SLHCI_D_XFER = 0x0004; 527const int SLHCI_D_XFER = 0x0004;
534const int SLHCI_D_MEM = 0x0008; 528const int SLHCI_D_MEM = 0x0008;
535const int SLHCI_D_INTR = 0x0010; 529const int SLHCI_D_INTR = 0x0010;
536const int SLHCI_D_SXFER = 0x0020; 530const int SLHCI_D_SXFER = 0x0020;
537const int SLHCI_D_ERR = 0x0080; 531const int SLHCI_D_ERR = 0x0080;
538const int SLHCI_D_BUF = 0x0100; 532const int SLHCI_D_BUF = 0x0100;
539const int SLHCI_D_SOFT = 0x0200; 533const int SLHCI_D_SOFT = 0x0200;
540const int SLHCI_D_WAIT = 0x0400; 534const int SLHCI_D_WAIT = 0x0400;
541const int SLHCI_D_ROOT = 0x0800; 535const int SLHCI_D_ROOT = 0x0800;
542/* SOF/NAK alone normally ignored, SOF also needs D_INTR */ 536/* SOF/NAK alone normally ignored, SOF also needs D_INTR */
543const int SLHCI_D_SOF = 0x1000; 537const int SLHCI_D_SOF = 0x1000;
544const int SLHCI_D_NAK = 0x2000; 538const int SLHCI_D_NAK = 0x2000;
545 539
546int slhcidebug = 0x1cbc; /* 0xc8c; */ /* 0xffff; */ /* 0xd8c; */ 540int slhcidebug = 0x1cbc; /* 0xc8c; */ /* 0xffff; */ /* 0xd8c; */
547 541
548SYSCTL_SETUP(sysctl_hw_slhci_setup, "sysctl hw.slhci setup") 542SYSCTL_SETUP(sysctl_hw_slhci_setup, "sysctl hw.slhci setup")
549{ 543{
550 int err; 544 int err;
551 const struct sysctlnode *rnode; 545 const struct sysctlnode *rnode;
552 const struct sysctlnode *cnode; 546 const struct sysctlnode *cnode;
553 547
554 err = sysctl_createv(clog, 0, NULL, &rnode, 548 err = sysctl_createv(clog, 0, NULL, &rnode,
555 CTLFLAG_PERMANENT, CTLTYPE_NODE, "slhci", 549 CTLFLAG_PERMANENT, CTLTYPE_NODE, "slhci",
556 SYSCTL_DESCR("slhci global controls"), 550 SYSCTL_DESCR("slhci global controls"),
557 NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL); 551 NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL);
558 552
559 if (err) 553 if (err)
560 goto fail; 554 goto fail;
561 555
562 /* control debugging printfs */ 556 /* control debugging printfs */
563 err = sysctl_createv(clog, 0, &rnode, &cnode, 557 err = sysctl_createv(clog, 0, &rnode, &cnode,
564 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, 558 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
565 "debug", SYSCTL_DESCR("Enable debugging output"), 559 "debug", SYSCTL_DESCR("Enable debugging output"),
566 NULL, 0, &slhcidebug, sizeof(slhcidebug), CTL_CREATE, CTL_EOL); 560 NULL, 0, &slhcidebug, sizeof(slhcidebug), CTL_CREATE, CTL_EOL);
567 if (err) 561 if (err)
568 goto fail; 562 goto fail;
569 563
570 return; 564 return;
571fail: 565fail:
572 aprint_error("%s: sysctl_createv failed (err = %d)\n", __func__, err); 566 aprint_error("%s: sysctl_createv failed (err = %d)\n", __func__, err);
573} 567}
574 568
575struct slhci_softc *ssc; 569struct slhci_softc *ssc;
576 570
577#define SLHCI_DEXEC(x, y) do { if ((slhcidebug & SLHCI_ ## x)) { y; } \ 571#define SLHCI_DEXEC(x, y) do { if ((slhcidebug & SLHCI_ ## x)) { y; } \
578} while (/*CONSTCOND*/ 0) 572} while (/*CONSTCOND*/ 0)
579#define DDOLOG(f, a, b, c, d) do { KERNHIST_LOG(usbhist, f, a, b, c, d); \ 573#define DDOLOG(f, a, b, c, d) do { KERNHIST_LOG(usbhist, f, a, b, c, d); \
580} while (/*CONSTCOND*/0) 574} while (/*CONSTCOND*/0)
581#define DLOG(x, f, a, b, c, d) SLHCI_DEXEC(x, DDOLOG(f, a, b, c, d)) 575#define DLOG(x, f, a, b, c, d) SLHCI_DEXEC(x, DDOLOG(f, a, b, c, d))
582 576
583/* 577/*
584 * DDOLOGBUF logs a buffer up to 8 bytes at a time. No identifier so that we 578 * DDOLOGBUF logs a buffer up to 8 bytes at a time. No identifier so that we
585 * can make it a real function. 579 * can make it a real function.
586 */ 580 */
587static void 581static void
588DDOLOGBUF(uint8_t *buf, unsigned int length) 582DDOLOGBUF(uint8_t *buf, unsigned int length)
589{ 583{
590 SLHCIHIST_FUNC(); SLHCIHIST_CALLED(); 584 SLHCIHIST_FUNC(); SLHCIHIST_CALLED();
591 int i; 585 int i;
592 586
593 for(i=0; i+8 <= length; i+=8) 587 for(i=0; i+8 <= length; i+=8)
594 DDOLOG("%.4x %.4x %.4x %.4x", (buf[i] << 8) | buf[i+1], 588 DDOLOG("%.4x %.4x %.4x %.4x", (buf[i] << 8) | buf[i+1],
595 (buf[i+2] << 8) | buf[i+3], (buf[i+4] << 8) | buf[i+5], 589 (buf[i+2] << 8) | buf[i+3], (buf[i+4] << 8) | buf[i+5],
596 (buf[i+6] << 8) | buf[i+7]); 590 (buf[i+6] << 8) | buf[i+7]);
597 if (length == i+7) 591 if (length == i+7)
598 DDOLOG("%.4x %.4x %.4x %.2x", (buf[i] << 8) | buf[i+1], 592 DDOLOG("%.4x %.4x %.4x %.2x", (buf[i] << 8) | buf[i+1],
599 (buf[i+2] << 8) | buf[i+3], (buf[i+4] << 8) | buf[i+5], 593 (buf[i+2] << 8) | buf[i+3], (buf[i+4] << 8) | buf[i+5],
600 buf[i+6]); 594 buf[i+6]);
601 else if (length == i+6) 595 else if (length == i+6)
602 DDOLOG("%.4x %.4x %.4x", (buf[i] << 8) | buf[i+1], 596 DDOLOG("%.4x %.4x %.4x", (buf[i] << 8) | buf[i+1],
603 (buf[i+2] << 8) | buf[i+3], (buf[i+4] << 8) | buf[i+5], 0); 597 (buf[i+2] << 8) | buf[i+3], (buf[i+4] << 8) | buf[i+5], 0);
604 else if (length == i+5) 598 else if (length == i+5)
605 DDOLOG("%.4x %.4x %.2x", (buf[i] << 8) | buf[i+1], 599 DDOLOG("%.4x %.4x %.2x", (buf[i] << 8) | buf[i+1],
606 (buf[i+2] << 8) | buf[i+3], buf[i+4], 0); 600 (buf[i+2] << 8) | buf[i+3], buf[i+4], 0);
607 else if (length == i+4) 601 else if (length == i+4)
608 DDOLOG("%.4x %.4x", (buf[i] << 8) | buf[i+1], 602 DDOLOG("%.4x %.4x", (buf[i] << 8) | buf[i+1],
609 (buf[i+2] << 8) | buf[i+3], 0,0); 603 (buf[i+2] << 8) | buf[i+3], 0,0);
610 else if (length == i+3) 604 else if (length == i+3)
611 DDOLOG("%.4x %.2x", (buf[i] << 8) | buf[i+1], buf[i+2], 0,0); 605 DDOLOG("%.4x %.2x", (buf[i] << 8) | buf[i+1], buf[i+2], 0,0);
612 else if (length == i+2) 606 else if (length == i+2)
613 DDOLOG("%.4x", (buf[i] << 8) | buf[i+1], 0,0,0); 607 DDOLOG("%.4x", (buf[i] << 8) | buf[i+1], 0,0,0);
614 else if (length == i+1) 608 else if (length == i+1)
615 DDOLOG("%.2x", buf[i], 0,0,0); 609 DDOLOG("%.2x", buf[i], 0,0,0);
616} 610}
617#define DLOGBUF(x, b, l) SLHCI_DEXEC(x, DDOLOGBUF(b, l)) 611#define DLOGBUF(x, b, l) SLHCI_DEXEC(x, DDOLOGBUF(b, l))
618 612
619#define DDOLOGCTRL(x) do { \ 613#define DDOLOGCTRL(x) do { \
620 DDOLOG("CTRL suspend=%d", !!((x) & SL11_CTRL_SUSPEND), 0, 0, 0); \ 614 DDOLOG("CTRL suspend=%d", !!((x) & SL11_CTRL_SUSPEND), 0, 0, 0); \
621 DDOLOG("CTRL ls =%d jk =%d reset =%d sof =%d", \ 615 DDOLOG("CTRL ls =%d jk =%d reset =%d sof =%d", \
622 !!((x) & SL11_CTRL_LOWSPEED), !!((x) & SL11_CTRL_JKSTATE), \ 616 !!((x) & SL11_CTRL_LOWSPEED), !!((x) & SL11_CTRL_JKSTATE), \
623 !!((x) & SL11_CTRL_RESETENGINE), !!((x) & SL11_CTRL_ENABLESOF));\ 617 !!((x) & SL11_CTRL_RESETENGINE), !!((x) & SL11_CTRL_ENABLESOF));\
624} while (0) 618} while (0)
625 619
626#define DDOLOGISR(r) do { \ 620#define DDOLOGISR(r) do { \
627 DDOLOG("ISR data =%d det/res=%d insert =%d sof =%d", \ 621 DDOLOG("ISR data =%d det/res=%d insert =%d sof =%d", \
628 !!((r) & SL11_ISR_DATA), !!((r) & SL11_ISR_RESUME), \ 622 !!((r) & SL11_ISR_DATA), !!((r) & SL11_ISR_RESUME), \
629 !!((r) & SL11_ISR_INSERT), !!!!((r) & SL11_ISR_SOF)); \ 623 !!((r) & SL11_ISR_INSERT), !!!!((r) & SL11_ISR_SOF)); \
630 DDOLOG("ISR babble =%d usbb =%d usba =%d", \ 624 DDOLOG("ISR babble =%d usbb =%d usba =%d", \
631 !!((r) & SL11_ISR_BABBLE), !!((r) & SL11_ISR_USBB), \ 625 !!((r) & SL11_ISR_BABBLE), !!((r) & SL11_ISR_USBB), \
632 !!((r) & SL11_ISR_USBA), 0); \ 626 !!((r) & SL11_ISR_USBA), 0); \
633} while (0) 627} while (0)
634 628
635#define DDOLOGIER(r) do { \ 629#define DDOLOGIER(r) do { \
636 DDOLOG("IER det/res=%d insert =%d sof =%d", \ 630 DDOLOG("IER det/res=%d insert =%d sof =%d", \
637 !!((r) & SL11_IER_RESUME), \ 631 !!((r) & SL11_IER_RESUME), \
638 !!((r) & SL11_IER_INSERT), !!!!((r) & SL11_IER_SOF), 0); \ 632 !!((r) & SL11_IER_INSERT), !!!!((r) & SL11_IER_SOF), 0); \
639 DDOLOG("IER babble =%d usbb =%d usba =%d", \ 633 DDOLOG("IER babble =%d usbb =%d usba =%d", \
640 !!((r) & SL11_IER_BABBLE), !!((r) & SL11_IER_USBB), \ 634 !!((r) & SL11_IER_BABBLE), !!((r) & SL11_IER_USBB), \
641 !!((r) & SL11_IER_USBA), 0); \ 635 !!((r) & SL11_IER_USBA), 0); \
642} while (0) 636} while (0)
643 637
644#define DDOLOGSTATUS(s) do { \ 638#define DDOLOGSTATUS(s) do { \
645 DDOLOG("STAT stall =%d nak =%d overflow =%d setup =%d", \ 639 DDOLOG("STAT stall =%d nak =%d overflow =%d setup =%d", \
646 !!((s) & SL11_EPSTAT_STALL), !!((s) & SL11_EPSTAT_NAK), \ 640 !!((s) & SL11_EPSTAT_STALL), !!((s) & SL11_EPSTAT_NAK), \
647 !!((s) & SL11_EPSTAT_OVERFLOW), !!((s) & SL11_EPSTAT_SETUP)); \ 641 !!((s) & SL11_EPSTAT_OVERFLOW), !!((s) & SL11_EPSTAT_SETUP)); \
648 DDOLOG("STAT sequence=%d timeout =%d error =%d ack =%d", \ 642 DDOLOG("STAT sequence=%d timeout =%d error =%d ack =%d", \
649 !!((s) & SL11_EPSTAT_SEQUENCE), !!((s) & SL11_EPSTAT_TIMEOUT), \ 643 !!((s) & SL11_EPSTAT_SEQUENCE), !!((s) & SL11_EPSTAT_TIMEOUT), \
650 !!((s) & SL11_EPSTAT_ERROR), !!((s) & SL11_EPSTAT_ACK)); \ 644 !!((s) & SL11_EPSTAT_ERROR), !!((s) & SL11_EPSTAT_ACK)); \
651} while (0) 645} while (0)
652 646
653#define DDOLOGEPCTRL(r) do { \ 647#define DDOLOGEPCTRL(r) do { \
654 DDOLOG("CTRL preamble=%d toggle =%d sof =%d iso =%d", \ 648 DDOLOG("CTRL preamble=%d toggle =%d sof =%d iso =%d", \
655 !!((r) & SL11_EPCTRL_PREAMBLE), !!((r) & SL11_EPCTRL_DATATOGGLE),\ 649 !!((r) & SL11_EPCTRL_PREAMBLE), !!((r) & SL11_EPCTRL_DATATOGGLE),\
656 !!((r) & SL11_EPCTRL_SOF), !!((r) & SL11_EPCTRL_ISO)); \ 650 !!((r) & SL11_EPCTRL_SOF), !!((r) & SL11_EPCTRL_ISO)); \
657 DDOLOG("CTRL out =%d enable =%d arm =%d", \ 651 DDOLOG("CTRL out =%d enable =%d arm =%d", \
658 !!((r) & SL11_EPCTRL_DIRECTION), \ 652 !!((r) & SL11_EPCTRL_DIRECTION), \
659 !!((r) & SL11_EPCTRL_ENABLE), !!((r) & SL11_EPCTRL_ARM), 0); \ 653 !!((r) & SL11_EPCTRL_ENABLE), !!((r) & SL11_EPCTRL_ARM), 0); \
660} while (0) 654} while (0)
661 655
662#define DDOLOGEPSTAT(r) do { \ 656#define DDOLOGEPSTAT(r) do { \
663 DDOLOG("STAT stall =%d nak =%d overflow =%d setup =%d", \ 657 DDOLOG("STAT stall =%d nak =%d overflow =%d setup =%d", \
664 !!((r) & SL11_EPSTAT_STALL), !!((r) & SL11_EPSTAT_NAK), \ 658 !!((r) & SL11_EPSTAT_STALL), !!((r) & SL11_EPSTAT_NAK), \
665 !!((r) & SL11_EPSTAT_OVERFLOW), !!((r) & SL11_EPSTAT_SETUP)); \ 659 !!((r) & SL11_EPSTAT_OVERFLOW), !!((r) & SL11_EPSTAT_SETUP)); \
666 DDOLOG("STAT sequence=%d timeout =%d error =%d ack =%d", \ 660 DDOLOG("STAT sequence=%d timeout =%d error =%d ack =%d", \
667 !!((r) & SL11_EPSTAT_SEQUENCE), !!((r) & SL11_EPSTAT_TIMEOUT), \ 661 !!((r) & SL11_EPSTAT_SEQUENCE), !!((r) & SL11_EPSTAT_TIMEOUT), \
668 !!((r) & SL11_EPSTAT_ERROR), !!((r) & SL11_EPSTAT_ACK)); \ 662 !!((r) & SL11_EPSTAT_ERROR), !!((r) & SL11_EPSTAT_ACK)); \
669} while (0) 663} while (0)
670#else /* now !SLHCI_DEBUG */ 664#else /* now !SLHCI_DEBUG */
671#define slhcidebug 0 665#define slhcidebug 0
672#define slhci_log_spipe(spipe) ((void)0) 666#define slhci_log_spipe(spipe) ((void)0)
673#define slhci_log_xfer(xfer) ((void)0) 667#define slhci_log_xfer(xfer) ((void)0)
674#define SLHCI_DEXEC(x, y) ((void)0) 668#define SLHCI_DEXEC(x, y) ((void)0)
675#define DDOLOG(f, a, b, c, d) ((void)0) 669#define DDOLOG(f, a, b, c, d) ((void)0)
676#define DLOG(x, f, a, b, c, d) ((void)0) 670#define DLOG(x, f, a, b, c, d) ((void)0)
677#define DDOLOGBUF(b, l) ((void)0) 671#define DDOLOGBUF(b, l) ((void)0)
678#define DLOGBUF(x, b, l) ((void)0) 672#define DLOGBUF(x, b, l) ((void)0)
679#define DDOLOGCTRL(x) ((void)0) 673#define DDOLOGCTRL(x) ((void)0)
680#define DDOLOGISR(r) ((void)0) 674#define DDOLOGISR(r) ((void)0)
681#define DDOLOGIER(r) ((void)0) 675#define DDOLOGIER(r) ((void)0)
682#define DDOLOGSTATUS(s) ((void)0) 676#define DDOLOGSTATUS(s) ((void)0)
683#define DDOLOGEPCTRL(r) ((void)0) 677#define DDOLOGEPCTRL(r) ((void)0)
684#define DDOLOGEPSTAT(r) ((void)0) 678#define DDOLOGEPSTAT(r) ((void)0)
685#endif /* SLHCI_DEBUG */ 679#endif /* SLHCI_DEBUG */
686 680
687#ifdef DIAGNOSTIC 681#ifdef DIAGNOSTIC
688#define LK_SLASSERT(exp, sc, spipe, xfer, ext) do { \ 682#define LK_SLASSERT(exp, sc, spipe, xfer, ext) do { \
689 if (!(exp)) { \ 683 if (!(exp)) { \
690 printf("%s: assertion %s failed line %u function %s!" \ 684 printf("%s: assertion %s failed line %u function %s!" \
691 " halted\n", SC_NAME(sc), #exp, __LINE__, __func__);\ 685 " halted\n", SC_NAME(sc), #exp, __LINE__, __func__);\
692 slhci_halt(sc, spipe, xfer); \ 686 slhci_halt(sc, spipe, xfer); \
693 ext; \ 687 ext; \
694 } \ 688 } \
695} while (/*CONSTCOND*/0) 689} while (/*CONSTCOND*/0)
696#define UL_SLASSERT(exp, sc, spipe, xfer, ext) do { \ 690#define UL_SLASSERT(exp, sc, spipe, xfer, ext) do { \
697 if (!(exp)) { \ 691 if (!(exp)) { \
698 printf("%s: assertion %s failed line %u function %s!" \ 692 printf("%s: assertion %s failed line %u function %s!" \
699 " halted\n", SC_NAME(sc), #exp, __LINE__, __func__); \ 693 " halted\n", SC_NAME(sc), #exp, __LINE__, __func__); \
700 slhci_lock_call(sc, &slhci_halt, spipe, xfer); \ 694 slhci_lock_call(sc, &slhci_halt, spipe, xfer); \
701 ext; \ 695 ext; \
702 } \ 696 } \
703} while (/*CONSTCOND*/0) 697} while (/*CONSTCOND*/0)
704#else 698#else
705#define LK_SLASSERT(exp, sc, spipe, xfer, ext) ((void)0) 699#define LK_SLASSERT(exp, sc, spipe, xfer, ext) ((void)0)
706#define UL_SLASSERT(exp, sc, spipe, xfer, ext) ((void)0) 700#define UL_SLASSERT(exp, sc, spipe, xfer, ext) ((void)0)
707#endif 701#endif
708 702
709const struct usbd_bus_methods slhci_bus_methods = { 703const struct usbd_bus_methods slhci_bus_methods = {
710 .ubm_open = slhci_open, 704 .ubm_open = slhci_open,
711 .ubm_softint= slhci_void, 705 .ubm_softint= slhci_void,
712 .ubm_dopoll = slhci_poll, 706 .ubm_dopoll = slhci_poll,
713 .ubm_allocx = slhci_allocx, 707 .ubm_allocx = slhci_allocx,
714 .ubm_freex = slhci_freex, 708 .ubm_freex = slhci_freex,
715 .ubm_getlock = slhci_get_lock, 709 .ubm_getlock = slhci_get_lock,
716 .ubm_rhctrl = slhci_roothub_ctrl, 710 .ubm_rhctrl = slhci_roothub_ctrl,
717}; 711};
718 712
719const struct usbd_pipe_methods slhci_pipe_methods = { 713const struct usbd_pipe_methods slhci_pipe_methods = {
720 .upm_transfer = slhci_transfer, 714 .upm_transfer = slhci_transfer,
721 .upm_start = slhci_start, 715 .upm_start = slhci_start,
722 .upm_abort = slhci_abort, 716 .upm_abort = slhci_abort,
723 .upm_close = slhci_close, 717 .upm_close = slhci_close,
724 .upm_cleartoggle = slhci_clear_toggle, 718 .upm_cleartoggle = slhci_clear_toggle,
725 .upm_done = slhci_done, 719 .upm_done = slhci_done,
726}; 720};
727 721
728const struct usbd_pipe_methods slhci_root_methods = { 722const struct usbd_pipe_methods slhci_root_methods = {
729 .upm_transfer = slhci_transfer, 723 .upm_transfer = slhci_transfer,
730 .upm_start = slhci_root_start, 724 .upm_start = slhci_root_start,
731 .upm_abort = slhci_abort, 725 .upm_abort = slhci_abort,
732 .upm_close = (void (*)(struct usbd_pipe *))slhci_void, /* XXX safe? */ 726 .upm_close = (void (*)(struct usbd_pipe *))slhci_void, /* XXX safe? */
733 .upm_cleartoggle = slhci_clear_toggle, 727 .upm_cleartoggle = slhci_clear_toggle,
734 .upm_done = slhci_done, 728 .upm_done = slhci_done,
735}; 729};
736 730
737/* Queue inlines */ 731/* Queue inlines */
738 732
739#define GOT_FIRST_TO(tvar, t) \ 733#define GOT_FIRST_TO(tvar, t) \
740 GCQ_GOT_FIRST_TYPED(tvar, &(t)->to, struct slhci_pipe, to) 734 GCQ_GOT_FIRST_TYPED(tvar, &(t)->to, struct slhci_pipe, to)
741 735
742#define FIND_TO(var, t, tvar, cond) \ 736#define FIND_TO(var, t, tvar, cond) \
743 GCQ_FIND_TYPED(var, &(t)->to, tvar, struct slhci_pipe, to, cond) 737 GCQ_FIND_TYPED(var, &(t)->to, tvar, struct slhci_pipe, to, cond)
744 738
745#define FOREACH_AP(var, t, tvar) \ 739#define FOREACH_AP(var, t, tvar) \
746 GCQ_FOREACH_TYPED(var, &(t)->ap, tvar, struct slhci_pipe, ap) 740 GCQ_FOREACH_TYPED(var, &(t)->ap, tvar, struct slhci_pipe, ap)
747 741
748#define GOT_FIRST_TIMED_COND(tvar, t, cond) \ 742#define GOT_FIRST_TIMED_COND(tvar, t, cond) \
749 GCQ_GOT_FIRST_COND_TYPED(tvar, &(t)->timed, struct slhci_pipe, xq, cond) 743 GCQ_GOT_FIRST_COND_TYPED(tvar, &(t)->timed, struct slhci_pipe, xq, cond)
750 744
751#define GOT_FIRST_CB(tvar, t) \ 745#define GOT_FIRST_CB(tvar, t) \
752 GCQ_GOT_FIRST_TYPED(tvar, &(t)->q[Q_CB], struct slhci_pipe, xq) 746 GCQ_GOT_FIRST_TYPED(tvar, &(t)->q[Q_CB], struct slhci_pipe, xq)
753 747
754#define DEQUEUED_CALLBACK(tvar, t) \ 748#define DEQUEUED_CALLBACK(tvar, t) \
755 GCQ_DEQUEUED_FIRST_TYPED(tvar, &(t)->q[Q_CALLBACKS], struct slhci_pipe, xq) 749 GCQ_DEQUEUED_FIRST_TYPED(tvar, &(t)->q[Q_CALLBACKS], struct slhci_pipe, xq)
756 750
757#define FIND_TIMED(var, t, tvar, cond) \ 751#define FIND_TIMED(var, t, tvar, cond) \
758 GCQ_FIND_TYPED(var, &(t)->timed, tvar, struct slhci_pipe, xq, cond) 752 GCQ_FIND_TYPED(var, &(t)->timed, tvar, struct slhci_pipe, xq, cond)
759 753
760#define DEQUEUED_WAITQ(tvar, sc) \ 754#define DEQUEUED_WAITQ(tvar, sc) \
761 GCQ_DEQUEUED_FIRST_TYPED(tvar, &(sc)->sc_waitq, struct slhci_pipe, xq) 755 GCQ_DEQUEUED_FIRST_TYPED(tvar, &(sc)->sc_waitq, struct slhci_pipe, xq)
762 756
763static inline void 757static inline void
764enter_waitq(struct slhci_softc *sc, struct slhci_pipe *spipe) 758enter_waitq(struct slhci_softc *sc, struct slhci_pipe *spipe)
765{ 759{
766 gcq_insert_tail(&sc->sc_waitq, &spipe->xq); 760 gcq_insert_tail(&sc->sc_waitq, &spipe->xq);
767} 761}
768 762
769static inline void 763static inline void
770enter_q(struct slhci_transfers *t, struct slhci_pipe *spipe, int i) 764enter_q(struct slhci_transfers *t, struct slhci_pipe *spipe, int i)
771{ 765{
772 gcq_insert_tail(&t->q[i], &spipe->xq); 766 gcq_insert_tail(&t->q[i], &spipe->xq);
773} 767}
774 768
775static inline void 769static inline void
776enter_callback(struct slhci_transfers *t, struct slhci_pipe *spipe) 770enter_callback(struct slhci_transfers *t, struct slhci_pipe *spipe)
777{ 771{
778 gcq_insert_tail(&t->q[Q_CALLBACKS], &spipe->xq); 772 gcq_insert_tail(&t->q[Q_CALLBACKS], &spipe->xq);
779} 773}
780 774
781static inline void 775static inline void
782enter_all_pipes(struct slhci_transfers *t, struct slhci_pipe *spipe) 776enter_all_pipes(struct slhci_transfers *t, struct slhci_pipe *spipe)
783{ 777{
784 gcq_insert_tail(&t->ap, &spipe->ap); 778 gcq_insert_tail(&t->ap, &spipe->ap);
785} 779}
786 780
787/* Start out of lock functions. */ 781/* Start out of lock functions. */
788 782
789struct usbd_xfer * 783struct usbd_xfer *
790slhci_allocx(struct usbd_bus *bus, unsigned int nframes) 784slhci_allocx(struct usbd_bus *bus, unsigned int nframes)
791{ 785{
792 SLHCIHIST_FUNC(); SLHCIHIST_CALLED(); 786 SLHCIHIST_FUNC(); SLHCIHIST_CALLED();
793 struct usbd_xfer *xfer; 787 struct usbd_xfer *xfer;
794 788
795 xfer = kmem_zalloc(sizeof(*xfer), KM_SLEEP); 789 xfer = kmem_zalloc(sizeof(*xfer), KM_SLEEP);
796 790
797 DLOG(D_MEM, "allocx %p", xfer, 0,0,0); 791 DLOG(D_MEM, "allocx %p", xfer, 0,0,0);
798 792
799#ifdef SLHCI_MEM_ACCOUNTING 793#ifdef SLHCI_MEM_ACCOUNTING
800 slhci_mem_use(bus, 1); 794 slhci_mem_use(bus, 1);
801#endif 795#endif
802#ifdef DIAGNOSTIC 796#ifdef DIAGNOSTIC
803 if (xfer != NULL) 797 if (xfer != NULL)
804 xfer->ux_state = XFER_BUSY; 798 xfer->ux_state = XFER_BUSY;
805#endif 799#endif
806 return xfer; 800 return xfer;
807} 801}
808 802
809void 803void
810slhci_freex(struct usbd_bus *bus, struct usbd_xfer *xfer) 804slhci_freex(struct usbd_bus *bus, struct usbd_xfer *xfer)
811{ 805{
812 SLHCIHIST_FUNC(); SLHCIHIST_CALLED(); 806 SLHCIHIST_FUNC(); SLHCIHIST_CALLED();
813 DLOG(D_MEM, "freex xfer %p spipe %p", xfer, xfer->ux_pipe,0,0); 807 DLOG(D_MEM, "freex xfer %p spipe %p", xfer, xfer->ux_pipe,0,0);
814 808
815#ifdef SLHCI_MEM_ACCOUNTING 809#ifdef SLHCI_MEM_ACCOUNTING
816 slhci_mem_use(bus, -1); 810 slhci_mem_use(bus, -1);
817#endif 811#endif
818#ifdef DIAGNOSTIC 812#ifdef DIAGNOSTIC
819 if (xfer->ux_state != XFER_BUSY) { 813 if (xfer->ux_state != XFER_BUSY) {
820 struct slhci_softc *sc = SLHCI_BUS2SC(bus); 814 struct slhci_softc *sc = SLHCI_BUS2SC(bus);
821 printf("%s: slhci_freex: xfer=%p not busy, %#08x halted\n", 815 printf("%s: slhci_freex: xfer=%p not busy, %#08x halted\n",
822 SC_NAME(sc), xfer, xfer->ux_state); 816 SC_NAME(sc), xfer, xfer->ux_state);
823 DDOLOG("xfer=%p not busy, %#08x halted\n", xfer, 817 DDOLOG("xfer=%p not busy, %#08x halted\n", xfer,
824 xfer->ux_state, 0, 0); 818 xfer->ux_state, 0, 0);
825 slhci_lock_call(sc, &slhci_halt, NULL, NULL); 819 slhci_lock_call(sc, &slhci_halt, NULL, NULL);
826 return; 820 return;
827 } 821 }
828 xfer->ux_state = XFER_FREE; 822 xfer->ux_state = XFER_FREE;
829#endif 823#endif
830 824
831 kmem_free(xfer, sizeof(*xfer)); 825 kmem_free(xfer, sizeof(*xfer));
832} 826}
833 827
834static void 828static void
835slhci_get_lock(struct usbd_bus *bus, kmutex_t **lock) 829slhci_get_lock(struct usbd_bus *bus, kmutex_t **lock)
836{ 830{
837 struct slhci_softc *sc = SLHCI_BUS2SC(bus); 831 struct slhci_softc *sc = SLHCI_BUS2SC(bus);
838 832
839 *lock = &sc->sc_lock; 833 *lock = &sc->sc_lock;
840} 834}
841 835
842usbd_status 836usbd_status
843slhci_transfer(struct usbd_xfer *xfer) 837slhci_transfer(struct usbd_xfer *xfer)
844{ 838{
845 SLHCIHIST_FUNC(); SLHCIHIST_CALLED(); 839 SLHCIHIST_FUNC(); SLHCIHIST_CALLED();
846 struct slhci_softc *sc = SLHCI_XFER2SC(xfer); 840 struct slhci_softc *sc = SLHCI_XFER2SC(xfer);
847 usbd_status error; 841 usbd_status error;
848 842
849 DLOG(D_TRACE, "transfer type %d xfer %p spipe %p ", 843 DLOG(D_TRACE, "transfer type %d xfer %p spipe %p ",
850 SLHCI_XFER_TYPE(xfer), xfer, xfer->ux_pipe, 0); 844 SLHCI_XFER_TYPE(xfer), xfer, xfer->ux_pipe, 0);
851 845
852 /* Insert last in queue */ 846 /* Insert last in queue */
853 mutex_enter(&sc->sc_lock); 847 mutex_enter(&sc->sc_lock);
854 error = usb_insert_transfer(xfer); 848 error = usb_insert_transfer(xfer);
855 mutex_exit(&sc->sc_lock); 849 mutex_exit(&sc->sc_lock);
856 if (error) { 850 if (error) {
857 if (error != USBD_IN_PROGRESS) 851 if (error != USBD_IN_PROGRESS)
858 DLOG(D_ERR, "usb_insert_transfer returns %d!", error, 852 DLOG(D_ERR, "usb_insert_transfer returns %d!", error,
859 0,0,0); 853 0,0,0);
860 return error; 854 return error;
861 } 855 }
862 856
863 /* 857 /*
864 * Pipe isn't running (otherwise error would be USBD_INPROG), 858 * Pipe isn't running (otherwise error would be USBD_INPROG),
865 * so start it first. 859 * so start it first.
866 */ 860 */
867 861
868 /* 862 /*
869 * Start will take the lock. 863 * Start will take the lock.
870 */ 864 */
871 error = xfer->ux_pipe->up_methods->upm_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); 865 error = xfer->ux_pipe->up_methods->upm_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue));
872 866
873 return error; 867 return error;
874} 868}
875 869
876/* It is not safe for start to return anything other than USBD_INPROG. */ 870/* It is not safe for start to return anything other than USBD_INPROG. */
877usbd_status 871usbd_status
878slhci_start(struct usbd_xfer *xfer) 872slhci_start(struct usbd_xfer *xfer)
879{ 873{
880 SLHCIHIST_FUNC(); SLHCIHIST_CALLED(); 874 SLHCIHIST_FUNC(); SLHCIHIST_CALLED();
881 struct slhci_softc *sc = SLHCI_XFER2SC(xfer); 875 struct slhci_softc *sc = SLHCI_XFER2SC(xfer);
882 struct usbd_pipe *pipe = xfer->ux_pipe; 876 struct usbd_pipe *pipe = xfer->ux_pipe;
883 struct slhci_pipe *spipe = SLHCI_PIPE2SPIPE(pipe); 877 struct slhci_pipe *spipe = SLHCI_PIPE2SPIPE(pipe);
884 struct slhci_transfers *t = &sc->sc_transfers; 878 struct slhci_transfers *t = &sc->sc_transfers;
885 usb_endpoint_descriptor_t *ed = pipe->up_endpoint->ue_edesc; 879 usb_endpoint_descriptor_t *ed = pipe->up_endpoint->ue_edesc;
886 unsigned int max_packet; 880 unsigned int max_packet;
887 881
888 mutex_enter(&sc->sc_lock); 882 mutex_enter(&sc->sc_lock);
889 883
890 max_packet = UGETW(ed->wMaxPacketSize); 884 max_packet = UGETW(ed->wMaxPacketSize);
891 885
892 DLOG(D_TRACE, "transfer type %d start xfer %p spipe %p length %d", 886 DLOG(D_TRACE, "transfer type %d start xfer %p spipe %p length %d",
893 spipe->ptype, xfer, spipe, xfer->ux_length); 887 spipe->ptype, xfer, spipe, xfer->ux_length);
894 888
895 /* root transfers use slhci_root_start */ 889 /* root transfers use slhci_root_start */
896 890
897 KASSERT(spipe->xfer == NULL); /* not SLASSERT */ 891 KASSERT(spipe->xfer == NULL); /* not SLASSERT */
898 892
899 xfer->ux_actlen = 0; 893 xfer->ux_actlen = 0;
900 xfer->ux_status = USBD_IN_PROGRESS; 894 xfer->ux_status = USBD_IN_PROGRESS;
901 895
902 spipe->xfer = xfer; 896 spipe->xfer = xfer;
903 897
904 spipe->nerrs = 0; 898 spipe->nerrs = 0;
905 spipe->frame = t->frame; 899 spipe->frame = t->frame;
906 spipe->control = SL11_EPCTRL_ARM_ENABLE; 900 spipe->control = SL11_EPCTRL_ARM_ENABLE;
907 spipe->tregs[DEV] = pipe->up_dev->ud_addr; 901 spipe->tregs[DEV] = pipe->up_dev->ud_addr;
908 spipe->tregs[PID] = spipe->newpid = UE_GET_ADDR(ed->bEndpointAddress) 902 spipe->tregs[PID] = spipe->newpid = UE_GET_ADDR(ed->bEndpointAddress)
909 | (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN ? SL11_PID_IN : 903 | (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN ? SL11_PID_IN :
910 SL11_PID_OUT); 904 SL11_PID_OUT);
911 spipe->newlen[0] = xfer->ux_length % max_packet; 905 spipe->newlen[0] = xfer->ux_length % max_packet;
912 spipe->newlen[1] = min(xfer->ux_length, max_packet); 906 spipe->newlen[1] = min(xfer->ux_length, max_packet);
913 907
914 if (spipe->ptype == PT_BULK || spipe->ptype == PT_INTR) { 908 if (spipe->ptype == PT_BULK || spipe->ptype == PT_INTR) {
915 if (spipe->pflags & PF_TOGGLE) 909 if (spipe->pflags & PF_TOGGLE)
916 spipe->control |= SL11_EPCTRL_DATATOGGLE; 910 spipe->control |= SL11_EPCTRL_DATATOGGLE;
917 spipe->tregs[LEN] = spipe->newlen[1]; 911 spipe->tregs[LEN] = spipe->newlen[1];
918 if (spipe->tregs[LEN]) 912 if (spipe->tregs[LEN])
919 spipe->buffer = xfer->ux_buf; 913 spipe->buffer = xfer->ux_buf;
920 else 914 else
921 spipe->buffer = NULL; 915 spipe->buffer = NULL;
922 spipe->lastframe = t->frame; 916 spipe->lastframe = t->frame;
923 if (spipe->ptype == PT_INTR) { 917 if (spipe->ptype == PT_INTR) {
924 spipe->frame = spipe->lastframe + 918 spipe->frame = spipe->lastframe +
925 spipe->pipe.up_interval; 919 spipe->pipe.up_interval;
926 } 920 }
927 921
928#if defined(DEBUG) || defined(SLHCI_DEBUG) 922#if defined(DEBUG) || defined(SLHCI_DEBUG)
929 if (__predict_false(spipe->ptype == PT_INTR && 923 if (__predict_false(spipe->ptype == PT_INTR &&
930 xfer->ux_length > spipe->tregs[LEN])) { 924 xfer->ux_length > spipe->tregs[LEN])) {
931 printf("%s: Long INTR transfer not supported!\n", 925 printf("%s: Long INTR transfer not supported!\n",
932 SC_NAME(sc)); 926 SC_NAME(sc));
933 DDOLOG("Long INTR transfer not supported!", 0, 0, 0, 0); 927 DDOLOG("Long INTR transfer not supported!", 0, 0, 0, 0);
934 xfer->ux_status = USBD_INVAL; 928 xfer->ux_status = USBD_INVAL;
935 } 929 }
936#endif 930#endif
937 } else { 931 } else {
938 /* ptype may be currently set to any control transfer type. */ 932 /* ptype may be currently set to any control transfer type. */
939 SLHCI_DEXEC(D_TRACE, slhci_log_xfer(xfer)); 933 SLHCI_DEXEC(D_TRACE, slhci_log_xfer(xfer));
940 934
941 /* SETUP contains IN/OUT bits also */ 935 /* SETUP contains IN/OUT bits also */
942 spipe->tregs[PID] |= SL11_PID_SETUP; 936 spipe->tregs[PID] |= SL11_PID_SETUP;
943 spipe->tregs[LEN] = 8; 937 spipe->tregs[LEN] = 8;
944 spipe->buffer = (uint8_t *)&xfer->ux_request; 938 spipe->buffer = (uint8_t *)&xfer->ux_request;
945 DLOGBUF(D_XFER, spipe->buffer, spipe->tregs[LEN]); 939 DLOGBUF(D_XFER, spipe->buffer, spipe->tregs[LEN]);
946 spipe->ptype = PT_CTRL_SETUP; 940 spipe->ptype = PT_CTRL_SETUP;
947 spipe->newpid &= ~SL11_PID_BITS; 941 spipe->newpid &= ~SL11_PID_BITS;
948 if (xfer->ux_length == 0 || 942 if (xfer->ux_length == 0 ||
949 (xfer->ux_request.bmRequestType & UT_READ)) 943 (xfer->ux_request.bmRequestType & UT_READ))
950 spipe->newpid |= SL11_PID_IN; 944 spipe->newpid |= SL11_PID_IN;
951 else 945 else
952 spipe->newpid |= SL11_PID_OUT; 946 spipe->newpid |= SL11_PID_OUT;
953 } 947 }
954 948
955 if (xfer->ux_flags & USBD_FORCE_SHORT_XFER && 949 if (xfer->ux_flags & USBD_FORCE_SHORT_XFER &&
956 spipe->tregs[LEN] == max_packet && 950 spipe->tregs[LEN] == max_packet &&
957 (spipe->newpid & SL11_PID_BITS) == SL11_PID_OUT) 951 (spipe->newpid & SL11_PID_BITS) == SL11_PID_OUT)
958 spipe->wantshort = 1; 952 spipe->wantshort = 1;
959 else 953 else
960 spipe->wantshort = 0; 954 spipe->wantshort = 0;
961 955
962 /* 956 /*
963 * The goal of newbustime and newlen is to avoid bustime calculation 957 * The goal of newbustime and newlen is to avoid bustime calculation
964 * in the interrupt. The calculations are not too complex, but they 958 * in the interrupt. The calculations are not too complex, but they
965 * complicate the conditional logic somewhat and doing them all in the 959 * complicate the conditional logic somewhat and doing them all in the
966 * same place shares constants. Index 0 is "short length" for bulk and 960 * same place shares constants. Index 0 is "short length" for bulk and
967 * ctrl data and 1 is "full length" for ctrl data (bulk/intr are 961 * ctrl data and 1 is "full length" for ctrl data (bulk/intr are
968 * already set to full length). 962 * already set to full length).
969 */ 963 */
970 if (spipe->pflags & PF_LS) { 964 if (spipe->pflags & PF_LS) {
971 /* 965 /*
972 * Setting PREAMBLE for directly connected LS devices will 966 * Setting PREAMBLE for directly connected LS devices will
973 * lock up the chip. 967 * lock up the chip.
974 */ 968 */
975 if (spipe->pflags & PF_PREAMBLE) 969 if (spipe->pflags & PF_PREAMBLE)
976 spipe->control |= SL11_EPCTRL_PREAMBLE; 970 spipe->control |= SL11_EPCTRL_PREAMBLE;
977 if (max_packet <= 8) { 971 if (max_packet <= 8) {
978 spipe->bustime = SLHCI_LS_CONST + 972 spipe->bustime = SLHCI_LS_CONST +
979 SLHCI_LS_DATA_TIME(spipe->tregs[LEN]); 973 SLHCI_LS_DATA_TIME(spipe->tregs[LEN]);
980 spipe->newbustime[0] = SLHCI_LS_CONST + 974 spipe->newbustime[0] = SLHCI_LS_CONST +
981 SLHCI_LS_DATA_TIME(spipe->newlen[0]); 975 SLHCI_LS_DATA_TIME(spipe->newlen[0]);
982 spipe->newbustime[1] = SLHCI_LS_CONST + 976 spipe->newbustime[1] = SLHCI_LS_CONST +
983 SLHCI_LS_DATA_TIME(spipe->newlen[1]); 977 SLHCI_LS_DATA_TIME(spipe->newlen[1]);
984 } else 978 } else
985 xfer->ux_status = USBD_INVAL; 979 xfer->ux_status = USBD_INVAL;
986 } else { 980 } else {
987 UL_SLASSERT(pipe->up_dev->ud_speed == USB_SPEED_FULL, sc, 981 UL_SLASSERT(pipe->up_dev->ud_speed == USB_SPEED_FULL, sc,
988 spipe, xfer, return USBD_IN_PROGRESS); 982 spipe, xfer, return USBD_IN_PROGRESS);
989 if (max_packet <= SL11_MAX_PACKET_SIZE) { 983 if (max_packet <= SL11_MAX_PACKET_SIZE) {
990 spipe->bustime = SLHCI_FS_CONST + 984 spipe->bustime = SLHCI_FS_CONST +
991 SLHCI_FS_DATA_TIME(spipe->tregs[LEN]); 985 SLHCI_FS_DATA_TIME(spipe->tregs[LEN]);
992 spipe->newbustime[0] = SLHCI_FS_CONST + 986 spipe->newbustime[0] = SLHCI_FS_CONST +
993 SLHCI_FS_DATA_TIME(spipe->newlen[0]); 987 SLHCI_FS_DATA_TIME(spipe->newlen[0]);
994 spipe->newbustime[1] = SLHCI_FS_CONST + 988 spipe->newbustime[1] = SLHCI_FS_CONST +
995 SLHCI_FS_DATA_TIME(spipe->newlen[1]); 989 SLHCI_FS_DATA_TIME(spipe->newlen[1]);
996 } else 990 } else
997 xfer->ux_status = USBD_INVAL; 991 xfer->ux_status = USBD_INVAL;
998 } 992 }
999 993
1000 /* 994 /*
1001 * The datasheet incorrectly indicates that DIRECTION is for 995 * The datasheet incorrectly indicates that DIRECTION is for
1002 * "transmit to host". It is for OUT and SETUP. The app note 996 * "transmit to host". It is for OUT and SETUP. The app note
1003 * describes its use correctly. 997 * describes its use correctly.
1004 */ 998 */
1005 if ((spipe->tregs[PID] & SL11_PID_BITS) != SL11_PID_IN) 999 if ((spipe->tregs[PID] & SL11_PID_BITS) != SL11_PID_IN)
1006 spipe->control |= SL11_EPCTRL_DIRECTION; 1000 spipe->control |= SL11_EPCTRL_DIRECTION;
1007 1001
1008 slhci_start_entry(sc, spipe); 1002 slhci_start_entry(sc, spipe);
1009 1003
1010 mutex_exit(&sc->sc_lock); 1004 mutex_exit(&sc->sc_lock);
1011 1005
1012 return USBD_IN_PROGRESS; 1006 return USBD_IN_PROGRESS;
1013} 1007}
1014 1008
1015usbd_status 1009usbd_status
1016slhci_root_start(struct usbd_xfer *xfer) 1010slhci_root_start(struct usbd_xfer *xfer)
1017{ 1011{
1018 SLHCIHIST_FUNC(); SLHCIHIST_CALLED(); 1012 SLHCIHIST_FUNC(); SLHCIHIST_CALLED();
1019 struct slhci_softc *sc; 1013 struct slhci_softc *sc;
1020 struct slhci_pipe *spipe __diagused; 1014 struct slhci_pipe *spipe __diagused;
1021 1015
1022 spipe = SLHCI_PIPE2SPIPE(xfer->ux_pipe); 1016 spipe = SLHCI_PIPE2SPIPE(xfer->ux_pipe);
1023 sc = SLHCI_XFER2SC(xfer); 1017 sc = SLHCI_XFER2SC(xfer);
1024 1018
1025 struct slhci_transfers *t = &sc->sc_transfers; 1019 struct slhci_transfers *t = &sc->sc_transfers;
1026 1020
1027 LK_SLASSERT(spipe != NULL && xfer != NULL, sc, spipe, xfer, return 1021 LK_SLASSERT(spipe != NULL && xfer != NULL, sc, spipe, xfer, return
1028 USBD_CANCELLED); 1022 USBD_CANCELLED);
1029 1023
1030 DLOG(D_TRACE, "transfer type %d start", SLHCI_XFER_TYPE(xfer), 0, 0, 0); 1024 DLOG(D_TRACE, "transfer type %d start", SLHCI_XFER_TYPE(xfer), 0, 0, 0);
1031 1025
1032 KASSERT(spipe->ptype == PT_ROOT_INTR); 1026 KASSERT(spipe->ptype == PT_ROOT_INTR);
1033 1027
1034 mutex_enter(&sc->sc_intr_lock); 1028 mutex_enter(&sc->sc_intr_lock);
1035 t->rootintr = xfer; 1029 t->rootintr = xfer;
1036 mutex_exit(&sc->sc_intr_lock); 1030 mutex_exit(&sc->sc_intr_lock);
1037 1031
1038 return USBD_IN_PROGRESS; 1032 return USBD_IN_PROGRESS;
1039} 1033}
1040 1034
1041usbd_status 1035usbd_status
1042slhci_open(struct usbd_pipe *pipe) 1036slhci_open(struct usbd_pipe *pipe)
1043{ 1037{
1044 SLHCIHIST_FUNC(); SLHCIHIST_CALLED(); 1038 SLHCIHIST_FUNC(); SLHCIHIST_CALLED();
1045 struct usbd_device *dev; 1039 struct usbd_device *dev;
1046 struct slhci_softc *sc; 1040 struct slhci_softc *sc;
1047 struct slhci_pipe *spipe; 1041 struct slhci_pipe *spipe;
1048 usb_endpoint_descriptor_t *ed; 1042 usb_endpoint_descriptor_t *ed;
1049 unsigned int max_packet, pmaxpkt; 1043 unsigned int max_packet, pmaxpkt;
1050 uint8_t rhaddr; 1044 uint8_t rhaddr;
1051 1045
1052 dev = pipe->up_dev; 1046 dev = pipe->up_dev;
1053 sc = SLHCI_PIPE2SC(pipe); 1047 sc = SLHCI_PIPE2SC(pipe);
1054 spipe = SLHCI_PIPE2SPIPE(pipe); 1048 spipe = SLHCI_PIPE2SPIPE(pipe);
1055 ed = pipe->up_endpoint->ue_edesc; 1049 ed = pipe->up_endpoint->ue_edesc;
1056 rhaddr = dev->ud_bus->ub_rhaddr; 1050 rhaddr = dev->ud_bus->ub_rhaddr;
1057 1051
1058 DLOG(D_TRACE, "slhci_open(addr=%d,ep=%d,rootaddr=%d)", 1052 DLOG(D_TRACE, "slhci_open(addr=%d,ep=%d,rootaddr=%d)",
1059 dev->ud_addr, ed->bEndpointAddress, rhaddr, 0); 1053 dev->ud_addr, ed->bEndpointAddress, rhaddr, 0);
1060 1054
1061 spipe->pflags = 0; 1055 spipe->pflags = 0;
1062 spipe->frame = 0; 1056 spipe->frame = 0;
1063 spipe->lastframe = 0; 1057 spipe->lastframe = 0;
1064 spipe->xfer = NULL; 1058 spipe->xfer = NULL;
1065 spipe->buffer = NULL; 1059 spipe->buffer = NULL;
1066 1060
1067 gcq_init(&spipe->ap); 1061 gcq_init(&spipe->ap);
1068 gcq_init(&spipe->to); 1062 gcq_init(&spipe->to);
1069 gcq_init(&spipe->xq); 1063 gcq_init(&spipe->xq);
1070 1064
1071 /* 1065 /*
1072 * The endpoint descriptor will not have been set up yet in the case 1066 * The endpoint descriptor will not have been set up yet in the case
1073 * of the standard control pipe, so the max packet checks are also 1067 * of the standard control pipe, so the max packet checks are also
1074 * necessary in start. 1068 * necessary in start.
1075 */ 1069 */
1076 1070
1077 max_packet = UGETW(ed->wMaxPacketSize); 1071 max_packet = UGETW(ed->wMaxPacketSize);
1078 1072
1079 if (dev->ud_speed == USB_SPEED_LOW) { 1073 if (dev->ud_speed == USB_SPEED_LOW) {
1080 spipe->pflags |= PF_LS; 1074 spipe->pflags |= PF_LS;
1081 if (dev->ud_myhub->ud_addr != rhaddr) { 1075 if (dev->ud_myhub->ud_addr != rhaddr) {
1082 spipe->pflags |= PF_PREAMBLE; 1076 spipe->pflags |= PF_PREAMBLE;
1083 if (!slhci_try_lsvh) 1077 if (!slhci_try_lsvh)
1084 return slhci_lock_call(sc, &slhci_lsvh_warn, 1078 return slhci_lock_call(sc, &slhci_lsvh_warn,
1085 spipe, NULL); 1079 spipe, NULL);
1086 } 1080 }
1087 pmaxpkt = 8; 1081 pmaxpkt = 8;
1088 } else 1082 } else
1089 pmaxpkt = SL11_MAX_PACKET_SIZE; 1083 pmaxpkt = SL11_MAX_PACKET_SIZE;
1090 1084
1091 if (max_packet > pmaxpkt) { 1085 if (max_packet > pmaxpkt) {
1092 DLOG(D_ERR, "packet too large! size %d spipe %p", max_packet, 1086 DLOG(D_ERR, "packet too large! size %d spipe %p", max_packet,
1093 spipe, 0,0); 1087 spipe, 0,0);
1094 return USBD_INVAL; 1088 return USBD_INVAL;
1095 } 1089 }
1096 1090
1097 if (dev->ud_addr == rhaddr) { 1091 if (dev->ud_addr == rhaddr) {
1098 switch (ed->bEndpointAddress) { 1092 switch (ed->bEndpointAddress) {
1099 case USB_CONTROL_ENDPOINT: 1093 case USB_CONTROL_ENDPOINT:
1100 spipe->ptype = PT_ROOT_CTRL; 1094 spipe->ptype = PT_ROOT_CTRL;
1101 pipe->up_interval = 0; 1095 pipe->up_interval = 0;
1102 pipe->up_methods = &roothub_ctrl_methods; 1096 pipe->up_methods = &roothub_ctrl_methods;
1103 break; 1097 break;
1104 case UE_DIR_IN | USBROOTHUB_INTR_ENDPT: 1098 case UE_DIR_IN | USBROOTHUB_INTR_ENDPT:
1105 spipe->ptype = PT_ROOT_INTR; 1099 spipe->ptype = PT_ROOT_INTR;
1106 pipe->up_interval = 1; 1100 pipe->up_interval = 1;
1107 pipe->up_methods = &slhci_root_methods; 1101 pipe->up_methods = &slhci_root_methods;
1108 break; 1102 break;
1109 default: 1103 default:
1110 printf("%s: Invalid root endpoint!\n", SC_NAME(sc)); 1104 printf("%s: Invalid root endpoint!\n", SC_NAME(sc));
1111 DDOLOG("Invalid root endpoint", 0, 0, 0, 0); 1105 DDOLOG("Invalid root endpoint", 0, 0, 0, 0);
1112 return USBD_INVAL; 1106 return USBD_INVAL;
1113 } 1107 }
1114 return USBD_NORMAL_COMPLETION; 1108 return USBD_NORMAL_COMPLETION;
1115 } else { 1109 } else {
1116 switch (ed->bmAttributes & UE_XFERTYPE) { 1110 switch (ed->bmAttributes & UE_XFERTYPE) {
1117 case UE_CONTROL: 1111 case UE_CONTROL:
1118 spipe->ptype = PT_CTRL_SETUP; 1112 spipe->ptype = PT_CTRL_SETUP;
1119 pipe->up_interval = 0; 1113 pipe->up_interval = 0;
1120 break; 1114 break;
1121 case UE_INTERRUPT: 1115 case UE_INTERRUPT:
1122 spipe->ptype = PT_INTR; 1116 spipe->ptype = PT_INTR;
1123 if (pipe->up_interval == USBD_DEFAULT_INTERVAL) 1117 if (pipe->up_interval == USBD_DEFAULT_INTERVAL)
1124 pipe->up_interval = ed->bInterval; 1118 pipe->up_interval = ed->bInterval;
1125 break; 1119 break;
1126 case UE_ISOCHRONOUS: 1120 case UE_ISOCHRONOUS:
1127 return slhci_lock_call(sc, &slhci_isoc_warn, spipe, 1121 return slhci_lock_call(sc, &slhci_isoc_warn, spipe,
1128 NULL); 1122 NULL);
1129 case UE_BULK: 1123 case UE_BULK:
1130 spipe->ptype = PT_BULK; 1124 spipe->ptype = PT_BULK;
1131 pipe->up_interval = 0; 1125 pipe->up_interval = 0;
1132 break; 1126 break;
1133 } 1127 }
1134 1128
1135 DLOG(D_MSG, "open pipe type %d interval %d", spipe->ptype, 1129 DLOG(D_MSG, "open pipe type %d interval %d", spipe->ptype,
1136 pipe->up_interval, 0,0); 1130 pipe->up_interval, 0,0);
1137 1131
1138 pipe->up_methods = __UNCONST(&slhci_pipe_methods); 1132 pipe->up_methods = __UNCONST(&slhci_pipe_methods);
1139 1133
1140 return slhci_lock_call(sc, &slhci_open_pipe, spipe, NULL); 1134 return slhci_lock_call(sc, &slhci_open_pipe, spipe, NULL);
1141 } 1135 }
1142} 1136}
1143 1137
1144int 1138int
1145slhci_supported_rev(uint8_t rev) 1139slhci_supported_rev(uint8_t rev)
1146{ 1140{
1147 return rev >= SLTYPE_SL811HS_R12 && rev <= SLTYPE_SL811HS_R15; 1141 return rev >= SLTYPE_SL811HS_R12 && rev <= SLTYPE_SL811HS_R15;
1148} 1142}
1149 1143
1150/* 1144/*
1151 * Must be called before the ISR is registered. Interrupts can be shared so 1145 * Must be called before the ISR is registered. Interrupts can be shared so
1152 * slhci_intr could be called as soon as the ISR is registered. 1146 * slhci_intr could be called as soon as the ISR is registered.
1153 * Note max_current argument is actual current, but stored as current/2 1147 * Note max_current argument is actual current, but stored as current/2
1154 */ 1148 */
1155void 1149void
1156slhci_preinit(struct slhci_softc *sc, PowerFunc pow, bus_space_tag_t iot, 1150slhci_preinit(struct slhci_softc *sc, PowerFunc pow, bus_space_tag_t iot,
1157 bus_space_handle_t ioh, uint16_t max_current, uint32_t stride) 1151 bus_space_handle_t ioh, uint16_t max_current, uint32_t stride)
1158{ 1152{
1159 struct slhci_transfers *t; 1153 struct slhci_transfers *t;
1160 int i; 1154 int i;
1161 1155
1162 t = &sc->sc_transfers; 1156 t = &sc->sc_transfers;
1163 1157
1164#ifdef SLHCI_DEBUG 1158#ifdef SLHCI_DEBUG
1165 ssc = sc; 1159 ssc = sc;
1166#endif 1160#endif
1167 1161
1168 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB); 1162 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB);
1169 mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_USB); 1163 mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_USB);
1170 1164
1171 /* sc->sc_ier = 0; */ 1165 /* sc->sc_ier = 0; */
1172 /* t->rootintr = NULL; */ 1166 /* t->rootintr = NULL; */
1173 t->flags = F_NODEV|F_UDISABLED; 1167 t->flags = F_NODEV|F_UDISABLED;
1174 t->pend = INT_MAX; 1168 t->pend = INT_MAX;
1175 KASSERT(slhci_wait_time != INT_MAX); 1169 KASSERT(slhci_wait_time != INT_MAX);
1176 t->len[0] = t->len[1] = -1; 1170 t->len[0] = t->len[1] = -1;
1177 if (max_current > 500) 1171 if (max_current > 500)
1178 max_current = 500; 1172 max_current = 500;
1179 t->max_current = (uint8_t)(max_current / 2); 1173 t->max_current = (uint8_t)(max_current / 2);
1180 sc->sc_enable_power = pow; 1174 sc->sc_enable_power = pow;
1181 sc->sc_iot = iot; 1175 sc->sc_iot = iot;
1182 sc->sc_ioh = ioh; 1176 sc->sc_ioh = ioh;
1183 sc->sc_stride = stride; 1177 sc->sc_stride = stride;
1184 1178
1185 KASSERT(Q_MAX+1 == sizeof(t->q) / sizeof(t->q[0])); 1179 KASSERT(Q_MAX+1 == sizeof(t->q) / sizeof(t->q[0]));
1186 1180
1187 for (i = 0; i <= Q_MAX; i++) 1181 for (i = 0; i <= Q_MAX; i++)
1188 gcq_init_head(&t->q[i]); 1182 gcq_init_head(&t->q[i]);
1189 gcq_init_head(&t->timed); 1183 gcq_init_head(&t->timed);
1190 gcq_init_head(&t->to); 1184 gcq_init_head(&t->to);
1191 gcq_init_head(&t->ap); 1185 gcq_init_head(&t->ap);
1192 gcq_init_head(&sc->sc_waitq); 1186 gcq_init_head(&sc->sc_waitq);