source: rtems-libbsd/freebsd/sys/dev/usb/controller/saf1761_otg.c @ 1e77a45

55-freebsd-126-freebsd-12
Last change on this file since 1e77a45 was 1e77a45, checked in by Sebastian Huber <sebastian.huber@…>, on 10/04/18 at 10:06:44

saf1761_otg: Use real interrupt handler

The USB_BUS_SPIN_LOCK() is only used internally to the bus driver.
Replace the mutex with an interrupt disable/enable section. Execute the
interrupt filter in a real interrupt context and forward the interrupt
handler to the interrupt server if necessary.

  • Property mode set to 100644
File size: 91.6 KB
Line 
1#include <machine/rtems-bsd-kernel-space.h>
2
3/* $FreeBSD$ */
4/*-
5 * Copyright (c) 2014 Hans Petter Selasky <hselasky@FreeBSD.org>
6 * All rights reserved.
7 *
8 * This software was developed by SRI International and the University of
9 * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237)
10 * ("CTSRD"), as part of the DARPA CRASH research programme.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 *    notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 *    notice, this list of conditions and the following disclaimer in the
19 *    documentation and/or other materials provided with the distribution.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34/*
35 * This file contains the driver for the SAF1761 series USB OTG
36 * controller.
37 *
38 * Datasheet is available from:
39 * http://www.nxp.com/products/automotive/multimedia/usb/SAF1761BE.html
40 */
41
42#ifdef USB_GLOBAL_INCLUDE_FILE
43#include USB_GLOBAL_INCLUDE_FILE
44#else
45#include <sys/stdint.h>
46#include <sys/stddef.h>
47#include <sys/param.h>
48#include <sys/queue.h>
49#include <sys/types.h>
50#include <sys/systm.h>
51#include <sys/kernel.h>
52#include <sys/bus.h>
53#include <sys/module.h>
54#include <sys/lock.h>
55#include <sys/mutex.h>
56#include <sys/condvar.h>
57#include <sys/sysctl.h>
58#include <sys/sx.h>
59#include <rtems/bsd/sys/unistd.h>
60#include <sys/callout.h>
61#include <sys/malloc.h>
62#include <sys/priv.h>
63#include <sys/libkern.h>
64
65#include <dev/usb/usb.h>
66#include <dev/usb/usbdi.h>
67
68#define USB_DEBUG_VAR saf1761_otg_debug
69
70#include <dev/usb/usb_core.h>
71#include <dev/usb/usb_debug.h>
72#include <dev/usb/usb_busdma.h>
73#include <dev/usb/usb_process.h>
74#include <dev/usb/usb_transfer.h>
75#include <dev/usb/usb_device.h>
76#include <dev/usb/usb_hub.h>
77#include <dev/usb/usb_util.h>
78
79#include <dev/usb/usb_controller.h>
80#include <dev/usb/usb_bus.h>
81#endif                                  /* USB_GLOBAL_INCLUDE_FILE */
82
83#include <dev/usb/controller/saf1761_otg.h>
84#include <dev/usb/controller/saf1761_otg_reg.h>
85#ifdef __rtems__
86#include <rtems.h>
87#include <bsp.h>
88#ifdef LIBBSP_ARM_ATSAM_BSP_H
89#include <bsp/pin-config.h>
90#endif /* LIBBSP_ARM_ATSAM_BSP_H */
91#undef  USB_BUS_SPIN_LOCK
92#undef  USB_BUS_SPIN_UNLOCK
93#define USB_BUS_SPIN_LOCK(_b) \
94    do { \
95        rtems_interrupt_level usb_bus_spin_lock; \
96        rtems_interrupt_disable(usb_bus_spin_lock)
97#define USB_BUS_SPIN_UNLOCK(_b) \
98        rtems_interrupt_enable(usb_bus_spin_lock); \
99    } while (0)
100#endif /* __rtems__ */
101
102#define SAF1761_OTG_BUS2SC(bus) \
103   ((struct saf1761_otg_softc *)(((uint8_t *)(bus)) - \
104    ((uint8_t *)&(((struct saf1761_otg_softc *)0)->sc_bus))))
105
106#define SAF1761_OTG_PC2UDEV(pc) \
107   (USB_DMATAG_TO_XROOT((pc)->tag_parent)->udev)
108
109#define SAF1761_DCINTERRUPT_THREAD_IRQ                  \
110  (SOTG_DCINTERRUPT_IEVBUS | SOTG_DCINTERRUPT_IEBRST |  \
111  SOTG_DCINTERRUPT_IERESM | SOTG_DCINTERRUPT_IESUSP)
112
113#ifdef USB_DEBUG
114static int saf1761_otg_debug = 0;
115static int saf1761_otg_forcefs = 0;
116
117static
118SYSCTL_NODE(_hw_usb, OID_AUTO, saf1761_otg, CTLFLAG_RW, 0,
119    "USB SAF1761 DCI");
120
121SYSCTL_INT(_hw_usb_saf1761_otg, OID_AUTO, debug, CTLFLAG_RWTUN,
122    &saf1761_otg_debug, 0, "SAF1761 DCI debug level");
123SYSCTL_INT(_hw_usb_saf1761_otg, OID_AUTO, forcefs, CTLFLAG_RWTUN,
124    &saf1761_otg_forcefs, 0, "SAF1761 DCI force FULL speed");
125#endif
126
127#define SAF1761_OTG_INTR_ENDPT 1
128
129/* prototypes */
130
131static const struct usb_bus_methods saf1761_otg_bus_methods;
132static const struct usb_pipe_methods saf1761_otg_non_isoc_methods;
133static const struct usb_pipe_methods saf1761_otg_device_isoc_methods;
134static const struct usb_pipe_methods saf1761_otg_host_isoc_methods;
135
136static saf1761_otg_cmd_t saf1761_host_setup_tx;
137static saf1761_otg_cmd_t saf1761_host_bulk_data_rx;
138static saf1761_otg_cmd_t saf1761_host_bulk_data_tx;
139static saf1761_otg_cmd_t saf1761_host_intr_data_rx;
140static saf1761_otg_cmd_t saf1761_host_intr_data_tx;
141static saf1761_otg_cmd_t saf1761_host_isoc_data_rx;
142static saf1761_otg_cmd_t saf1761_host_isoc_data_tx;
143static saf1761_otg_cmd_t saf1761_device_setup_rx;
144static saf1761_otg_cmd_t saf1761_device_data_rx;
145static saf1761_otg_cmd_t saf1761_device_data_tx;
146static saf1761_otg_cmd_t saf1761_device_data_tx_sync;
147static void saf1761_otg_device_done(struct usb_xfer *, usb_error_t);
148static void saf1761_otg_do_poll(struct usb_bus *);
149static void saf1761_otg_standard_done(struct usb_xfer *);
150static void saf1761_otg_intr_set(struct usb_xfer *, uint8_t);
151static void saf1761_otg_root_intr(struct saf1761_otg_softc *);
152static void saf1761_otg_enable_psof(struct saf1761_otg_softc *, uint8_t);
153
154/*
155 * Here is a list of what the SAF1761 chip can support. The main
156 * limitation is that the sum of the buffer sizes must be less than
157 * 8192 bytes.
158 */
159static const struct usb_hw_ep_profile saf1761_otg_ep_profile[] = {
160
161        [0] = {
162                .max_in_frame_size = 64,
163                .max_out_frame_size = 64,
164                .is_simplex = 0,
165                .support_control = 1,
166        },
167        [1] = {
168                .max_in_frame_size = SOTG_HS_MAX_PACKET_SIZE,
169                .max_out_frame_size = SOTG_HS_MAX_PACKET_SIZE,
170                .is_simplex = 0,
171                .support_interrupt = 1,
172                .support_bulk = 1,
173                .support_isochronous = 1,
174                .support_in = 1,
175                .support_out = 1,
176        },
177};
178
179static void
180saf1761_otg_get_hw_ep_profile(struct usb_device *udev,
181    const struct usb_hw_ep_profile **ppf, uint8_t ep_addr)
182{
183        if (ep_addr == 0) {
184                *ppf = saf1761_otg_ep_profile + 0;
185        } else if (ep_addr < 8) {
186                *ppf = saf1761_otg_ep_profile + 1;
187        } else {
188                *ppf = NULL;
189        }
190}
191
192static void
193saf1761_otg_pull_up(struct saf1761_otg_softc *sc)
194{
195        /* activate pullup on D+, if possible */
196
197        if (!sc->sc_flags.d_pulled_up && sc->sc_flags.port_powered) {
198                DPRINTF("\n");
199
200                sc->sc_flags.d_pulled_up = 1;
201        }
202}
203
204static void
205saf1761_otg_pull_down(struct saf1761_otg_softc *sc)
206{
207        /* release pullup on D+, if possible */
208
209        if (sc->sc_flags.d_pulled_up) {
210                DPRINTF("\n");
211
212                sc->sc_flags.d_pulled_up = 0;
213        }
214}
215
216static void
217saf1761_otg_wakeup_peer(struct saf1761_otg_softc *sc)
218{
219        uint16_t temp;
220
221        if (!(sc->sc_flags.status_suspend))
222                return;
223
224        DPRINTFN(5, "\n");
225
226        temp = SAF1761_READ_LE_4(sc, SOTG_MODE);
227        SAF1761_WRITE_LE_4(sc, SOTG_MODE, temp | SOTG_MODE_SNDRSU);
228        SAF1761_WRITE_LE_4(sc, SOTG_MODE, temp & ~SOTG_MODE_SNDRSU);
229
230        /* Wait 8ms for remote wakeup to complete. */
231        usb_pause_mtx(&sc->sc_bus.bus_mtx, hz / 125);
232}
233
234static uint8_t
235saf1761_host_channel_alloc(struct saf1761_otg_softc *sc, struct saf1761_otg_td *td)
236{
237        uint32_t map;
238        int x;
239
240        if (td->channel < SOTG_HOST_CHANNEL_MAX)
241                return (0);
242
243        /* check if device is suspended */
244        if (SAF1761_OTG_PC2UDEV(td->pc)->flags.self_suspended != 0)
245                return (1);             /* busy - cannot transfer data */
246
247        switch (td->ep_type) {
248        case UE_INTERRUPT:
249                map = ~(sc->sc_host_intr_map |
250                    sc->sc_host_intr_busy_map[0] |
251                    sc->sc_host_intr_busy_map[1]);
252                /* find first set bit */
253                x = ffs(map) - 1;
254                if (x < 0 || x > 31)
255                        break;
256                sc->sc_host_intr_map |= (1U << x);
257                td->channel = 32 + x;
258                return (0);
259        case UE_ISOCHRONOUS:
260                map = ~(sc->sc_host_isoc_map |
261                    sc->sc_host_isoc_busy_map[0] |
262                    sc->sc_host_isoc_busy_map[1]);
263                /* find first set bit */
264                x = ffs(map) - 1;
265                if (x < 0 || x > 31)
266                        break;
267                sc->sc_host_isoc_map |= (1U << x);
268                td->channel = x;
269                return (0);
270        default:
271                map = ~(sc->sc_host_async_map |
272                    sc->sc_host_async_busy_map[0] |
273                    sc->sc_host_async_busy_map[1]);
274                /* find first set bit */
275                x = ffs(map) - 1;
276                if (x < 0 || x > 31)
277                        break;
278                sc->sc_host_async_map |= (1U << x);
279                td->channel = 64 + x;
280                return (0);
281        }
282        return (1);
283}
284
285static void
286saf1761_host_channel_free(struct saf1761_otg_softc *sc, struct saf1761_otg_td *td)
287{
288        uint32_t x;
289
290        if (td->channel >= SOTG_HOST_CHANNEL_MAX)
291                return;
292
293        switch (td->ep_type) {
294        case UE_INTERRUPT:
295                x = td->channel - 32;
296                td->channel = SOTG_HOST_CHANNEL_MAX;
297                sc->sc_host_intr_map &= ~(1U << x);
298                sc->sc_host_intr_suspend_map &= ~(1U << x);
299                sc->sc_host_intr_busy_map[0] |= (1U << x);
300                SAF1761_WRITE_LE_4(sc, SOTG_INT_PTD_SKIP_PTD,
301                    (~sc->sc_host_intr_map) | sc->sc_host_intr_suspend_map);
302                break;
303        case UE_ISOCHRONOUS:
304                x = td->channel;
305                td->channel = SOTG_HOST_CHANNEL_MAX;
306                sc->sc_host_isoc_map &= ~(1U << x);
307                sc->sc_host_isoc_suspend_map &= ~(1U << x);
308                sc->sc_host_isoc_busy_map[0] |= (1U << x);
309                SAF1761_WRITE_LE_4(sc, SOTG_ISO_PTD_SKIP_PTD,
310                    (~sc->sc_host_isoc_map) | sc->sc_host_isoc_suspend_map);
311                break;
312        default:
313                x = td->channel - 64;
314                td->channel = SOTG_HOST_CHANNEL_MAX;
315                sc->sc_host_async_map &= ~(1U << x);
316                sc->sc_host_async_suspend_map &= ~(1U << x);
317                sc->sc_host_async_busy_map[0] |= (1U << x);
318                SAF1761_WRITE_LE_4(sc, SOTG_ATL_PTD_SKIP_PTD,
319                    (~sc->sc_host_async_map) | sc->sc_host_async_suspend_map);
320                break;
321        }
322        saf1761_otg_enable_psof(sc, 1);
323}
324
325static uint32_t
326saf1761_peek_host_status_le_4(struct saf1761_otg_softc *sc, uint32_t offset)
327{
328        uint32_t x = 0;
329        while (1) {
330                uint32_t retval;
331
332                SAF1761_WRITE_LE_4(sc, SOTG_MEMORY_REG, offset);
333                SAF1761_90NS_DELAY(sc); /* read prefetch time is 90ns */
334                retval = SAF1761_READ_LE_4(sc, offset);
335                if (retval != 0)
336                        return (retval);
337                if (++x == 8) {
338                        DPRINTF("STAUS is zero at offset 0x%x\n", offset);
339                        break;
340                }
341        }
342        return (0);
343}
344
345static void
346saf1761_read_host_memory(struct saf1761_otg_softc *sc,
347    struct saf1761_otg_td *td, uint32_t len)
348{
349        struct usb_page_search buf_res;
350        uint32_t offset;
351        uint32_t count;
352
353        if (len == 0)
354                return;
355
356        offset = SOTG_DATA_ADDR(td->channel);
357        SAF1761_WRITE_LE_4(sc, SOTG_MEMORY_REG, offset);
358        SAF1761_90NS_DELAY(sc); /* read prefetch time is 90ns */
359
360        /* optimised read first */
361        while (len > 0) {
362                usbd_get_page(td->pc, td->offset, &buf_res);
363
364                /* get correct length */
365                if (buf_res.length > len)
366                        buf_res.length = len;
367
368                /* check buffer alignment */
369                if (((uintptr_t)buf_res.buffer) & 3)
370                        break;
371
372                count = buf_res.length & ~3;
373                if (count == 0)
374                        break;
375
376                bus_space_read_region_4((sc)->sc_io_tag, (sc)->sc_io_hdl,
377                    offset, buf_res.buffer, count / 4);
378
379                len -= count;
380                offset += count;
381
382                /* update remainder and offset */
383                td->remainder -= count;
384                td->offset += count;
385        }
386
387        if (len > 0) {
388                /* use bounce buffer */
389                bus_space_read_region_4((sc)->sc_io_tag, (sc)->sc_io_hdl,
390                    offset, sc->sc_bounce_buffer, (len + 3) / 4);
391                usbd_copy_in(td->pc, td->offset,
392                    sc->sc_bounce_buffer, len);
393
394                /* update remainder and offset */
395                td->remainder -= len;
396                td->offset += len;
397        }
398}
399
400static void
401saf1761_write_host_memory(struct saf1761_otg_softc *sc,
402    struct saf1761_otg_td *td, uint32_t len)
403{
404        struct usb_page_search buf_res;
405        uint32_t offset;
406        uint32_t count;
407
408        if (len == 0)
409                return;
410
411        offset = SOTG_DATA_ADDR(td->channel);
412
413        /* optimised write first */
414        while (len > 0) {
415                usbd_get_page(td->pc, td->offset, &buf_res);
416
417                /* get correct length */
418                if (buf_res.length > len)
419                        buf_res.length = len;
420
421                /* check buffer alignment */
422                if (((uintptr_t)buf_res.buffer) & 3)
423                        break;
424
425                count = buf_res.length & ~3;
426                if (count == 0)
427                        break;
428
429                bus_space_write_region_4((sc)->sc_io_tag, (sc)->sc_io_hdl,
430                    offset, buf_res.buffer, count / 4);
431
432                len -= count;
433                offset += count;
434
435                /* update remainder and offset */
436                td->remainder -= count;
437                td->offset += count;
438        }
439        if (len > 0) {
440                /* use bounce buffer */
441                usbd_copy_out(td->pc, td->offset, sc->sc_bounce_buffer, len);
442                bus_space_write_region_4((sc)->sc_io_tag, (sc)->sc_io_hdl,
443                    offset, sc->sc_bounce_buffer, (len + 3) / 4);
444
445                /* update remainder and offset */
446                td->remainder -= len;
447                td->offset += len;
448        }
449}
450
451static uint8_t
452saf1761_host_setup_tx(struct saf1761_otg_softc *sc, struct saf1761_otg_td *td)
453{
454        uint32_t pdt_addr;
455        uint32_t status;
456        uint32_t count;
457        uint32_t temp;
458
459        if (td->channel < SOTG_HOST_CHANNEL_MAX) {
460                pdt_addr = SOTG_PTD(td->channel);
461
462                status = saf1761_peek_host_status_le_4(sc, pdt_addr + SOTG_PTD_DW3);
463
464                DPRINTFN(5, "STATUS=0x%08x\n", status);
465
466                if (status & SOTG_PTD_DW3_ACTIVE) {
467                        goto busy;
468                } else if (status & SOTG_PTD_DW3_HALTED) {
469                        td->error_any = 1;
470                }
471                goto complete;
472        }
473        if (saf1761_host_channel_alloc(sc, td))
474                goto busy;
475
476        count = 8;
477
478        if (count != td->remainder) {
479                td->error_any = 1;
480                goto complete;
481        }
482
483        saf1761_write_host_memory(sc, td, count);
484
485        pdt_addr = SOTG_PTD(td->channel);
486
487        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW7, 0);
488        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW6, 0);
489        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW5, 0);
490        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW4, 0);
491
492        temp = SOTG_PTD_DW3_ACTIVE | (td->toggle << 25) | SOTG_PTD_DW3_CERR_3;
493        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW3, temp);
494           
495        temp = SOTG_HC_MEMORY_ADDR(SOTG_DATA_ADDR(td->channel)) << 8;
496        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW2, temp);
497
498        temp = td->dw1_value | (2 << 10) /* SETUP PID */ | (td->ep_index >> 1);
499        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW1, temp);
500
501        temp = (td->ep_index << 31) | (1 << 29) /* pkt-multiplier */ |
502            (td->max_packet_size << 18) /* wMaxPacketSize */ |
503            (count << 3) /* transfer count */ |
504            SOTG_PTD_DW0_VALID;
505        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW0, temp);
506
507        /* activate PTD */
508        SAF1761_WRITE_LE_4(sc, SOTG_ATL_PTD_SKIP_PTD,
509            (~sc->sc_host_async_map) | sc->sc_host_async_suspend_map);
510
511        td->toggle = 1;
512busy:
513        return (1);     /* busy */
514complete:
515        saf1761_host_channel_free(sc, td);
516        return (0);     /* complete */
517}
518
519static uint8_t
520saf1761_host_bulk_data_rx(struct saf1761_otg_softc *sc, struct saf1761_otg_td *td)
521{
522        uint32_t pdt_addr;
523        uint32_t temp;
524
525        if (td->channel < SOTG_HOST_CHANNEL_MAX) {
526                uint32_t status;
527                uint32_t count;
528                uint8_t got_short;
529
530                pdt_addr = SOTG_PTD(td->channel);
531
532                status = saf1761_peek_host_status_le_4(sc, pdt_addr + SOTG_PTD_DW3);
533
534                DPRINTFN(5, "STATUS=0x%08x\n", status);
535
536                if (status & SOTG_PTD_DW3_ACTIVE) {
537                        temp = saf1761_peek_host_status_le_4(sc,
538                            pdt_addr + SOTG_PTD_DW0);
539                        if (temp & SOTG_PTD_DW0_VALID) {
540                                goto busy;
541                        } else {
542                                status = saf1761_peek_host_status_le_4(sc,
543                                    pdt_addr + SOTG_PTD_DW3);
544
545                                /* check if still active */
546                                if (status & SOTG_PTD_DW3_ACTIVE) {
547                                        saf1761_host_channel_free(sc, td);
548                                        goto retry;
549                                } else if (status & SOTG_PTD_DW3_HALTED) {
550                                        if (!(status & SOTG_PTD_DW3_ERRORS))
551                                                td->error_stall = 1;
552                                        td->error_any = 1;
553                                        goto complete;
554                                }
555                        }
556                } else if (status & SOTG_PTD_DW3_HALTED) {
557                        if (!(status & SOTG_PTD_DW3_ERRORS))
558                                td->error_stall = 1;
559                        td->error_any = 1;
560                        goto complete;
561                }
562                if (td->dw1_value & SOTG_PTD_DW1_ENABLE_SPLIT)
563                        count = (status & SOTG_PTD_DW3_XFER_COUNT_SPLIT);
564                else
565                        count = (status & SOTG_PTD_DW3_XFER_COUNT_HS);
566                got_short = 0;
567
568                /* verify the packet byte count */
569                if (count != td->max_packet_size) {
570                        if (count < td->max_packet_size) {
571                                /* we have a short packet */
572                                td->short_pkt = 1;
573                                got_short = 1;
574                        } else {
575                                /* invalid USB packet */
576                                td->error_any = 1;
577                                goto complete;
578                        }
579                }
580                td->toggle ^= 1;
581
582                /* verify the packet byte count */
583                if (count > td->remainder) {
584                        /* invalid USB packet */
585                        td->error_any = 1;
586                        goto complete;
587                }
588
589                saf1761_read_host_memory(sc, td, count);
590
591                /* check if we are complete */
592                if ((td->remainder == 0) || got_short) {
593                        if (td->short_pkt)
594                                goto complete;
595                        /* else need to receive a zero length packet */
596                }
597                saf1761_host_channel_free(sc, td);
598        }
599retry:
600        if (saf1761_host_channel_alloc(sc, td))
601                goto busy;
602
603        /* set toggle, if any */
604        if (td->set_toggle) {
605                td->set_toggle = 0;
606                td->toggle = 1;
607        }
608
609        /* receive one more packet */
610
611        pdt_addr = SOTG_PTD(td->channel);
612
613        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW7, 0);
614        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW6, 0);
615        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW5, 0);
616        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW4, 0);
617
618        temp = SOTG_PTD_DW3_ACTIVE | (td->toggle << 25) |
619            SOTG_PTD_DW3_CERR_2;
620        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW3, temp);
621
622        temp = (SOTG_HC_MEMORY_ADDR(SOTG_DATA_ADDR(td->channel)) << 8);
623        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW2, temp);
624
625        temp = td->dw1_value | (1 << 10) /* IN-PID */ | (td->ep_index >> 1);
626        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW1, temp);
627
628        temp = (td->ep_index << 31) | (1 << 29) /* pkt-multiplier */ |
629            (td->max_packet_size << 18) /* wMaxPacketSize */ |
630            (td->max_packet_size << 3) /* transfer count */ |
631            SOTG_PTD_DW0_VALID;
632        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW0, temp);
633
634        /* activate PTD */
635        SAF1761_WRITE_LE_4(sc, SOTG_ATL_PTD_SKIP_PTD,
636            (~sc->sc_host_async_map) | sc->sc_host_async_suspend_map);
637busy:
638        return (1);     /* busy */
639complete:
640        saf1761_host_channel_free(sc, td);
641        return (0);     /* complete */
642}
643
644static uint8_t
645saf1761_host_bulk_data_tx(struct saf1761_otg_softc *sc, struct saf1761_otg_td *td)
646{
647        uint32_t pdt_addr;
648        uint32_t temp;
649        uint32_t count;
650
651        if (td->channel < SOTG_HOST_CHANNEL_MAX) {
652                uint32_t status;
653
654                pdt_addr = SOTG_PTD(td->channel);
655
656                status = saf1761_peek_host_status_le_4(sc, pdt_addr + SOTG_PTD_DW3);
657
658                DPRINTFN(5, "STATUS=0x%08x\n", status);
659
660                if (status & SOTG_PTD_DW3_ACTIVE) {
661                        goto busy;
662                } else if (status & SOTG_PTD_DW3_HALTED) {
663                        if (!(status & SOTG_PTD_DW3_ERRORS))
664                                td->error_stall = 1;
665                        td->error_any = 1;
666                        goto complete;
667                }
668                /* check remainder */
669                if (td->remainder == 0) {
670                        if (td->short_pkt)
671                                goto complete;
672                        /* else we need to transmit a short packet */
673                }
674                saf1761_host_channel_free(sc, td);
675        }
676        if (saf1761_host_channel_alloc(sc, td))
677                goto busy;
678
679        count = td->max_packet_size;
680        if (td->remainder < count) {
681                /* we have a short packet */
682                td->short_pkt = 1;
683                count = td->remainder;
684        }
685
686        saf1761_write_host_memory(sc, td, count);
687
688        /* set toggle, if any */
689        if (td->set_toggle) {
690                td->set_toggle = 0;
691                td->toggle = 1;
692        }
693
694        /* send one more packet */
695
696        pdt_addr = SOTG_PTD(td->channel);
697
698        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW7, 0);
699        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW6, 0);
700        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW5, 0);
701        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW4, 0);
702
703        temp = SOTG_PTD_DW3_ACTIVE | (td->toggle << 25) |
704            SOTG_PTD_DW3_CERR_2;
705        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW3, temp);
706
707        temp = (SOTG_HC_MEMORY_ADDR(SOTG_DATA_ADDR(td->channel)) << 8);
708        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW2, temp);
709
710        temp = td->dw1_value | (0 << 10) /* OUT-PID */ | (td->ep_index >> 1);
711        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW1, temp);
712
713        temp = (td->ep_index << 31) | (1 << 29) /* pkt-multiplier */ |
714            (td->max_packet_size << 18) /* wMaxPacketSize */ |
715            (count << 3) /* transfer count */ |
716            SOTG_PTD_DW0_VALID;
717        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW0, temp);
718
719        /* activate PTD */
720        SAF1761_WRITE_LE_4(sc, SOTG_ATL_PTD_SKIP_PTD,
721            (~sc->sc_host_async_map) | sc->sc_host_async_suspend_map);
722
723        td->toggle ^= 1;
724busy:
725        return (1);     /* busy */
726complete:
727        saf1761_host_channel_free(sc, td);
728        return (0);     /* complete */
729}
730
731static uint8_t
732saf1761_host_intr_data_rx(struct saf1761_otg_softc *sc, struct saf1761_otg_td *td)
733{
734        uint32_t pdt_addr;
735        uint32_t temp;
736
737        if (td->channel < SOTG_HOST_CHANNEL_MAX) {
738                uint32_t status;
739                uint32_t count;
740                uint8_t got_short;
741
742                pdt_addr = SOTG_PTD(td->channel);
743
744                status = saf1761_peek_host_status_le_4(sc, pdt_addr + SOTG_PTD_DW3);
745
746                DPRINTFN(5, "STATUS=0x%08x\n", status);
747
748                if (status & SOTG_PTD_DW3_ACTIVE) {
749                        goto busy;
750                } else if (status & SOTG_PTD_DW3_HALTED) {
751                        if (!(status & SOTG_PTD_DW3_ERRORS))
752                                td->error_stall = 1;
753                        td->error_any = 1;
754                        goto complete;
755                }
756                if (td->dw1_value & SOTG_PTD_DW1_ENABLE_SPLIT)
757                        count = (status & SOTG_PTD_DW3_XFER_COUNT_SPLIT);
758                else
759                        count = (status & SOTG_PTD_DW3_XFER_COUNT_HS);
760                got_short = 0;
761
762                /* verify the packet byte count */
763                if (count != td->max_packet_size) {
764                        if (count < td->max_packet_size) {
765                                /* we have a short packet */
766                                td->short_pkt = 1;
767                                got_short = 1;
768                        } else {
769                                /* invalid USB packet */
770                                td->error_any = 1;
771                                goto complete;
772                        }
773                }
774                td->toggle ^= 1;
775
776                /* verify the packet byte count */
777                if (count > td->remainder) {
778                        /* invalid USB packet */
779                        td->error_any = 1;
780                        goto complete;
781                }
782
783                saf1761_read_host_memory(sc, td, count);
784
785                /* check if we are complete */
786                if ((td->remainder == 0) || got_short) {
787                        if (td->short_pkt)
788                                goto complete;
789                        /* else need to receive a zero length packet */
790                }
791                saf1761_host_channel_free(sc, td);
792        }
793        if (saf1761_host_channel_alloc(sc, td))
794                goto busy;
795
796        /* set toggle, if any */
797        if (td->set_toggle) {
798                td->set_toggle = 0;
799                td->toggle = 1;
800        }
801
802        /* receive one more packet */
803
804        pdt_addr = SOTG_PTD(td->channel);
805
806        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW7, 0);
807        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW6, 0);
808
809        if (td->dw1_value & SOTG_PTD_DW1_ENABLE_SPLIT) {
810                temp = (0xFC << td->uframe) & 0xFF;     /* complete split */
811        } else {
812                temp = 0;
813        }
814        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW5, temp);
815
816        temp = (1U << td->uframe);              /* start mask or start split */
817        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW4, temp);
818
819        temp = SOTG_PTD_DW3_ACTIVE | (td->toggle << 25) | SOTG_PTD_DW3_CERR_3;
820        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW3, temp);
821
822        temp = (SOTG_HC_MEMORY_ADDR(SOTG_DATA_ADDR(td->channel)) << 8) |
823            (td->interval & 0xF8);
824        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW2, temp);
825
826        temp = td->dw1_value | (1 << 10) /* IN-PID */ | (td->ep_index >> 1);
827        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW1, temp);
828
829        temp = (td->ep_index << 31) | (1 << 29) /* pkt-multiplier */ |
830            (td->max_packet_size << 18) /* wMaxPacketSize */ |
831            (td->max_packet_size << 3) /* transfer count */ |
832            SOTG_PTD_DW0_VALID;
833        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW0, temp);
834
835        /* activate PTD */
836        SAF1761_WRITE_LE_4(sc, SOTG_INT_PTD_SKIP_PTD,
837            (~sc->sc_host_intr_map) | sc->sc_host_intr_suspend_map);
838busy:
839        return (1);     /* busy */
840complete:
841        saf1761_host_channel_free(sc, td);
842        return (0);     /* complete */
843}
844
845static uint8_t
846saf1761_host_intr_data_tx(struct saf1761_otg_softc *sc, struct saf1761_otg_td *td)
847{
848        uint32_t pdt_addr;
849        uint32_t temp;
850        uint32_t count;
851
852        if (td->channel < SOTG_HOST_CHANNEL_MAX) {
853                uint32_t status;
854
855                pdt_addr = SOTG_PTD(td->channel);
856
857                status = saf1761_peek_host_status_le_4(sc, pdt_addr + SOTG_PTD_DW3);
858
859                DPRINTFN(5, "STATUS=0x%08x\n", status);
860
861                if (status & SOTG_PTD_DW3_ACTIVE) {
862                        goto busy;
863                } else if (status & SOTG_PTD_DW3_HALTED) {
864                        if (!(status & SOTG_PTD_DW3_ERRORS))
865                                td->error_stall = 1;
866                        td->error_any = 1;
867                        goto complete;
868                }
869
870                /* check remainder */
871                if (td->remainder == 0) {
872                        if (td->short_pkt)
873                                goto complete;
874                        /* else we need to transmit a short packet */
875                }
876                saf1761_host_channel_free(sc, td);
877        }
878        if (saf1761_host_channel_alloc(sc, td))
879                goto busy;
880
881        count = td->max_packet_size;
882        if (td->remainder < count) {
883                /* we have a short packet */
884                td->short_pkt = 1;
885                count = td->remainder;
886        }
887
888        saf1761_write_host_memory(sc, td, count);
889
890        /* set toggle, if any */
891        if (td->set_toggle) {
892                td->set_toggle = 0;
893                td->toggle = 1;
894        }
895
896        /* send one more packet */
897
898        pdt_addr = SOTG_PTD(td->channel);
899
900        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW7, 0);
901        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW6, 0);
902
903        if (td->dw1_value & SOTG_PTD_DW1_ENABLE_SPLIT) {
904                temp = (0xFC << td->uframe) & 0xFF;     /* complete split */
905        } else {
906                temp = 0;
907        }
908        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW5, temp);
909
910        temp = (1U << td->uframe);              /* start mask or start split */
911        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW4, temp);
912
913        temp = SOTG_PTD_DW3_ACTIVE | (td->toggle << 25) | SOTG_PTD_DW3_CERR_3;
914        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW3, temp);
915
916        temp = (SOTG_HC_MEMORY_ADDR(SOTG_DATA_ADDR(td->channel)) << 8) |
917            (td->interval & 0xF8);
918        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW2, temp);
919
920        temp = td->dw1_value | (0 << 10) /* OUT-PID */ | (td->ep_index >> 1);
921        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW1, temp);
922
923        temp = (td->ep_index << 31) | (1 << 29) /* pkt-multiplier */ |
924            (td->max_packet_size << 18) /* wMaxPacketSize */ |
925            (count << 3) /* transfer count */ |
926            SOTG_PTD_DW0_VALID;
927        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW0, temp);
928
929        /* activate PTD */
930        SAF1761_WRITE_LE_4(sc, SOTG_INT_PTD_SKIP_PTD,
931            (~sc->sc_host_intr_map) | sc->sc_host_intr_suspend_map);
932
933        td->toggle ^= 1;
934busy:
935        return (1);     /* busy */
936complete:
937        saf1761_host_channel_free(sc, td);
938        return (0);     /* complete */
939}
940
941static uint8_t
942saf1761_host_isoc_data_rx(struct saf1761_otg_softc *sc, struct saf1761_otg_td *td)
943{
944        uint32_t pdt_addr;
945        uint32_t temp;
946
947        if (td->channel < SOTG_HOST_CHANNEL_MAX) {
948                uint32_t status;
949                uint32_t count;
950
951                pdt_addr = SOTG_PTD(td->channel);
952
953                status = saf1761_peek_host_status_le_4(sc, pdt_addr + SOTG_PTD_DW3);
954
955                DPRINTFN(5, "STATUS=0x%08x\n", status);
956
957                if (status & SOTG_PTD_DW3_ACTIVE) {
958                        goto busy;
959                } else if (status & SOTG_PTD_DW3_HALTED) {
960                        goto complete;
961                }
962                if (td->dw1_value & SOTG_PTD_DW1_ENABLE_SPLIT)
963                        count = (status & SOTG_PTD_DW3_XFER_COUNT_SPLIT);
964                else
965                        count = (status & SOTG_PTD_DW3_XFER_COUNT_HS);
966
967                /* verify the packet byte count */
968                if (count != td->max_packet_size) {
969                        if (count < td->max_packet_size) {
970                                /* we have a short packet */
971                                td->short_pkt = 1;
972                        } else {
973                                /* invalid USB packet */
974                                td->error_any = 1;
975                                goto complete;
976                        }
977                }
978
979                /* verify the packet byte count */
980                if (count > td->remainder) {
981                        /* invalid USB packet */
982                        td->error_any = 1;
983                        goto complete;
984                }
985
986                saf1761_read_host_memory(sc, td, count);
987                goto complete;
988        }
989
990        if (saf1761_host_channel_alloc(sc, td))
991                goto busy;
992
993        /* receive one more packet */
994
995        pdt_addr = SOTG_PTD(td->channel);
996
997        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW7, 0);
998        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW6, 0);
999
1000        if (td->dw1_value & SOTG_PTD_DW1_ENABLE_SPLIT) {
1001                temp = (0xFC << (td->uframe & 7)) & 0xFF;       /* complete split */
1002        } else {
1003                temp = 0;
1004        }
1005        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW5, temp);
1006
1007        temp = (1U << (td->uframe & 7));        /* start mask or start split */
1008        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW4, temp);
1009
1010        temp = SOTG_PTD_DW3_ACTIVE | SOTG_PTD_DW3_CERR_3;
1011        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW3, temp);
1012
1013        temp = (SOTG_HC_MEMORY_ADDR(SOTG_DATA_ADDR(td->channel)) << 8) |
1014            (td->uframe & 0xF8);
1015        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW2, temp);
1016
1017        temp = td->dw1_value | (1 << 10) /* IN-PID */ | (td->ep_index >> 1);
1018        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW1, temp);
1019
1020        temp = (td->ep_index << 31) | (1 << 29) /* pkt-multiplier */ |
1021            (td->max_packet_size << 18) /* wMaxPacketSize */ |
1022            (td->max_packet_size << 3) /* transfer count */ |
1023            SOTG_PTD_DW0_VALID;
1024        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW0, temp);
1025
1026        /* activate PTD */
1027        SAF1761_WRITE_LE_4(sc, SOTG_ISO_PTD_SKIP_PTD,
1028            (~sc->sc_host_isoc_map) | sc->sc_host_isoc_suspend_map);
1029busy:
1030        return (1);     /* busy */
1031complete:
1032        saf1761_host_channel_free(sc, td);
1033        return (0);     /* complete */
1034}
1035
1036static uint8_t
1037saf1761_host_isoc_data_tx(struct saf1761_otg_softc *sc, struct saf1761_otg_td *td)
1038{
1039        uint32_t pdt_addr;
1040        uint32_t temp;
1041        uint32_t count;
1042
1043        if (td->channel < SOTG_HOST_CHANNEL_MAX) {
1044                uint32_t status;
1045
1046                pdt_addr = SOTG_PTD(td->channel);
1047
1048                status = saf1761_peek_host_status_le_4(sc, pdt_addr + SOTG_PTD_DW3);
1049
1050                DPRINTFN(5, "STATUS=0x%08x\n", status);
1051
1052                if (status & SOTG_PTD_DW3_ACTIVE) {
1053                        goto busy;
1054                } else if (status & SOTG_PTD_DW3_HALTED) {
1055                        goto complete;
1056                }
1057                goto complete;
1058        }
1059        if (saf1761_host_channel_alloc(sc, td))
1060                goto busy;
1061
1062        count = td->max_packet_size;
1063        if (td->remainder < count) {
1064                /* we have a short packet */
1065                td->short_pkt = 1;
1066                count = td->remainder;
1067        }
1068
1069        saf1761_write_host_memory(sc, td, count);
1070
1071        /* send one more packet */
1072
1073        pdt_addr = SOTG_PTD(td->channel);
1074
1075        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW7, 0);
1076        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW6, 0);
1077        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW5, 0);
1078
1079        temp = (1U << (td->uframe & 7));        /* start mask or start split */
1080        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW4, temp);
1081
1082        temp = SOTG_PTD_DW3_ACTIVE | SOTG_PTD_DW3_CERR_3;
1083        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW3, temp);
1084
1085        temp = (SOTG_HC_MEMORY_ADDR(SOTG_DATA_ADDR(td->channel)) << 8) |
1086            (td->uframe & 0xF8);
1087        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW2, temp);
1088
1089        temp = td->dw1_value | (0 << 10) /* OUT-PID */ | (td->ep_index >> 1);
1090        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW1, temp);
1091
1092        temp = (td->ep_index << 31) | (1 << 29) /* pkt-multiplier */ |
1093            (count << 18) /* wMaxPacketSize */ |
1094            (count << 3) /* transfer count */ |
1095            SOTG_PTD_DW0_VALID;
1096        SAF1761_WRITE_LE_4(sc, pdt_addr + SOTG_PTD_DW0, temp);
1097
1098        /* activate PTD */
1099        SAF1761_WRITE_LE_4(sc, SOTG_ISO_PTD_SKIP_PTD,
1100            (~sc->sc_host_isoc_map) | sc->sc_host_isoc_suspend_map);
1101busy:
1102        return (1);     /* busy */
1103complete:
1104        saf1761_host_channel_free(sc, td);
1105        return (0);     /* complete */
1106}
1107
1108static void
1109saf1761_otg_set_address(struct saf1761_otg_softc *sc, uint8_t addr)
1110{
1111        DPRINTFN(5, "addr=%d\n", addr);
1112
1113        SAF1761_WRITE_LE_4(sc, SOTG_ADDRESS, addr | SOTG_ADDRESS_ENABLE);
1114}
1115
1116
1117static void
1118saf1761_read_device_fifo(struct saf1761_otg_softc *sc,
1119    struct saf1761_otg_td *td, uint32_t len)
1120{
1121        struct usb_page_search buf_res;
1122        uint32_t count;
1123
1124        /* optimised read first */
1125        while (len > 0) {
1126                usbd_get_page(td->pc, td->offset, &buf_res);
1127
1128                /* get correct length */
1129                if (buf_res.length > len)
1130                        buf_res.length = len;
1131
1132                /* check buffer alignment */
1133                if (((uintptr_t)buf_res.buffer) & 3)
1134                        break;
1135
1136                count = buf_res.length & ~3;
1137                if (count == 0)
1138                        break;
1139
1140                bus_space_read_multi_4((sc)->sc_io_tag, (sc)->sc_io_hdl,
1141                    SOTG_DATA_PORT, buf_res.buffer, count / 4);
1142
1143                len -= count;
1144
1145                /* update remainder and offset */
1146                td->remainder -= count;
1147                td->offset += count;
1148        }
1149
1150        if (len > 0) {
1151                /* use bounce buffer */
1152                bus_space_read_multi_4((sc)->sc_io_tag, (sc)->sc_io_hdl,
1153                    SOTG_DATA_PORT, sc->sc_bounce_buffer, (len + 3) / 4);
1154                usbd_copy_in(td->pc, td->offset,
1155                    sc->sc_bounce_buffer, len);
1156
1157                /* update remainder and offset */
1158                td->remainder -= len;
1159                td->offset += len;
1160        }
1161}
1162
1163static void
1164saf1761_write_device_fifo(struct saf1761_otg_softc *sc,
1165    struct saf1761_otg_td *td, uint32_t len)
1166{
1167        struct usb_page_search buf_res;
1168        uint32_t count;
1169
1170        /* optimised write first */
1171        while (len > 0) {
1172                usbd_get_page(td->pc, td->offset, &buf_res);
1173
1174                /* get correct length */
1175                if (buf_res.length > len)
1176                        buf_res.length = len;
1177
1178                /* check buffer alignment */
1179                if (((uintptr_t)buf_res.buffer) & 3)
1180                        break;
1181
1182                count = buf_res.length & ~3;
1183                if (count == 0)
1184                        break;
1185
1186                bus_space_write_multi_4((sc)->sc_io_tag, (sc)->sc_io_hdl,
1187                    SOTG_DATA_PORT, buf_res.buffer, count / 4);
1188
1189                len -= count;
1190
1191                /* update remainder and offset */
1192                td->remainder -= count;
1193                td->offset += count;
1194        }
1195        if (len > 0) {
1196                /* use bounce buffer */
1197                usbd_copy_out(td->pc, td->offset, sc->sc_bounce_buffer, len);
1198                bus_space_write_multi_4((sc)->sc_io_tag, (sc)->sc_io_hdl,
1199                    SOTG_DATA_PORT, sc->sc_bounce_buffer, (len + 3) / 4);
1200
1201                /* update remainder and offset */
1202                td->remainder -= len;
1203                td->offset += len;
1204        }
1205}
1206
1207static uint8_t
1208saf1761_device_setup_rx(struct saf1761_otg_softc *sc, struct saf1761_otg_td *td)
1209{
1210        struct usb_device_request req;
1211        uint32_t count;
1212
1213        /* select the correct endpoint */
1214        SAF1761_WRITE_LE_4(sc, SOTG_EP_INDEX, SOTG_EP_INDEX_EP0SETUP);
1215
1216        count = SAF1761_READ_LE_4(sc, SOTG_BUF_LENGTH);
1217
1218        /* check buffer status */
1219        if ((count & SOTG_BUF_LENGTH_FILLED_MASK) == 0)
1220                goto busy;
1221
1222        /* get buffer length */
1223        count &= SOTG_BUF_LENGTH_BUFLEN_MASK;
1224
1225        DPRINTFN(5, "count=%u rem=%u\n", count, td->remainder);
1226
1227        /* clear did stall */
1228        td->did_stall = 0;
1229
1230        /* clear stall */
1231        SAF1761_WRITE_LE_4(sc, SOTG_CTRL_FUNC, 0);
1232
1233        /* verify data length */
1234        if (count != td->remainder) {
1235                DPRINTFN(0, "Invalid SETUP packet "
1236                    "length, %d bytes\n", count);
1237                goto busy;
1238        }
1239        if (count != sizeof(req)) {
1240                DPRINTFN(0, "Unsupported SETUP packet "
1241                    "length, %d bytes\n", count);
1242                goto busy;
1243        }
1244        /* receive data */
1245        saf1761_read_device_fifo(sc, td, sizeof(req));
1246
1247        /* extract SETUP packet again */
1248        usbd_copy_out(td->pc, 0, &req, sizeof(req));
1249
1250        /* sneak peek the set address request */
1251        if ((req.bmRequestType == UT_WRITE_DEVICE) &&
1252            (req.bRequest == UR_SET_ADDRESS)) {
1253                sc->sc_dv_addr = req.wValue[0] & 0x7F;
1254                DPRINTF("Set address %d\n", sc->sc_dv_addr);
1255        } else {
1256                sc->sc_dv_addr = 0xFF;
1257        }
1258        return (0);                     /* complete */
1259
1260busy:
1261        /* abort any ongoing transfer */
1262        if (!td->did_stall) {
1263                DPRINTFN(5, "stalling\n");
1264
1265                /* set stall */
1266                SAF1761_WRITE_LE_4(sc, SOTG_CTRL_FUNC, SOTG_CTRL_FUNC_STALL);
1267
1268                td->did_stall = 1;
1269        }
1270        return (1);                     /* not complete */
1271}
1272
1273static uint8_t
1274saf1761_device_data_rx(struct saf1761_otg_softc *sc, struct saf1761_otg_td *td)
1275{
1276        uint32_t count;
1277        uint8_t got_short = 0;
1278
1279        if (td->ep_index == 0) {
1280                /* select the correct endpoint */
1281                SAF1761_WRITE_LE_4(sc, SOTG_EP_INDEX, SOTG_EP_INDEX_EP0SETUP);
1282
1283                count = SAF1761_READ_LE_4(sc, SOTG_BUF_LENGTH);
1284
1285                /* check buffer status */
1286                if ((count & SOTG_BUF_LENGTH_FILLED_MASK) != 0) {
1287
1288                        if (td->remainder == 0) {
1289                                /*
1290                                 * We are actually complete and have
1291                                 * received the next SETUP:
1292                                 */
1293                                DPRINTFN(5, "faking complete\n");
1294                                return (0);     /* complete */
1295                        }
1296                        DPRINTFN(5, "SETUP packet while receiving data\n");
1297                        /*
1298                         * USB Host Aborted the transfer.
1299                         */
1300                        td->error_any = 1;
1301                        return (0);     /* complete */
1302                }
1303        }
1304        /* select the correct endpoint */
1305        SAF1761_WRITE_LE_4(sc, SOTG_EP_INDEX,
1306            (td->ep_index << SOTG_EP_INDEX_ENDP_INDEX_SHIFT) |
1307            SOTG_EP_INDEX_DIR_OUT);
1308
1309        /* enable data stage */
1310        if (td->set_toggle) {
1311                td->set_toggle = 0;
1312                SAF1761_WRITE_LE_4(sc, SOTG_CTRL_FUNC, SOTG_CTRL_FUNC_DSEN);
1313        }
1314
1315        count = SAF1761_READ_LE_4(sc, SOTG_BUF_LENGTH);
1316
1317        /* check buffer status */
1318        if ((count & SOTG_BUF_LENGTH_FILLED_MASK) == 0)
1319                return (1);             /* not complete */
1320
1321        /* get buffer length */
1322        count &= SOTG_BUF_LENGTH_BUFLEN_MASK;
1323
1324        DPRINTFN(5, "rem=%u count=0x%04x\n", td->remainder, count);
1325
1326        /* verify the packet byte count */
1327        if (count != td->max_packet_size) {
1328                if (count < td->max_packet_size) {
1329                        /* we have a short packet */
1330                        td->short_pkt = 1;
1331                        got_short = 1;
1332                } else {
1333                        /* invalid USB packet */
1334                        td->error_any = 1;
1335                        return (0);     /* we are complete */
1336                }
1337        }
1338        /* verify the packet byte count */
1339        if (count > td->remainder) {
1340                /* invalid USB packet */
1341                td->error_any = 1;
1342                return (0);             /* we are complete */
1343        }
1344        /* receive data */
1345        saf1761_read_device_fifo(sc, td, count);
1346
1347        /* check if we are complete */
1348        if ((td->remainder == 0) || got_short) {
1349                if (td->short_pkt) {
1350                        /* we are complete */
1351                        return (0);
1352                }
1353                /* else need to receive a zero length packet */
1354        }
1355        return (1);                     /* not complete */
1356}
1357
1358static uint8_t
1359saf1761_device_data_tx(struct saf1761_otg_softc *sc, struct saf1761_otg_td *td)
1360{
1361        uint32_t count;
1362
1363        if (td->ep_index == 0) {
1364                /* select the correct endpoint */
1365                SAF1761_WRITE_LE_4(sc, SOTG_EP_INDEX, SOTG_EP_INDEX_EP0SETUP);
1366
1367                count = SAF1761_READ_LE_4(sc, SOTG_BUF_LENGTH);
1368
1369                /* check buffer status */
1370                if ((count & SOTG_BUF_LENGTH_FILLED_MASK) != 0) {
1371                        DPRINTFN(5, "SETUP abort\n");
1372                        /*
1373                         * USB Host Aborted the transfer.
1374                         */
1375                        td->error_any = 1;
1376                        return (0);     /* complete */
1377                }
1378        }
1379        /* select the correct endpoint */
1380        SAF1761_WRITE_LE_4(sc, SOTG_EP_INDEX,
1381            (td->ep_index << SOTG_EP_INDEX_ENDP_INDEX_SHIFT) |
1382            SOTG_EP_INDEX_DIR_IN);
1383
1384        count = SAF1761_READ_LE_4(sc, SOTG_BUF_LENGTH);
1385
1386        /* check buffer status */
1387        if ((count & SOTG_BUF_LENGTH_FILLED_MASK) != 0)
1388                return (1);             /* not complete */
1389
1390        /* enable data stage */
1391        if (td->set_toggle) {
1392                td->set_toggle = 0;
1393                SAF1761_WRITE_LE_4(sc, SOTG_CTRL_FUNC, SOTG_CTRL_FUNC_DSEN);
1394        }
1395
1396        DPRINTFN(5, "rem=%u\n", td->remainder);
1397
1398        count = td->max_packet_size;
1399        if (td->remainder < count) {
1400                /* we have a short packet */
1401                td->short_pkt = 1;
1402                count = td->remainder;
1403        }
1404        /* transmit data */
1405        saf1761_write_device_fifo(sc, td, count);
1406
1407        if (td->ep_index == 0) {
1408                if (count < SOTG_FS_MAX_PACKET_SIZE) {
1409                        /* set end of packet */
1410                        SAF1761_WRITE_LE_4(sc, SOTG_CTRL_FUNC, SOTG_CTRL_FUNC_VENDP);
1411                }
1412        } else {
1413                if (count < SOTG_HS_MAX_PACKET_SIZE) {
1414                        /* set end of packet */
1415                        SAF1761_WRITE_LE_4(sc, SOTG_CTRL_FUNC, SOTG_CTRL_FUNC_VENDP);
1416                }
1417        }
1418
1419        /* check remainder */
1420        if (td->remainder == 0) {
1421                if (td->short_pkt) {
1422                        return (0);     /* complete */
1423                }
1424                /* else we need to transmit a short packet */
1425        }
1426        return (1);                     /* not complete */
1427}
1428
1429static uint8_t
1430saf1761_device_data_tx_sync(struct saf1761_otg_softc *sc, struct saf1761_otg_td *td)
1431{
1432        uint32_t count;
1433
1434        if (td->ep_index == 0) {
1435                /* select the correct endpoint */
1436                SAF1761_WRITE_LE_4(sc, SOTG_EP_INDEX, SOTG_EP_INDEX_EP0SETUP);
1437
1438                count = SAF1761_READ_LE_4(sc, SOTG_BUF_LENGTH);
1439
1440                /* check buffer status */
1441                if ((count & SOTG_BUF_LENGTH_FILLED_MASK) != 0) {
1442                        DPRINTFN(5, "Faking complete\n");
1443                        return (0);     /* complete */
1444                }
1445        }
1446        /* select the correct endpoint */
1447        SAF1761_WRITE_LE_4(sc, SOTG_EP_INDEX,
1448            (td->ep_index << SOTG_EP_INDEX_ENDP_INDEX_SHIFT) |
1449            SOTG_EP_INDEX_DIR_IN);
1450
1451        count = SAF1761_READ_LE_4(sc, SOTG_BUF_LENGTH);
1452
1453        /* check buffer status */
1454        if ((count & SOTG_BUF_LENGTH_FILLED_MASK) != 0)
1455                return (1);             /* busy */
1456
1457        if (sc->sc_dv_addr != 0xFF) {
1458                /* write function address */
1459                saf1761_otg_set_address(sc, sc->sc_dv_addr);
1460        }
1461        return (0);                     /* complete */
1462}
1463
1464static void
1465saf1761_otg_xfer_do_fifo(struct saf1761_otg_softc *sc, struct usb_xfer *xfer)
1466{
1467        struct saf1761_otg_td *td;
1468        uint8_t toggle;
1469
1470        DPRINTFN(9, "\n");
1471
1472        td = xfer->td_transfer_cache;
1473        if (td == NULL)
1474                return;
1475
1476        while (1) {
1477                if ((td->func) (sc, td)) {
1478                        /* operation in progress */
1479                        break;
1480                }
1481                if (((void *)td) == xfer->td_transfer_last) {
1482                        goto done;
1483                }
1484                if (td->error_any) {
1485                        goto done;
1486                } else if (td->remainder > 0) {
1487                        /*
1488                         * We had a short transfer. If there is no alternate
1489                         * next, stop processing !
1490                         */
1491                        if (!td->alt_next) {
1492                                goto done;
1493                        }
1494                }
1495                /*
1496                 * Fetch the next transfer descriptor.
1497                 */
1498                toggle = td->toggle;
1499                td = td->obj_next;
1500                td->toggle = toggle;
1501                xfer->td_transfer_cache = td;
1502        }
1503        return;
1504
1505done:
1506        /* compute all actual lengths */
1507        xfer->td_transfer_cache = NULL;
1508        sc->sc_xfer_complete = 1;
1509}
1510
1511static uint8_t
1512saf1761_otg_xfer_do_complete(struct saf1761_otg_softc *sc, struct usb_xfer *xfer)
1513{
1514        struct saf1761_otg_td *td;
1515
1516        DPRINTFN(9, "\n");
1517
1518        td = xfer->td_transfer_cache;
1519        if (td == NULL) {
1520                /* compute all actual lengths */
1521                saf1761_otg_standard_done(xfer);
1522                return (1);
1523        }
1524        return (0);
1525}
1526
1527static void
1528saf1761_otg_interrupt_poll_locked(struct saf1761_otg_softc *sc)
1529{
1530        struct usb_xfer *xfer;
1531
1532        TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry)
1533                saf1761_otg_xfer_do_fifo(sc, xfer);
1534}
1535
1536static void
1537saf1761_otg_enable_psof(struct saf1761_otg_softc *sc, uint8_t on)
1538{
1539        if (on) {
1540                sc->sc_intr_enable |= SOTG_DCINTERRUPT_IEPSOF;
1541        } else {
1542                sc->sc_intr_enable &= ~SOTG_DCINTERRUPT_IEPSOF;
1543        }
1544        SAF1761_WRITE_LE_4(sc, SOTG_DCINTERRUPT_EN, sc->sc_intr_enable);
1545}
1546
1547static void
1548saf1761_otg_wait_suspend(struct saf1761_otg_softc *sc, uint8_t on)
1549{
1550        if (on) {
1551                sc->sc_intr_enable |= SOTG_DCINTERRUPT_IESUSP;
1552                sc->sc_intr_enable &= ~SOTG_DCINTERRUPT_IERESM;
1553        } else {
1554                sc->sc_intr_enable &= ~SOTG_DCINTERRUPT_IESUSP;
1555                sc->sc_intr_enable |= SOTG_DCINTERRUPT_IERESM;
1556        }
1557        SAF1761_WRITE_LE_4(sc, SOTG_DCINTERRUPT_EN, sc->sc_intr_enable);
1558}
1559
1560static void
1561saf1761_otg_update_vbus(struct saf1761_otg_softc *sc)
1562{
1563        uint16_t status;
1564
1565        /* read fresh status */
1566        status = SAF1761_READ_LE_4(sc, SOTG_STATUS);
1567
1568        DPRINTFN(4, "STATUS=0x%04x\n", status);
1569
1570        if ((status & SOTG_STATUS_VBUS_VLD) &&
1571            (status & SOTG_STATUS_ID)) {
1572                /* VBUS present and device mode */
1573                if (!sc->sc_flags.status_vbus) {
1574                        sc->sc_flags.status_vbus = 1;
1575
1576                        /* complete root HUB interrupt endpoint */
1577                        saf1761_otg_root_intr(sc);
1578                }
1579        } else {
1580                /* VBUS not-present or host mode */
1581                if (sc->sc_flags.status_vbus) {
1582                        sc->sc_flags.status_vbus = 0;
1583                        sc->sc_flags.status_bus_reset = 0;
1584                        sc->sc_flags.status_suspend = 0;
1585                        sc->sc_flags.change_suspend = 0;
1586                        sc->sc_flags.change_connect = 1;
1587
1588                        /* complete root HUB interrupt endpoint */
1589                        saf1761_otg_root_intr(sc);
1590                }
1591        }
1592}
1593
1594static void
1595saf1761_otg_interrupt_complete_locked(struct saf1761_otg_softc *sc)
1596{
1597        struct usb_xfer *xfer;
1598repeat:
1599        /* scan for completion events */
1600        TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) {
1601                if (saf1761_otg_xfer_do_complete(sc, xfer))
1602                        goto repeat;
1603        }
1604}
1605
1606int
1607saf1761_otg_filter_interrupt(void *arg)
1608{
1609        struct saf1761_otg_softc *sc = arg;
1610        int retval = FILTER_HANDLED;
1611        uint32_t hcstat;
1612        uint32_t status;
1613
1614        USB_BUS_SPIN_LOCK(&sc->sc_bus);
1615
1616        hcstat = SAF1761_READ_LE_4(sc, SOTG_HCINTERRUPT);
1617        /* acknowledge all host controller interrupts */
1618        SAF1761_WRITE_LE_4(sc, SOTG_HCINTERRUPT, hcstat);
1619
1620        status = SAF1761_READ_LE_4(sc, SOTG_DCINTERRUPT);
1621        /* acknowledge all device controller interrupts */
1622        SAF1761_WRITE_LE_4(sc, SOTG_DCINTERRUPT,
1623            status & ~SAF1761_DCINTERRUPT_THREAD_IRQ);
1624
1625        (void) SAF1761_READ_LE_4(sc, SOTG_ATL_PTD_DONE_PTD);
1626        (void) SAF1761_READ_LE_4(sc, SOTG_INT_PTD_DONE_PTD);
1627        (void) SAF1761_READ_LE_4(sc, SOTG_ISO_PTD_DONE_PTD);
1628
1629        DPRINTFN(9, "HCINTERRUPT=0x%08x DCINTERRUPT=0x%08x\n", hcstat, status);
1630
1631        if (status & SOTG_DCINTERRUPT_IEPSOF) {
1632                if ((sc->sc_host_async_busy_map[1] | sc->sc_host_async_busy_map[0] |
1633                     sc->sc_host_intr_busy_map[1] | sc->sc_host_intr_busy_map[0] |
1634                     sc->sc_host_isoc_busy_map[1] | sc->sc_host_isoc_busy_map[0]) != 0) {
1635                        /* busy waiting is active */
1636                        retval = FILTER_SCHEDULE_THREAD;
1637
1638                        sc->sc_host_async_busy_map[1] = sc->sc_host_async_busy_map[0];
1639                        sc->sc_host_async_busy_map[0] = 0;
1640
1641                        sc->sc_host_intr_busy_map[1] = sc->sc_host_intr_busy_map[0];
1642                        sc->sc_host_intr_busy_map[0] = 0;
1643
1644                        sc->sc_host_isoc_busy_map[1] = sc->sc_host_isoc_busy_map[0];
1645                        sc->sc_host_isoc_busy_map[0] = 0;
1646                } else {
1647                        /* busy waiting is not active */
1648                        saf1761_otg_enable_psof(sc, 0);
1649                }
1650        }
1651
1652        if (status & SAF1761_DCINTERRUPT_THREAD_IRQ)
1653                retval = FILTER_SCHEDULE_THREAD;
1654
1655        /* poll FIFOs, if any */
1656        saf1761_otg_interrupt_poll_locked(sc);
1657
1658        if (sc->sc_xfer_complete != 0)
1659                retval = FILTER_SCHEDULE_THREAD;
1660
1661        USB_BUS_SPIN_UNLOCK(&sc->sc_bus);
1662
1663#ifdef __rtems__
1664#ifdef LIBBSP_ARM_ATSAM_BSP_H
1665        const Pio *saf_irq_pio = PIOC;
1666        /* The PIOC is used only by the SAF1761. So we can just reset the status
1667         * without any further handling. */
1668        (void) saf_irq_pio->PIO_ISR;
1669#endif /* LIBBSP_ARM_ATSAM_BSP_H */
1670
1671#endif /* __rtems__ */
1672        return (retval);
1673}
1674
1675void
1676saf1761_otg_interrupt(void *arg)
1677{
1678        struct saf1761_otg_softc *sc = arg;
1679        uint32_t status;
1680        bool xfer_complete;
1681
1682        USB_BUS_LOCK(&sc->sc_bus);
1683        USB_BUS_SPIN_LOCK(&sc->sc_bus);
1684
1685        status = SAF1761_READ_LE_4(sc, SOTG_DCINTERRUPT) &
1686            SAF1761_DCINTERRUPT_THREAD_IRQ;
1687
1688        /* acknowledge all device controller interrupts */
1689        SAF1761_WRITE_LE_4(sc, SOTG_DCINTERRUPT, status);
1690
1691        DPRINTF("DCINTERRUPT=0x%08x SOF=0x%08x "
1692            "FRINDEX=0x%08x\n", status,
1693            SAF1761_READ_LE_4(sc, SOTG_FRAME_NUM),
1694            SAF1761_READ_LE_4(sc, SOTG_FRINDEX));
1695
1696        /* update VBUS and ID bits, if any */
1697        if (status & SOTG_DCINTERRUPT_IEVBUS)
1698                saf1761_otg_update_vbus(sc);
1699
1700        if (status & SOTG_DCINTERRUPT_IEBRST) {
1701                /* unlock device */
1702                SAF1761_WRITE_LE_4(sc, SOTG_UNLOCK_DEVICE,
1703                    SOTG_UNLOCK_DEVICE_CODE);
1704
1705                /* Enable device address */
1706                SAF1761_WRITE_LE_4(sc, SOTG_ADDRESS,
1707                    SOTG_ADDRESS_ENABLE);
1708
1709                sc->sc_flags.status_bus_reset = 1;
1710                sc->sc_flags.status_suspend = 0;
1711                sc->sc_flags.change_suspend = 0;
1712                sc->sc_flags.change_connect = 1;
1713
1714                /* disable resume interrupt */
1715                saf1761_otg_wait_suspend(sc, 1);
1716                /* complete root HUB interrupt endpoint */
1717                saf1761_otg_root_intr(sc);
1718        }
1719        /*
1720         * If "RESUME" and "SUSPEND" is set at the same time we
1721         * interpret that like "RESUME". Resume is set when there is
1722         * at least 3 milliseconds of inactivity on the USB BUS:
1723         */
1724        if (status & SOTG_DCINTERRUPT_IERESM) {
1725                /* unlock device */
1726                SAF1761_WRITE_LE_4(sc, SOTG_UNLOCK_DEVICE,
1727                    SOTG_UNLOCK_DEVICE_CODE);
1728
1729                if (sc->sc_flags.status_suspend) {
1730                        sc->sc_flags.status_suspend = 0;
1731                        sc->sc_flags.change_suspend = 1;
1732                        /* disable resume interrupt */
1733                        saf1761_otg_wait_suspend(sc, 1);
1734                        /* complete root HUB interrupt endpoint */
1735                        saf1761_otg_root_intr(sc);
1736                }
1737        } else if (status & SOTG_DCINTERRUPT_IESUSP) {
1738                if (!sc->sc_flags.status_suspend) {
1739                        sc->sc_flags.status_suspend = 1;
1740                        sc->sc_flags.change_suspend = 1;
1741                        /* enable resume interrupt */
1742                        saf1761_otg_wait_suspend(sc, 0);
1743                        /* complete root HUB interrupt endpoint */
1744                        saf1761_otg_root_intr(sc);
1745                }
1746        }
1747
1748        xfer_complete = (sc->sc_xfer_complete != 0);
1749        if (xfer_complete)
1750                sc->sc_xfer_complete = 0;
1751
1752        USB_BUS_SPIN_UNLOCK(&sc->sc_bus);
1753
1754        if (xfer_complete)
1755                /* complete FIFOs, if any */
1756                saf1761_otg_interrupt_complete_locked(sc);
1757
1758        USB_BUS_UNLOCK(&sc->sc_bus);
1759}
1760
1761static void
1762saf1761_otg_setup_standard_chain_sub(struct saf1761_otg_std_temp *temp)
1763{
1764        struct saf1761_otg_td *td;
1765
1766        /* get current Transfer Descriptor */
1767        td = temp->td_next;
1768        temp->td = td;
1769
1770        /* prepare for next TD */
1771        temp->td_next = td->obj_next;
1772
1773        /* fill out the Transfer Descriptor */
1774        td->func = temp->func;
1775        td->pc = temp->pc;
1776        td->offset = temp->offset;
1777        td->remainder = temp->len;
1778        td->error_any = 0;
1779        td->error_stall = 0;
1780        td->set_toggle = 0;
1781        td->did_stall = temp->did_stall;
1782        td->short_pkt = temp->short_pkt;
1783        td->alt_next = temp->setup_alt_next;
1784        td->channel = SOTG_HOST_CHANNEL_MAX;
1785}
1786
1787static void
1788saf1761_otg_setup_standard_chain(struct usb_xfer *xfer)
1789{
1790        struct saf1761_otg_std_temp temp;
1791        struct saf1761_otg_softc *sc;
1792        struct saf1761_otg_td *td;
1793        uint32_t x;
1794        uint8_t ep_no;
1795        uint8_t ep_type;
1796        uint8_t need_sync;
1797        uint8_t is_host;
1798        uint8_t uframe_start;
1799        uint8_t uframe_interval;
1800
1801        DPRINTFN(9, "addr=%d endpt=%d sumlen=%d speed=%d\n",
1802            xfer->address, UE_GET_ADDR(xfer->endpointno),
1803            xfer->sumlen, usbd_get_speed(xfer->xroot->udev));
1804
1805        temp.max_frame_size = xfer->max_frame_size;
1806
1807        td = xfer->td_start[0];
1808        xfer->td_transfer_first = td;
1809        xfer->td_transfer_cache = td;
1810
1811        /* setup temp */
1812
1813        temp.pc = NULL;
1814        temp.td = NULL;
1815        temp.td_next = xfer->td_start[0];
1816        temp.offset = 0;
1817        temp.setup_alt_next = xfer->flags_int.short_frames_ok ||
1818            xfer->flags_int.isochronous_xfr;
1819        temp.did_stall = !xfer->flags_int.control_stall;
1820
1821        is_host = (xfer->xroot->udev->flags.usb_mode == USB_MODE_HOST);
1822
1823        sc = SAF1761_OTG_BUS2SC(xfer->xroot->bus);
1824        ep_no = (xfer->endpointno & UE_ADDR);
1825        ep_type = (xfer->endpoint->edesc->bmAttributes & UE_XFERTYPE);
1826
1827        /* check if we should prepend a setup message */
1828
1829        if (xfer->flags_int.control_xfr) {
1830                if (xfer->flags_int.control_hdr) {
1831
1832                        if (is_host)
1833                                temp.func = &saf1761_host_setup_tx;
1834                        else
1835                                temp.func = &saf1761_device_setup_rx;
1836
1837                        temp.len = xfer->frlengths[0];
1838                        temp.pc = xfer->frbuffers + 0;
1839                        temp.short_pkt = temp.len ? 1 : 0;
1840                        /* check for last frame */
1841                        if (xfer->nframes == 1) {
1842                                /* no STATUS stage yet, SETUP is last */
1843                                if (xfer->flags_int.control_act)
1844                                        temp.setup_alt_next = 0;
1845                        }
1846                        saf1761_otg_setup_standard_chain_sub(&temp);
1847                }
1848                x = 1;
1849        } else {
1850                x = 0;
1851        }
1852
1853        uframe_start = 0;
1854        uframe_interval = 0;
1855
1856        if (x != xfer->nframes) {
1857                if (xfer->endpointno & UE_DIR_IN) {
1858                        if (is_host) {
1859                                if (ep_type == UE_INTERRUPT) {
1860                                        temp.func = &saf1761_host_intr_data_rx;
1861                                } else if (ep_type == UE_ISOCHRONOUS) {
1862                                        temp.func = &saf1761_host_isoc_data_rx;
1863                                        uframe_start = (SAF1761_READ_LE_4(sc, SOTG_FRINDEX) + 8) &
1864                                            (SOTG_FRINDEX_MASK & ~7);
1865                                        if (xfer->xroot->udev->speed == USB_SPEED_HIGH)
1866                                                uframe_interval = 1U << xfer->fps_shift;
1867                                        else
1868                                                uframe_interval = 8U;
1869                                } else {
1870                                        temp.func = &saf1761_host_bulk_data_rx;
1871                                }
1872                                need_sync = 0;
1873                        } else {
1874                                temp.func = &saf1761_device_data_tx;
1875                                need_sync = 1;
1876                        }
1877                } else {
1878                        if (is_host) {
1879                                if (ep_type == UE_INTERRUPT) {
1880                                        temp.func = &saf1761_host_intr_data_tx;
1881                                } else if (ep_type == UE_ISOCHRONOUS) {
1882                                        temp.func = &saf1761_host_isoc_data_tx;
1883                                        uframe_start = (SAF1761_READ_LE_4(sc, SOTG_FRINDEX) + 8) &
1884                                            (SOTG_FRINDEX_MASK & ~7);
1885                                        if (xfer->xroot->udev->speed == USB_SPEED_HIGH)
1886                                                uframe_interval = 1U << xfer->fps_shift;
1887                                        else
1888                                                uframe_interval = 8U;
1889                                } else {
1890                                        temp.func = &saf1761_host_bulk_data_tx;
1891                                }
1892                                need_sync = 0;
1893                        } else {
1894                                temp.func = &saf1761_device_data_rx;
1895                                need_sync = 0;
1896                        }
1897                }
1898
1899                /* setup "pc" pointer */
1900                temp.pc = xfer->frbuffers + x;
1901        } else {
1902                need_sync = 0;
1903        }
1904
1905        while (x != xfer->nframes) {
1906
1907                /* DATA0 / DATA1 message */
1908
1909                temp.len = xfer->frlengths[x];
1910
1911                x++;
1912
1913                if (x == xfer->nframes) {
1914                        if (xfer->flags_int.control_xfr) {
1915                                if (xfer->flags_int.control_act) {
1916                                        temp.setup_alt_next = 0;
1917                                }
1918                        } else {
1919                                temp.setup_alt_next = 0;
1920                        }
1921                }
1922                if (temp.len == 0) {
1923
1924                        /* make sure that we send an USB packet */
1925
1926                        temp.short_pkt = 0;
1927
1928                } else {
1929
1930                        /* regular data transfer */
1931
1932                        temp.short_pkt = (xfer->flags.force_short_xfer) ? 0 : 1;
1933                }
1934
1935                saf1761_otg_setup_standard_chain_sub(&temp);
1936
1937                if (xfer->flags_int.isochronous_xfr) {
1938                        temp.offset += temp.len;
1939
1940                        /* stamp the starting point for this transaction */
1941                        temp.td->uframe = uframe_start;
1942
1943                        /* advance to next */
1944                        uframe_start += uframe_interval;
1945                } else {
1946                        /* get next Page Cache pointer */
1947                        temp.pc = xfer->frbuffers + x;
1948                }
1949        }
1950
1951        /* check for control transfer */
1952        if (xfer->flags_int.control_xfr) {
1953                /* always setup a valid "pc" pointer for status and sync */
1954                temp.pc = xfer->frbuffers + 0;
1955                temp.len = 0;
1956                temp.short_pkt = 0;
1957                temp.setup_alt_next = 0;
1958
1959                /* check if we should append a status stage */
1960                if (!xfer->flags_int.control_act) {
1961
1962                        /*
1963                         * Send a DATA1 message and invert the current
1964                         * endpoint direction.
1965                         */
1966                        if (xfer->endpointno & UE_DIR_IN) {
1967                                if (is_host) {
1968                                        temp.func = &saf1761_host_bulk_data_tx;
1969                                        need_sync = 0;
1970                                } else {
1971                                        temp.func = &saf1761_device_data_rx;
1972                                        need_sync = 0;
1973                                }
1974                        } else {
1975                                if (is_host) {
1976                                        temp.func = &saf1761_host_bulk_data_rx;
1977                                        need_sync = 0;
1978                                } else {
1979                                        temp.func = &saf1761_device_data_tx;
1980                                        need_sync = 1;
1981                                }
1982                        }
1983                        temp.len = 0;
1984                        temp.short_pkt = 0;
1985
1986                        saf1761_otg_setup_standard_chain_sub(&temp);
1987
1988                        /* data toggle should be DATA1 */
1989                        td = temp.td;
1990                        td->set_toggle = 1;
1991
1992                        if (need_sync) {
1993                                /* we need a SYNC point after TX */
1994                                temp.func = &saf1761_device_data_tx_sync;
1995                                saf1761_otg_setup_standard_chain_sub(&temp);
1996                        }
1997                }
1998        } else {
1999                if (need_sync) {
2000                        temp.pc = xfer->frbuffers + 0;
2001                        temp.len = 0;
2002                        temp.short_pkt = 0;
2003                        temp.setup_alt_next = 0;
2004
2005                        /* we need a SYNC point after TX */
2006                        temp.func = &saf1761_device_data_tx_sync;
2007                        saf1761_otg_setup_standard_chain_sub(&temp);
2008                }
2009        }
2010
2011        /* must have at least one frame! */
2012        td = temp.td;
2013        xfer->td_transfer_last = td;
2014
2015        if (is_host) {
2016                /* get first again */
2017                td = xfer->td_transfer_first;
2018                td->toggle = (xfer->endpoint->toggle_next ? 1 : 0);
2019        }
2020}
2021
2022static void
2023saf1761_otg_timeout(void *arg)
2024{
2025        struct usb_xfer *xfer = arg;
2026
2027        DPRINTF("xfer=%p\n", xfer);
2028
2029        USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
2030
2031        /* transfer is transferred */
2032        saf1761_otg_device_done(xfer, USB_ERR_TIMEOUT);
2033}
2034
2035static void
2036saf1761_otg_intr_set(struct usb_xfer *xfer, uint8_t set)
2037{
2038        struct saf1761_otg_softc *sc = SAF1761_OTG_BUS2SC(xfer->xroot->bus);
2039        uint8_t ep_no = (xfer->endpointno & UE_ADDR);
2040        uint32_t mask;
2041
2042        DPRINTFN(15, "endpoint=%d set=%d\n", xfer->endpointno, set);
2043
2044        if (ep_no == 0) {
2045                mask = SOTG_DCINTERRUPT_IEPRX(0) |
2046                    SOTG_DCINTERRUPT_IEPTX(0) |
2047                    SOTG_DCINTERRUPT_IEP0SETUP;
2048        } else if (xfer->endpointno & UE_DIR_IN) {
2049                mask = SOTG_DCINTERRUPT_IEPTX(ep_no);
2050        } else {
2051                mask = SOTG_DCINTERRUPT_IEPRX(ep_no);
2052        }
2053
2054        if (set)
2055                sc->sc_intr_enable |= mask;
2056        else
2057                sc->sc_intr_enable &= ~mask;
2058
2059        SAF1761_WRITE_LE_4(sc, SOTG_DCINTERRUPT_EN, sc->sc_intr_enable);
2060}
2061
2062static void
2063saf1761_otg_start_standard_chain(struct usb_xfer *xfer)
2064{
2065        struct saf1761_otg_softc *sc = SAF1761_OTG_BUS2SC(xfer->xroot->bus);
2066
2067        DPRINTFN(9, "\n");
2068
2069        USB_BUS_SPIN_LOCK(&sc->sc_bus);
2070
2071        /* poll one time */
2072        saf1761_otg_xfer_do_fifo(sc, xfer);
2073
2074        if (saf1761_otg_xfer_do_complete(sc, xfer) == 0) {
2075                /*
2076                 * Only enable the endpoint interrupt when we are
2077                 * actually waiting for data, hence we are dealing
2078                 * with level triggered interrupts !
2079                 */
2080                saf1761_otg_intr_set(xfer, 1);
2081
2082                /* put transfer on interrupt queue */
2083                usbd_transfer_enqueue(&xfer->xroot->bus->intr_q, xfer);
2084
2085                /* start timeout, if any */
2086                if (xfer->timeout != 0) {
2087                        usbd_transfer_timeout_ms(xfer,
2088                            &saf1761_otg_timeout, xfer->timeout);
2089                }
2090        }
2091        USB_BUS_SPIN_UNLOCK(&sc->sc_bus);
2092}
2093
2094static void
2095saf1761_otg_root_intr(struct saf1761_otg_softc *sc)
2096{
2097        DPRINTFN(9, "\n");
2098
2099        USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
2100
2101        /* set port bit - we only have one port */
2102        sc->sc_hub_idata[0] = 0x02;
2103
2104        uhub_root_intr(&sc->sc_bus, sc->sc_hub_idata,
2105            sizeof(sc->sc_hub_idata));
2106}
2107
2108static usb_error_t
2109saf1761_otg_standard_done_sub(struct usb_xfer *xfer)
2110{
2111        struct saf1761_otg_td *td;
2112        uint32_t len;
2113        usb_error_t error;
2114
2115        DPRINTFN(9, "\n");
2116
2117        td = xfer->td_transfer_cache;
2118
2119        do {
2120                len = td->remainder;
2121
2122                /* store last data toggle */
2123                xfer->endpoint->toggle_next = td->toggle;
2124
2125                if (xfer->aframes != xfer->nframes) {
2126                        /*
2127                         * Verify the length and subtract
2128                         * the remainder from "frlengths[]":
2129                         */
2130                        if (len > xfer->frlengths[xfer->aframes]) {
2131                                td->error_any = 1;
2132                        } else {
2133                                xfer->frlengths[xfer->aframes] -= len;
2134                        }
2135                }
2136                /* Check for transfer error */
2137                if (td->error_any) {
2138                        /* the transfer is finished */
2139                        error = (td->error_stall ?
2140                            USB_ERR_STALLED : USB_ERR_IOERROR);
2141                        td = NULL;
2142                        break;
2143                }
2144                /* Check for short transfer */
2145                if (len > 0) {
2146                        if (xfer->flags_int.short_frames_ok ||
2147                            xfer->flags_int.isochronous_xfr) {
2148                                /* follow alt next */
2149                                if (td->alt_next) {
2150                                        td = td->obj_next;
2151                                } else {
2152                                        td = NULL;
2153                                }
2154                        } else {
2155                                /* the transfer is finished */
2156                                td = NULL;
2157                        }
2158                        error = 0;
2159                        break;
2160                }
2161                td = td->obj_next;
2162
2163                /* this USB frame is complete */
2164                error = 0;
2165                break;
2166
2167        } while (0);
2168
2169        /* update transfer cache */
2170
2171        xfer->td_transfer_cache = td;
2172
2173        return (error);
2174}
2175
2176static void
2177saf1761_otg_standard_done(struct usb_xfer *xfer)
2178{
2179        usb_error_t err = 0;
2180
2181        DPRINTFN(13, "xfer=%p endpoint=%p transfer done\n",
2182            xfer, xfer->endpoint);
2183
2184        /* reset scanner */
2185
2186        xfer->td_transfer_cache = xfer->td_transfer_first;
2187
2188        if (xfer->flags_int.control_xfr) {
2189
2190                if (xfer->flags_int.control_hdr) {
2191
2192                        err = saf1761_otg_standard_done_sub(xfer);
2193                }
2194                xfer->aframes = 1;
2195
2196                if (xfer->td_transfer_cache == NULL) {
2197                        goto done;
2198                }
2199        }
2200        while (xfer->aframes != xfer->nframes) {
2201
2202                err = saf1761_otg_standard_done_sub(xfer);
2203                xfer->aframes++;
2204
2205                if (xfer->td_transfer_cache == NULL) {
2206                        goto done;
2207                }
2208        }
2209
2210        if (xfer->flags_int.control_xfr &&
2211            !xfer->flags_int.control_act) {
2212
2213                err = saf1761_otg_standard_done_sub(xfer);
2214        }
2215done:
2216        saf1761_otg_device_done(xfer, err);
2217}
2218
2219/*------------------------------------------------------------------------*
2220 *      saf1761_otg_device_done
2221 *
2222 * NOTE: this function can be called more than one time on the
2223 * same USB transfer!
2224 *------------------------------------------------------------------------*/
2225static void
2226saf1761_otg_device_done(struct usb_xfer *xfer, usb_error_t error)
2227{
2228        struct saf1761_otg_softc *sc = SAF1761_OTG_BUS2SC(xfer->xroot->bus);
2229
2230        USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
2231
2232        DPRINTFN(2, "xfer=%p, endpoint=%p, error=%d\n",
2233            xfer, xfer->endpoint, error);
2234
2235        USB_BUS_SPIN_LOCK(&sc->sc_bus);
2236
2237        if (xfer->flags_int.usb_mode == USB_MODE_DEVICE) {
2238                saf1761_otg_intr_set(xfer, 0);
2239        } else {
2240                struct saf1761_otg_td *td;
2241
2242                td = xfer->td_transfer_cache;
2243
2244                if (td != NULL)
2245                        saf1761_host_channel_free(sc, td);
2246        }
2247
2248        USB_BUS_SPIN_UNLOCK(&sc->sc_bus);
2249
2250        /* dequeue transfer and start next transfer */
2251        usbd_transfer_done(xfer, error);
2252}
2253
2254static void
2255saf1761_otg_xfer_stall(struct usb_xfer *xfer)
2256{
2257        saf1761_otg_device_done(xfer, USB_ERR_STALLED);
2258}
2259
2260static void
2261saf1761_otg_set_stall(struct usb_device *udev,
2262    struct usb_endpoint *ep, uint8_t *did_stall)
2263{
2264        struct saf1761_otg_softc *sc;
2265        uint8_t ep_no;
2266        uint8_t ep_type;
2267        uint8_t ep_dir;
2268
2269        USB_BUS_LOCK_ASSERT(udev->bus, MA_OWNED);
2270
2271        /* check mode */
2272        if (udev->flags.usb_mode != USB_MODE_DEVICE) {
2273                /* not supported */
2274                return;
2275        }
2276
2277        DPRINTFN(5, "endpoint=%p\n", ep);
2278
2279        /* set STALL bit */
2280        sc = SAF1761_OTG_BUS2SC(udev->bus);
2281
2282        ep_no = (ep->edesc->bEndpointAddress & UE_ADDR);
2283        ep_dir = (ep->edesc->bEndpointAddress & (UE_DIR_IN | UE_DIR_OUT));
2284        ep_type = (ep->edesc->bmAttributes & UE_XFERTYPE);
2285
2286        if (ep_type == UE_CONTROL) {
2287                /* should not happen */
2288                return;
2289        }
2290        USB_BUS_SPIN_LOCK(&sc->sc_bus);
2291
2292        /* select the correct endpoint */
2293        SAF1761_WRITE_LE_4(sc, SOTG_EP_INDEX,
2294            (ep_no << SOTG_EP_INDEX_ENDP_INDEX_SHIFT) |
2295            ((ep_dir == UE_DIR_IN) ? SOTG_EP_INDEX_DIR_IN :
2296            SOTG_EP_INDEX_DIR_OUT));
2297
2298        /* set stall */
2299        SAF1761_WRITE_LE_4(sc, SOTG_CTRL_FUNC, SOTG_CTRL_FUNC_STALL);
2300
2301        USB_BUS_SPIN_UNLOCK(&sc->sc_bus);
2302}
2303
2304static void
2305saf1761_otg_clear_stall_sub_locked(struct saf1761_otg_softc *sc,
2306    uint8_t ep_no, uint8_t ep_type, uint8_t ep_dir)
2307{
2308        if (ep_type == UE_CONTROL) {
2309                /* clearing stall is not needed */
2310                return;
2311        }
2312        /* select the correct endpoint */
2313        SAF1761_WRITE_LE_4(sc, SOTG_EP_INDEX,
2314            (ep_no << SOTG_EP_INDEX_ENDP_INDEX_SHIFT) |
2315            ((ep_dir == UE_DIR_IN) ? SOTG_EP_INDEX_DIR_IN :
2316            SOTG_EP_INDEX_DIR_OUT));
2317
2318        /* disable endpoint */
2319        SAF1761_WRITE_LE_4(sc, SOTG_EP_TYPE, 0);
2320        /* enable endpoint again - will clear data toggle */
2321        SAF1761_WRITE_LE_4(sc, SOTG_EP_TYPE, ep_type | SOTG_EP_TYPE_ENABLE);
2322
2323        /* clear buffer */
2324        SAF1761_WRITE_LE_4(sc, SOTG_CTRL_FUNC, SOTG_CTRL_FUNC_CLBUF);
2325        /* clear stall */
2326        SAF1761_WRITE_LE_4(sc, SOTG_CTRL_FUNC, 0);
2327}
2328
2329static void
2330saf1761_otg_clear_stall(struct usb_device *udev, struct usb_endpoint *ep)
2331{
2332        struct saf1761_otg_softc *sc;
2333        struct usb_endpoint_descriptor *ed;
2334
2335        USB_BUS_LOCK_ASSERT(udev->bus, MA_OWNED);
2336
2337        DPRINTFN(5, "endpoint=%p\n", ep);
2338
2339        /* check mode */
2340        if (udev->flags.usb_mode != USB_MODE_DEVICE) {
2341                /* not supported */
2342                return;
2343        }
2344        /* get softc */
2345        sc = SAF1761_OTG_BUS2SC(udev->bus);
2346
2347        USB_BUS_SPIN_LOCK(&sc->sc_bus);
2348
2349        /* get endpoint descriptor */
2350        ed = ep->edesc;
2351
2352        /* reset endpoint */
2353        saf1761_otg_clear_stall_sub_locked(sc,
2354            (ed->bEndpointAddress & UE_ADDR),
2355            (ed->bmAttributes & UE_XFERTYPE),
2356            (ed->bEndpointAddress & (UE_DIR_IN | UE_DIR_OUT)));
2357
2358        USB_BUS_SPIN_UNLOCK(&sc->sc_bus);
2359}
2360
2361usb_error_t
2362saf1761_otg_init(struct saf1761_otg_softc *sc)
2363{
2364        const struct usb_hw_ep_profile *pf;
2365        uint32_t x;
2366
2367        DPRINTF("\n");
2368
2369        /* set up the bus structure */
2370        sc->sc_bus.usbrev = USB_REV_2_0;
2371        sc->sc_bus.methods = &saf1761_otg_bus_methods;
2372
2373        USB_BUS_LOCK(&sc->sc_bus);
2374
2375        /* Reset Host controller, including HW mode */
2376        SAF1761_WRITE_LE_4(sc, SOTG_SW_RESET, SOTG_SW_RESET_ALL);
2377
2378        DELAY(1000);
2379
2380        /* Reset Host controller, including HW mode */
2381        SAF1761_WRITE_LE_4(sc, SOTG_SW_RESET, SOTG_SW_RESET_HC);
2382
2383        /* wait a bit */
2384        DELAY(1000);
2385
2386        SAF1761_WRITE_LE_4(sc, SOTG_SW_RESET, 0);
2387
2388        /* wait a bit */
2389        DELAY(1000);
2390
2391        /* Enable interrupts */
2392        sc->sc_hw_mode |= SOTG_HW_MODE_CTRL_GLOBAL_INTR_EN |
2393            SOTG_HW_MODE_CTRL_COMN_INT;
2394
2395        /* unlock device */
2396        SAF1761_WRITE_LE_4(sc, SOTG_UNLOCK_DEVICE, SOTG_UNLOCK_DEVICE_CODE);
2397
2398        /*
2399         * Set correct hardware mode, must be written twice if bus
2400         * width is changed:
2401         */
2402        SAF1761_WRITE_LE_4(sc, SOTG_HW_MODE_CTRL, sc->sc_hw_mode);
2403        SAF1761_WRITE_LE_4(sc, SOTG_HW_MODE_CTRL, sc->sc_hw_mode);
2404
2405        SAF1761_WRITE_LE_4(sc, SOTG_DCSCRATCH, 0xdeadbeef);
2406        SAF1761_WRITE_LE_4(sc, SOTG_HCSCRATCH, 0xdeadbeef);
2407
2408        DPRINTF("DCID=0x%08x VEND_PROD=0x%08x HWMODE=0x%08x SCRATCH=0x%08x,0x%08x\n",
2409            SAF1761_READ_LE_4(sc, SOTG_DCCHIP_ID),
2410            SAF1761_READ_LE_4(sc, SOTG_VEND_PROD_ID),
2411            SAF1761_READ_LE_4(sc, SOTG_HW_MODE_CTRL),
2412            SAF1761_READ_LE_4(sc, SOTG_DCSCRATCH),
2413            SAF1761_READ_LE_4(sc, SOTG_HCSCRATCH));
2414
2415        /* reset device controller */
2416        SAF1761_WRITE_LE_4(sc, SOTG_MODE, SOTG_MODE_SFRESET);
2417        SAF1761_WRITE_LE_4(sc, SOTG_MODE, 0);
2418
2419        /* wait a bit */
2420        DELAY(1000);
2421
2422        /* reset host controller */
2423        SAF1761_WRITE_LE_4(sc, SOTG_USBCMD, SOTG_USBCMD_HCRESET);
2424
2425        /* wait for reset to clear */
2426        for (x = 0; x != 10; x++) {
2427                if ((SAF1761_READ_LE_4(sc, SOTG_USBCMD) & SOTG_USBCMD_HCRESET) == 0)
2428                        break;
2429                usb_pause_mtx(&sc->sc_bus.bus_mtx, hz / 10);
2430        }
2431
2432        SAF1761_WRITE_LE_4(sc, SOTG_HW_MODE_CTRL, sc->sc_hw_mode |
2433            SOTG_HW_MODE_CTRL_ALL_ATX_RESET);
2434
2435        /* wait a bit */
2436        DELAY(1000);
2437
2438        SAF1761_WRITE_LE_4(sc, SOTG_HW_MODE_CTRL, sc->sc_hw_mode);
2439
2440        /* wait a bit */
2441        DELAY(1000);
2442
2443        /* do a pulldown */
2444        saf1761_otg_pull_down(sc);
2445
2446        /* wait 10ms for pulldown to stabilise */
2447        usb_pause_mtx(&sc->sc_bus.bus_mtx, hz / 100);
2448
2449        for (x = 1;; x++) {
2450
2451                saf1761_otg_get_hw_ep_profile(NULL, &pf, x);
2452                if (pf == NULL)
2453                        break;
2454
2455                /* select the correct endpoint */
2456                SAF1761_WRITE_LE_4(sc, SOTG_EP_INDEX,
2457                    (x << SOTG_EP_INDEX_ENDP_INDEX_SHIFT) |
2458                    SOTG_EP_INDEX_DIR_IN);
2459
2460                /* select the maximum packet size */
2461                SAF1761_WRITE_LE_4(sc, SOTG_EP_MAXPACKET, pf->max_in_frame_size);
2462
2463                /* select the correct endpoint */
2464                SAF1761_WRITE_LE_4(sc, SOTG_EP_INDEX,
2465                    (x << SOTG_EP_INDEX_ENDP_INDEX_SHIFT) |
2466                    SOTG_EP_INDEX_DIR_OUT);
2467
2468                /* select the maximum packet size */
2469                SAF1761_WRITE_LE_4(sc, SOTG_EP_MAXPACKET, pf->max_out_frame_size);
2470        }
2471
2472        /* enable interrupts */
2473        SAF1761_WRITE_LE_4(sc, SOTG_MODE, SOTG_MODE_GLINTENA |
2474            SOTG_MODE_CLKAON | SOTG_MODE_WKUPCS);
2475
2476        sc->sc_interrupt_cfg |=
2477            SOTG_INTERRUPT_CFG_CDBGMOD |
2478            SOTG_INTERRUPT_CFG_DDBGMODIN |
2479            SOTG_INTERRUPT_CFG_DDBGMODOUT;
2480
2481        /* set default values */
2482        SAF1761_WRITE_LE_4(sc, SOTG_INTERRUPT_CFG, sc->sc_interrupt_cfg);
2483
2484        /* enable VBUS and ID interrupt */
2485        SAF1761_WRITE_LE_4(sc, SOTG_IRQ_ENABLE_SET_CLR,
2486            SOTG_IRQ_ENABLE_CLR(0xFFFF));
2487        SAF1761_WRITE_LE_4(sc, SOTG_IRQ_ENABLE_SET_CLR,
2488            SOTG_IRQ_ENABLE_SET(SOTG_IRQ_ID | SOTG_IRQ_VBUS_VLD));
2489
2490        /* enable interrupts */
2491        sc->sc_intr_enable = SOTG_DCINTERRUPT_IEVBUS |
2492            SOTG_DCINTERRUPT_IEBRST | SOTG_DCINTERRUPT_IESUSP;
2493        SAF1761_WRITE_LE_4(sc, SOTG_DCINTERRUPT_EN, sc->sc_intr_enable);
2494
2495        /*
2496         * Connect ATX port 1 to device controller, select external
2497         * charge pump and driver VBUS to +5V:
2498         */
2499        SAF1761_WRITE_LE_4(sc, SOTG_CTRL_SET_CLR,
2500            SOTG_CTRL_CLR(0xFFFF));
2501#ifdef __rtems__
2502        SAF1761_WRITE_LE_4(sc, SOTG_CTRL_SET_CLR,
2503            SOTG_CTRL_SET(SOTG_CTRL_SEL_CP_EXT | SOTG_CTRL_VBUS_DRV));
2504#else
2505        SAF1761_WRITE_LE_4(sc, SOTG_CTRL_SET_CLR,
2506            SOTG_CTRL_SET(SOTG_CTRL_SW_SEL_HC_DC |
2507            SOTG_CTRL_BDIS_ACON_EN | SOTG_CTRL_SEL_CP_EXT |
2508            SOTG_CTRL_VBUS_DRV));
2509#endif
2510        /* disable device address */
2511        SAF1761_WRITE_LE_4(sc, SOTG_ADDRESS, 0);
2512
2513        /* enable host controller clock and preserve reserved bits */
2514        x = SAF1761_READ_LE_4(sc, SOTG_POWER_DOWN);
2515        SAF1761_WRITE_LE_4(sc, SOTG_POWER_DOWN, x | SOTG_POWER_DOWN_HC_CLK_EN);
2516
2517        /* wait 10ms for clock */
2518        usb_pause_mtx(&sc->sc_bus.bus_mtx, hz / 100);
2519
2520        /* enable configuration flag */
2521        SAF1761_WRITE_LE_4(sc, SOTG_CONFIGFLAG, SOTG_CONFIGFLAG_ENABLE);
2522
2523        /* clear RAM block */
2524        for (x = 0x400; x != 0x10000; x += 4)
2525                SAF1761_WRITE_LE_4(sc, x, 0);
2526
2527        /* start the HC */
2528        SAF1761_WRITE_LE_4(sc, SOTG_USBCMD, SOTG_USBCMD_RS);
2529
2530        DPRINTF("USBCMD=0x%08x\n", SAF1761_READ_LE_4(sc, SOTG_USBCMD));
2531
2532        /* make HC scan all PTDs */
2533        SAF1761_WRITE_LE_4(sc, SOTG_ATL_PTD_LAST_PTD, (1 << 31));
2534        SAF1761_WRITE_LE_4(sc, SOTG_INT_PTD_LAST_PTD, (1 << 31));
2535        SAF1761_WRITE_LE_4(sc, SOTG_ISO_PTD_LAST_PTD, (1 << 31));
2536
2537        /* skip all PTDs by default */
2538        SAF1761_WRITE_LE_4(sc, SOTG_ATL_PTD_SKIP_PTD, -1U);
2539        SAF1761_WRITE_LE_4(sc, SOTG_INT_PTD_SKIP_PTD, -1U);
2540        SAF1761_WRITE_LE_4(sc, SOTG_ISO_PTD_SKIP_PTD, -1U);
2541
2542        /* activate all PTD types */
2543        SAF1761_WRITE_LE_4(sc, SOTG_HCBUFFERSTATUS,
2544            SOTG_HCBUFFERSTATUS_ISO_BUF_FILL |
2545            SOTG_HCBUFFERSTATUS_INT_BUF_FILL |
2546            SOTG_HCBUFFERSTATUS_ATL_BUF_FILL);
2547
2548        /* we don't use the AND mask */
2549        SAF1761_WRITE_LE_4(sc, SOTG_ISO_IRQ_MASK_AND, 0);
2550        SAF1761_WRITE_LE_4(sc, SOTG_INT_IRQ_MASK_AND, 0);
2551        SAF1761_WRITE_LE_4(sc, SOTG_ATL_IRQ_MASK_AND, 0);
2552
2553        /* enable all PTD OR interrupts by default */
2554        SAF1761_WRITE_LE_4(sc, SOTG_ISO_IRQ_MASK_OR, -1U);
2555        SAF1761_WRITE_LE_4(sc, SOTG_INT_IRQ_MASK_OR, -1U);
2556        SAF1761_WRITE_LE_4(sc, SOTG_ATL_IRQ_MASK_OR, -1U);
2557
2558        /* enable HC interrupts */
2559        SAF1761_WRITE_LE_4(sc, SOTG_HCINTERRUPT_ENABLE,
2560            SOTG_HCINTERRUPT_OTG_IRQ |
2561            SOTG_HCINTERRUPT_ISO_IRQ |
2562            SOTG_HCINTERRUPT_ALT_IRQ |
2563            SOTG_HCINTERRUPT_INT_IRQ);
2564
2565        /* poll initial VBUS status */
2566        saf1761_otg_update_vbus(sc);
2567
2568        USB_BUS_UNLOCK(&sc->sc_bus);
2569
2570        /* catch any lost interrupts */
2571
2572        saf1761_otg_do_poll(&sc->sc_bus);
2573
2574        return (0);                     /* success */
2575}
2576
2577void
2578saf1761_otg_uninit(struct saf1761_otg_softc *sc)
2579{
2580        USB_BUS_LOCK(&sc->sc_bus);
2581
2582        /* disable all interrupts */
2583        SAF1761_WRITE_LE_4(sc, SOTG_MODE, 0);
2584
2585        sc->sc_flags.port_powered = 0;
2586        sc->sc_flags.status_vbus = 0;
2587        sc->sc_flags.status_bus_reset = 0;
2588        sc->sc_flags.status_suspend = 0;
2589        sc->sc_flags.change_suspend = 0;
2590        sc->sc_flags.change_connect = 1;
2591
2592        saf1761_otg_pull_down(sc);
2593        USB_BUS_UNLOCK(&sc->sc_bus);
2594}
2595
2596static void
2597saf1761_otg_suspend(struct saf1761_otg_softc *sc)
2598{
2599        /* TODO */
2600}
2601
2602static void
2603saf1761_otg_resume(struct saf1761_otg_softc *sc)
2604{
2605        /* TODO */
2606}
2607
2608static void
2609saf1761_otg_do_poll(struct usb_bus *bus)
2610{
2611        struct saf1761_otg_softc *sc = SAF1761_OTG_BUS2SC(bus);
2612
2613        USB_BUS_LOCK(&sc->sc_bus);
2614        USB_BUS_SPIN_LOCK(&sc->sc_bus);
2615        saf1761_otg_interrupt_poll_locked(sc);
2616        USB_BUS_SPIN_UNLOCK(&sc->sc_bus);
2617        saf1761_otg_interrupt_complete_locked(sc);
2618        USB_BUS_UNLOCK(&sc->sc_bus);
2619}
2620
2621/*------------------------------------------------------------------------*
2622 * saf1761_otg control support
2623 * saf1761_otg interrupt support
2624 * saf1761_otg bulk support
2625 *------------------------------------------------------------------------*/
2626static void
2627saf1761_otg_device_non_isoc_open(struct usb_xfer *xfer)
2628{
2629        return;
2630}
2631
2632static void
2633saf1761_otg_device_non_isoc_close(struct usb_xfer *xfer)
2634{
2635        saf1761_otg_device_done(xfer, USB_ERR_CANCELLED);
2636}
2637
2638static void
2639saf1761_otg_device_non_isoc_enter(struct usb_xfer *xfer)
2640{
2641        return;
2642}
2643
2644static void
2645saf1761_otg_device_non_isoc_start(struct usb_xfer *xfer)
2646{
2647        /* setup TDs */
2648        saf1761_otg_setup_standard_chain(xfer);
2649        saf1761_otg_start_standard_chain(xfer);
2650}
2651
2652static const struct usb_pipe_methods saf1761_otg_non_isoc_methods =
2653{
2654        .open = saf1761_otg_device_non_isoc_open,
2655        .close = saf1761_otg_device_non_isoc_close,
2656        .enter = saf1761_otg_device_non_isoc_enter,
2657        .start = saf1761_otg_device_non_isoc_start,
2658};
2659
2660/*------------------------------------------------------------------------*
2661 * saf1761_otg device side isochronous support
2662 *------------------------------------------------------------------------*/
2663static void
2664saf1761_otg_device_isoc_open(struct usb_xfer *xfer)
2665{
2666        return;
2667}
2668
2669static void
2670saf1761_otg_device_isoc_close(struct usb_xfer *xfer)
2671{
2672        saf1761_otg_device_done(xfer, USB_ERR_CANCELLED);
2673}
2674
2675static void
2676saf1761_otg_device_isoc_enter(struct usb_xfer *xfer)
2677{
2678        struct saf1761_otg_softc *sc = SAF1761_OTG_BUS2SC(xfer->xroot->bus);
2679        uint32_t temp;
2680        uint32_t nframes;
2681
2682        DPRINTFN(6, "xfer=%p next=%d nframes=%d\n",
2683            xfer, xfer->endpoint->isoc_next, xfer->nframes);
2684
2685        /* get the current frame index - we don't need the high bits */
2686
2687        nframes = SAF1761_READ_LE_4(sc, SOTG_FRAME_NUM);
2688
2689        /*
2690         * check if the frame index is within the window where the
2691         * frames will be inserted
2692         */
2693        temp = (nframes - xfer->endpoint->isoc_next) & SOTG_FRAME_NUM_SOFR_MASK;
2694
2695        if ((xfer->endpoint->is_synced == 0) ||
2696            (temp < xfer->nframes)) {
2697                /*
2698                 * If there is data underflow or the pipe queue is
2699                 * empty we schedule the transfer a few frames ahead
2700                 * of the current frame position. Else two isochronous
2701                 * transfers might overlap.
2702                 */
2703                xfer->endpoint->isoc_next = (nframes + 3) & SOTG_FRAME_NUM_SOFR_MASK;
2704                xfer->endpoint->is_synced = 1;
2705                DPRINTFN(3, "start next=%d\n", xfer->endpoint->isoc_next);
2706        }
2707        /*
2708         * compute how many milliseconds the insertion is ahead of the
2709         * current frame position:
2710         */
2711        temp = (xfer->endpoint->isoc_next - nframes) & SOTG_FRAME_NUM_SOFR_MASK;
2712
2713        /*
2714         * pre-compute when the isochronous transfer will be finished:
2715         */
2716        xfer->isoc_time_complete =
2717            usb_isoc_time_expand(&sc->sc_bus, nframes) + temp +
2718            xfer->nframes;
2719
2720        /* compute frame number for next insertion */
2721        xfer->endpoint->isoc_next += xfer->nframes;
2722
2723        /* setup TDs */
2724        saf1761_otg_setup_standard_chain(xfer);
2725}
2726
2727static void
2728saf1761_otg_device_isoc_start(struct usb_xfer *xfer)
2729{
2730        /* start TD chain */
2731        saf1761_otg_start_standard_chain(xfer);
2732}
2733
2734static const struct usb_pipe_methods saf1761_otg_device_isoc_methods =
2735{
2736        .open = saf1761_otg_device_isoc_open,
2737        .close = saf1761_otg_device_isoc_close,
2738        .enter = saf1761_otg_device_isoc_enter,
2739        .start = saf1761_otg_device_isoc_start,
2740};
2741
2742/*------------------------------------------------------------------------*
2743 * saf1761_otg host side isochronous support
2744 *------------------------------------------------------------------------*/
2745static void
2746saf1761_otg_host_isoc_open(struct usb_xfer *xfer)
2747{
2748        return;
2749}
2750
2751static void
2752saf1761_otg_host_isoc_close(struct usb_xfer *xfer)
2753{
2754        saf1761_otg_device_done(xfer, USB_ERR_CANCELLED);
2755}
2756
2757static void
2758saf1761_otg_host_isoc_enter(struct usb_xfer *xfer)
2759{
2760        struct saf1761_otg_softc *sc = SAF1761_OTG_BUS2SC(xfer->xroot->bus);
2761        uint32_t temp;
2762        uint32_t nframes;
2763
2764        DPRINTFN(6, "xfer=%p next=%d nframes=%d\n",
2765            xfer, xfer->endpoint->isoc_next, xfer->nframes);
2766
2767        /* get the current frame index - we don't need the high bits */
2768
2769        nframes = (SAF1761_READ_LE_4(sc, SOTG_FRINDEX) & SOTG_FRINDEX_MASK) >> 3;
2770
2771        /*
2772         * check if the frame index is within the window where the
2773         * frames will be inserted
2774         */
2775        temp = (nframes - xfer->endpoint->isoc_next) & (SOTG_FRINDEX_MASK >> 3);
2776
2777        if ((xfer->endpoint->is_synced == 0) ||
2778            (temp < xfer->nframes)) {
2779                /*
2780                 * If there is data underflow or the pipe queue is
2781                 * empty we schedule the transfer a few frames ahead
2782                 * of the current frame position. Else two isochronous
2783                 * transfers might overlap.
2784                 */
2785                xfer->endpoint->isoc_next = (nframes + 3) & (SOTG_FRINDEX_MASK >> 3);
2786                xfer->endpoint->is_synced = 1;
2787                DPRINTFN(3, "start next=%d\n", xfer->endpoint->isoc_next);
2788        }
2789        /*
2790         * compute how many milliseconds the insertion is ahead of the
2791         * current frame position:
2792         */
2793        temp = (xfer->endpoint->isoc_next - nframes) & (SOTG_FRINDEX_MASK >> 3);
2794
2795        /*
2796         * pre-compute when the isochronous transfer will be finished:
2797         */
2798        xfer->isoc_time_complete =
2799            usb_isoc_time_expand(&sc->sc_bus, nframes) + temp +
2800            xfer->nframes;
2801
2802        /* compute frame number for next insertion */
2803        xfer->endpoint->isoc_next += xfer->nframes;
2804
2805        /* setup TDs */
2806        saf1761_otg_setup_standard_chain(xfer);
2807}
2808
2809static void
2810saf1761_otg_host_isoc_start(struct usb_xfer *xfer)
2811{
2812        /* start TD chain */
2813        saf1761_otg_start_standard_chain(xfer);
2814}
2815
2816static const struct usb_pipe_methods saf1761_otg_host_isoc_methods =
2817{
2818        .open = saf1761_otg_host_isoc_open,
2819        .close = saf1761_otg_host_isoc_close,
2820        .enter = saf1761_otg_host_isoc_enter,
2821        .start = saf1761_otg_host_isoc_start,
2822};
2823
2824/*------------------------------------------------------------------------*
2825 * saf1761_otg root control support
2826 *------------------------------------------------------------------------*
2827 * Simulate a hardware HUB by handling all the necessary requests.
2828 *------------------------------------------------------------------------*/
2829
2830#define HSETW(ptr, val) ptr = { (uint8_t)(val), (uint8_t)((val) >> 8) }
2831
2832static const struct usb_device_descriptor saf1761_otg_devd = {
2833        .bLength = sizeof(struct usb_device_descriptor),
2834        .bDescriptorType = UDESC_DEVICE,
2835        HSETW(.idVendor, 0x04cc),
2836        HSETW(.idProduct, 0x1761),
2837        .bcdUSB = {0x00, 0x02},
2838        .bDeviceClass = UDCLASS_HUB,
2839        .bDeviceSubClass = UDSUBCLASS_HUB,
2840        .bDeviceProtocol = UDPROTO_FSHUB,
2841        .bMaxPacketSize = 64,
2842        .bcdDevice = {0x00, 0x01},
2843        .iManufacturer = 1,
2844        .iProduct = 2,
2845        .bNumConfigurations = 1,
2846};
2847
2848static const struct usb_device_qualifier saf1761_otg_odevd = {
2849        .bLength = sizeof(struct usb_device_qualifier),
2850        .bDescriptorType = UDESC_DEVICE_QUALIFIER,
2851        .bcdUSB = {0x00, 0x02},
2852        .bDeviceClass = UDCLASS_HUB,
2853        .bDeviceSubClass = UDSUBCLASS_HUB,
2854        .bDeviceProtocol = UDPROTO_FSHUB,
2855        .bMaxPacketSize0 = 0,
2856        .bNumConfigurations = 0,
2857};
2858
2859static const struct saf1761_otg_config_desc saf1761_otg_confd = {
2860        .confd = {
2861                .bLength = sizeof(struct usb_config_descriptor),
2862                .bDescriptorType = UDESC_CONFIG,
2863                .wTotalLength[0] = sizeof(saf1761_otg_confd),
2864                .bNumInterface = 1,
2865                .bConfigurationValue = 1,
2866                .iConfiguration = 0,
2867                .bmAttributes = UC_SELF_POWERED,
2868                .bMaxPower = 0,
2869        },
2870        .ifcd = {
2871                .bLength = sizeof(struct usb_interface_descriptor),
2872                .bDescriptorType = UDESC_INTERFACE,
2873                .bNumEndpoints = 1,
2874                .bInterfaceClass = UICLASS_HUB,
2875                .bInterfaceSubClass = UISUBCLASS_HUB,
2876                .bInterfaceProtocol = 0,
2877        },
2878
2879        .endpd = {
2880                .bLength = sizeof(struct usb_endpoint_descriptor),
2881                .bDescriptorType = UDESC_ENDPOINT,
2882                .bEndpointAddress = (UE_DIR_IN | SAF1761_OTG_INTR_ENDPT),
2883                .bmAttributes = UE_INTERRUPT,
2884                .wMaxPacketSize[0] = 8,
2885                .bInterval = 255,
2886        },
2887};
2888
2889static const struct usb_hub_descriptor_min saf1761_otg_hubd = {
2890        .bDescLength = sizeof(saf1761_otg_hubd),
2891        .bDescriptorType = UDESC_HUB,
2892        .bNbrPorts = SOTG_NUM_PORTS,
2893        HSETW(.wHubCharacteristics, (UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL)),
2894        .bPwrOn2PwrGood = 50,
2895        .bHubContrCurrent = 0,
2896        .DeviceRemovable = {0},         /* port is removable */
2897};
2898
2899#define STRING_VENDOR \
2900  "N\0X\0P"
2901
2902#define STRING_PRODUCT \
2903  "D\0C\0I\0 \0R\0o\0o\0t\0 \0H\0U\0B"
2904
2905USB_MAKE_STRING_DESC(STRING_VENDOR, saf1761_otg_vendor);
2906USB_MAKE_STRING_DESC(STRING_PRODUCT, saf1761_otg_product);
2907
2908static usb_error_t
2909saf1761_otg_roothub_exec(struct usb_device *udev,
2910    struct usb_device_request *req, const void **pptr, uint16_t *plength)
2911{
2912        struct saf1761_otg_softc *sc = SAF1761_OTG_BUS2SC(udev->bus);
2913        const void *ptr;
2914        uint16_t len;
2915        uint16_t value;
2916        uint16_t index;
2917        uint32_t temp;
2918        uint32_t i;
2919        usb_error_t err;
2920
2921        USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
2922
2923        /* buffer reset */
2924        ptr = (const void *)&sc->sc_hub_temp;
2925        len = 0;
2926        err = 0;
2927
2928        value = UGETW(req->wValue);
2929        index = UGETW(req->wIndex);
2930
2931        /* demultiplex the control request */
2932
2933        switch (req->bmRequestType) {
2934        case UT_READ_DEVICE:
2935                switch (req->bRequest) {
2936                case UR_GET_DESCRIPTOR:
2937                        goto tr_handle_get_descriptor;
2938                case UR_GET_CONFIG:
2939                        goto tr_handle_get_config;
2940                case UR_GET_STATUS:
2941                        goto tr_handle_get_status;
2942                default:
2943                        goto tr_stalled;
2944                }
2945                break;
2946
2947        case UT_WRITE_DEVICE:
2948                switch (req->bRequest) {
2949                case UR_SET_ADDRESS:
2950                        goto tr_handle_set_address;
2951                case UR_SET_CONFIG:
2952                        goto tr_handle_set_config;
2953                case UR_CLEAR_FEATURE:
2954                        goto tr_valid;  /* nop */
2955                case UR_SET_DESCRIPTOR:
2956                        goto tr_valid;  /* nop */
2957                case UR_SET_FEATURE:
2958                default:
2959                        goto tr_stalled;
2960                }
2961                break;
2962
2963        case UT_WRITE_ENDPOINT:
2964                switch (req->bRequest) {
2965                case UR_CLEAR_FEATURE:
2966                        switch (UGETW(req->wValue)) {
2967                        case UF_ENDPOINT_HALT:
2968                                goto tr_handle_clear_halt;
2969                        case UF_DEVICE_REMOTE_WAKEUP:
2970                                goto tr_handle_clear_wakeup;
2971                        default:
2972                                goto tr_stalled;
2973                        }
2974                        break;
2975                case UR_SET_FEATURE:
2976                        switch (UGETW(req->wValue)) {
2977                        case UF_ENDPOINT_HALT:
2978                                goto tr_handle_set_halt;
2979                        case UF_DEVICE_REMOTE_WAKEUP:
2980                                goto tr_handle_set_wakeup;
2981                        default:
2982                                goto tr_stalled;
2983                        }
2984                        break;
2985                case UR_SYNCH_FRAME:
2986                        goto tr_valid;  /* nop */
2987                default:
2988                        goto tr_stalled;
2989                }
2990                break;
2991
2992        case UT_READ_ENDPOINT:
2993                switch (req->bRequest) {
2994                case UR_GET_STATUS:
2995                        goto tr_handle_get_ep_status;
2996                default:
2997                        goto tr_stalled;
2998                }
2999                break;
3000
3001        case UT_WRITE_INTERFACE:
3002                switch (req->bRequest) {
3003                case UR_SET_INTERFACE:
3004                        goto tr_handle_set_interface;
3005                case UR_CLEAR_FEATURE:
3006                        goto tr_valid;  /* nop */
3007                case UR_SET_FEATURE:
3008                default:
3009                        goto tr_stalled;
3010                }
3011                break;
3012
3013        case UT_READ_INTERFACE:
3014                switch (req->bRequest) {
3015                case UR_GET_INTERFACE:
3016                        goto tr_handle_get_interface;
3017                case UR_GET_STATUS:
3018                        goto tr_handle_get_iface_status;
3019                default:
3020                        goto tr_stalled;
3021                }
3022                break;
3023
3024        case UT_WRITE_CLASS_INTERFACE:
3025        case UT_WRITE_VENDOR_INTERFACE:
3026                /* XXX forward */
3027                break;
3028
3029        case UT_READ_CLASS_INTERFACE:
3030        case UT_READ_VENDOR_INTERFACE:
3031                /* XXX forward */
3032                break;
3033
3034        case UT_WRITE_CLASS_DEVICE:
3035                switch (req->bRequest) {
3036                case UR_CLEAR_FEATURE:
3037                        goto tr_valid;
3038                case UR_SET_DESCRIPTOR:
3039                case UR_SET_FEATURE:
3040                        break;
3041                default:
3042                        goto tr_stalled;
3043                }
3044                break;
3045
3046        case UT_WRITE_CLASS_OTHER:
3047                switch (req->bRequest) {
3048                case UR_CLEAR_FEATURE:
3049                        if (index == SOTG_HOST_PORT_NUM)
3050                                goto tr_handle_clear_port_feature_host;
3051                        else if (index == SOTG_DEVICE_PORT_NUM)
3052                                goto tr_handle_clear_port_feature_device;
3053                        else
3054                                goto tr_stalled;
3055                case UR_SET_FEATURE:
3056                        if (index == SOTG_HOST_PORT_NUM)
3057                                goto tr_handle_set_port_feature_host;
3058                        else if (index == SOTG_DEVICE_PORT_NUM)
3059                                goto tr_handle_set_port_feature_device;
3060                        else
3061                                goto tr_stalled;
3062                case UR_CLEAR_TT_BUFFER:
3063                case UR_RESET_TT:
3064                case UR_STOP_TT:
3065                        goto tr_valid;
3066
3067                default:
3068                        goto tr_stalled;
3069                }
3070                break;
3071
3072        case UT_READ_CLASS_OTHER:
3073                switch (req->bRequest) {
3074                case UR_GET_TT_STATE:
3075                        goto tr_handle_get_tt_state;
3076                case UR_GET_STATUS:
3077                        if (index == SOTG_HOST_PORT_NUM)
3078                                goto tr_handle_get_port_status_host;
3079                        else if (index == SOTG_DEVICE_PORT_NUM)
3080                                goto tr_handle_get_port_status_device;
3081                        else
3082                                goto tr_stalled;
3083                default:
3084                        goto tr_stalled;
3085                }
3086                break;
3087
3088        case UT_READ_CLASS_DEVICE:
3089                switch (req->bRequest) {
3090                case UR_GET_DESCRIPTOR:
3091                        goto tr_handle_get_class_descriptor;
3092                case UR_GET_STATUS:
3093                        goto tr_handle_get_class_status;
3094
3095                default:
3096                        goto tr_stalled;
3097                }
3098                break;
3099        default:
3100                goto tr_stalled;
3101        }
3102        goto tr_valid;
3103
3104tr_handle_get_descriptor:
3105        switch (value >> 8) {
3106        case UDESC_DEVICE:
3107                if (value & 0xff)
3108                        goto tr_stalled;
3109                len = sizeof(saf1761_otg_devd);
3110                ptr = (const void *)&saf1761_otg_devd;
3111                goto tr_valid;
3112        case UDESC_DEVICE_QUALIFIER:
3113                if (value & 0xff)
3114                        goto tr_stalled;
3115                len = sizeof(saf1761_otg_odevd);
3116                ptr = (const void *)&saf1761_otg_odevd;
3117                goto tr_valid;
3118        case UDESC_CONFIG:
3119                if (value & 0xff)
3120                        goto tr_stalled;
3121                len = sizeof(saf1761_otg_confd);
3122                ptr = (const void *)&saf1761_otg_confd;
3123                goto tr_valid;
3124        case UDESC_STRING:
3125                switch (value & 0xff) {
3126                case 0:         /* Language table */
3127                        len = sizeof(usb_string_lang_en);
3128                        ptr = (const void *)&usb_string_lang_en;
3129                        goto tr_valid;
3130
3131                case 1:         /* Vendor */
3132                        len = sizeof(saf1761_otg_vendor);
3133                        ptr = (const void *)&saf1761_otg_vendor;
3134                        goto tr_valid;
3135
3136                case 2:         /* Product */
3137                        len = sizeof(saf1761_otg_product);
3138                        ptr = (const void *)&saf1761_otg_product;
3139                        goto tr_valid;
3140                default:
3141                        break;
3142                }
3143                break;
3144        default:
3145                goto tr_stalled;
3146        }
3147        goto tr_stalled;
3148
3149tr_handle_get_config:
3150        len = 1;
3151        sc->sc_hub_temp.wValue[0] = sc->sc_conf;
3152        goto tr_valid;
3153
3154tr_handle_get_status:
3155        len = 2;
3156        USETW(sc->sc_hub_temp.wValue, UDS_SELF_POWERED);
3157        goto tr_valid;
3158
3159tr_handle_set_address:
3160        if (value & 0xFF00)
3161                goto tr_stalled;
3162
3163        sc->sc_rt_addr = value;
3164        goto tr_valid;
3165
3166tr_handle_set_config:
3167        if (value >= 2)
3168                goto tr_stalled;
3169        sc->sc_conf = value;
3170        goto tr_valid;
3171
3172tr_handle_get_interface:
3173        len = 1;
3174        sc->sc_hub_temp.wValue[0] = 0;
3175        goto tr_valid;
3176
3177tr_handle_get_tt_state:
3178tr_handle_get_class_status:
3179tr_handle_get_iface_status:
3180tr_handle_get_ep_status:
3181        len = 2;
3182        USETW(sc->sc_hub_temp.wValue, 0);
3183        goto tr_valid;
3184
3185tr_handle_set_halt:
3186tr_handle_set_interface:
3187tr_handle_set_wakeup:
3188tr_handle_clear_wakeup:
3189tr_handle_clear_halt:
3190        goto tr_valid;
3191
3192tr_handle_clear_port_feature_device:
3193        DPRINTFN(9, "UR_CLEAR_FEATURE on port %d\n", index);
3194
3195        switch (value) {
3196        case UHF_PORT_SUSPEND:
3197                saf1761_otg_wakeup_peer(sc);
3198                break;
3199
3200        case UHF_PORT_ENABLE:
3201                sc->sc_flags.port_enabled = 0;
3202                break;
3203
3204        case UHF_PORT_TEST:
3205        case UHF_PORT_INDICATOR:
3206        case UHF_C_PORT_ENABLE:
3207        case UHF_C_PORT_OVER_CURRENT:
3208        case UHF_C_PORT_RESET:
3209                /* nops */
3210                break;
3211        case UHF_PORT_POWER:
3212                sc->sc_flags.port_powered = 0;
3213                saf1761_otg_pull_down(sc);
3214                break;
3215        case UHF_C_PORT_CONNECTION:
3216                sc->sc_flags.change_connect = 0;
3217                break;
3218        case UHF_C_PORT_SUSPEND:
3219                sc->sc_flags.change_suspend = 0;
3220                break;
3221        default:
3222                err = USB_ERR_IOERROR;
3223                goto tr_valid;
3224        }
3225        goto tr_valid;
3226
3227tr_handle_clear_port_feature_host:
3228        DPRINTFN(9, "UR_CLEAR_FEATURE on port %d\n", index);
3229
3230        temp = SAF1761_READ_LE_4(sc, SOTG_PORTSC1);
3231
3232        switch (value) {
3233        case UHF_PORT_ENABLE:
3234                SAF1761_WRITE_LE_4(sc, SOTG_PORTSC1, temp & ~SOTG_PORTSC1_PED);
3235                break;
3236        case UHF_PORT_SUSPEND:
3237                if ((temp & SOTG_PORTSC1_SUSP) && (!(temp & SOTG_PORTSC1_FPR)))
3238                        SAF1761_WRITE_LE_4(sc, SOTG_PORTSC1, temp | SOTG_PORTSC1_FPR);
3239
3240                /* wait 20ms for resume sequence to complete */
3241                usb_pause_mtx(&sc->sc_bus.bus_mtx, hz / 50);
3242
3243                SAF1761_WRITE_LE_4(sc, SOTG_PORTSC1, temp & ~(SOTG_PORTSC1_SUSP |
3244                    SOTG_PORTSC1_FPR | SOTG_PORTSC1_LS /* High Speed */ ));
3245
3246                /* 4ms settle time */
3247                usb_pause_mtx(&sc->sc_bus.bus_mtx, hz / 250);
3248                break;
3249        case UHF_PORT_INDICATOR:
3250                SAF1761_WRITE_LE_4(sc, SOTG_PORTSC1, temp & ~SOTG_PORTSC1_PIC);
3251                break;
3252        case UHF_PORT_TEST:
3253        case UHF_C_PORT_ENABLE:
3254        case UHF_C_PORT_OVER_CURRENT:
3255        case UHF_C_PORT_RESET:
3256        case UHF_C_PORT_SUSPEND:
3257                /* NOPs */
3258                break;
3259        case UHF_PORT_POWER:
3260                SAF1761_WRITE_LE_4(sc, SOTG_PORTSC1, temp & ~SOTG_PORTSC1_PP);
3261                break;
3262        case UHF_C_PORT_CONNECTION:
3263                SAF1761_WRITE_LE_4(sc, SOTG_PORTSC1, temp & ~SOTG_PORTSC1_ECSC);
3264                break;
3265        default:
3266                err = USB_ERR_IOERROR;
3267                goto tr_valid;
3268        }
3269        goto tr_valid;
3270
3271tr_handle_set_port_feature_device:
3272        DPRINTFN(9, "UR_SET_FEATURE on port %d\n", index);
3273
3274        switch (value) {
3275        case UHF_PORT_ENABLE:
3276                sc->sc_flags.port_enabled = 1;
3277                break;
3278        case UHF_PORT_SUSPEND:
3279        case UHF_PORT_RESET:
3280        case UHF_PORT_TEST:
3281        case UHF_PORT_INDICATOR:
3282                /* nops */
3283                break;
3284        case UHF_PORT_POWER:
3285                sc->sc_flags.port_powered = 1;
3286                break;
3287        default:
3288                err = USB_ERR_IOERROR;
3289                goto tr_valid;
3290        }
3291        goto tr_valid;
3292
3293tr_handle_set_port_feature_host:
3294        DPRINTFN(9, "UR_SET_FEATURE on port %d\n", index);
3295
3296        temp = SAF1761_READ_LE_4(sc, SOTG_PORTSC1);
3297
3298        switch (value) {
3299        case UHF_PORT_ENABLE:
3300                SAF1761_WRITE_LE_4(sc, SOTG_PORTSC1, temp | SOTG_PORTSC1_PED);
3301                break;
3302        case UHF_PORT_SUSPEND:
3303                SAF1761_WRITE_LE_4(sc, SOTG_PORTSC1, temp | SOTG_PORTSC1_SUSP);
3304                break;
3305        case UHF_PORT_RESET:
3306                DPRINTFN(6, "reset port %d\n", index);
3307
3308                /* Start reset sequence. */
3309                temp &= ~(SOTG_PORTSC1_PED | SOTG_PORTSC1_PR);
3310
3311                SAF1761_WRITE_LE_4(sc, SOTG_PORTSC1, temp | SOTG_PORTSC1_PR);
3312
3313                /* Wait for reset to complete. */
3314                usb_pause_mtx(&sc->sc_bus.bus_mtx,
3315                    USB_MS_TO_TICKS(usb_port_root_reset_delay));
3316
3317                SAF1761_WRITE_LE_4(sc, SOTG_PORTSC1, temp);
3318
3319                /* Wait for HC to complete reset. */
3320                usb_pause_mtx(&sc->sc_bus.bus_mtx, USB_MS_TO_TICKS(2));
3321
3322                temp = SAF1761_READ_LE_4(sc, SOTG_PORTSC1);
3323
3324                DPRINTF("After reset, status=0x%08x\n", temp);
3325                if (temp & SOTG_PORTSC1_PR) {
3326                        device_printf(sc->sc_bus.bdev, "port reset timeout\n");
3327                        err = USB_ERR_TIMEOUT;
3328                        goto tr_valid;
3329                }
3330                if (!(temp & SOTG_PORTSC1_PED)) {
3331                        /* Not a high speed device, give up ownership.*/
3332                        SAF1761_WRITE_LE_4(sc, SOTG_PORTSC1, temp | SOTG_PORTSC1_PO);
3333                        break;
3334                }
3335                sc->sc_isreset = 1;
3336                DPRINTF("port %d reset, status = 0x%08x\n", index, temp);
3337                break;
3338        case UHF_PORT_POWER:
3339                DPRINTFN(3, "set port power %d\n", index);
3340                SAF1761_WRITE_LE_4(sc, SOTG_PORTSC1, temp | SOTG_PORTSC1_PP);
3341                break;
3342
3343        case UHF_PORT_TEST:
3344                DPRINTFN(3, "set port test %d\n", index);
3345                break;
3346
3347        case UHF_PORT_INDICATOR:
3348                DPRINTFN(3, "set port ind %d\n", index);
3349                SAF1761_WRITE_LE_4(sc, SOTG_PORTSC1, temp | SOTG_PORTSC1_PIC);
3350                break;
3351        default:
3352                err = USB_ERR_IOERROR;
3353                goto tr_valid;
3354        }
3355        goto tr_valid;
3356
3357tr_handle_get_port_status_device:
3358
3359        DPRINTFN(9, "UR_GET_PORT_STATUS on port %d\n", index);
3360
3361        if (sc->sc_flags.status_vbus) {
3362                saf1761_otg_pull_up(sc);
3363        } else {
3364                saf1761_otg_pull_down(sc);
3365        }
3366
3367        /* Select FULL-speed and Device Side Mode */
3368
3369        value = UPS_PORT_MODE_DEVICE;
3370
3371        if (sc->sc_flags.port_powered)
3372                value |= UPS_PORT_POWER;
3373
3374        if (sc->sc_flags.port_enabled)
3375                value |= UPS_PORT_ENABLED;
3376
3377        if (sc->sc_flags.status_vbus &&
3378            sc->sc_flags.status_bus_reset)
3379                value |= UPS_CURRENT_CONNECT_STATUS;
3380
3381        if (sc->sc_flags.status_suspend)
3382                value |= UPS_SUSPEND;
3383
3384        USETW(sc->sc_hub_temp.ps.wPortStatus, value);
3385
3386        value = 0;
3387
3388        if (sc->sc_flags.change_connect)
3389                value |= UPS_C_CONNECT_STATUS;
3390
3391        if (sc->sc_flags.change_suspend)
3392                value |= UPS_C_SUSPEND;
3393
3394        USETW(sc->sc_hub_temp.ps.wPortChange, value);
3395        len = sizeof(sc->sc_hub_temp.ps);
3396        goto tr_valid;
3397
3398tr_handle_get_port_status_host:
3399
3400        temp = SAF1761_READ_LE_4(sc, SOTG_PORTSC1);
3401
3402        DPRINTFN(9, "UR_GET_PORT_STATUS on port %d = 0x%08x\n", index, temp);
3403
3404        i = UPS_HIGH_SPEED;
3405
3406        if (temp & SOTG_PORTSC1_ECCS)
3407                i |= UPS_CURRENT_CONNECT_STATUS;
3408        if (temp & SOTG_PORTSC1_PED)
3409                i |= UPS_PORT_ENABLED;
3410        if ((temp & SOTG_PORTSC1_SUSP) && !(temp & SOTG_PORTSC1_FPR))
3411                i |= UPS_SUSPEND;
3412        if (temp & SOTG_PORTSC1_PR)
3413                i |= UPS_RESET;
3414        if (temp & SOTG_PORTSC1_PP)
3415                i |= UPS_PORT_POWER;
3416
3417        USETW(sc->sc_hub_temp.ps.wPortStatus, i);
3418        i = 0;
3419
3420        if (temp & SOTG_PORTSC1_ECSC)
3421                i |= UPS_C_CONNECT_STATUS;
3422        if (temp & SOTG_PORTSC1_FPR)
3423                i |= UPS_C_SUSPEND;
3424        if (sc->sc_isreset)
3425                i |= UPS_C_PORT_RESET;
3426        USETW(sc->sc_hub_temp.ps.wPortChange, i);
3427        len = sizeof(sc->sc_hub_temp.ps);
3428        goto tr_valid;
3429
3430tr_handle_get_class_descriptor:
3431        if (value & 0xFF)
3432                goto tr_stalled;
3433        ptr = (const void *)&saf1761_otg_hubd;
3434        len = sizeof(saf1761_otg_hubd);
3435        goto tr_valid;
3436
3437tr_stalled:
3438        err = USB_ERR_STALLED;
3439tr_valid:
3440        *plength = len;
3441        *pptr = ptr;
3442        return (err);
3443}
3444
3445static void
3446saf1761_otg_xfer_setup(struct usb_setup_params *parm)
3447{
3448        struct saf1761_otg_softc *sc;
3449        struct usb_xfer *xfer;
3450        void *last_obj;
3451        uint32_t dw1;
3452        uint32_t ntd;
3453        uint32_t n;
3454        uint8_t ep_no;
3455        uint8_t ep_type;
3456
3457        sc = SAF1761_OTG_BUS2SC(parm->udev->bus);
3458        xfer = parm->curr_xfer;
3459
3460        /*
3461         * NOTE: This driver does not use any of the parameters that
3462         * are computed from the following values. Just set some
3463         * reasonable dummies:
3464         */
3465        parm->hc_max_packet_size = 0x500;
3466        parm->hc_max_packet_count = 1;
3467        parm->hc_max_frame_size = 0x500;
3468
3469        usbd_transfer_setup_sub(parm);
3470
3471        /*
3472         * Compute maximum number of TDs:
3473         */
3474        ep_type = (xfer->endpoint->edesc->bmAttributes & UE_XFERTYPE);
3475
3476        if (ep_type == UE_CONTROL) {
3477
3478                ntd = xfer->nframes + 1 /* STATUS */ + 1 /* SYNC */ ;
3479
3480        } else {
3481                ntd = xfer->nframes + 1 /* SYNC */ ;
3482        }
3483
3484        /*
3485         * check if "usbd_transfer_setup_sub" set an error
3486         */
3487        if (parm->err)
3488                return;
3489
3490        /*
3491         * allocate transfer descriptors
3492         */
3493        last_obj = NULL;
3494
3495        ep_no = xfer->endpointno & UE_ADDR;
3496
3497        /*
3498         * Check profile stuff
3499         */
3500        if (parm->udev->flags.usb_mode == USB_MODE_DEVICE) {
3501                const struct usb_hw_ep_profile *pf;
3502
3503                saf1761_otg_get_hw_ep_profile(parm->udev, &pf, ep_no);
3504
3505                if (pf == NULL) {
3506                        /* should not happen */
3507                        parm->err = USB_ERR_INVAL;
3508                        return;
3509                }
3510        }
3511
3512        dw1 = (xfer->address << 3) | (ep_type << 12);
3513
3514        switch (parm->udev->speed) {
3515        case USB_SPEED_FULL:
3516        case USB_SPEED_LOW:
3517                /* check if root HUB port is running High Speed */
3518                if (parm->udev->parent_hs_hub != NULL) {
3519                        dw1 |= SOTG_PTD_DW1_ENABLE_SPLIT;
3520                        dw1 |= (parm->udev->hs_port_no << 18);
3521                        dw1 |= (parm->udev->hs_hub_addr << 25);
3522                        if (parm->udev->speed == USB_SPEED_LOW)
3523                                dw1 |= (1 << 17);
3524                }
3525                break;
3526        default:
3527                break;
3528        }
3529
3530        /* align data */
3531        parm->size[0] += ((-parm->size[0]) & (USB_HOST_ALIGN - 1));
3532
3533        for (n = 0; n != ntd; n++) {
3534
3535                struct saf1761_otg_td *td;
3536
3537                if (parm->buf) {
3538
3539                        td = USB_ADD_BYTES(parm->buf, parm->size[0]);
3540
3541                        /* init TD */
3542                        td->max_packet_size = xfer->max_packet_size;
3543                        td->ep_index = ep_no;
3544                        td->ep_type = ep_type;
3545                        td->dw1_value = dw1;
3546                        td->uframe = 0;
3547
3548                        if (ep_type == UE_INTERRUPT) {
3549                                if (xfer->interval > 32)
3550                                        td->interval = (32 / 2) << 3;
3551                                else
3552                                        td->interval = (xfer->interval / 2) << 3;
3553                        } else {
3554                                td->interval = 0;
3555                        }
3556                        td->obj_next = last_obj;
3557
3558                        last_obj = td;
3559                }
3560                parm->size[0] += sizeof(*td);
3561        }
3562
3563        xfer->td_start[0] = last_obj;
3564}
3565
3566static void
3567saf1761_otg_xfer_unsetup(struct usb_xfer *xfer)
3568{
3569}
3570
3571static void
3572saf1761_otg_ep_init(struct usb_device *udev, struct usb_endpoint_descriptor *edesc,
3573    struct usb_endpoint *ep)
3574{
3575        uint16_t mps;
3576
3577        DPRINTFN(2, "endpoint=%p, addr=%d, endpt=%d, mode=%d\n",
3578            ep, udev->address,
3579            edesc->bEndpointAddress, udev->flags.usb_mode);
3580
3581        if (udev->parent_hub == NULL) {
3582                /* root HUB has special endpoint handling */
3583                return;
3584        }
3585
3586        /* Verify wMaxPacketSize */
3587        mps = UGETW(edesc->wMaxPacketSize);
3588        if (udev->speed == USB_SPEED_HIGH) {
3589                if ((mps >> 11) & 3) {
3590                        DPRINTF("A packet multiplier different from "
3591                            "1 is not supported\n");
3592                        return;
3593                }
3594        }
3595        if (mps > SOTG_HS_MAX_PACKET_SIZE) {
3596                DPRINTF("Packet size %d bigger than %d\n",
3597                    (int)mps, SOTG_HS_MAX_PACKET_SIZE);
3598                return;
3599        }
3600        if (udev->flags.usb_mode == USB_MODE_DEVICE) {
3601                if (udev->speed != USB_SPEED_FULL &&
3602                    udev->speed != USB_SPEED_HIGH) {
3603                        /* not supported */
3604                        return;
3605                }
3606                switch (edesc->bmAttributes & UE_XFERTYPE) {
3607                case UE_ISOCHRONOUS:
3608                        ep->methods = &saf1761_otg_device_isoc_methods;
3609                        break;
3610                default:
3611                        ep->methods = &saf1761_otg_non_isoc_methods;
3612                        break;
3613                }
3614        } else {
3615                switch (edesc->bmAttributes & UE_XFERTYPE) {
3616                case UE_ISOCHRONOUS:
3617                        ep->methods = &saf1761_otg_host_isoc_methods;
3618                        break;
3619                default:
3620                        ep->methods = &saf1761_otg_non_isoc_methods;
3621                        break;
3622                }
3623        }
3624}
3625
3626static void
3627saf1761_otg_set_hw_power_sleep(struct usb_bus *bus, uint32_t state)
3628{
3629        struct saf1761_otg_softc *sc = SAF1761_OTG_BUS2SC(bus);
3630
3631        switch (state) {
3632        case USB_HW_POWER_SUSPEND:
3633                saf1761_otg_suspend(sc);
3634                break;
3635        case USB_HW_POWER_SHUTDOWN:
3636                saf1761_otg_uninit(sc);
3637                break;
3638        case USB_HW_POWER_RESUME:
3639                saf1761_otg_resume(sc);
3640                break;
3641        default:
3642                break;
3643        }
3644}
3645
3646static void
3647saf1761_otg_device_resume(struct usb_device *udev)
3648{
3649        struct saf1761_otg_softc *sc;
3650        struct saf1761_otg_td *td;
3651        struct usb_xfer *xfer;
3652        uint8_t x;
3653
3654        DPRINTF("\n");
3655
3656        if (udev->flags.usb_mode != USB_MODE_HOST)
3657                return;
3658
3659        sc = SAF1761_OTG_BUS2SC(udev->bus);
3660
3661        USB_BUS_LOCK(&sc->sc_bus);
3662        USB_BUS_SPIN_LOCK(&sc->sc_bus);
3663
3664        TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) {
3665
3666                if (xfer->xroot->udev != udev)
3667                        continue;
3668
3669                td = xfer->td_transfer_cache;
3670                if (td == NULL || td->channel >= SOTG_HOST_CHANNEL_MAX)
3671                        continue;
3672
3673                switch (td->ep_type) {
3674                case UE_INTERRUPT:
3675                        x = td->channel - 32;
3676                        sc->sc_host_intr_suspend_map &= ~(1U << x);
3677                        SAF1761_WRITE_LE_4(sc, SOTG_INT_PTD_SKIP_PTD,
3678                            (~sc->sc_host_intr_map) | sc->sc_host_intr_suspend_map);
3679                        break;
3680                case UE_ISOCHRONOUS:
3681                        x = td->channel;
3682                        sc->sc_host_isoc_suspend_map &= ~(1U << x);
3683                        SAF1761_WRITE_LE_4(sc, SOTG_ISO_PTD_SKIP_PTD,
3684                            (~sc->sc_host_isoc_map) | sc->sc_host_isoc_suspend_map);
3685                        break;
3686                default:
3687                        x = td->channel - 64;
3688                        sc->sc_host_async_suspend_map &= ~(1U << x);
3689                        SAF1761_WRITE_LE_4(sc, SOTG_ATL_PTD_SKIP_PTD,
3690                            (~sc->sc_host_async_map) | sc->sc_host_async_suspend_map);
3691                        break;
3692                }
3693        }
3694
3695        USB_BUS_SPIN_UNLOCK(&sc->sc_bus);
3696        USB_BUS_UNLOCK(&sc->sc_bus);
3697
3698        /* poll all transfers again to restart resumed ones */
3699        saf1761_otg_do_poll(&sc->sc_bus);
3700}
3701
3702static void
3703saf1761_otg_device_suspend(struct usb_device *udev)
3704{
3705        struct saf1761_otg_softc *sc;
3706        struct saf1761_otg_td *td;
3707        struct usb_xfer *xfer;
3708        uint8_t x;
3709
3710        DPRINTF("\n");
3711
3712        if (udev->flags.usb_mode != USB_MODE_HOST)
3713                return;
3714
3715        sc = SAF1761_OTG_BUS2SC(udev->bus);
3716
3717        USB_BUS_LOCK(&sc->sc_bus);
3718        USB_BUS_SPIN_LOCK(&sc->sc_bus);
3719
3720        TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) {
3721
3722                if (xfer->xroot->udev != udev)
3723                        continue;
3724
3725                td = xfer->td_transfer_cache;
3726                if (td == NULL || td->channel >= SOTG_HOST_CHANNEL_MAX)
3727                        continue;
3728
3729                switch (td->ep_type) {
3730                case UE_INTERRUPT:
3731                        x = td->channel - 32;
3732                        sc->sc_host_intr_suspend_map |= (1U << x);
3733                        SAF1761_WRITE_LE_4(sc, SOTG_INT_PTD_SKIP_PTD,
3734                            (~sc->sc_host_intr_map) | sc->sc_host_intr_suspend_map);
3735                        break;
3736                case UE_ISOCHRONOUS:
3737                        x = td->channel;
3738                        sc->sc_host_isoc_suspend_map |= (1U << x);
3739                        SAF1761_WRITE_LE_4(sc, SOTG_ISO_PTD_SKIP_PTD,
3740                            (~sc->sc_host_isoc_map) | sc->sc_host_isoc_suspend_map);
3741                        break;
3742                default:
3743                        x = td->channel - 64;
3744                        sc->sc_host_async_suspend_map |= (1U << x);
3745                        SAF1761_WRITE_LE_4(sc, SOTG_ATL_PTD_SKIP_PTD,
3746                            (~sc->sc_host_async_map) | sc->sc_host_async_suspend_map);
3747                        break;
3748                }
3749        }
3750
3751        USB_BUS_SPIN_UNLOCK(&sc->sc_bus);
3752        USB_BUS_UNLOCK(&sc->sc_bus);
3753}
3754
3755static const struct usb_bus_methods saf1761_otg_bus_methods =
3756{
3757        .endpoint_init = &saf1761_otg_ep_init,
3758        .xfer_setup = &saf1761_otg_xfer_setup,
3759        .xfer_unsetup = &saf1761_otg_xfer_unsetup,
3760        .get_hw_ep_profile = &saf1761_otg_get_hw_ep_profile,
3761        .xfer_stall = &saf1761_otg_xfer_stall,
3762        .set_stall = &saf1761_otg_set_stall,
3763        .clear_stall = &saf1761_otg_clear_stall,
3764        .roothub_exec = &saf1761_otg_roothub_exec,
3765        .xfer_poll = &saf1761_otg_do_poll,
3766        .set_hw_power_sleep = saf1761_otg_set_hw_power_sleep,
3767        .device_resume = &saf1761_otg_device_resume,
3768        .device_suspend = &saf1761_otg_device_suspend,
3769};
Note: See TracBrowser for help on using the repository browser.