1 /* $NetBSD: sl811hs.c,v 1.24 2009/11/12 19:35:59 dyoung Exp $ */
4 * Not (c) 2007 Matthew Orgass
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,
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
13 * Cypress/ScanLogic SL811HS/T USB Host Controller
14 * Datasheet, Errata, and App Note available at www.cypress.com
16 * Uses: Ratoc CFU1U PCMCIA USB Host Controller, Nereid Mac 68k USB HC, ISA
17 * HCs. The Ratoc CFU2 uses a different chip.
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,
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
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
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
27 * per-frame bulk transfer.
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,
31 * auto-increment does not work reliably so write and bus speed is
32 * approximately the same for full speed devices.
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
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
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
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
42 * once interrupted, would stay out of sync. All isoc support has been
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
47 * comment in dointr(). All performance enhancing features of this chip seem
48 * not to work properly, most confirmed buggy in errata doc.
53 * The hard interrupt is the main entry point. Start, callbacks, and repeat
54 * are the only others called frequently.
56 * Since this driver attaches to pcmcia, card removal at any point should be
57 * expected and not cause panics or infinite loops.
59 * This driver does fine grained locking for its own data structures, however
60 * the general USB code does not yet have locks, some of which would need to
61 * be used in this driver. This is mostly for debug use on single processor
64 * The theory of the wait lock is that start is the only function that would
65 * be frequently called from arbitrary processors, so it should not need to
66 * wait for the rest to be completed. However, once entering the lock as much
67 * device access as possible is done, so any other CPU that tries to service
68 * an interrupt would be blocked. Ideally, the hard and soft interrupt could
69 * be assigned to the same CPU and start would normally just put work on the
70 * wait queue and generate a soft interrupt.
72 * Any use of the main lock must check the wait lock before returning. The
73 * aquisition order is main lock then wait lock, but the wait lock must be
74 * released last when clearing the wait queue.
78 * copy next output packet while transfering
80 * could keep track of known values of all buffer space?
81 * combined print/log function for errors
83 * use_polling support is untested and may not work
86 #include <sys/cdefs.h>
87 __KERNEL_RCSID(0, "$NetBSD: sl811hs.c,v 1.24 2009/11/12 19:35:59 dyoung Exp $");
89 #include <sys/cdefs.h>
90 #include <sys/param.h>
91 #include <sys/systm.h>
92 #include <sys/kernel.h>
94 #include <sys/device.h>
95 #include <sys/malloc.h>
96 #include <sys/queue.h>
98 #include <sys/simplelock.h>
103 #include <dev/usb/usb.h>
104 #include <dev/usb/usbdi.h>
105 #include <dev/usb/usbdivar.h>
106 #include <dev/usb/usb_mem.h>
107 #include <dev/usb/usbdevs.h>
108 #include <dev/usb/usbroothub_subr.h>
110 #include <dev/ic/sl811hsreg.h>
111 #include <dev/ic/sl811hsvar.h>
113 #define Q_CB 0 /* Control/Bulk */
115 #define Q_MAX_XFER Q_CB
116 #define Q_CALLBACKS 2
117 #define Q_MAX Q_CALLBACKS
119 #define F_AREADY (0x00000001)
120 #define F_BREADY (0x00000002)
121 #define F_AINPROG (0x00000004)
122 #define F_BINPROG (0x00000008)
123 #define F_LOWSPEED (0x00000010)
124 #define F_UDISABLED (0x00000020) /* Consider disabled for USB */
125 #define F_NODEV (0x00000040)
126 #define F_ROOTINTR (0x00000080)
127 #define F_REALPOWER (0x00000100) /* Actual power state */
128 #define F_POWER (0x00000200) /* USB reported power state */
129 #define F_ACTIVE (0x00000400)
130 #define F_CALLBACK (0x00000800) /* Callback scheduled */
131 #define F_SOFCHECK1 (0x00001000)
132 #define F_SOFCHECK2 (0x00002000)
133 #define F_CRESET (0x00004000) /* Reset done not reported */
134 #define F_CCONNECT (0x00008000) /* Connect change not reported */
135 #define F_RESET (0x00010000)
136 #define F_ISOC_WARNED (0x00020000)
137 #define F_LSVH_WARNED (0x00040000)
139 #define F_DISABLED (F_NODEV|F_UDISABLED)
140 #define F_CHANGE (F_CRESET|F_CCONNECT)
142 #ifdef SLHCI_TRY_LSVH
143 unsigned int slhci_try_lsvh
= 1;
145 unsigned int slhci_try_lsvh
= 0;
158 static const uint8_t slhci_tregs
[2][4] =
159 {{SL11_E0ADDR
, SL11_E0LEN
, SL11_E0PID
, SL11_E0DEV
},
160 {SL11_E1ADDR
, SL11_E1LEN
, SL11_E1PID
, SL11_E1DEV
}};
162 #define PT_ROOT_CTRL 0
163 #define PT_ROOT_INTR 1
164 #define PT_CTRL_SETUP 2
165 #define PT_CTRL_DATA 3
166 #define PT_CTRL_STATUS 4
172 #define SLHCI_MEM_ACCOUNTING
176 static const char * const names
[] = { "ROOT Ctrl", "ROOT Intr",
177 "Control (setup)", "Control (data)", "Control (status)",
178 "Interrupt", "Bulk", "BAD PTYPE" };
180 KASSERT(sizeof(names
) / sizeof(names
[0]) == PT_MAX
+ 2);
187 #define SLHCI_XFER_TYPE(x) (((struct slhci_pipe *)((x)->pipe))->ptype)
189 /* Maximum allowable reserved bus time. Since intr/isoc transfers have
190 * unconditional priority, this is all that ensures control and bulk transfers
191 * get a chance. It is a single value for all frames since all transfers can
192 * use multiple consecutive frames if an error is encountered. Note that it
193 * is not really possible to fill the bus with transfers, so this value should
194 * be on the low side. Defaults to giving a warning unless SLHCI_NO_OVERTIME
195 * is defined. Full time is 12000 - END_BUSTIME. */
196 #ifndef SLHCI_RESERVED_BUSTIME
197 #define SLHCI_RESERVED_BUSTIME 5000
200 /* Rate for "exceeds reserved bus time" warnings (default) or errors.
201 * Warnings only happen when an endpoint open causes the time to go above
202 * SLHCI_RESERVED_BUSTIME, not if it is already above. */
203 #ifndef SLHCI_OVERTIME_WARNING_RATE
204 #define SLHCI_OVERTIME_WARNING_RATE { 60, 0 } /* 60 seconds */
206 static const struct timeval reserved_warn_rate
= SLHCI_OVERTIME_WARNING_RATE
;
208 /* Rate for overflow warnings */
209 #ifndef SLHCI_OVERFLOW_WARNING_RATE
210 #define SLHCI_OVERFLOW_WARNING_RATE { 60, 0 } /* 60 seconds */
212 static const struct timeval overflow_warn_rate
= SLHCI_OVERFLOW_WARNING_RATE
;
214 /* For EOF, the spec says 42 bit times, plus (I think) a possible hub skew of
215 * 20 bit times. By default leave 66 bit times to start the transfer beyond
216 * the required time. Units are full-speed bit times (a bit over 5us per 64).
217 * Only multiples of 64 are significant. */
218 #define SLHCI_STANDARD_END_BUSTIME 128
219 #ifndef SLHCI_EXTRA_END_BUSTIME
220 #define SLHCI_EXTRA_END_BUSTIME 0
223 #define SLHCI_END_BUSTIME (SLHCI_STANDARD_END_BUSTIME+SLHCI_EXTRA_END_BUSTIME)
225 /* This is an approximation of the USB worst-case timings presented on p. 54 of
226 * the USB 1.1 spec translated to full speed bit times.
227 * FS = full speed with handshake, FSII = isoc in, FSIO = isoc out,
228 * FSI = isoc (worst case), LS = low speed */
229 #define SLHCI_FS_CONST 114
230 #define SLHCI_FSII_CONST 92
231 #define SLHCI_FSIO_CONST 80
232 #define SLHCI_FSI_CONST 92
233 #define SLHCI_LS_CONST 804
234 #ifndef SLHCI_PRECICE_BUSTIME
235 /* These values are < 3% too high (compared to the multiply and divide) for
236 * max sized packets. */
237 #define SLHCI_FS_DATA_TIME(len) (((u_int)(len)<<3)+(len)+((len)>>1))
238 #define SLHCI_LS_DATA_TIME(len) (((u_int)(len)<<6)+((u_int)(len)<<4))
240 #define SLHCI_FS_DATA_TIME(len) (56*(len)/6)
241 #define SLHCI_LS_DATA_TIME(len) (449*(len)/6)
244 /* Set SLHCI_WAIT_SIZE to the desired maximum size of single FS transfer
245 * to poll for after starting a transfer. 64 gets all full speed transfers.
246 * Note that even if 0 polling will occur if data equal or greater than the
247 * transfer size is copied to the chip while the transfer is in progress.
248 * Setting SLHCI_WAIT_TIME to -12000 will disable polling.
250 #ifndef SLHCI_WAIT_SIZE
251 #define SLHCI_WAIT_SIZE 8
253 #ifndef SLHCI_WAIT_TIME
254 #define SLHCI_WAIT_TIME (SLHCI_FS_CONST + \
255 SLHCI_FS_DATA_TIME(SLHCI_WAIT_SIZE))
257 const int slhci_wait_time
= SLHCI_WAIT_TIME
;
259 /* Root hub intr endpoint */
260 #define ROOT_INTR_ENDPT 1
262 #ifndef SLHCI_MAX_RETRIES
263 #define SLHCI_MAX_RETRIES 3
266 /* Check IER values for corruption after this many unrecognized interrupts. */
267 #ifndef SLHCI_IER_CHECK_FREQUENCY
269 #define SLHCI_IER_CHECK_FREQUENCY 1
271 #define SLHCI_IER_CHECK_FREQUENCY 100
275 /* Note that buffer points to the start of the buffer for this transfer. */
277 struct usbd_pipe pipe
;
278 struct usbd_xfer
*xfer
; /* xfer in progress */
279 uint8_t *buffer
; /* I/O buffer (if needed) */
280 struct gcq ap
; /* All pipes */
281 struct gcq to
; /* Timeout list */
282 struct gcq xq
; /* Xfer queues */
283 unsigned int pflags
; /* Pipe flags */
284 #define PF_GONE (0x01) /* Pipe is on disabled device */
285 #define PF_TOGGLE (0x02) /* Data toggle status */
286 #define PF_LS (0x04) /* Pipe is low speed */
287 #define PF_PREAMBLE (0x08) /* Needs preamble */
288 Frame to_frame
; /* Frame number for timeout */
289 Frame frame
; /* Frame number for intr xfer */
290 Frame lastframe
; /* Previous frame number for intr */
291 uint16_t bustime
; /* Worst case bus time usage */
292 uint16_t newbustime
[2]; /* new bustimes (see index below) */
293 uint8_t tregs
[4]; /* ADR, LEN, PID, DEV */
294 uint8_t newlen
[2]; /* 0 = short data, 1 = ctrl data */
295 uint8_t newpid
; /* for ctrl */
296 uint8_t wantshort
; /* last xfer must be short */
297 uint8_t control
; /* Host control register settings */
298 uint8_t nerrs
; /* Current number of errors */
299 uint8_t ptype
; /* Pipe type */
302 #if defined(MULTIPROCESSOR) || defined(LOCKDEBUG)
303 #define SLHCI_WAITLOCK 1
306 #ifdef SLHCI_PROFILE_TRANSFER
307 #if defined(__mips__)
308 /* MIPS cycle counter does not directly count cpu cycles but is a different
309 * fraction of cpu cycles depending on the cpu. */
310 typedef u_int32_t cc_type
;
311 #define CC_TYPE_FMT "%u"
312 #define slhci_cc_set(x) __asm volatile ("mfc0 %[cc], $9\n\tnop\n\tnop\n\tnop" \
314 #elif defined(__i386__)
315 typedef u_int64_t cc_type
;
316 #define CC_TYPE_FMT "%llu"
317 #define slhci_cc_set(x) __asm volatile ("rdtsc" : "=A"(x))
319 #error "SLHCI_PROFILE_TRANSFER not implemented on this MACHINE_ARCH (see sys/dev/ic/sl811hs.c)"
321 struct slhci_cc_time
{
324 unsigned int miscdata
;
326 #ifndef SLHCI_N_TIMES
327 #define SLHCI_N_TIMES 200
329 struct slhci_cc_times
{
330 struct slhci_cc_time times
[SLHCI_N_TIMES
];
335 static struct slhci_cc_times t_ab
[2];
336 static struct slhci_cc_times t_abdone
;
337 static struct slhci_cc_times t_copy_to_dev
;
338 static struct slhci_cc_times t_copy_from_dev
;
339 static struct slhci_cc_times t_intr
;
340 static struct slhci_cc_times t_lock
;
341 static struct slhci_cc_times t_delay
;
342 static struct slhci_cc_times t_hard_int
;
343 static struct slhci_cc_times t_callback
;
346 start_cc_time(struct slhci_cc_times
*times
, unsigned int misc
) {
347 times
->times
[times
->current
].miscdata
= misc
;
348 slhci_cc_set(times
->times
[times
->current
].start
);
351 stop_cc_time(struct slhci_cc_times
*times
) {
352 slhci_cc_set(times
->times
[times
->current
].stop
);
353 if (++times
->current
>= SLHCI_N_TIMES
) {
355 times
->wraparound
= 1;
359 void slhci_dump_cc_times(int);
362 slhci_dump_cc_times(int n
) {
363 struct slhci_cc_times
*times
;
369 printf("USBA start transfer to intr:\n");
373 printf("USBB start transfer to intr:\n");
381 printf("copy to device:\n");
382 times
= &t_copy_to_dev
;
385 printf("copy from device:\n");
386 times
= &t_copy_from_dev
;
389 printf("intr to intr:\n");
393 printf("lock to release:\n");
397 printf("delay time:\n");
401 printf("hard interrupt enter to exit:\n");
405 printf("callback:\n");
410 if (times
->wraparound
)
411 for (i
= times
->current
+ 1; i
< SLHCI_N_TIMES
; i
++)
412 printf("start " CC_TYPE_FMT
" stop " CC_TYPE_FMT
413 " difference %8i miscdata %#x\n",
414 times
->times
[i
].start
, times
->times
[i
].stop
,
415 (int)(times
->times
[i
].stop
-
416 times
->times
[i
].start
), times
->times
[i
].miscdata
);
418 for (i
= 0; i
< times
->current
; i
++)
419 printf("start " CC_TYPE_FMT
" stop " CC_TYPE_FMT
420 " difference %8i miscdata %#x\n", times
->times
[i
].start
,
421 times
->times
[i
].stop
, (int)(times
->times
[i
].stop
-
422 times
->times
[i
].start
), times
->times
[i
].miscdata
);
425 #define start_cc_time(x, y)
426 #define stop_cc_time(x)
427 #endif /* SLHCI_PROFILE_TRANSFER */
429 typedef usbd_status (*LockCallFunc
)(struct slhci_softc
*, struct slhci_pipe
430 *, struct usbd_xfer
*);
432 usbd_status
slhci_allocm(struct usbd_bus
*, usb_dma_t
*, u_int32_t
);
433 void slhci_freem(struct usbd_bus
*, usb_dma_t
*);
434 struct usbd_xfer
* slhci_allocx(struct usbd_bus
*);
435 void slhci_freex(struct usbd_bus
*, struct usbd_xfer
*);
437 usbd_status
slhci_transfer(struct usbd_xfer
*);
438 usbd_status
slhci_start(struct usbd_xfer
*);
439 usbd_status
slhci_root_start(struct usbd_xfer
*);
440 usbd_status
slhci_open(struct usbd_pipe
*);
442 /* slhci_supported_rev, slhci_preinit, slhci_attach, slhci_detach,
445 void slhci_abort(struct usbd_xfer
*);
446 void slhci_close(struct usbd_pipe
*);
447 void slhci_clear_toggle(struct usbd_pipe
*);
448 void slhci_poll(struct usbd_bus
*);
449 void slhci_done(struct usbd_xfer
*);
450 void slhci_void(void *);
452 /* lock entry functions */
454 #ifdef SLHCI_MEM_ACCOUNTING
455 void slhci_mem_use(struct usbd_bus
*, int);
458 void slhci_reset_entry(void *);
459 usbd_status
slhci_lock_call(struct slhci_softc
*, LockCallFunc
,
460 struct slhci_pipe
*, struct usbd_xfer
*);
461 void slhci_start_entry(struct slhci_softc
*, struct slhci_pipe
*);
462 void slhci_callback_entry(void *arg
);
463 void slhci_do_callback(struct slhci_softc
*, struct usbd_xfer
*, int *);
467 void slhci_main(struct slhci_softc
*, int *);
469 /* in lock functions */
471 static void slhci_write(struct slhci_softc
*, uint8_t, uint8_t);
472 static uint8_t slhci_read(struct slhci_softc
*, uint8_t);
473 static void slhci_write_multi(struct slhci_softc
*, uint8_t, uint8_t *, int);
474 static void slhci_read_multi(struct slhci_softc
*, uint8_t, uint8_t *, int);
476 static void slhci_waitintr(struct slhci_softc
*, int);
477 static int slhci_dointr(struct slhci_softc
*);
478 static void slhci_abdone(struct slhci_softc
*, int);
479 static void slhci_tstart(struct slhci_softc
*);
480 static void slhci_dotransfer(struct slhci_softc
*);
482 static void slhci_callback(struct slhci_softc
*, int *);
483 static void slhci_enter_xfer(struct slhci_softc
*, struct slhci_pipe
*);
484 #ifdef SLHCI_WAITLOCK
485 static void slhci_enter_xfers(struct slhci_softc
*);
487 static void slhci_queue_timed(struct slhci_softc
*, struct slhci_pipe
*);
488 static void slhci_xfer_timer(struct slhci_softc
*, struct slhci_pipe
*);
490 static void slhci_do_repeat(struct slhci_softc
*, struct usbd_xfer
*);
491 static void slhci_callback_schedule(struct slhci_softc
*);
492 static void slhci_do_callback_schedule(struct slhci_softc
*);
494 void slhci_pollxfer(struct slhci_softc
*, struct usbd_xfer
*, int *); /* XXX */
497 static usbd_status
slhci_do_poll(struct slhci_softc
*, struct slhci_pipe
*,
499 static usbd_status
slhci_lsvh_warn(struct slhci_softc
*, struct slhci_pipe
*,
501 static usbd_status
slhci_isoc_warn(struct slhci_softc
*, struct slhci_pipe
*,
503 static usbd_status
slhci_open_pipe(struct slhci_softc
*, struct slhci_pipe
*,
505 static usbd_status
slhci_close_pipe(struct slhci_softc
*, struct slhci_pipe
*,
507 static usbd_status
slhci_do_abort(struct slhci_softc
*, struct slhci_pipe
*,
509 static usbd_status
slhci_do_attach(struct slhci_softc
*, struct slhci_pipe
*,
511 static usbd_status
slhci_halt(struct slhci_softc
*, struct slhci_pipe
*,
514 static void slhci_intrchange(struct slhci_softc
*, uint8_t);
515 static void slhci_drain(struct slhci_softc
*);
516 static void slhci_reset(struct slhci_softc
*);
517 static int slhci_reserve_bustime(struct slhci_softc
*, struct slhci_pipe
*,
519 static void slhci_insert(struct slhci_softc
*);
521 static usbd_status
slhci_clear_feature(struct slhci_softc
*, unsigned int);
522 static usbd_status
slhci_set_feature(struct slhci_softc
*, unsigned int);
523 static void slhci_get_status(struct slhci_softc
*, usb_port_status_t
*);
524 static usbd_status
slhci_root(struct slhci_softc
*, struct slhci_pipe
*,
528 void slhci_log_buffer(struct usbd_xfer
*);
529 void slhci_log_req(usb_device_request_t
*);
530 void slhci_log_req_hub(usb_device_request_t
*);
531 void slhci_log_dumpreg(void);
532 void slhci_log_xfer(struct usbd_xfer
*);
533 void slhci_log_spipe(struct slhci_pipe
*);
534 void slhci_print_intr(void);
535 void slhci_log_sc(void);
536 void slhci_log_slreq(struct slhci_pipe
*);
540 /* Constified so you can read the values from ddb */
541 const int SLHCI_D_TRACE
= 0x0001;
542 const int SLHCI_D_MSG
= 0x0002;
543 const int SLHCI_D_XFER
= 0x0004;
544 const int SLHCI_D_MEM
= 0x0008;
545 const int SLHCI_D_INTR
= 0x0010;
546 const int SLHCI_D_SXFER
= 0x0020;
547 const int SLHCI_D_ERR
= 0x0080;
548 const int SLHCI_D_BUF
= 0x0100;
549 const int SLHCI_D_SOFT
= 0x0200;
550 const int SLHCI_D_WAIT
= 0x0400;
551 const int SLHCI_D_ROOT
= 0x0800;
552 /* SOF/NAK alone normally ignored, SOF also needs D_INTR */
553 const int SLHCI_D_SOF
= 0x1000;
554 const int SLHCI_D_NAK
= 0x2000;
556 int slhci_debug
= 0x1cbc; /* 0xc8c; */ /* 0xffff; */ /* 0xd8c; */
557 struct slhci_softc
*ssc
;
559 int slhci_usbdebug
= -1; /* value to set usbdebug on attach, -1 = leave alone */
562 /* Add UVMHIST history for debugging:
564 * Before uvm_hist in sys/uvm/uvm_stat.c add:
565 * UVMHIST_DECL(slhcihist);
568 * if ((bitmask & UVMHIST_SLHCI))
569 * hists[i++] = &slhcihist;
571 * In sys/uvm/uvm_stat.h add UVMHIST_SLHCI define.
574 #include <uvm/uvm_stat.h>
575 UVMHIST_DECL(slhcihist
);
577 #if !defined(UVMHIST) || !defined(UVMHIST_SLHCI)
578 #error "SLHCI_DEBUG requires UVMHIST (with modifications, see sys/dev/ic/sl81hs.c)"
582 #define SLHCI_NHIST 409600
584 const unsigned int SLHCI_HISTMASK
= UVMHIST_SLHCI
;
585 struct uvm_history_ent slhci_he
[SLHCI_NHIST
];
587 #define SLHCI_DEXEC(x, y) do { if ((slhci_debug & SLHCI_ ## x)) { y; } \
588 } while (/*CONSTCOND*/ 0)
589 #define DDOLOG(f, a, b, c, d) do { const char *_uvmhist_name = __func__; \
590 u_long _uvmhist_call = 0; UVMHIST_LOG(slhcihist, f, a, b, c, d); \
591 } while (/*CONSTCOND*/0)
592 #define DLOG(x, f, a, b, c, d) SLHCI_DEXEC(x, DDOLOG(f, a, b, c, d))
593 /* DLOGFLAG8 is a macro not a function so that flag name expressions are not
594 * evaluated unless the flag bit is set (which could save a register read).
595 * x is debug mask, y is flag identifier, z is flag variable,
596 * a-h are flag names (must evaluate to string constants, msb first). */
597 #define DDOLOGFLAG8(y, z, a, b, c, d, e, f, g, h) do { uint8_t _DLF8 = (z); \
598 const char *_uvmhist_name = __func__; u_long _uvmhist_call = 0; \
599 if (_DLF8 & 0xf0) UVMHIST_LOG(slhcihist, y " %s %s %s %s", _DLF8 & 0x80 ? \
600 (a) : "", _DLF8 & 0x40 ? (b) : "", _DLF8 & 0x20 ? (c) : "", _DLF8 & 0x10 ? \
601 (d) : ""); if (_DLF8 & 0x0f) UVMHIST_LOG(slhcihist, y " %s %s %s %s", \
602 _DLF8 & 0x08 ? (e) : "", _DLF8 & 0x04 ? (f) : "", _DLF8 & 0x02 ? (g) : "", \
603 _DLF8 & 0x01 ? (h) : ""); \
604 } while (/*CONSTCOND*/ 0)
605 #define DLOGFLAG8(x, y, z, a, b, c, d, e, f, g, h) \
606 SLHCI_DEXEC(x, DDOLOGFLAG8(y, z, a, b, c, d, e, f, g, h))
607 /* DDOLOGBUF logs a buffer up to 8 bytes at a time. No identifier so that we
608 * can make it a real function. */
610 DDOLOGBUF(uint8_t *buf
, unsigned int length
)
614 for(i
=0; i
+8 <= length
; i
+=8)
615 DDOLOG("%.4x %.4x %.4x %.4x", (buf
[i
] << 8) | buf
[i
+1],
616 (buf
[i
+2] << 8) | buf
[i
+3], (buf
[i
+4] << 8) | buf
[i
+5],
617 (buf
[i
+6] << 8) | buf
[i
+7]);
619 DDOLOG("%.4x %.4x %.4x %.2x", (buf
[i
] << 8) | buf
[i
+1],
620 (buf
[i
+2] << 8) | buf
[i
+3], (buf
[i
+4] << 8) | buf
[i
+5],
622 else if (length
== i
+6)
623 DDOLOG("%.4x %.4x %.4x", (buf
[i
] << 8) | buf
[i
+1],
624 (buf
[i
+2] << 8) | buf
[i
+3], (buf
[i
+4] << 8) | buf
[i
+5], 0);
625 else if (length
== i
+5)
626 DDOLOG("%.4x %.4x %.2x", (buf
[i
] << 8) | buf
[i
+1],
627 (buf
[i
+2] << 8) | buf
[i
+3], buf
[i
+4], 0);
628 else if (length
== i
+4)
629 DDOLOG("%.4x %.4x", (buf
[i
] << 8) | buf
[i
+1],
630 (buf
[i
+2] << 8) | buf
[i
+3], 0,0);
631 else if (length
== i
+3)
632 DDOLOG("%.4x %.2x", (buf
[i
] << 8) | buf
[i
+1], buf
[i
+2], 0,0);
633 else if (length
== i
+2)
634 DDOLOG("%.4x", (buf
[i
] << 8) | buf
[i
+1], 0,0,0);
635 else if (length
== i
+1)
636 DDOLOG("%.2x", buf
[i
], 0,0,0);
638 #define DLOGBUF(x, b, l) SLHCI_DEXEC(x, DDOLOGBUF(b, l))
639 #else /* now !SLHCI_DEBUG */
640 #define slhci_log_spipe(spipe) ((void)0)
641 #define slhci_log_xfer(xfer) ((void)0)
642 #define SLHCI_DEXEC(x, y) ((void)0)
643 #define DDOLOG(f, a, b, c, d) ((void)0)
644 #define DLOG(x, f, a, b, c, d) ((void)0)
645 #define DDOLOGFLAG8(y, z, a, b, c, d, e, f, g, h) ((void)0)
646 #define DLOGFLAG8(x, y, z, a, b, c, d, e, f, g, h) ((void)0)
647 #define DDOLOGBUF(b, l) ((void)0)
648 #define DLOGBUF(x, b, l) ((void)0)
649 #endif /* SLHCI_DEBUG */
651 #define SLHCI_MAINLOCKASSERT(sc) ((void)0)
652 #define SLHCI_LOCKASSERT(sc, main, wait) ((void)0)
655 #define LK_SLASSERT(exp, sc, spipe, xfer, ext) do { \
657 printf("%s: assertion %s failed line %u function %s!" \
658 " halted\n", SC_NAME(sc), #exp, __LINE__, __func__);\
659 DDOLOG("%s: assertion %s failed line %u function %s!" \
660 " halted\n", SC_NAME(sc), #exp, __LINE__, __func__);\
661 slhci_halt(sc, spipe, xfer); \
664 } while (/*CONSTCOND*/0)
665 #define UL_SLASSERT(exp, sc, spipe, xfer, ext) do { \
667 printf("%s: assertion %s failed line %u function %s!" \
668 " halted\n", SC_NAME(sc), #exp, __LINE__, __func__); \
669 DDOLOG("%s: assertion %s failed line %u function %s!" \
670 " halted\n", SC_NAME(sc), #exp, __LINE__, __func__); \
671 slhci_lock_call(sc, &slhci_halt, spipe, xfer); \
674 } while (/*CONSTCOND*/0)
676 #define LK_SLASSERT(exp, sc, spipe, xfer, ext) ((void)0)
677 #define UL_SLASSERT(exp, sc, spipe, xfer, ext) ((void)0)
680 const struct usbd_bus_methods slhci_bus_methods
= {
690 const struct usbd_pipe_methods slhci_pipe_methods
= {
699 const struct usbd_pipe_methods slhci_root_methods
= {
703 (void (*)(struct usbd_pipe
*))slhci_void
, /* XXX safe? */
710 #define GOT_FIRST_TO(tvar, t) \
711 GCQ_GOT_FIRST_TYPED(tvar, &(t)->to, struct slhci_pipe, to)
713 #define FIND_TO(var, t, tvar, cond) \
714 GCQ_FIND_TYPED(var, &(t)->to, tvar, struct slhci_pipe, to, cond)
716 #define FOREACH_AP(var, t, tvar) \
717 GCQ_FOREACH_TYPED(var, &(t)->ap, tvar, struct slhci_pipe, ap)
719 #define GOT_FIRST_TIMED_COND(tvar, t, cond) \
720 GCQ_GOT_FIRST_COND_TYPED(tvar, &(t)->timed, struct slhci_pipe, xq, cond)
722 #define GOT_FIRST_CB(tvar, t) \
723 GCQ_GOT_FIRST_TYPED(tvar, &(t)->q[Q_CB], struct slhci_pipe, xq)
725 #define DEQUEUED_CALLBACK(tvar, t) \
726 GCQ_DEQUEUED_FIRST_TYPED(tvar, &(t)->q[Q_CALLBACKS], struct slhci_pipe, xq)
728 #define FIND_TIMED(var, t, tvar, cond) \
729 GCQ_FIND_TYPED(var, &(t)->timed, tvar, struct slhci_pipe, xq, cond)
731 #ifdef SLHCI_WAITLOCK
732 #define DEQUEUED_WAITQ(tvar, sc) \
733 GCQ_DEQUEUED_FIRST_TYPED(tvar, &(sc)->sc_waitq, struct slhci_pipe, xq)
736 enter_waitq(struct slhci_softc
*sc
, struct slhci_pipe
*spipe
)
738 gcq_insert_tail(&sc
->sc_waitq
, &spipe
->xq
);
743 enter_q(struct slhci_transfers
*t
, struct slhci_pipe
*spipe
, int i
)
745 gcq_insert_tail(&t
->q
[i
], &spipe
->xq
);
749 enter_callback(struct slhci_transfers
*t
, struct slhci_pipe
*spipe
)
751 gcq_insert_tail(&t
->q
[Q_CALLBACKS
], &spipe
->xq
);
755 enter_all_pipes(struct slhci_transfers
*t
, struct slhci_pipe
*spipe
)
757 gcq_insert_tail(&t
->ap
, &spipe
->ap
);
760 /* Start out of lock functions. */
763 usb_dma_block_t block
;
767 /* The SL811HS does not do DMA as a host controller, but NetBSD's USB interface
768 * assumes DMA is used. So we fake the DMA block. */
770 slhci_allocm(struct usbd_bus
*bus
, usb_dma_t
*dma
, u_int32_t size
)
772 struct slhci_mem
*mem
;
774 mem
= malloc(sizeof(struct slhci_mem
) + size
, M_USB
, M_NOWAIT
|M_ZERO
);
776 DLOG(D_MEM
, "allocm %p", mem
, 0,0,0);
781 dma
->block
= &mem
->block
;
782 dma
->block
->kaddr
= mem
->data
;
785 dma
->block
->nsegs
= 1;
786 dma
->block
->size
= size
;
787 dma
->block
->align
= size
;
788 dma
->block
->flags
|= USB_DMA_FULLBLOCK
;
790 #ifdef SLHCI_MEM_ACCOUNTING
791 slhci_mem_use(bus
, 1);
794 return USBD_NORMAL_COMPLETION
;
798 slhci_freem(struct usbd_bus
*bus
, usb_dma_t
*dma
)
800 DLOG(D_MEM
, "freem %p", dma
->block
, 0,0,0);
802 #ifdef SLHCI_MEM_ACCOUNTING
803 slhci_mem_use(bus
, -1);
806 free(dma
->block
, M_USB
);
810 slhci_allocx(struct usbd_bus
*bus
)
812 struct usbd_xfer
*xfer
;
814 xfer
= malloc(sizeof(*xfer
), M_USB
, M_NOWAIT
|M_ZERO
);
816 DLOG(D_MEM
, "allocx %p", xfer
, 0,0,0);
818 #ifdef SLHCI_MEM_ACCOUNTING
819 slhci_mem_use(bus
, 1);
823 xfer
->busy_free
= XFER_BUSY
;
829 slhci_freex(struct usbd_bus
*bus
, struct usbd_xfer
*xfer
)
831 DLOG(D_MEM
, "freex xfer %p spipe %p", xfer
, xfer
->pipe
,0,0);
833 #ifdef SLHCI_MEM_ACCOUNTING
834 slhci_mem_use(bus
, -1);
837 if (xfer
->busy_free
!= XFER_BUSY
) {
838 struct slhci_softc
*sc
= bus
->hci_private
;
839 printf("%s: slhci_freex: xfer=%p not busy, %#08x halted\n",
840 SC_NAME(sc
), xfer
, xfer
->busy_free
);
841 DDOLOG("%s: slhci_freex: xfer=%p not busy, %#08x halted\n",
842 SC_NAME(sc
), xfer
, xfer
->busy_free
, 0);
843 slhci_lock_call(sc
, &slhci_halt
, NULL
, NULL
);
846 xfer
->busy_free
= XFER_FREE
;
853 slhci_transfer(struct usbd_xfer
*xfer
)
858 DLOG(D_TRACE
, "%s transfer xfer %p spipe %p ",
859 pnames(SLHCI_XFER_TYPE(xfer
)), xfer
, xfer
->pipe
,0);
861 /* Insert last in queue */
862 error
= usb_insert_transfer(xfer
);
864 if (error
!= USBD_IN_PROGRESS
)
865 DLOG(D_ERR
, "usb_insert_transfer returns %d!", error
,
871 * Pipe isn't running (otherwise error would be USBD_INPROG),
875 /* Start next is always done at splsoftusb, so we do this here so
876 * start functions are always called at softusb. XXX */
878 error
= xfer
->pipe
->methods
->start(SIMPLEQ_FIRST(&xfer
->pipe
->queue
));
884 /* It is not safe for start to return anything other than USBD_INPROG. */
886 slhci_start(struct usbd_xfer
*xfer
)
888 struct slhci_softc
*sc
;
889 struct usbd_pipe
*pipe
;
890 struct slhci_pipe
*spipe
;
891 struct slhci_transfers
*t
;
892 usb_endpoint_descriptor_t
*ed
;
893 unsigned int max_packet
;
896 sc
= pipe
->device
->bus
->hci_private
;
897 spipe
= (struct slhci_pipe
*)xfer
->pipe
;
898 t
= &sc
->sc_transfers
;
899 ed
= pipe
->endpoint
->edesc
;
901 max_packet
= UGETW(ed
->wMaxPacketSize
);
903 DLOG(D_TRACE
, "%s start xfer %p spipe %p length %d",
904 pnames(spipe
->ptype
), xfer
, spipe
, xfer
->length
);
906 /* root transfers use slhci_root_start */
908 KASSERT(spipe
->xfer
== NULL
); /* not SLASSERT */
911 xfer
->status
= USBD_IN_PROGRESS
;
916 spipe
->frame
= t
->frame
;
917 spipe
->control
= SL11_EPCTRL_ARM_ENABLE
;
918 spipe
->tregs
[DEV
] = pipe
->device
->address
;
919 spipe
->tregs
[PID
] = spipe
->newpid
= UE_GET_ADDR(ed
->bEndpointAddress
)
920 | (UE_GET_DIR(ed
->bEndpointAddress
) == UE_DIR_IN
? SL11_PID_IN
:
922 spipe
->newlen
[0] = xfer
->length
% max_packet
;
923 spipe
->newlen
[1] = min(xfer
->length
, max_packet
);
925 if (spipe
->ptype
== PT_BULK
|| spipe
->ptype
== PT_INTR
) {
926 if (spipe
->pflags
& PF_TOGGLE
)
927 spipe
->control
|= SL11_EPCTRL_DATATOGGLE
;
928 spipe
->tregs
[LEN
] = spipe
->newlen
[1];
929 if (spipe
->tregs
[LEN
])
930 spipe
->buffer
= KERNADDR(&xfer
->dmabuf
, 0);
932 spipe
->buffer
= NULL
;
933 spipe
->lastframe
= t
->frame
;
934 #if defined(DEBUG) || defined(SLHCI_DEBUG)
935 if (__predict_false(spipe
->ptype
== PT_INTR
&&
936 xfer
->length
> spipe
->tregs
[LEN
])) {
937 printf("%s: Long INTR transfer not supported!\n",
939 DDOLOG("%s: Long INTR transfer not supported!\n",
941 xfer
->status
= USBD_INVAL
;
945 /* ptype may be currently set to any control transfer type. */
946 SLHCI_DEXEC(D_TRACE
, slhci_log_xfer(xfer
));
948 /* SETUP contains IN/OUT bits also */
949 spipe
->tregs
[PID
] |= SL11_PID_SETUP
;
950 spipe
->tregs
[LEN
] = 8;
951 spipe
->buffer
= (uint8_t *)&xfer
->request
;
952 DLOGBUF(D_XFER
, spipe
->buffer
, spipe
->tregs
[LEN
]);
953 spipe
->ptype
= PT_CTRL_SETUP
;
954 spipe
->newpid
&= ~SL11_PID_BITS
;
955 if (xfer
->length
== 0 || (xfer
->request
.bmRequestType
&
957 spipe
->newpid
|= SL11_PID_IN
;
959 spipe
->newpid
|= SL11_PID_OUT
;
962 if (xfer
->flags
& USBD_FORCE_SHORT_XFER
&& spipe
->tregs
[LEN
] ==
963 max_packet
&& (spipe
->newpid
& SL11_PID_BITS
) == SL11_PID_OUT
)
964 spipe
->wantshort
= 1;
966 spipe
->wantshort
= 0;
968 /* The goal of newbustime and newlen is to avoid bustime calculation
969 * in the interrupt. The calculations are not too complex, but they
970 * complicate the conditional logic somewhat and doing them all in the
971 * same place shares constants. Index 0 is "short length" for bulk and
972 * ctrl data and 1 is "full length" for ctrl data (bulk/intr are
973 * already set to full length). */
974 if (spipe
->pflags
& PF_LS
) {
975 /* Setting PREAMBLE for directly connnected LS devices will
976 * lock up the chip. */
977 if (spipe
->pflags
& PF_PREAMBLE
)
978 spipe
->control
|= SL11_EPCTRL_PREAMBLE
;
979 if (max_packet
<= 8) {
980 spipe
->bustime
= SLHCI_LS_CONST
+
981 SLHCI_LS_DATA_TIME(spipe
->tregs
[LEN
]);
982 spipe
->newbustime
[0] = SLHCI_LS_CONST
+
983 SLHCI_LS_DATA_TIME(spipe
->newlen
[0]);
984 spipe
->newbustime
[1] = SLHCI_LS_CONST
+
985 SLHCI_LS_DATA_TIME(spipe
->newlen
[1]);
987 xfer
->status
= USBD_INVAL
;
989 UL_SLASSERT(pipe
->device
->speed
== USB_SPEED_FULL
, sc
,
990 spipe
, xfer
, return USBD_IN_PROGRESS
);
991 if (max_packet
<= SL11_MAX_PACKET_SIZE
) {
992 spipe
->bustime
= SLHCI_FS_CONST
+
993 SLHCI_FS_DATA_TIME(spipe
->tregs
[LEN
]);
994 spipe
->newbustime
[0] = SLHCI_FS_CONST
+
995 SLHCI_FS_DATA_TIME(spipe
->newlen
[0]);
996 spipe
->newbustime
[1] = SLHCI_FS_CONST
+
997 SLHCI_FS_DATA_TIME(spipe
->newlen
[1]);
999 xfer
->status
= USBD_INVAL
;
1002 /* The datasheet incorrectly indicates that DIRECTION is for
1003 * "transmit to host". It is for OUT and SETUP. The app note
1004 * describes its use correctly. */
1005 if ((spipe
->tregs
[PID
] & SL11_PID_BITS
) != SL11_PID_IN
)
1006 spipe
->control
|= SL11_EPCTRL_DIRECTION
;
1008 slhci_start_entry(sc
, spipe
);
1010 return USBD_IN_PROGRESS
;
1014 slhci_root_start(struct usbd_xfer
*xfer
)
1016 struct slhci_softc
*sc
;
1017 struct slhci_pipe
*spipe
;
1019 spipe
= (struct slhci_pipe
*)xfer
->pipe
;
1020 sc
= xfer
->pipe
->device
->bus
->hci_private
;
1022 return slhci_lock_call(sc
, &slhci_root
, spipe
, xfer
);
1026 slhci_open(struct usbd_pipe
*pipe
)
1028 struct usbd_device
*dev
;
1029 struct slhci_softc
*sc
;
1030 struct slhci_pipe
*spipe
;
1031 usb_endpoint_descriptor_t
*ed
;
1032 struct slhci_transfers
*t
;
1033 unsigned int max_packet
, pmaxpkt
;
1036 sc
= dev
->bus
->hci_private
;
1037 spipe
= (struct slhci_pipe
*)pipe
;
1038 ed
= pipe
->endpoint
->edesc
;
1039 t
= &sc
->sc_transfers
;
1041 DLOG(D_TRACE
, "slhci_open(addr=%d,ep=%d,rootaddr=%d)",
1042 dev
->address
, ed
->bEndpointAddress
, t
->rootaddr
, 0);
1046 spipe
->lastframe
= 0;
1048 spipe
->buffer
= NULL
;
1050 gcq_init(&spipe
->ap
);
1051 gcq_init(&spipe
->to
);
1052 gcq_init(&spipe
->xq
);
1054 /* The endpoint descriptor will not have been set up yet in the case
1055 * of the standard control pipe, so the max packet checks are also
1056 * necessary in start. */
1058 max_packet
= UGETW(ed
->wMaxPacketSize
);
1060 if (dev
->speed
== USB_SPEED_LOW
) {
1061 spipe
->pflags
|= PF_LS
;
1062 if (dev
->myhub
->address
!= t
->rootaddr
) {
1063 spipe
->pflags
|= PF_PREAMBLE
;
1064 if (!slhci_try_lsvh
)
1065 return slhci_lock_call(sc
, &slhci_lsvh_warn
,
1070 pmaxpkt
= SL11_MAX_PACKET_SIZE
;
1072 if (max_packet
> pmaxpkt
) {
1073 DLOG(D_ERR
, "packet too large! size %d spipe %p", max_packet
,
1078 if (dev
->address
== t
->rootaddr
) {
1079 switch (ed
->bEndpointAddress
) {
1080 case USB_CONTROL_ENDPOINT
:
1081 spipe
->ptype
= PT_ROOT_CTRL
;
1084 case UE_DIR_IN
| ROOT_INTR_ENDPT
:
1085 spipe
->ptype
= PT_ROOT_INTR
;
1089 printf("%s: Invalid root endpoint!\n", SC_NAME(sc
));
1090 DDOLOG("%s: Invalid root endpoint!\n", SC_NAME(sc
),
1094 pipe
->methods
= __UNCONST(&slhci_root_methods
);
1095 return USBD_NORMAL_COMPLETION
;
1097 switch (ed
->bmAttributes
& UE_XFERTYPE
) {
1099 spipe
->ptype
= PT_CTRL_SETUP
;
1103 spipe
->ptype
= PT_INTR
;
1104 if (pipe
->interval
== USBD_DEFAULT_INTERVAL
)
1105 pipe
->interval
= ed
->bInterval
;
1107 case UE_ISOCHRONOUS
:
1108 return slhci_lock_call(sc
, &slhci_isoc_warn
, spipe
,
1111 spipe
->ptype
= PT_BULK
;
1116 DLOG(D_MSG
, "open pipe %s interval %d", pnames(spipe
->ptype
),
1117 pipe
->interval
, 0,0);
1119 pipe
->methods
= __UNCONST(&slhci_pipe_methods
);
1121 return slhci_lock_call(sc
, &slhci_open_pipe
, spipe
, NULL
);
1126 slhci_supported_rev(uint8_t rev
)
1128 return (rev
>= SLTYPE_SL811HS_R12
&& rev
<= SLTYPE_SL811HS_R15
);
1131 /* Must be called before the ISR is registered. Interrupts can be shared so
1132 * slhci_intr could be called as soon as the ISR is registered.
1133 * Note max_current argument is actual current, but stored as current/2 */
1135 slhci_preinit(struct slhci_softc
*sc
, PowerFunc pow
, bus_space_tag_t iot
,
1136 bus_space_handle_t ioh
, uint16_t max_current
, uint8_t stride
)
1138 struct slhci_transfers
*t
;
1141 t
= &sc
->sc_transfers
;
1144 UVMHIST_INIT_STATIC(slhcihist
, slhci_he
);
1146 simple_lock_init(&sc
->sc_lock
);
1147 #ifdef SLHCI_WAITLOCK
1148 simple_lock_init(&sc
->sc_wait_lock
);
1150 /* sc->sc_ier = 0; */
1151 /* t->rootintr = NULL; */
1152 t
->flags
= F_NODEV
|F_UDISABLED
;
1154 KASSERT(slhci_wait_time
!= INT_MAX
);
1155 t
->len
[0] = t
->len
[1] = -1;
1156 if (max_current
> 500)
1158 t
->max_current
= (uint8_t)(max_current
/ 2);
1159 sc
->sc_enable_power
= pow
;
1162 sc
->sc_stride
= stride
;
1164 KASSERT(Q_MAX
+1 == sizeof(t
->q
) / sizeof(t
->q
[0]));
1166 for (i
= 0; i
<= Q_MAX
; i
++)
1167 gcq_init_head(&t
->q
[i
]);
1168 gcq_init_head(&t
->timed
);
1169 gcq_init_head(&t
->to
);
1170 gcq_init_head(&t
->ap
);
1171 #ifdef SLHCI_WAITLOCK
1172 gcq_init_head(&sc
->sc_waitq
);
1177 slhci_attach(struct slhci_softc
*sc
)
1179 if (slhci_lock_call(sc
, &slhci_do_attach
, NULL
, NULL
) !=
1180 USBD_NORMAL_COMPLETION
)
1183 /* Attach usb and uhub. */
1184 sc
->sc_child
= config_found(SC_DEV(sc
), &sc
->sc_bus
, usbctlprint
);
1193 slhci_detach(struct slhci_softc
*sc
, int flags
)
1195 struct slhci_transfers
*t
;
1198 t
= &sc
->sc_transfers
;
1200 /* By this point bus access is no longer allowed. */
1202 KASSERT(!(t
->flags
& F_ACTIVE
));
1204 /* To be MPSAFE is not sufficient to cancel callouts and soft
1205 * interrupts and assume they are dead since the code could already be
1206 * running or about to run. Wait until they are known to be done. */
1207 while (t
->flags
& (F_RESET
|F_CALLBACK
))
1208 tsleep(&sc
, PPAUSE
, "slhci_detach", hz
);
1210 softint_disestablish(sc
->sc_cb_softintr
);
1215 ret
= config_detach(sc
->sc_child
, flags
);
1217 #ifdef SLHCI_MEM_ACCOUNTING
1218 if (sc
->sc_mem_use
) {
1219 printf("%s: Memory still in use after detach! mem_use (count)"
1220 " = %d\n", SC_NAME(sc
), sc
->sc_mem_use
);
1221 DDOLOG("%s: Memory still in use after detach! mem_use (count)"
1222 " = %d\n", SC_NAME(sc
), sc
->sc_mem_use
, 0,0);
1230 slhci_activate(device_t self
, enum devact act
)
1232 struct slhci_softc
*sc
= device_private(self
);
1235 case DVACT_DEACTIVATE
:
1236 slhci_lock_call(sc
, &slhci_halt
, NULL
, NULL
);
1244 slhci_abort(struct usbd_xfer
*xfer
)
1246 struct slhci_softc
*sc
;
1247 struct slhci_pipe
*spipe
;
1249 spipe
= (struct slhci_pipe
*)xfer
->pipe
;
1254 sc
= spipe
->pipe
.device
->bus
->hci_private
;
1256 DLOG(D_TRACE
, "%s abort xfer %p spipe %p spipe->xfer %p",
1257 pnames(spipe
->ptype
), xfer
, spipe
, spipe
->xfer
);
1259 slhci_lock_call(sc
, &slhci_do_abort
, spipe
, xfer
);
1262 xfer
->status
= USBD_CANCELLED
;
1263 /* Abort happens at splsoftusb. */
1264 usb_transfer_complete(xfer
);
1268 slhci_close(struct usbd_pipe
*pipe
)
1270 struct slhci_softc
*sc
;
1271 struct slhci_pipe
*spipe
;
1272 struct slhci_transfers
*t
;
1274 sc
= pipe
->device
->bus
->hci_private
;
1275 spipe
= (struct slhci_pipe
*)pipe
;
1276 t
= &sc
->sc_transfers
;
1278 DLOG(D_TRACE
, "%s close spipe %p spipe->xfer %p",
1279 pnames(spipe
->ptype
), spipe
, spipe
->xfer
, 0);
1281 slhci_lock_call(sc
, &slhci_close_pipe
, spipe
, NULL
);
1285 slhci_clear_toggle(struct usbd_pipe
*pipe
)
1287 struct slhci_pipe
*spipe
;
1289 spipe
= (struct slhci_pipe
*)pipe
;
1291 DLOG(D_TRACE
, "%s toggle spipe %p", pnames(spipe
->ptype
),
1294 spipe
->pflags
&= ~PF_TOGGLE
;
1297 if (spipe
->xfer
!= NULL
) {
1298 struct slhci_softc
*sc
= (struct slhci_softc
1299 *)pipe
->device
->bus
;
1301 printf("%s: Clear toggle on transfer in progress! halted\n",
1303 DDOLOG("%s: Clear toggle on transfer in progress! halted\n",
1304 SC_NAME(sc
), 0,0,0);
1305 slhci_halt(sc
, NULL
, NULL
);
1311 slhci_poll(struct usbd_bus
*bus
) /* XXX necessary? */
1313 struct slhci_softc
*sc
;
1315 sc
= bus
->hci_private
;
1317 DLOG(D_TRACE
, "slhci_poll", 0,0,0,0);
1319 slhci_lock_call(sc
, &slhci_do_poll
, NULL
, NULL
);
1323 slhci_done(struct usbd_xfer
*xfer
)
1325 /* xfer may not be valid here */
1329 slhci_void(void *v
) {}
1331 /* End out of lock functions. Start lock entry functions. */
1333 #ifdef SLHCI_MEM_ACCOUNTING
1335 slhci_mem_use(struct usbd_bus
*bus
, int val
)
1337 struct slhci_softc
*sc
= bus
->hci_private
;
1341 simple_lock(&sc
->sc_wait_lock
);
1342 sc
->sc_mem_use
+= val
;
1343 simple_unlock(&sc
->sc_wait_lock
);
1349 slhci_reset_entry(void *arg
)
1351 struct slhci_softc
*sc
;
1354 sc
= (struct slhci_softc
*)arg
;
1357 simple_lock(&sc
->sc_lock
);
1359 /* We cannot call the calback directly since we could then be reset
1360 * again before finishing and need the callout delay for timing.
1361 * Scheduling the callout again before we exit would defeat the reap
1362 * mechanism since we could be unlocked while the reset flag is not
1363 * set. The callback code will check the wait queue. */
1364 slhci_callback_schedule(sc
);
1365 simple_unlock(&sc
->sc_lock
);
1370 slhci_lock_call(struct slhci_softc
*sc
, LockCallFunc lcf
, struct slhci_pipe
1371 *spipe
, struct usbd_xfer
*xfer
)
1378 simple_lock(&sc
->sc_lock
);
1379 ret
= (*lcf
)(sc
, spipe
, xfer
);
1388 slhci_start_entry(struct slhci_softc
*sc
, struct slhci_pipe
*spipe
)
1390 struct slhci_transfers
*t
;
1393 t
= &sc
->sc_transfers
;
1396 #ifdef SLHCI_WAITLOCK
1397 if (simple_lock_try(&sc
->sc_lock
))
1399 simple_lock(&sc
->sc_lock
);
1402 slhci_enter_xfer(sc
, spipe
);
1403 slhci_dotransfer(sc
);
1405 #ifdef SLHCI_WAITLOCK
1407 simple_lock(&sc
->sc_wait_lock
);
1408 enter_waitq(sc
, spipe
);
1409 simple_unlock(&sc
->sc_wait_lock
);
1416 slhci_callback_entry(void *arg
)
1418 struct slhci_softc
*sc
;
1419 struct slhci_transfers
*t
;
1423 sc
= (struct slhci_softc
*)arg
;
1427 simple_lock(&sc
->sc_lock
);
1428 t
= &sc
->sc_transfers
;
1429 DLOG(D_SOFT
, "callback_entry flags %#x", t
->flags
, 0,0,0);
1431 #ifdef SLHCI_WAITLOCK
1434 slhci_callback(sc
, &s
);
1436 #ifdef SLHCI_WAITLOCK
1437 simple_lock(&sc
->sc_wait_lock
);
1438 if (!gcq_empty(&sc
->sc_waitq
)) {
1439 slhci_enter_xfers(sc
);
1440 simple_unlock(&sc
->sc_wait_lock
);
1441 slhci_dotransfer(sc
);
1442 slhci_waitintr(sc
, 0);
1446 t
->flags
&= ~F_CALLBACK
;
1447 simple_unlock(&sc
->sc_lock
);
1448 simple_unlock(&sc
->sc_wait_lock
);
1450 t
->flags
&= ~F_CALLBACK
;
1451 simple_unlock(&sc
->sc_lock
);
1458 slhci_do_callback(struct slhci_softc
*sc
, struct usbd_xfer
*xfer
, int *s
)
1460 SLHCI_LOCKASSERT(sc
, locked
, unlocked
);
1464 sc
->sc_bus
.intr_context
++;
1465 start_cc_time(&t_callback
, (u_int
)xfer
);
1466 simple_unlock(&sc
->sc_lock
);
1469 repeat
= xfer
->pipe
->repeat
;
1471 usb_transfer_complete(xfer
);
1474 simple_lock(&sc
->sc_lock
);
1475 stop_cc_time(&t_callback
);
1476 sc
->sc_bus
.intr_context
--;
1478 if (repeat
&& !sc
->sc_bus
.use_polling
)
1479 slhci_do_repeat(sc
, xfer
);
1483 slhci_intr(void *arg
)
1485 struct slhci_softc
*sc
;
1488 sc
= (struct slhci_softc
*)arg
;
1490 start_cc_time(&t_hard_int
, (unsigned int)arg
);
1491 simple_lock(&sc
->sc_lock
);
1493 ret
= slhci_dointr(sc
);
1494 slhci_main(sc
, NULL
);
1496 stop_cc_time(&t_hard_int
);
1500 /* called with main lock only held, returns with locks released. */
1502 slhci_main(struct slhci_softc
*sc
, int *s
)
1504 struct slhci_transfers
*t
;
1506 t
= &sc
->sc_transfers
;
1508 SLHCI_LOCKASSERT(sc
, locked
, unlocked
);
1510 #ifdef SLHCI_WAITLOCK
1513 slhci_waitintr(sc
, slhci_wait_time
);
1517 * XXX Directly calling the callback anytime s != NULL
1518 * causes panic:sbdrop with aue (simultaneously using umass).
1519 * Doing that affects process accounting, but is supposed to work as
1520 * far as I can tell.
1522 * The direct call is needed in the use_polling and disabled cases
1523 * since the soft interrupt is not available. In the disabled case,
1524 * this code can be reached from the usb detach, after the reaping of
1525 * the soft interrupt. That test could be !F_ACTIVE (in which case
1526 * s != NULL could be an assertion), but there is no reason not to
1527 * make the callbacks directly in the other DISABLED cases.
1529 if ((t
->flags
& F_ROOTINTR
) || !gcq_empty(&t
->q
[Q_CALLBACKS
])) {
1530 if (__predict_false(sc
->sc_bus
.use_polling
|| t
->flags
&
1531 F_DISABLED
) && s
!= NULL
)
1532 slhci_callback(sc
, s
);
1534 slhci_callback_schedule(sc
);
1537 #ifdef SLHCI_WAITLOCK
1538 simple_lock(&sc
->sc_wait_lock
);
1540 if (!gcq_empty(&sc
->sc_waitq
)) {
1541 slhci_enter_xfers(sc
);
1542 simple_unlock(&sc
->sc_wait_lock
);
1543 slhci_dotransfer(sc
);
1547 simple_unlock(&sc
->sc_lock
);
1548 simple_unlock(&sc
->sc_wait_lock
);
1550 simple_unlock(&sc
->sc_lock
);
1554 /* End lock entry functions. Start in lock function. */
1556 /* Register read/write routines and barriers. */
1557 #ifdef SLHCI_BUS_SPACE_BARRIERS
1558 #define BSB(a, b, c, d, e) bus_space_barrier(a, b, c, d, BUS_SPACE_BARRIER_ # e)
1559 #define BSB_SYNC(a, b, c, d) bus_space_barrier(a, b, c, d, BUS_SPACE_BARRIER_SYNC)
1560 #else /* now !SLHCI_BUS_SPACE_BARRIERS */
1561 #define BSB(a, b, c, d, e)
1562 #define BSB_SYNC(a, b, c, d)
1563 #endif /* SLHCI_BUS_SPACE_BARRIERS */
1566 slhci_write(struct slhci_softc
*sc
, uint8_t addr
, uint8_t data
)
1568 bus_size_t paddr
, pdata
, pst
, psz
;
1569 bus_space_tag_t iot
;
1570 bus_space_handle_t ioh
;
1573 pdata
= sc
->sc_stride
;
1578 bus_space_write_1(iot
, ioh
, paddr
, addr
);
1579 BSB(iot
, ioh
, pst
, psz
, WRITE_BEFORE_WRITE
);
1580 bus_space_write_1(iot
, ioh
, pdata
, data
);
1581 BSB(iot
, ioh
, pst
, psz
, WRITE_BEFORE_WRITE
);
1585 slhci_read(struct slhci_softc
*sc
, uint8_t addr
)
1587 bus_size_t paddr
, pdata
, pst
, psz
;
1588 bus_space_tag_t iot
;
1589 bus_space_handle_t ioh
;
1593 pdata
= sc
->sc_stride
;
1598 bus_space_write_1(iot
, ioh
, paddr
, addr
);
1599 BSB(iot
, ioh
, pst
, psz
, WRITE_BEFORE_READ
);
1600 data
= bus_space_read_1(iot
, ioh
, pdata
);
1601 BSB(iot
, ioh
, pst
, psz
, READ_BEFORE_WRITE
);
1605 #if 0 /* auto-increment mode broken, see errata doc */
1607 slhci_write_multi(struct slhci_softc
*sc
, uint8_t addr
, uint8_t *buf
, int l
)
1609 bus_size_t paddr
, pdata
, pst
, psz
;
1610 bus_space_tag_t iot
;
1611 bus_space_handle_t ioh
;
1614 pdata
= sc
->sc_stride
;
1619 bus_space_write_1(iot
, ioh
, paddr
, addr
);
1620 BSB(iot
, ioh
, pst
, psz
, WRITE_BEFORE_WRITE
);
1621 bus_space_write_multi_1(iot
, ioh
, pdata
, buf
, l
);
1622 BSB(iot
, ioh
, pst
, psz
, WRITE_BEFORE_WRITE
);
1626 slhci_read_multi(struct slhci_softc
*sc
, uint8_t addr
, uint8_t *buf
, int l
)
1628 bus_size_t paddr
, pdata
, pst
, psz
;
1629 bus_space_tag_t iot
;
1630 bus_space_handle_t ioh
;
1633 pdata
= sc
->sc_stride
;
1638 bus_space_write_1(iot
, ioh
, paddr
, addr
);
1639 BSB(iot
, ioh
, pst
, psz
, WRITE_BEFORE_READ
);
1640 bus_space_read_multi_1(iot
, ioh
, pdata
, buf
, l
);
1641 BSB(iot
, ioh
, pst
, psz
, READ_BEFORE_WRITE
);
1645 slhci_write_multi(struct slhci_softc
*sc
, uint8_t addr
, uint8_t *buf
, int l
)
1648 for (; l
; addr
++, buf
++, l
--)
1649 slhci_write(sc
, addr
, *buf
);
1651 bus_size_t paddr
, pdata
, pst
, psz
;
1652 bus_space_tag_t iot
;
1653 bus_space_handle_t ioh
;
1656 pdata
= sc
->sc_stride
;
1661 for (; l
; addr
++, buf
++, l
--) {
1662 bus_space_write_1(iot
, ioh
, paddr
, addr
);
1663 BSB(iot
, ioh
, pst
, psz
, WRITE_BEFORE_WRITE
);
1664 bus_space_write_1(iot
, ioh
, pdata
, *buf
);
1665 BSB(iot
, ioh
, pst
, psz
, WRITE_BEFORE_WRITE
);
1671 slhci_read_multi(struct slhci_softc
*sc
, uint8_t addr
, uint8_t *buf
, int l
)
1674 for (; l
; addr
++, buf
++, l
--)
1675 *buf
= slhci_read(sc
, addr
);
1677 bus_size_t paddr
, pdata
, pst
, psz
;
1678 bus_space_tag_t iot
;
1679 bus_space_handle_t ioh
;
1682 pdata
= sc
->sc_stride
;
1687 for (; l
; addr
++, buf
++, l
--) {
1688 bus_space_write_1(iot
, ioh
, paddr
, addr
);
1689 BSB(iot
, ioh
, pst
, psz
, WRITE_BEFORE_READ
);
1690 *buf
= bus_space_read_1(iot
, ioh
, pdata
);
1691 BSB(iot
, ioh
, pst
, psz
, READ_BEFORE_WRITE
);
1697 /* After calling waitintr it is necessary to either call slhci_callback or
1698 * schedule the callback if necessary. The callback cannot be called directly
1699 * from the hard interrupt since it interrupts at a high IPL and callbacks
1700 * can do copyout and such. */
1702 slhci_waitintr(struct slhci_softc
*sc
, int wait_time
)
1704 struct slhci_transfers
*t
;
1706 t
= &sc
->sc_transfers
;
1708 SLHCI_LOCKASSERT(sc
, locked
, unlocked
);
1710 if (__predict_false(sc
->sc_bus
.use_polling
))
1713 while (t
->pend
<= wait_time
) {
1714 DLOG(D_WAIT
, "waiting... frame %d pend %d flags %#x",
1715 t
->frame
, t
->pend
, t
->flags
, 0);
1716 LK_SLASSERT(t
->flags
& F_ACTIVE
, sc
, NULL
, NULL
, return);
1717 LK_SLASSERT(t
->flags
& (F_AINPROG
|F_BINPROG
), sc
, NULL
, NULL
,
1724 slhci_dointr(struct slhci_softc
*sc
)
1726 struct slhci_transfers
*t
;
1727 struct slhci_pipe
*tosp
;
1730 t
= &sc
->sc_transfers
;
1732 SLHCI_LOCKASSERT(sc
, locked
, unlocked
);
1734 if (sc
->sc_ier
== 0)
1737 r
= slhci_read(sc
, SL11_ISR
);
1740 if (slhci_debug
& SLHCI_D_INTR
&& r
& sc
->sc_ier
&&
1741 ((r
& ~(SL11_ISR_SOF
|SL11_ISR_DATA
)) || slhci_debug
&
1745 e
= slhci_read(sc
, SL11_IER
);
1746 f
= slhci_read(sc
, SL11_CTRL
);
1747 DDOLOG("Flags=%#x IER=%#x ISR=%#x", t
->flags
, e
, r
, 0);
1748 DDOLOGFLAG8("Status=", r
, "D+", (f
& SL11_CTRL_SUSPEND
) ?
1749 "RESUME" : "NODEV", "INSERT", "SOF", "res", "BABBLE",
1754 /* check IER for corruption occasionally. Assume that the above
1755 * sc_ier == 0 case works correctly. */
1756 if (__predict_false(sc
->sc_ier_check
++ > SLHCI_IER_CHECK_FREQUENCY
)) {
1757 sc
->sc_ier_check
= 0;
1758 if (sc
->sc_ier
!= slhci_read(sc
, SL11_IER
)) {
1759 printf("%s: IER value corrupted! halted\n",
1761 DDOLOG("%s: IER value corrupted! halted\n",
1762 SC_NAME(sc
), 0,0,0);
1763 slhci_halt(sc
, NULL
, NULL
);
1773 sc
->sc_ier_check
= 0;
1775 slhci_write(sc
, SL11_ISR
, r
);
1776 BSB_SYNC(sc
->iot
, sc
->ioh
, sc
->pst
, sc
->psz
);
1779 /* If we have an insertion event we do not care about anything else. */
1780 if (__predict_false(r
& SL11_ISR_INSERT
)) {
1785 stop_cc_time(&t_intr
);
1786 start_cc_time(&t_intr
, r
);
1788 if (r
& SL11_ISR_SOF
) {
1791 gcq_merge_tail(&t
->q
[Q_CB
], &t
->q
[Q_NEXT_CB
]);
1793 /* SOFCHECK flags are cleared in tstart. Two flags are needed
1794 * since the first SOF interrupt processed after the transfer
1795 * is started might have been generated before the transfer
1797 if (__predict_false(t
->flags
& F_SOFCHECK2
&& t
->flags
&
1798 (F_AINPROG
|F_BINPROG
))) {
1799 printf("%s: Missed transfer completion. halted\n",
1801 DDOLOG("%s: Missed transfer completion. halted\n",
1802 SC_NAME(sc
), 0,0,0);
1803 slhci_halt(sc
, NULL
, NULL
);
1805 } else if (t
->flags
& F_SOFCHECK1
) {
1806 t
->flags
|= F_SOFCHECK2
;
1808 t
->flags
|= F_SOFCHECK1
;
1810 if (t
->flags
& F_CHANGE
)
1811 t
->flags
|= F_ROOTINTR
;
1813 while (__predict_true(GOT_FIRST_TO(tosp
, t
)) &&
1814 __predict_false(tosp
->to_frame
<= t
->frame
)) {
1815 tosp
->xfer
->status
= USBD_TIMEOUT
;
1816 slhci_do_abort(sc
, tosp
, tosp
->xfer
);
1817 enter_callback(t
, tosp
);
1820 /* Start any waiting transfers right away. If none, we will
1821 * start any new transfers later. */
1825 if (r
& (SL11_ISR_USBA
|SL11_ISR_USBB
)) {
1828 if ((r
& (SL11_ISR_USBA
|SL11_ISR_USBB
)) ==
1829 (SL11_ISR_USBA
|SL11_ISR_USBB
)) {
1830 if (!(t
->flags
& (F_AINPROG
|F_BINPROG
)))
1831 return 1; /* presume card pulled */
1833 LK_SLASSERT((t
->flags
& (F_AINPROG
|F_BINPROG
)) !=
1834 (F_AINPROG
|F_BINPROG
), sc
, NULL
, NULL
, return 1);
1836 /* This should never happen (unless card removal just
1837 * occurred) but appeared frequently when both
1838 * transfers were started at the same time and was
1839 * accompanied by data corruption. It still happens
1840 * at times. I have not seen data correption except
1841 * when the STATUS bit gets set, which now causes the
1842 * driver to halt, however this should still not
1843 * happen so the warning is kept. See comment in
1846 printf("%s: Transfer reported done but not started! "
1847 "Verify data integrity if not detaching. "
1848 " flags %#x r %x\n", SC_NAME(sc
), t
->flags
, r
);
1850 if (!(t
->flags
& F_AINPROG
))
1851 r
&= ~SL11_ISR_USBA
;
1853 r
&= ~SL11_ISR_USBB
;
1857 if (r
& SL11_ISR_USBA
)
1862 /* This happens when a low speed device is attached to
1863 * a hub with chip rev 1.5. SOF stops, but a few transfers
1864 * still work before causing this error.
1866 if (!(t
->flags
& (ab
? F_BINPROG
: F_AINPROG
))) {
1867 printf("%s: %s done but not in progress! halted\n",
1868 SC_NAME(sc
), ab
? "B" : "A");
1869 DDOLOG("%s: %s done but not in progress! halted\n",
1870 SC_NAME(sc
), ab
? "B" : "A", 0,0);
1871 slhci_halt(sc
, NULL
, NULL
);
1875 t
->flags
&= ~(ab
? F_BINPROG
: F_AINPROG
);
1877 stop_cc_time(&t_ab
[ab
]);
1878 start_cc_time(&t_abdone
, t
->flags
);
1879 slhci_abdone(sc
, ab
);
1880 stop_cc_time(&t_abdone
);
1883 slhci_dotransfer(sc
);
1889 slhci_abdone(struct slhci_softc
*sc
, int ab
)
1891 struct slhci_transfers
*t
;
1892 struct slhci_pipe
*spipe
;
1893 struct usbd_xfer
*xfer
;
1894 uint8_t status
, buf_start
;
1895 uint8_t *target_buf
;
1896 unsigned int actlen
;
1899 t
= &sc
->sc_transfers
;
1901 SLHCI_LOCKASSERT(sc
, locked
, unlocked
);
1903 DLOG(D_TRACE
, "ABDONE flags %#x", t
->flags
, 0,0,0);
1905 DLOG(D_MSG
, "DONE %s spipe %p len %d xfer %p", ab
? "B" : "A",
1906 t
->spipe
[ab
], t
->len
[ab
], t
->spipe
[ab
] ?
1907 t
->spipe
[ab
]->xfer
: NULL
);
1909 spipe
= t
->spipe
[ab
];
1911 /* skip this one if aborted; do not call return from the rest of the
1912 * function unless halting, else t->len will not be cleared. */
1916 t
->spipe
[ab
] = NULL
;
1920 gcq_remove(&spipe
->to
);
1922 LK_SLASSERT(xfer
!= NULL
, sc
, spipe
, NULL
, return);
1924 status
= slhci_read(sc
, slhci_tregs
[ab
][STAT
]);
1927 * I saw no status or remaining length greater than the requested
1928 * length in early driver versions in circumstances I assumed caused
1929 * excess power draw. I am no longer able to reproduce this when
1930 * causing excess power draw circumstances.
1932 * Disabling a power check and attaching aue to a keyboard and hub
1933 * that is directly attached (to CFU1U, 100mA max, aue 160mA, keyboard
1934 * 98mA) sometimes works and sometimes fails to configure. After
1935 * removing the aue and attaching a self-powered umass dvd reader
1936 * (unknown if it draws power from the host also) soon a single Error
1937 * status occurs then only timeouts. The controller soon halts freeing
1938 * memory due to being ONQU instead of BUSY. This may be the same
1939 * basic sequence that caused the no status/bad length errors. The
1940 * umass device seems to work (better at least) with the keyboard hub
1941 * when not first attaching aue (tested once reading an approximately
1944 * Overflow can indicate that the device and host disagree about how
1945 * much data has been transfered. This may indicate a problem at any
1946 * point during the transfer, not just when the error occurs. It may
1947 * indicate data corruption. A warning message is printed.
1949 * Trying to use both A and B transfers at the same time results in
1950 * incorrect transfer completion ISR reports and the status will then
1951 * include SL11_EPSTAT_SETUP, which is apparently set while the
1952 * transfer is in progress. I also noticed data corruption, even
1953 * after waiting for the transfer to complete. The driver now avoids
1954 * trying to start both at the same time.
1956 * I had accidently initialized the B registers before they were valid
1957 * in some driver versions. Since every other performance enhancing
1958 * feature has been confirmed buggy in the errata doc, I have not
1959 * tried both transfers at once again with the documented
1960 * initialization order.
1962 * However, I have seen this problem again ("done but not started"
1963 * errors), which in some cases cases the SETUP status bit to remain
1964 * set on future transfers. In other cases, the SETUP bit is not set
1965 * and no data corruption occurs. This occured while using both umass
1966 * and aue on a powered hub (maybe triggered by some local activity
1967 * also) and needs several reads of the 200MB file to trigger. The
1968 * driver now halts if SETUP is detected.
1973 if (__predict_false(!status
)) {
1974 DDOLOG("no status! xfer %p spipe %p", xfer
, spipe
, 0,0);
1975 printf("%s: no status! halted\n", SC_NAME(sc
));
1976 slhci_halt(sc
, spipe
, xfer
);
1981 if (slhci_debug
& SLHCI_D_NAK
|| (status
& SL11_EPSTAT_ERRBITS
) !=
1983 DLOGFLAG8(D_XFER
, "STATUS=", status
, "STALL", "NAK",
1984 "Overflow", "Setup", "Data Toggle", "Timeout", "Error",
1988 if (!(status
& SL11_EPSTAT_ERRBITS
)) {
1990 cont
= slhci_read(sc
, slhci_tregs
[ab
][CONT
]);
1992 DLOG(D_XFER
, "cont %d len %d", cont
,
1993 spipe
->tregs
[LEN
], 0,0);
1994 if (__predict_false(cont
> spipe
->tregs
[LEN
])) {
1995 DDOLOG("cont > len! cont %d len %d xfer->length %d "
1996 "spipe %p", cont
, spipe
->tregs
[LEN
], xfer
->length
,
1998 printf("%s: cont > len! cont %d len %d xfer->length "
1999 "%d", SC_NAME(sc
), cont
, spipe
->tregs
[LEN
],
2001 slhci_halt(sc
, spipe
, xfer
);
2005 actlen
= spipe
->tregs
[LEN
] - cont
;
2009 /* Actual copyin done after starting next transfer. */
2010 if (actlen
&& (spipe
->tregs
[PID
] & SL11_PID_BITS
) == SL11_PID_IN
) {
2011 target_buf
= spipe
->buffer
;
2012 buf_start
= spipe
->tregs
[ADR
];
2015 buf_start
= 0; /* XXX gcc uninitialized warnings */
2018 if (status
& SL11_EPSTAT_ERRBITS
) {
2019 status
&= SL11_EPSTAT_ERRBITS
;
2020 if (status
& SL11_EPSTAT_SETUP
) {
2021 printf("%s: Invalid controller state detected! "
2022 "halted\n", SC_NAME(sc
));
2023 DDOLOG("%s: Invalid controller state detected! "
2024 "halted\n", SC_NAME(sc
), 0,0,0);
2025 slhci_halt(sc
, spipe
, xfer
);
2027 } else if (__predict_false(sc
->sc_bus
.use_polling
)) {
2028 if (status
== SL11_EPSTAT_STALL
)
2029 xfer
->status
= USBD_STALLED
;
2030 else if (status
== SL11_EPSTAT_TIMEOUT
)
2031 xfer
->status
= USBD_TIMEOUT
;
2032 else if (status
== SL11_EPSTAT_NAK
)
2033 xfer
->status
= USBD_TIMEOUT
; /*XXX*/
2035 xfer
->status
= USBD_IOERROR
;
2037 } else if (status
== SL11_EPSTAT_NAK
) {
2038 if (spipe
->pipe
.interval
) {
2039 spipe
->lastframe
= spipe
->frame
=
2040 t
->frame
+ spipe
->pipe
.interval
;
2041 slhci_queue_timed(sc
, spipe
);
2045 } else if (++spipe
->nerrs
> SLHCI_MAX_RETRIES
||
2046 status
== SL11_EPSTAT_STALL
) {
2047 if (status
== SL11_EPSTAT_STALL
)
2048 xfer
->status
= USBD_STALLED
;
2049 else if (status
== SL11_EPSTAT_TIMEOUT
)
2050 xfer
->status
= USBD_TIMEOUT
;
2052 xfer
->status
= USBD_IOERROR
;
2054 DLOG(D_ERR
, "Max retries reached! status %#x "
2055 "xfer->status %#x", status
, xfer
->status
, 0,0);
2056 DLOGFLAG8(D_ERR
, "STATUS=", status
, "STALL",
2057 "NAK", "Overflow", "Setup", "Data Toggle",
2058 "Timeout", "Error", "ACK");
2060 if (status
== SL11_EPSTAT_OVERFLOW
&&
2061 ratecheck(&sc
->sc_overflow_warn_rate
,
2062 &overflow_warn_rate
)) {
2063 printf("%s: Overflow condition: "
2064 "data corruption possible\n",
2066 DDOLOG("%s: Overflow condition: "
2067 "data corruption possible\n",
2068 SC_NAME(sc
), 0,0,0);
2074 } else if (spipe
->ptype
== PT_CTRL_SETUP
) {
2075 spipe
->tregs
[PID
] = spipe
->newpid
;
2078 LK_SLASSERT(spipe
->newlen
[1] != 0, sc
, spipe
, xfer
,
2080 spipe
->tregs
[LEN
] = spipe
->newlen
[1];
2081 spipe
->bustime
= spipe
->newbustime
[1];
2082 spipe
->buffer
= KERNADDR(&xfer
->dmabuf
, 0);
2083 spipe
->ptype
= PT_CTRL_DATA
;
2086 /* CTRL_DATA swaps direction in PID then jumps here */
2087 spipe
->tregs
[LEN
] = 0;
2088 if (spipe
->pflags
& PF_LS
)
2089 spipe
->bustime
= SLHCI_LS_CONST
;
2091 spipe
->bustime
= SLHCI_FS_CONST
;
2092 spipe
->ptype
= PT_CTRL_STATUS
;
2093 spipe
->buffer
= NULL
;
2096 /* Status or first data packet must be DATA1. */
2097 spipe
->control
|= SL11_EPCTRL_DATATOGGLE
;
2098 if ((spipe
->tregs
[PID
] & SL11_PID_BITS
) == SL11_PID_IN
)
2099 spipe
->control
&= ~SL11_EPCTRL_DIRECTION
;
2101 spipe
->control
|= SL11_EPCTRL_DIRECTION
;
2104 } else if (spipe
->ptype
== PT_CTRL_STATUS
) {
2106 } else { /* bulk, intr, control data */
2107 xfer
->actlen
+= actlen
;
2108 spipe
->control
^= SL11_EPCTRL_DATATOGGLE
;
2110 if (actlen
== spipe
->tregs
[LEN
] && (xfer
->length
>
2111 xfer
->actlen
|| spipe
->wantshort
)) {
2112 spipe
->buffer
+= actlen
;
2113 LK_SLASSERT(xfer
->length
>= xfer
->actlen
, sc
,
2114 spipe
, xfer
, return);
2115 if (xfer
->length
- xfer
->actlen
< actlen
) {
2116 spipe
->wantshort
= 0;
2117 spipe
->tregs
[LEN
] = spipe
->newlen
[0];
2118 spipe
->bustime
= spipe
->newbustime
[0];
2119 LK_SLASSERT(xfer
->actlen
+
2120 spipe
->tregs
[LEN
] == xfer
->length
, sc
,
2121 spipe
, xfer
, return);
2124 } else if (spipe
->ptype
== PT_CTRL_DATA
) {
2125 spipe
->tregs
[PID
] ^= SLHCI_PID_SWAP_IN_OUT
;
2128 if (spipe
->ptype
== PT_INTR
) {
2130 spipe
->pipe
.interval
;
2131 /* If ack, we try to keep the
2132 * interrupt rate by using lastframe
2133 * instead of the current frame. */
2134 spipe
->frame
= spipe
->lastframe
+
2135 spipe
->pipe
.interval
;
2138 /* Set the toggle for the next transfer. It
2139 * has already been toggled above, so the
2140 * current setting will apply to the next
2142 if (spipe
->control
& SL11_EPCTRL_DATATOGGLE
)
2143 spipe
->pflags
|= PF_TOGGLE
;
2145 spipe
->pflags
&= ~PF_TOGGLE
;
2151 if (head
== Q_CALLBACKS
) {
2152 gcq_remove(&spipe
->to
);
2154 if (xfer
->status
== USBD_IN_PROGRESS
) {
2155 LK_SLASSERT(xfer
->actlen
<= xfer
->length
, sc
,
2156 spipe
, xfer
, return);
2157 xfer
->status
= USBD_NORMAL_COMPLETION
;
2158 #if 0 /* usb_transfer_complete will do this */
2159 if (xfer
->length
== xfer
->actlen
|| xfer
->flags
&
2161 xfer
->status
= USBD_NORMAL_COMPLETION
;
2163 xfer
->status
= USBD_SHORT_XFER
;
2168 enter_q(t
, spipe
, head
);
2171 if (target_buf
!= NULL
) {
2172 slhci_dotransfer(sc
);
2173 start_cc_time(&t_copy_from_dev
, actlen
);
2174 slhci_read_multi(sc
, buf_start
, target_buf
, actlen
);
2175 stop_cc_time(&t_copy_from_dev
);
2176 DLOGBUF(D_BUF
, target_buf
, actlen
);
2177 t
->pend
-= SLHCI_FS_CONST
+ SLHCI_FS_DATA_TIME(actlen
);
2185 slhci_tstart(struct slhci_softc
*sc
)
2187 struct slhci_transfers
*t
;
2188 struct slhci_pipe
*spipe
;
2189 int remaining_bustime
;
2192 t
= &sc
->sc_transfers
;
2194 SLHCI_LOCKASSERT(sc
, locked
, unlocked
);
2196 if (!(t
->flags
& (F_AREADY
|F_BREADY
)))
2199 if (t
->flags
& (F_AINPROG
|F_BINPROG
|F_DISABLED
))
2202 /* We have about 6 us to get from the bus time check to
2203 * starting the transfer or we might babble or the chip might fail to
2204 * signal transfer complete. This leaves no time for any other
2208 remaining_bustime
= (int)(slhci_read(sc
, SL811_CSOF
)) << 6;
2209 remaining_bustime
-= SLHCI_END_BUSTIME
;
2211 /* Start one transfer only, clearing any aborted transfers that are
2212 * not yet in progress and skipping missed isoc. It is easier to copy
2213 * & paste most of the A/B sections than to make the logic work
2214 * otherwise and this allows better constant use. */
2215 if (t
->flags
& F_AREADY
) {
2216 spipe
= t
->spipe
[A
];
2217 if (spipe
== NULL
) {
2218 t
->flags
&= ~F_AREADY
;
2220 } else if (remaining_bustime
>= spipe
->bustime
) {
2221 t
->flags
&= ~(F_AREADY
|F_SOFCHECK1
|F_SOFCHECK2
);
2222 t
->flags
|= F_AINPROG
;
2223 start_cc_time(&t_ab
[A
], spipe
->tregs
[LEN
]);
2224 slhci_write(sc
, SL11_E0CTRL
, spipe
->control
);
2228 if (t
->flags
& F_BREADY
) {
2229 spipe
= t
->spipe
[B
];
2230 if (spipe
== NULL
) {
2231 t
->flags
&= ~F_BREADY
;
2233 } else if (remaining_bustime
>= spipe
->bustime
) {
2234 t
->flags
&= ~(F_BREADY
|F_SOFCHECK1
|F_SOFCHECK2
);
2235 t
->flags
|= F_BINPROG
;
2236 start_cc_time(&t_ab
[B
], spipe
->tregs
[LEN
]);
2237 slhci_write(sc
, SL11_E1CTRL
, spipe
->control
);
2239 t
->pend
= spipe
->bustime
;
2246 slhci_dotransfer(struct slhci_softc
*sc
)
2248 struct slhci_transfers
*t
;
2249 struct slhci_pipe
*spipe
;
2252 t
= &sc
->sc_transfers
;
2254 SLHCI_LOCKASSERT(sc
, locked
, unlocked
);
2256 while ((t
->len
[A
] == -1 || t
->len
[B
] == -1) &&
2257 (GOT_FIRST_TIMED_COND(spipe
, t
, spipe
->frame
<= t
->frame
) ||
2258 GOT_FIRST_CB(spipe
, t
))) {
2259 LK_SLASSERT(spipe
->xfer
!= NULL
, sc
, spipe
, NULL
, return);
2260 LK_SLASSERT(spipe
->ptype
!= PT_ROOT_CTRL
&& spipe
->ptype
!=
2261 PT_ROOT_INTR
, sc
, spipe
, NULL
, return);
2263 /* Check that this transfer can fit in the remaining memory. */
2264 if (t
->len
[A
] + t
->len
[B
] + spipe
->tregs
[LEN
] + 1 >
2265 SL11_MAX_PACKET_SIZE
) {
2266 DLOG(D_XFER
, "Transfer does not fit. alen %d blen %d "
2267 "len %d", t
->len
[A
], t
->len
[B
], spipe
->tregs
[LEN
],
2272 gcq_remove(&spipe
->xq
);
2274 if (t
->len
[A
] == -1) {
2276 spipe
->tregs
[ADR
] = SL11_BUFFER_START
;
2279 spipe
->tregs
[ADR
] = SL11_BUFFER_END
-
2283 t
->len
[ab
] = spipe
->tregs
[LEN
];
2285 if (spipe
->tregs
[LEN
] && (spipe
->tregs
[PID
] & SL11_PID_BITS
)
2287 start_cc_time(&t_copy_to_dev
,
2289 slhci_write_multi(sc
, spipe
->tregs
[ADR
],
2290 spipe
->buffer
, spipe
->tregs
[LEN
]);
2291 stop_cc_time(&t_copy_to_dev
);
2292 t
->pend
-= SLHCI_FS_CONST
+
2293 SLHCI_FS_DATA_TIME(spipe
->tregs
[LEN
]);
2296 DLOG(D_MSG
, "NEW TRANSFER %s flags %#x alen %d blen %d",
2297 ab
? "B" : "A", t
->flags
, t
->len
[0], t
->len
[1]);
2299 if (spipe
->tregs
[LEN
])
2305 if (t
->current_tregs
[ab
][i
] != spipe
->tregs
[i
]) {
2306 t
->current_tregs
[ab
][i
] = spipe
->tregs
[i
];
2307 slhci_write(sc
, slhci_tregs
[ab
][i
],
2311 DLOG(D_SXFER
, "Transfer len %d pid %#x dev %d type %s",
2312 spipe
->tregs
[LEN
], spipe
->tregs
[PID
], spipe
->tregs
[DEV
],
2313 pnames(spipe
->ptype
));
2315 t
->spipe
[ab
] = spipe
;
2316 t
->flags
|= ab
? F_BREADY
: F_AREADY
;
2322 /* slhci_callback is called after the lock is taken from splsoftusb.
2323 * s is pointer to old spl (splsoftusb). */
2325 slhci_callback(struct slhci_softc
*sc
, int *s
)
2327 struct slhci_transfers
*t
;
2328 struct slhci_pipe
*spipe
;
2329 struct usbd_xfer
*xfer
;
2331 t
= &sc
->sc_transfers
;
2333 SLHCI_LOCKASSERT(sc
, locked
, unlocked
);
2335 DLOG(D_SOFT
, "CB flags %#x", t
->flags
, 0,0,0);
2337 if (__predict_false(t
->flags
& F_ROOTINTR
)) {
2338 t
->flags
&= ~F_ROOTINTR
;
2339 if (t
->rootintr
!= NULL
) {
2342 p
= KERNADDR(&t
->rootintr
->dmabuf
, 0);
2344 t
->rootintr
->actlen
= 1;
2345 t
->rootintr
->status
= USBD_NORMAL_COMPLETION
;
2352 if (!DEQUEUED_CALLBACK(spipe
, t
))
2356 LK_SLASSERT(xfer
!= NULL
, sc
, spipe
, NULL
, return);
2358 DLOG(D_XFER
, "xfer callback length %d actlen %d spipe %x "
2359 "type %s", xfer
->length
, xfer
->actlen
, spipe
,
2360 pnames(spipe
->ptype
));
2362 slhci_do_callback(sc
, xfer
, s
);
2367 slhci_enter_xfer(struct slhci_softc
*sc
, struct slhci_pipe
*spipe
)
2369 struct slhci_transfers
*t
;
2371 t
= &sc
->sc_transfers
;
2373 SLHCI_MAINLOCKASSERT(sc
);
2375 if (__predict_false(t
->flags
& F_DISABLED
) ||
2376 __predict_false(spipe
->pflags
& PF_GONE
)) {
2377 DLOG(D_MSG
, "slhci_enter_xfer: DISABLED or GONE", 0,0,0,0);
2378 spipe
->xfer
->status
= USBD_CANCELLED
;
2381 if (spipe
->xfer
->status
== USBD_IN_PROGRESS
) {
2382 if (spipe
->xfer
->timeout
) {
2383 spipe
->to_frame
= t
->frame
+ spipe
->xfer
->timeout
;
2384 slhci_xfer_timer(sc
, spipe
);
2386 if (spipe
->pipe
.interval
)
2387 slhci_queue_timed(sc
, spipe
);
2389 enter_q(t
, spipe
, Q_CB
);
2391 enter_callback(t
, spipe
);
2394 #ifdef SLHCI_WAITLOCK
2396 slhci_enter_xfers(struct slhci_softc
*sc
)
2398 struct slhci_pipe
*spipe
;
2400 SLHCI_LOCKASSERT(sc
, locked
, locked
);
2402 while (DEQUEUED_WAITQ(spipe
, sc
))
2403 slhci_enter_xfer(sc
, spipe
);
2408 slhci_queue_timed(struct slhci_softc
*sc
, struct slhci_pipe
*spipe
)
2410 struct slhci_transfers
*t
;
2412 struct slhci_pipe
*spp
;
2414 t
= &sc
->sc_transfers
;
2416 SLHCI_MAINLOCKASSERT(sc
);
2418 FIND_TIMED(q
, t
, spp
, spp
->frame
> spipe
->frame
);
2419 gcq_insert_before(q
, &spipe
->xq
);
2423 slhci_xfer_timer(struct slhci_softc
*sc
, struct slhci_pipe
*spipe
)
2425 struct slhci_transfers
*t
;
2427 struct slhci_pipe
*spp
;
2429 t
= &sc
->sc_transfers
;
2431 SLHCI_MAINLOCKASSERT(sc
);
2433 FIND_TO(q
, t
, spp
, spp
->to_frame
>= spipe
->to_frame
);
2434 gcq_insert_before(q
, &spipe
->to
);
2438 slhci_do_repeat(struct slhci_softc
*sc
, struct usbd_xfer
*xfer
)
2440 struct slhci_transfers
*t
;
2441 struct slhci_pipe
*spipe
;
2443 t
= &sc
->sc_transfers
;
2444 spipe
= (struct slhci_pipe
*)xfer
->pipe
;
2446 if (xfer
== t
->rootintr
)
2449 DLOG(D_TRACE
, "REPEAT: xfer %p actlen %d frame %u now %u",
2450 xfer
, xfer
->actlen
, spipe
->frame
, sc
->sc_transfers
.frame
);
2454 if (spipe
->tregs
[LEN
])
2455 KASSERT(spipe
->buffer
== KERNADDR(&xfer
->dmabuf
, 0));
2456 slhci_queue_timed(sc
, spipe
);
2457 slhci_dotransfer(sc
);
2461 slhci_callback_schedule(struct slhci_softc
*sc
)
2463 struct slhci_transfers
*t
;
2465 t
= &sc
->sc_transfers
;
2467 SLHCI_LOCKASSERT(sc
, locked
, unlocked
);
2469 if (t
->flags
& F_ACTIVE
)
2470 slhci_do_callback_schedule(sc
);
2474 slhci_do_callback_schedule(struct slhci_softc
*sc
)
2476 struct slhci_transfers
*t
;
2478 t
= &sc
->sc_transfers
;
2480 SLHCI_LOCKASSERT(sc
, locked
, unlocked
);
2482 if (!(t
->flags
& F_CALLBACK
)) {
2483 t
->flags
|= F_CALLBACK
;
2484 softint_schedule(sc
->sc_cb_softintr
);
2489 /* must be called with lock taken from splsoftusb */
2490 /* XXX static */ void
2491 slhci_pollxfer(struct slhci_softc
*sc
, struct usbd_xfer
*xfer
, int *s
)
2493 SLHCI_LOCKASSERT(sc
, locked
, unlocked
);
2494 slhci_dotransfer(sc
);
2497 } while (xfer
->status
== USBD_IN_PROGRESS
);
2498 slhci_do_callback(sc
, xfer
, s
);
2503 slhci_do_poll(struct slhci_softc
*sc
, struct slhci_pipe
*spipe
, struct
2506 slhci_waitintr(sc
, 0);
2508 return USBD_NORMAL_COMPLETION
;
2512 slhci_lsvh_warn(struct slhci_softc
*sc
, struct slhci_pipe
*spipe
, struct
2515 struct slhci_transfers
*t
;
2517 t
= &sc
->sc_transfers
;
2519 if (!(t
->flags
& F_LSVH_WARNED
)) {
2520 printf("%s: Low speed device via hub disabled, "
2521 "see slhci(4)\n", SC_NAME(sc
));
2522 DDOLOG("%s: Low speed device via hub disabled, "
2523 "see slhci(4)\n", SC_NAME(sc
), 0,0,0);
2524 t
->flags
|= F_LSVH_WARNED
;
2530 slhci_isoc_warn(struct slhci_softc
*sc
, struct slhci_pipe
*spipe
, struct
2533 struct slhci_transfers
*t
;
2535 t
= &sc
->sc_transfers
;
2537 if (!(t
->flags
& F_ISOC_WARNED
)) {
2538 printf("%s: ISOC transfer not supported "
2539 "(see slhci(4))\n", SC_NAME(sc
));
2540 DDOLOG("%s: ISOC transfer not supported "
2541 "(see slhci(4))\n", SC_NAME(sc
), 0,0,0);
2542 t
->flags
|= F_ISOC_WARNED
;
2548 slhci_open_pipe(struct slhci_softc
*sc
, struct slhci_pipe
*spipe
, struct
2551 struct slhci_transfers
*t
;
2552 struct usbd_pipe
*pipe
;
2554 t
= &sc
->sc_transfers
;
2555 pipe
= &spipe
->pipe
;
2557 if (t
->flags
& F_DISABLED
)
2558 return USBD_CANCELLED
;
2559 else if (pipe
->interval
&& !slhci_reserve_bustime(sc
, spipe
, 1))
2560 return USBD_PENDING_REQUESTS
;
2562 enter_all_pipes(t
, spipe
);
2563 return USBD_NORMAL_COMPLETION
;
2568 slhci_close_pipe(struct slhci_softc
*sc
, struct slhci_pipe
*spipe
, struct
2571 struct slhci_transfers
*t
;
2572 struct usbd_pipe
*pipe
;
2574 t
= &sc
->sc_transfers
;
2575 pipe
= &spipe
->pipe
;
2577 if (pipe
->interval
&& spipe
->ptype
!= PT_ROOT_INTR
)
2578 slhci_reserve_bustime(sc
, spipe
, 0);
2579 gcq_remove(&spipe
->ap
);
2580 return USBD_NORMAL_COMPLETION
;
2584 slhci_do_abort(struct slhci_softc
*sc
, struct slhci_pipe
*spipe
, struct
2587 struct slhci_transfers
*t
;
2589 t
= &sc
->sc_transfers
;
2591 SLHCI_MAINLOCKASSERT(sc
);
2593 if (spipe
->xfer
== xfer
) {
2594 if (spipe
->ptype
== PT_ROOT_INTR
) {
2595 if (t
->rootintr
== spipe
->xfer
) /* XXX assert? */
2598 gcq_remove(&spipe
->to
);
2599 gcq_remove(&spipe
->xq
);
2601 if (t
->spipe
[A
] == spipe
) {
2603 if (!(t
->flags
& F_AINPROG
))
2605 } else if (t
->spipe
[B
] == spipe
) {
2607 if (!(t
->flags
& F_BINPROG
))
2612 if (xfer
->status
!= USBD_TIMEOUT
) {
2614 spipe
->pipe
.repeat
= 0; /* XXX timeout? */
2618 return USBD_NORMAL_COMPLETION
;
2622 slhci_do_attach(struct slhci_softc
*sc
, struct slhci_pipe
*spipe
, struct
2625 struct slhci_transfers
*t
;
2628 t
= &sc
->sc_transfers
;
2630 SLHCI_LOCKASSERT(sc
, locked
, unlocked
);
2632 /* Detect and check the controller type */
2633 t
->sltype
= SL11_GET_REV(slhci_read(sc
, SL11_REV
));
2635 /* SL11H not supported */
2636 if (!slhci_supported_rev(t
->sltype
)) {
2637 if (t
->sltype
== SLTYPE_SL11H
)
2638 printf("%s: SL11H unsupported or bus error!\n",
2641 printf("%s: Unknown chip revision!\n", SC_NAME(sc
));
2645 callout_init(&sc
->sc_timer
, CALLOUT_MPSAFE
);
2646 callout_setfunc(&sc
->sc_timer
, slhci_reset_entry
, sc
);
2648 /* It is not safe to call the soft interrupt directly as
2649 * usb_schedsoftintr does in the use_polling case (due to locking).
2651 sc
->sc_cb_softintr
= softint_establish(SOFTINT_NET
,
2652 slhci_callback_entry
, sc
);
2657 if (slhci_usbdebug
>= 0)
2658 usbdebug
= slhci_usbdebug
;
2662 if (t
->sltype
== SLTYPE_SL811HS_R12
)
2664 else if (t
->sltype
== SLTYPE_SL811HS_R14
)
2665 rev
= " (rev 1.4 or 1.5)";
2667 rev
= " (unknown revision)";
2669 aprint_normal("%s: ScanLogic SL811HS/T USB Host Controller %s\n",
2672 aprint_normal("%s: Max Current %u mA (value by code, not by probe)\n",
2673 SC_NAME(sc
), t
->max_current
* 2);
2675 #if defined(SLHCI_DEBUG) || defined(SLHCI_NO_OVERTIME) || \
2676 defined(SLHCI_TRY_LSVH) || defined(SLHCI_PROFILE_TRANSFER)
2677 aprint_normal("%s: driver options:"
2681 #ifdef SLHCI_TRY_LSVH
2684 #ifdef SLHCI_NO_OVERTIME
2685 " SLHCI_NO_OVERTIME"
2687 #ifdef SLHCI_PROFILE_TRANSFER
2688 " SLHCI_PROFILE_TRANSFER"
2692 sc
->sc_bus
.usbrev
= USBREV_1_1
;
2693 sc
->sc_bus
.methods
= __UNCONST(&slhci_bus_methods
);
2694 sc
->sc_bus
.pipe_size
= sizeof(struct slhci_pipe
);
2696 if (!sc
->sc_enable_power
)
2697 t
->flags
|= F_REALPOWER
;
2699 t
->flags
|= F_ACTIVE
;
2701 return USBD_NORMAL_COMPLETION
;
2704 /* Called to deactivate or stop use of the controller instead of panicing.
2705 * Will cancel the xfer correctly even when not on a list.
2708 slhci_halt(struct slhci_softc
*sc
, struct slhci_pipe
*spipe
, struct usbd_xfer
2711 struct slhci_transfers
*t
;
2713 SLHCI_LOCKASSERT(sc
, locked
, unlocked
);
2715 t
= &sc
->sc_transfers
;
2717 DDOLOG("Halt! sc %p spipe %p xfer %p", sc
, spipe
, xfer
, 0);
2720 slhci_log_spipe(spipe
);
2723 slhci_log_xfer(xfer
);
2725 if (spipe
!= NULL
&& xfer
!= NULL
&& spipe
->xfer
== xfer
&&
2726 !gcq_onlist(&spipe
->xq
) && t
->spipe
[A
] != spipe
&& t
->spipe
[B
] !=
2728 xfer
->status
= USBD_CANCELLED
;
2729 enter_callback(t
, spipe
);
2732 if (t
->flags
& F_ACTIVE
) {
2733 slhci_intrchange(sc
, 0);
2734 /* leave power on when halting in case flash devices or disks
2735 * are attached, which may be writing and could be damaged
2736 * by abrupt power loss. The root hub clear power feature
2737 * should still work after halting.
2741 t
->flags
&= ~F_ACTIVE
;
2742 t
->flags
|= F_UDISABLED
;
2743 if (!(t
->flags
& F_NODEV
))
2744 t
->flags
|= F_NODEV
|F_CCONNECT
|F_ROOTINTR
;
2747 /* One last callback for the drain and device removal. */
2748 slhci_do_callback_schedule(sc
);
2750 return USBD_NORMAL_COMPLETION
;
2753 /* There are three interrupt states: no interrupts during reset and after
2754 * device deactivation, INSERT only for no device present but power on, and
2755 * SOF, INSERT, ADONE, and BDONE when device is present.
2758 slhci_intrchange(struct slhci_softc
*sc
, uint8_t new_ier
)
2760 SLHCI_MAINLOCKASSERT(sc
);
2761 if (sc
->sc_ier
!= new_ier
) {
2762 sc
->sc_ier
= new_ier
;
2763 slhci_write(sc
, SL11_IER
, new_ier
);
2764 BSB_SYNC(sc
->iot
, sc
->ioh
, sc
->pst
, sc
->psz
);
2768 /* Drain: cancel all pending transfers and put them on the callback list and
2769 * set the UDISABLED flag. UDISABLED is cleared only by reset. */
2771 slhci_drain(struct slhci_softc
*sc
)
2773 struct slhci_transfers
*t
;
2774 struct slhci_pipe
*spipe
;
2778 SLHCI_LOCKASSERT(sc
, locked
, unlocked
);
2780 t
= &sc
->sc_transfers
;
2782 DLOG(D_MSG
, "DRAIN flags %#x", t
->flags
, 0,0,0);
2786 for (i
=0; i
<=1; i
++) {
2788 if (t
->spipe
[i
] != NULL
) {
2789 enter_callback(t
, t
->spipe
[i
]);
2794 /* Merge the queues into the callback queue. */
2795 gcq_merge_tail(&t
->q
[Q_CALLBACKS
], &t
->q
[Q_CB
]);
2796 gcq_merge_tail(&t
->q
[Q_CALLBACKS
], &t
->q
[Q_NEXT_CB
]);
2797 gcq_merge_tail(&t
->q
[Q_CALLBACKS
], &t
->timed
);
2799 /* Cancel all pipes. Note that not all of these may be on the
2800 * callback queue yet; some could be in slhci_start, for example. */
2801 FOREACH_AP(q
, t
, spipe
) {
2802 spipe
->pflags
= PF_GONE
;
2803 spipe
->pipe
.repeat
= 0;
2804 spipe
->pipe
.aborting
= 1;
2805 if (spipe
->xfer
!= NULL
)
2806 spipe
->xfer
->status
= USBD_CANCELLED
;
2809 gcq_remove_all(&t
->to
);
2811 t
->flags
|= F_UDISABLED
;
2812 t
->flags
&= ~(F_AREADY
|F_BREADY
|F_AINPROG
|F_BINPROG
|F_LOWSPEED
);
2815 /* RESET: SL11_CTRL_RESETENGINE=1 and SL11_CTRL_JKSTATE=0 for 50ms
2816 * reconfigure SOF after reset, must wait 2.5us before USB bus activity (SOF)
2817 * check attached device speed.
2818 * must wait 100ms before USB transaction according to app note, 10ms
2819 * by spec. uhub does this delay
2821 * Started from root hub set feature reset, which does step one.
2822 * use_polling will call slhci_reset directly, otherwise the callout goes
2823 * through slhci_reset_entry.
2826 slhci_reset(struct slhci_softc
*sc
)
2828 struct slhci_transfers
*t
;
2829 uint8_t r
, pol
, ctrl
;
2831 t
= &sc
->sc_transfers
;
2832 SLHCI_MAINLOCKASSERT(sc
);
2834 stop_cc_time(&t_delay
);
2836 KASSERT(t
->flags
& F_ACTIVE
);
2838 start_cc_time(&t_delay
, 0);
2839 stop_cc_time(&t_delay
);
2841 slhci_write(sc
, SL11_CTRL
, 0);
2842 start_cc_time(&t_delay
, 3);
2844 stop_cc_time(&t_delay
);
2845 slhci_write(sc
, SL11_ISR
, 0xff);
2847 r
= slhci_read(sc
, SL11_ISR
);
2849 if (r
& SL11_ISR_INSERT
)
2850 slhci_write(sc
, SL11_ISR
, SL11_ISR_INSERT
);
2852 if (r
& SL11_ISR_NODEV
) {
2853 DLOG(D_MSG
, "NC", 0,0,0,0);
2854 /* Normally, the hard interrupt insert routine will issue
2855 * CCONNECT, however we need to do it here if the detach
2856 * happened during reset. */
2857 if (!(t
->flags
& F_NODEV
))
2858 t
->flags
|= F_CCONNECT
|F_ROOTINTR
|F_NODEV
;
2859 slhci_intrchange(sc
, SL11_IER_INSERT
);
2861 if (t
->flags
& F_NODEV
)
2862 t
->flags
|= F_CCONNECT
;
2863 t
->flags
&= ~(F_NODEV
|F_LOWSPEED
);
2864 if (r
& SL11_ISR_DATA
) {
2865 DLOG(D_MSG
, "FS", 0,0,0,0);
2868 DLOG(D_MSG
, "LS", 0,0,0,0);
2869 pol
= SL811_CSOF_POLARITY
;
2870 ctrl
= SL11_CTRL_LOWSPEED
;
2871 t
->flags
|= F_LOWSPEED
;
2874 /* Enable SOF auto-generation */
2875 t
->frame
= 0; /* write to SL811_CSOF will reset frame */
2876 slhci_write(sc
, SL11_SOFTIME
, 0xe0);
2877 slhci_write(sc
, SL811_CSOF
, pol
|SL811_CSOF_MASTER
|0x2e);
2878 slhci_write(sc
, SL11_CTRL
, ctrl
|SL11_CTRL_ENABLESOF
);
2880 /* According to the app note, ARM must be set
2881 * for SOF generation to work. We initialize all
2882 * USBA registers here for current_tregs. */
2883 slhci_write(sc
, SL11_E0ADDR
, SL11_BUFFER_START
);
2884 slhci_write(sc
, SL11_E0LEN
, 0);
2885 slhci_write(sc
, SL11_E0PID
, SL11_PID_SOF
);
2886 slhci_write(sc
, SL11_E0DEV
, 0);
2887 slhci_write(sc
, SL11_E0CTRL
, SL11_EPCTRL_ARM
);
2889 /* Initialize B registers. This can't be done earlier since
2890 * they are not valid until the SL811_CSOF register is written
2891 * above due to SL11H compatability. */
2892 slhci_write(sc
, SL11_E1ADDR
, SL11_BUFFER_END
- 8);
2893 slhci_write(sc
, SL11_E1LEN
, 0);
2894 slhci_write(sc
, SL11_E1PID
, 0);
2895 slhci_write(sc
, SL11_E1DEV
, 0);
2897 t
->current_tregs
[0][ADR
] = SL11_BUFFER_START
;
2898 t
->current_tregs
[0][LEN
] = 0;
2899 t
->current_tregs
[0][PID
] = SL11_PID_SOF
;
2900 t
->current_tregs
[0][DEV
] = 0;
2901 t
->current_tregs
[1][ADR
] = SL11_BUFFER_END
- 8;
2902 t
->current_tregs
[1][LEN
] = 0;
2903 t
->current_tregs
[1][PID
] = 0;
2904 t
->current_tregs
[1][DEV
] = 0;
2906 /* SOF start will produce USBA interrupt */
2908 t
->flags
|= F_AINPROG
;
2910 slhci_intrchange(sc
, SLHCI_NORMAL_INTERRUPTS
);
2913 t
->flags
&= ~(F_UDISABLED
|F_RESET
);
2914 t
->flags
|= F_CRESET
|F_ROOTINTR
;
2915 DLOG(D_MSG
, "RESET done flags %#x", t
->flags
, 0,0,0);
2918 /* returns 1 if succeeded, 0 if failed, reserve == 0 is unreserve */
2920 slhci_reserve_bustime(struct slhci_softc
*sc
, struct slhci_pipe
*spipe
, int
2923 struct slhci_transfers
*t
;
2924 int bustime
, max_packet
;
2926 SLHCI_LOCKASSERT(sc
, locked
, unlocked
);
2928 t
= &sc
->sc_transfers
;
2929 max_packet
= UGETW(spipe
->pipe
.endpoint
->edesc
->wMaxPacketSize
);
2931 if (spipe
->pflags
& PF_LS
)
2932 bustime
= SLHCI_LS_CONST
+ SLHCI_LS_DATA_TIME(max_packet
);
2934 bustime
= SLHCI_FS_CONST
+ SLHCI_FS_DATA_TIME(max_packet
);
2937 t
->reserved_bustime
-= bustime
;
2939 if (t
->reserved_bustime
< 0) {
2940 printf("%s: reserved_bustime %d < 0!\n",
2941 SC_NAME(sc
), t
->reserved_bustime
);
2942 DDOLOG("%s: reserved_bustime %d < 0!\n",
2943 SC_NAME(sc
), t
->reserved_bustime
, 0,0);
2944 t
->reserved_bustime
= 0;
2950 if (t
->reserved_bustime
+ bustime
> SLHCI_RESERVED_BUSTIME
) {
2951 if (ratecheck(&sc
->sc_reserved_warn_rate
,
2952 &reserved_warn_rate
))
2953 #ifdef SLHCI_NO_OVERTIME
2955 printf("%s: Max reserved bus time exceeded! "
2956 "Erroring request.\n", SC_NAME(sc
));
2957 DDOLOG("%s: Max reserved bus time exceeded! "
2958 "Erroring request.\n", SC_NAME(sc
), 0,0,0);
2963 printf("%s: Reserved bus time exceeds %d!\n",
2964 SC_NAME(sc
), SLHCI_RESERVED_BUSTIME
);
2965 DDOLOG("%s: Reserved bus time exceeds %d!\n",
2966 SC_NAME(sc
), SLHCI_RESERVED_BUSTIME
, 0,0);
2971 t
->reserved_bustime
+= bustime
;
2975 /* Device insertion/removal interrupt */
2977 slhci_insert(struct slhci_softc
*sc
)
2979 struct slhci_transfers
*t
;
2981 t
= &sc
->sc_transfers
;
2983 SLHCI_LOCKASSERT(sc
, locked
, unlocked
);
2985 if (t
->flags
& F_NODEV
)
2986 slhci_intrchange(sc
, 0);
2989 slhci_intrchange(sc
, SL11_IER_INSERT
);
2991 t
->flags
^= F_NODEV
;
2992 t
->flags
|= F_ROOTINTR
|F_CCONNECT
;
2993 DLOG(D_MSG
, "INSERT intr: flags after %#x", t
->flags
, 0,0,0);
2997 * Data structures and routines to emulate the root hub.
2999 static const usb_device_descriptor_t slhci_devd
= {
3000 USB_DEVICE_DESCRIPTOR_SIZE
,
3001 UDESC_DEVICE
, /* type */
3002 {0x01, 0x01}, /* USB version */
3003 UDCLASS_HUB
, /* class */
3004 UDSUBCLASS_HUB
, /* subclass */
3006 64, /* max packet */
3007 {USB_VENDOR_SCANLOGIC
& 0xff, /* vendor ID (low) */
3008 USB_VENDOR_SCANLOGIC
>> 8 }, /* vendor ID (high) */
3009 {0} /* ? */, /* product ID */
3011 1, /* index to manufacturer */
3012 2, /* index to product */
3013 0, /* index to serial number */
3014 1 /* number of configurations */
3017 static const struct slhci_confd_t
{
3018 const usb_config_descriptor_t confd
;
3019 const usb_interface_descriptor_t ifcd
;
3020 const usb_endpoint_descriptor_t endpd
;
3021 } UPACKED slhci_confd
= {
3022 { /* Configuration */
3023 USB_CONFIG_DESCRIPTOR_SIZE
,
3025 {USB_CONFIG_DESCRIPTOR_SIZE
+
3026 USB_INTERFACE_DESCRIPTOR_SIZE
+
3027 USB_ENDPOINT_DESCRIPTOR_SIZE
},
3028 1, /* number of interfaces */
3029 1, /* configuration value */
3030 0, /* index to configuration */
3031 UC_SELF_POWERED
, /* attributes */
3032 0 /* max current, filled in later */
3033 }, { /* Interface */
3034 USB_INTERFACE_DESCRIPTOR_SIZE
,
3036 0, /* interface number */
3037 0, /* alternate setting */
3038 1, /* number of endpoint */
3039 UICLASS_HUB
, /* class */
3040 UISUBCLASS_HUB
, /* subclass */
3042 0 /* index to interface */
3044 USB_ENDPOINT_DESCRIPTOR_SIZE
,
3046 UE_DIR_IN
| ROOT_INTR_ENDPT
, /* endpoint address */
3047 UE_INTERRUPT
, /* attributes */
3048 {240, 0}, /* max packet size */
3053 static const usb_hub_descriptor_t slhci_hubd
= {
3054 USB_HUB_DESCRIPTOR_SIZE
,
3056 1, /* number of ports */
3057 {UHD_PWR_INDIVIDUAL
| UHD_OC_NONE
, 0}, /* hub characteristics */
3058 50, /* 5:power on to power good, units of 2ms */
3059 0, /* 6:maximum current, filled in later */
3060 { 0x00 }, /* port is removable */
3061 { 0x00 } /* port power control mask */
3065 slhci_clear_feature(struct slhci_softc
*sc
, unsigned int what
)
3067 struct slhci_transfers
*t
;
3070 t
= &sc
->sc_transfers
;
3071 error
= USBD_NORMAL_COMPLETION
;
3073 SLHCI_LOCKASSERT(sc
, locked
, unlocked
);
3075 if (what
== UHF_PORT_POWER
) {
3076 DLOG(D_MSG
, "POWER_OFF", 0,0,0,0);
3077 t
->flags
&= ~F_POWER
;
3078 if (!(t
->flags
& F_NODEV
))
3079 t
->flags
|= F_NODEV
|F_CCONNECT
|F_ROOTINTR
;
3080 /* for x68k Nereid USB controller */
3081 if (sc
->sc_enable_power
&& (t
->flags
& F_REALPOWER
)) {
3082 t
->flags
&= ~F_REALPOWER
;
3083 sc
->sc_enable_power(sc
, POWER_OFF
);
3085 slhci_intrchange(sc
, 0);
3087 } else if (what
== UHF_C_PORT_CONNECTION
) {
3088 t
->flags
&= ~F_CCONNECT
;
3089 } else if (what
== UHF_C_PORT_RESET
) {
3090 t
->flags
&= ~F_CRESET
;
3091 } else if (what
== UHF_PORT_ENABLE
) {
3093 } else if (what
!= UHF_PORT_SUSPEND
) {
3094 DDOLOG("ClrPortFeatERR:value=%#.4x", what
, 0,0,0);
3095 error
= USBD_IOERROR
;
3102 slhci_set_feature(struct slhci_softc
*sc
, unsigned int what
)
3104 struct slhci_transfers
*t
;
3107 t
= &sc
->sc_transfers
;
3109 SLHCI_LOCKASSERT(sc
, locked
, unlocked
);
3111 if (what
== UHF_PORT_RESET
) {
3112 if (!(t
->flags
& F_ACTIVE
)) {
3113 DDOLOG("SET PORT_RESET when not ACTIVE!",
3117 if (!(t
->flags
& F_POWER
)) {
3118 DDOLOG("SET PORT_RESET without PORT_POWER! flags %p",
3122 if (t
->flags
& F_RESET
)
3123 return USBD_NORMAL_COMPLETION
;
3124 DLOG(D_MSG
, "RESET flags %#x", t
->flags
, 0,0,0);
3125 slhci_intrchange(sc
, 0);
3127 slhci_write(sc
, SL11_CTRL
, SL11_CTRL_RESETENGINE
);
3128 /* usb spec says delay >= 10ms, app note 50ms */
3129 start_cc_time(&t_delay
, 50000);
3130 if (sc
->sc_bus
.use_polling
) {
3134 t
->flags
|= F_RESET
;
3135 callout_schedule(&sc
->sc_timer
, max(mstohz(50), 2));
3137 } else if (what
== UHF_PORT_SUSPEND
) {
3138 printf("%s: USB Suspend not implemented!\n", SC_NAME(sc
));
3139 DDOLOG("%s: USB Suspend not implemented!\n", SC_NAME(sc
),
3141 } else if (what
== UHF_PORT_POWER
) {
3142 DLOG(D_MSG
, "PORT_POWER", 0,0,0,0);
3143 /* for x68k Nereid USB controller */
3144 if (!(t
->flags
& F_ACTIVE
))
3146 if (t
->flags
& F_POWER
)
3147 return USBD_NORMAL_COMPLETION
;
3148 if (!(t
->flags
& F_REALPOWER
)) {
3149 if (sc
->sc_enable_power
)
3150 sc
->sc_enable_power(sc
, POWER_ON
);
3151 t
->flags
|= F_REALPOWER
;
3153 t
->flags
|= F_POWER
;
3154 r
= slhci_read(sc
, SL11_ISR
);
3155 if (r
& SL11_ISR_INSERT
)
3156 slhci_write(sc
, SL11_ISR
, SL11_ISR_INSERT
);
3157 if (r
& SL11_ISR_NODEV
) {
3158 slhci_intrchange(sc
, SL11_IER_INSERT
);
3159 t
->flags
|= F_NODEV
;
3161 t
->flags
&= ~F_NODEV
;
3162 t
->flags
|= F_CCONNECT
|F_ROOTINTR
;
3165 DDOLOG("SetPortFeatERR=%#.8x", what
, 0,0,0);
3166 return USBD_IOERROR
;
3169 return USBD_NORMAL_COMPLETION
;
3173 slhci_get_status(struct slhci_softc
*sc
, usb_port_status_t
*ps
)
3175 struct slhci_transfers
*t
;
3176 unsigned int status
, change
;
3178 t
= &sc
->sc_transfers
;
3180 SLHCI_LOCKASSERT(sc
, locked
, unlocked
);
3182 /* We do not have a way to detect over current or bable and
3183 * suspend is currently not implemented, so connect and reset
3184 * are the only changes that need to be reported. */
3186 if (t
->flags
& F_CCONNECT
)
3187 change
|= UPS_C_CONNECT_STATUS
;
3188 if (t
->flags
& F_CRESET
)
3189 change
|= UPS_C_PORT_RESET
;
3192 if (!(t
->flags
& F_NODEV
))
3193 status
|= UPS_CURRENT_CONNECT_STATUS
;
3194 if (!(t
->flags
& F_UDISABLED
))
3195 status
|= UPS_PORT_ENABLED
;
3196 if (t
->flags
& F_RESET
)
3197 status
|= UPS_RESET
;
3198 if (t
->flags
& F_POWER
)
3199 status
|= UPS_PORT_POWER
;
3200 if (t
->flags
& F_LOWSPEED
)
3201 status
|= UPS_LOW_SPEED
;
3202 USETW(ps
->wPortStatus
, status
);
3203 USETW(ps
->wPortChange
, change
);
3204 DLOG(D_ROOT
, "status=%#.4x, change=%#.4x", status
, change
, 0,0);
3208 slhci_root(struct slhci_softc
*sc
, struct slhci_pipe
*spipe
, struct usbd_xfer
3211 struct slhci_transfers
*t
;
3212 usb_device_request_t
*req
;
3213 unsigned int len
, value
, index
, actlen
, type
;
3217 t
= &sc
->sc_transfers
;
3220 LK_SLASSERT(spipe
!= NULL
&& xfer
!= NULL
, sc
, spipe
, xfer
, return
3223 DLOG(D_TRACE
, "%s start", pnames(SLHCI_XFER_TYPE(xfer
)), 0,0,0);
3224 SLHCI_LOCKASSERT(sc
, locked
, unlocked
);
3226 if (spipe
->ptype
== PT_ROOT_INTR
) {
3227 LK_SLASSERT(t
->rootintr
== NULL
, sc
, spipe
, xfer
, return
3230 if (t
->flags
& F_CHANGE
)
3231 t
->flags
|= F_ROOTINTR
;
3232 return USBD_IN_PROGRESS
;
3235 error
= USBD_IOERROR
; /* XXX should be STALL */
3237 req
= &xfer
->request
;
3239 len
= UGETW(req
->wLength
);
3240 value
= UGETW(req
->wValue
);
3241 index
= UGETW(req
->wIndex
);
3243 type
= req
->bmRequestType
;
3246 buf
= KERNADDR(&xfer
->dmabuf
, 0);
3248 SLHCI_DEXEC(D_TRACE
, slhci_log_req_hub(req
));
3251 * USB requests for hubs have two basic types, standard and class.
3252 * Each could potentially have recipients of device, interface,
3253 * endpoint, or other. For the hub class, CLASS_OTHER means the port
3254 * and CLASS_DEVICE means the hub. For standard requests, OTHER
3255 * is not used. Standard request are described in section 9.4 of the
3256 * standard, hub class requests in 11.16. Each request is either read
3259 * Clear Feature, Set Feature, and Status are defined for each of the
3260 * used recipients. Get Descriptor and Set Descriptor are defined for
3261 * both standard and hub class types with different descriptors.
3262 * Other requests have only one defined recipient and type. These
3263 * include: Get/Set Address, Get/Set Configuration, Get/Set Interface,
3264 * and Synch Frame for standard requests and Get Bus State for hub
3267 * When a device is first powered up it has address 0 until the
3270 * Hubs are only allowed to support one interface and may not have
3271 * isochronous endpoints. The results of the related requests are
3274 * The standard requires invalid or unsupported requests to return
3275 * STALL in the data stage, however this does not work well with
3276 * current error handling. XXX
3278 * Some unsupported fields:
3279 * Clear Hub Feature is for C_HUB_LOCAL_POWER and C_HUB_OVER_CURRENT
3280 * Set Device Features is for ENDPOINT_HALT and DEVICE_REMOTE_WAKEUP
3281 * Get Bus State is optional sample of D- and D+ at EOF2
3284 switch (req
->bRequest
) {
3285 /* Write Requests */
3286 case UR_CLEAR_FEATURE
:
3287 if (type
== UT_WRITE_CLASS_OTHER
) {
3288 if (index
== 1 /* Port */)
3289 error
= slhci_clear_feature(sc
, value
);
3291 DLOG(D_ROOT
, "Clear Port Feature "
3292 "index = %#.4x", index
, 0,0,0);
3295 case UR_SET_FEATURE
:
3296 if (type
== UT_WRITE_CLASS_OTHER
) {
3297 if (index
== 1 /* Port */)
3298 error
= slhci_set_feature(sc
, value
);
3300 DLOG(D_ROOT
, "Set Port Feature "
3301 "index = %#.4x", index
, 0,0,0);
3302 } else if (type
!= UT_WRITE_CLASS_DEVICE
)
3303 DLOG(D_ROOT
, "Set Device Feature "
3304 "ENDPOINT_HALT or DEVICE_REMOTE_WAKEUP "
3305 "not supported", 0,0,0,0);
3307 case UR_SET_ADDRESS
:
3308 if (type
== UT_WRITE_DEVICE
) {
3309 DLOG(D_ROOT
, "Set Address %#.4x", value
, 0,0,0);
3310 if (value
< USB_MAX_DEVICES
) {
3311 t
->rootaddr
= value
;
3312 error
= USBD_NORMAL_COMPLETION
;
3317 if (type
== UT_WRITE_DEVICE
) {
3318 DLOG(D_ROOT
, "Set Config %#.4x", value
, 0,0,0);
3319 if (value
== 0 || value
== 1) {
3320 t
->rootconf
= value
;
3321 error
= USBD_NORMAL_COMPLETION
;
3327 if (type
== UT_READ_CLASS_OTHER
) {
3328 if (index
== 1 /* Port */ && len
== /* XXX >=? */
3329 sizeof(usb_port_status_t
)) {
3330 slhci_get_status(sc
, (usb_port_status_t
*)
3332 actlen
= sizeof(usb_port_status_t
);
3333 error
= USBD_NORMAL_COMPLETION
;
3335 DLOG(D_ROOT
, "Get Port Status index = %#.4x "
3336 "len = %#.4x", index
, len
, 0,0);
3337 } else if (type
== UT_READ_CLASS_DEVICE
) { /* XXX index? */
3338 if (len
== sizeof(usb_hub_status_t
)) {
3339 DLOG(D_ROOT
, "Get Hub Status",
3341 actlen
= sizeof(usb_hub_status_t
);
3342 memset(buf
, 0, actlen
);
3343 error
= USBD_NORMAL_COMPLETION
;
3345 DLOG(D_ROOT
, "Get Hub Status bad len %#.4x",
3347 } else if (type
== UT_READ_DEVICE
) {
3349 USETW(((usb_status_t
*)buf
)->wStatus
, UDS_SELF_POWERED
);
3351 error
= USBD_NORMAL_COMPLETION
;
3353 } else if (type
== (UT_READ_INTERFACE
|UT_READ_ENDPOINT
)) {
3355 USETW(((usb_status_t
*)buf
)->wStatus
, 0);
3357 error
= USBD_NORMAL_COMPLETION
;
3362 if (type
== UT_READ_DEVICE
) {
3363 DLOG(D_ROOT
, "Get Config", 0,0,0,0);
3367 error
= USBD_NORMAL_COMPLETION
;
3371 case UR_GET_INTERFACE
:
3372 if (type
== UT_READ_INTERFACE
) {
3376 error
= USBD_NORMAL_COMPLETION
;
3380 case UR_GET_DESCRIPTOR
:
3381 if (type
== UT_READ_DEVICE
) {
3382 /* value is type (&0xff00) and index (0xff) */
3383 if (value
== (UDESC_DEVICE
<<8)) {
3384 actlen
= min(len
, sizeof(slhci_devd
));
3385 memcpy(buf
, &slhci_devd
, actlen
);
3386 error
= USBD_NORMAL_COMPLETION
;
3387 } else if (value
== (UDESC_CONFIG
<<8)) {
3388 actlen
= min(len
, sizeof(slhci_confd
));
3389 memcpy(buf
, &slhci_confd
, actlen
);
3390 if (actlen
> offsetof(usb_config_descriptor_t
,
3392 ((usb_config_descriptor_t
*)
3393 buf
)->bMaxPower
= t
->max_current
;
3395 error
= USBD_NORMAL_COMPLETION
;
3396 } else if (value
== (UDESC_STRING
<<8)) {
3397 /* language table XXX */
3398 } else if (value
== ((UDESC_STRING
<<8)|1)) {
3400 actlen
= usb_makestrdesc((usb_string_descriptor_t
*)
3401 buf
, len
, "ScanLogic/Cypress");
3402 error
= USBD_NORMAL_COMPLETION
;
3403 } else if (value
== ((UDESC_STRING
<<8)|2)) {
3405 actlen
= usb_makestrdesc((usb_string_descriptor_t
*)
3406 buf
, len
, "SL811HS/T root hub");
3407 error
= USBD_NORMAL_COMPLETION
;
3409 DDOLOG("Unknown Get Descriptor %#.4x",
3411 } else if (type
== UT_READ_CLASS_DEVICE
) {
3412 /* Descriptor number is 0 */
3413 if (value
== (UDESC_HUB
<<8)) {
3414 actlen
= min(len
, sizeof(slhci_hubd
));
3415 memcpy(buf
, &slhci_hubd
, actlen
);
3416 if (actlen
> offsetof(usb_config_descriptor_t
,
3418 ((usb_hub_descriptor_t
*)
3419 buf
)->bHubContrCurrent
= 500 -
3421 error
= USBD_NORMAL_COMPLETION
;
3423 DDOLOG("Unknown Get Hub Descriptor %#.4x",
3429 if (error
== USBD_NORMAL_COMPLETION
)
3430 xfer
->actlen
= actlen
;
3431 xfer
->status
= error
;
3432 KASSERT(spipe
->xfer
== NULL
);
3434 enter_callback(t
, spipe
);
3436 return USBD_IN_PROGRESS
;
3439 /* End in lock functions. Start debug functions. */
3443 slhci_log_buffer(struct usbd_xfer
*xfer
)
3447 if(xfer
->length
> 0 &&
3448 UE_GET_DIR(xfer
->pipe
->endpoint
->edesc
->bEndpointAddress
) ==
3450 buf
= KERNADDR(&xfer
->dmabuf
, 0);
3451 DDOLOGBUF(buf
, xfer
->actlen
);
3452 DDOLOG("len %d actlen %d short %d", xfer
->length
,
3453 xfer
->actlen
, xfer
->length
- xfer
->actlen
, 0);
3458 slhci_log_req(usb_device_request_t
*r
)
3460 static const char *xmes
[]={
3476 int req
, mreq
, type
, value
, index
, len
;
3479 mreq
= (req
> 13) ? 13 : req
;
3480 type
= r
->bmRequestType
;
3481 value
= UGETW(r
->wValue
);
3482 index
= UGETW(r
->wIndex
);
3483 len
= UGETW(r
->wLength
);
3485 DDOLOG("request: %s %#x", xmes
[mreq
], type
, 0,0);
3486 DDOLOG("request: r=%d,v=%d,i=%d,l=%d ", req
, value
, index
, len
);
3490 slhci_log_req_hub(usb_device_request_t
*r
)
3492 static const struct {
3497 { 1, 0x20, "ClrHubFeat" },
3498 { 1, 0x23, "ClrPortFeat" },
3499 { 2, 0xa3, "GetBusState" },
3500 { 6, 0xa0, "GetHubDesc" },
3501 { 0, 0xa0, "GetHubStat" },
3502 { 0, 0xa3, "GetPortStat" },
3503 { 7, 0x20, "SetHubDesc" },
3504 { 3, 0x20, "SetHubFeat" },
3505 { 3, 0x23, "SetPortFeat" },
3509 int value
, index
, len
;
3512 value
= UGETW(r
->wValue
);
3513 index
= UGETW(r
->wIndex
);
3514 len
= UGETW(r
->wLength
);
3515 for (i
= 0; ; i
++) {
3516 if (conf
[i
].req
== -1 ) {
3520 if (r
->bmRequestType
== conf
[i
].type
&& r
->bRequest
== conf
[i
].req
) {
3525 DDOLOG("hub request: %s v=%d,i=%d,l=%d ", str
, value
, index
, len
);
3529 slhci_log_dumpreg(void)
3532 unsigned int aaddr
, alen
, baddr
, blen
;
3533 static u_char buf
[240];
3535 r
= slhci_read(ssc
, SL11_E0CTRL
);
3536 DDOLOG("USB A Host Control = %#.2x", r
, 0,0,0);
3537 DDOLOGFLAG8("E0CTRL=", r
, "Preamble", "Data Toggle", "SOF Sync",
3538 "ISOC", "res", "Out", "Enable", "Arm");
3539 aaddr
= slhci_read(ssc
, SL11_E0ADDR
);
3540 DDOLOG("USB A Base Address = %u", aaddr
, 0,0,0);
3541 alen
= slhci_read(ssc
, SL11_E0LEN
);
3542 DDOLOG("USB A Length = %u", alen
, 0,0,0);
3543 r
= slhci_read(ssc
, SL11_E0STAT
);
3544 DDOLOG("USB A Status = %#.2x", r
, 0,0,0);
3545 DDOLOGFLAG8("E0STAT=", r
, "STALL", "NAK", "Overflow", "Setup",
3546 "Data Toggle", "Timeout", "Error", "ACK");
3547 r
= slhci_read(ssc
, SL11_E0CONT
);
3548 DDOLOG("USB A Remaining or Overflow Length = %u", r
, 0,0,0);
3549 r
= slhci_read(ssc
, SL11_E1CTRL
);
3550 DDOLOG("USB B Host Control = %#.2x", r
, 0,0,0);
3551 DDOLOGFLAG8("E1CTRL=", r
, "Preamble", "Data Toggle", "SOF Sync",
3552 "ISOC", "res", "Out", "Enable", "Arm");
3553 baddr
= slhci_read(ssc
, SL11_E1ADDR
);
3554 DDOLOG("USB B Base Address = %u", baddr
, 0,0,0);
3555 blen
= slhci_read(ssc
, SL11_E1LEN
);
3556 DDOLOG("USB B Length = %u", blen
, 0,0,0);
3557 r
= slhci_read(ssc
, SL11_E1STAT
);
3558 DDOLOG("USB B Status = %#.2x", r
, 0,0,0);
3559 DDOLOGFLAG8("E1STAT=", r
, "STALL", "NAK", "Overflow", "Setup",
3560 "Data Toggle", "Timeout", "Error", "ACK");
3561 r
= slhci_read(ssc
, SL11_E1CONT
);
3562 DDOLOG("USB B Remaining or Overflow Length = %u", r
, 0,0,0);
3564 r
= slhci_read(ssc
, SL11_CTRL
);
3565 DDOLOG("Control = %#.2x", r
, 0,0,0);
3566 DDOLOGFLAG8("CTRL=", r
, "res", "Suspend", "LOW Speed",
3567 "J-K State Force", "Reset", "res", "res", "SOF");
3568 r
= slhci_read(ssc
, SL11_IER
);
3569 DDOLOG("Interrupt Enable = %#.2x", r
, 0,0,0);
3570 DDOLOGFLAG8("IER=", r
, "D+ **IER!**", "Device Detect/Resume",
3571 "Insert/Remove", "SOF", "res", "res", "USBB", "USBA");
3572 r
= slhci_read(ssc
, SL11_ISR
);
3573 DDOLOG("Interrupt Status = %#.2x", r
, 0,0,0);
3574 DDOLOGFLAG8("ISR=", r
, "D+", "Device Detect/Resume",
3575 "Insert/Remove", "SOF", "res", "res", "USBB", "USBA");
3576 r
= slhci_read(ssc
, SL11_REV
);
3577 DDOLOG("Revision = %#.2x", r
, 0,0,0);
3578 r
= slhci_read(ssc
, SL811_CSOF
);
3579 DDOLOG("SOF Counter = %#.2x", r
, 0,0,0);
3581 if (alen
&& aaddr
>= SL11_BUFFER_START
&& aaddr
< SL11_BUFFER_END
&&
3582 alen
<= SL11_MAX_PACKET_SIZE
&& aaddr
+ alen
<= SL11_BUFFER_END
) {
3583 slhci_read_multi(ssc
, aaddr
, buf
, alen
);
3584 DDOLOG("USBA Buffer: start %u len %u", aaddr
, alen
, 0,0);
3585 DDOLOGBUF(buf
, alen
);
3587 DDOLOG("USBA Buffer Invalid", 0,0,0,0);
3589 if (blen
&& baddr
>= SL11_BUFFER_START
&& baddr
< SL11_BUFFER_END
&&
3590 blen
<= SL11_MAX_PACKET_SIZE
&& baddr
+ blen
<= SL11_BUFFER_END
) {
3591 slhci_read_multi(ssc
, baddr
, buf
, blen
);
3592 DDOLOG("USBB Buffer: start %u len %u", baddr
, blen
, 0,0);
3593 DDOLOGBUF(buf
, blen
);
3595 DDOLOG("USBB Buffer Invalid", 0,0,0,0);
3599 slhci_log_xfer(struct usbd_xfer
*xfer
)
3601 DDOLOG("xfer: length=%u, actlen=%u, flags=%#x, timeout=%u,",
3602 xfer
->length
, xfer
->actlen
, xfer
->flags
, xfer
->timeout
);
3603 if (xfer
->dmabuf
.block
)
3604 DDOLOG("buffer=%p", KERNADDR(&xfer
->dmabuf
, 0), 0,0,0);
3605 slhci_log_req_hub(&xfer
->request
);
3609 slhci_log_spipe(struct slhci_pipe
*spipe
)
3611 DDOLOG("spipe %p onlists: %s %s %s", spipe
, gcq_onlist(&spipe
->ap
) ?
3612 "AP" : "", gcq_onlist(&spipe
->to
) ? "TO" : "",
3613 gcq_onlist(&spipe
->xq
) ? "XQ" : "");
3614 DDOLOG("spipe: xfer %p buffer %p pflags %#x ptype %s",
3615 spipe
->xfer
, spipe
->buffer
, spipe
->pflags
, pnames(spipe
->ptype
));
3619 slhci_print_intr(void)
3621 unsigned int ier
, isr
;
3622 ier
= slhci_read(ssc
, SL11_IER
);
3623 isr
= slhci_read(ssc
, SL11_ISR
);
3624 printf("IER: %#x ISR: %#x \n", ier
, isr
);
3631 struct slhci_transfers
*t
;
3634 t
= &ssc
->sc_transfers
;
3636 DDOLOG("Flags=%#x", t
->flags
, 0,0,0);
3637 DDOLOG("a = %p Alen=%d b = %p Blen=%d", t
->spipe
[0], t
->len
[0],
3638 t
->spipe
[1], t
->len
[1]);
3640 for (i
=0; i
<=Q_MAX
; i
++)
3641 DDOLOG("Q %d: %p", i
, gcq_first(&t
->q
[i
]), 0,0);
3643 DDOLOG("TIMED: %p", GCQ_ITEM(gcq_first(&t
->to
),
3644 struct slhci_pipe
, to
), 0,0,0);
3646 DDOLOG("frame=%d rootintr=%p", t
->frame
, t
->rootintr
, 0,0);
3648 DDOLOG("use_polling=%d intr_context=%d", ssc
->sc_bus
.use_polling
,
3649 ssc
->sc_bus
.intr_context
, 0,0);
3653 slhci_log_slreq(struct slhci_pipe
*r
)
3655 DDOLOG("next: %p", r
->q
.next
.sqe_next
, 0,0,0);
3656 DDOLOG("xfer: %p", r
->xfer
, 0,0,0);
3657 DDOLOG("buffer: %p", r
->buffer
, 0,0,0);
3658 DDOLOG("bustime: %u", r
->bustime
, 0,0,0);
3659 DDOLOG("control: %#x", r
->control
, 0,0,0);
3660 DDOLOGFLAG8("control=", r
->control
, "Preamble", "Data Toggle",
3661 "SOF Sync", "ISOC", "res", "Out", "Enable", "Arm");
3662 DDOLOG("pid: %#x", r
->tregs
[PID
], 0,0,0);
3663 DDOLOG("dev: %u", r
->tregs
[DEV
], 0,0,0);
3664 DDOLOG("len: %u", r
->tregs
[LEN
], 0,0,0);
3667 slhci_log_xfer(r
->xfer
);
3670 #endif /* SLHCI_DEBUG */
3671 /* End debug functions. */