apple_bce/vhci: add T2 virtual USB host controller
Implements a VHCI driver on top of the BCE transport: - Virtual USB bus registration via usb_controller - Port discovery and device enumeration - Control, interrupt, and bulk endpoint support - Firmware event handling with taskqueue - Suspend/resume via BCE mailbox Provides keyboard, trackpad, and Touch Bar access on T2 Macs. Tested-on: MacBookPro16,2 (A2251), Mac mini 8,1 (A1993) Reviewed by: adrian Differential Revision: https://reviews.freebsd.org/D57089
This commit is contained in:
committed by
Adrian Chadd
parent
6fd2ad9aa3
commit
9f90536c74
@@ -115,6 +115,7 @@ dev/amdgpio/amdgpio.c optional amdgpio
|
|||||||
dev/apple_bce/apple_bce.c optional apple_bce pci
|
dev/apple_bce/apple_bce.c optional apple_bce pci
|
||||||
dev/apple_bce/apple_bce_mailbox.c optional apple_bce pci
|
dev/apple_bce/apple_bce_mailbox.c optional apple_bce pci
|
||||||
dev/apple_bce/apple_bce_queue.c optional apple_bce pci
|
dev/apple_bce/apple_bce_queue.c optional apple_bce pci
|
||||||
|
dev/apple_bce/apple_bce_vhci.c optional apple_bce pci
|
||||||
dev/asmc/asmc.c optional asmc isa
|
dev/asmc/asmc.c optional asmc isa
|
||||||
dev/asmc/asmcmmio.c optional asmc isa
|
dev/asmc/asmcmmio.c optional asmc isa
|
||||||
dev/axgbe/if_axgbe_pci.c optional axp
|
dev/axgbe/if_axgbe_pci.c optional axp
|
||||||
|
|||||||
@@ -32,10 +32,13 @@
|
|||||||
#include "apple_bce.h"
|
#include "apple_bce.h"
|
||||||
#include "apple_bce_mailbox.h"
|
#include "apple_bce_mailbox.h"
|
||||||
#include "apple_bce_queue.h"
|
#include "apple_bce_queue.h"
|
||||||
|
#include "apple_bce_vhci.h"
|
||||||
|
|
||||||
static int apple_bce_probe(device_t dev);
|
static int apple_bce_probe(device_t dev);
|
||||||
static int apple_bce_attach(device_t dev);
|
static int apple_bce_attach(device_t dev);
|
||||||
static int apple_bce_detach(device_t dev);
|
static int apple_bce_detach(device_t dev);
|
||||||
|
static int apple_bce_suspend(device_t dev);
|
||||||
|
static int apple_bce_resume(device_t dev);
|
||||||
static void apple_bce_timestamp_cb(void *arg);
|
static void apple_bce_timestamp_cb(void *arg);
|
||||||
static void apple_bce_timestamp_init(struct apple_bce_softc *sc);
|
static void apple_bce_timestamp_init(struct apple_bce_softc *sc);
|
||||||
static void apple_bce_timestamp_start(struct apple_bce_softc *sc,
|
static void apple_bce_timestamp_start(struct apple_bce_softc *sc,
|
||||||
@@ -516,6 +519,12 @@ apple_bce_attach(device_t dev)
|
|||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
device_printf(dev, "Apple T2 BCE initialized\n");
|
device_printf(dev, "Apple T2 BCE initialized\n");
|
||||||
|
|
||||||
|
/* Create VHCI child for virtual USB */
|
||||||
|
error = bce_vhci_attach(sc);
|
||||||
|
if (error != 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
@@ -531,6 +540,9 @@ apple_bce_detach(device_t dev)
|
|||||||
{
|
{
|
||||||
struct apple_bce_softc *sc = device_get_softc(dev);
|
struct apple_bce_softc *sc = device_get_softc(dev);
|
||||||
|
|
||||||
|
/* 0. Detach VHCI child first (before destroying parent resources) */
|
||||||
|
bce_vhci_detach(sc);
|
||||||
|
|
||||||
/* 1. Stop timestamp */
|
/* 1. Stop timestamp */
|
||||||
if (sc->sc_bar4 != NULL && mtx_initialized(&sc->sc_timestamp_lock))
|
if (sc->sc_bar4 != NULL && mtx_initialized(&sc->sc_timestamp_lock))
|
||||||
apple_bce_timestamp_stop(sc);
|
apple_bce_timestamp_stop(sc);
|
||||||
@@ -616,10 +628,85 @@ apple_bce_detach(device_t dev)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
apple_bce_suspend(device_t dev)
|
||||||
|
{
|
||||||
|
struct apple_bce_softc *sc = device_get_softc(dev);
|
||||||
|
int error, restore_error;
|
||||||
|
|
||||||
|
apple_bce_timestamp_stop(sc);
|
||||||
|
|
||||||
|
error = bce_vhci_detach(sc);
|
||||||
|
if (error != 0) {
|
||||||
|
device_printf(dev, "failed to detach VHCI for suspend: %d\n",
|
||||||
|
error);
|
||||||
|
apple_bce_timestamp_start(sc, 0);
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
|
||||||
|
error = bce_mailbox_send(&sc->sc_mbox,
|
||||||
|
BCE_MB_MSG(BCE_MB_SLEEP_NO_STATE, 0), NULL,
|
||||||
|
BCE_MBOX_TIMEOUT_MS);
|
||||||
|
if (error != 0) {
|
||||||
|
device_printf(dev,
|
||||||
|
"failed to send SLEEP_NO_STATE mailbox command: %d\n",
|
||||||
|
error);
|
||||||
|
restore_error = bce_vhci_attach(sc);
|
||||||
|
if (restore_error != 0) {
|
||||||
|
device_printf(dev,
|
||||||
|
"failed to reattach VHCI after suspend error: %d\n",
|
||||||
|
restore_error);
|
||||||
|
}
|
||||||
|
apple_bce_timestamp_start(sc, 0);
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
apple_bce_resume(device_t dev)
|
||||||
|
{
|
||||||
|
struct apple_bce_softc *sc = device_get_softc(dev);
|
||||||
|
uint64_t reply;
|
||||||
|
int error;
|
||||||
|
|
||||||
|
error = bce_mailbox_send(&sc->sc_mbox,
|
||||||
|
BCE_MB_MSG(BCE_MB_RESTORE_NO_STATE, 0), &reply,
|
||||||
|
BCE_MBOX_TIMEOUT_MS);
|
||||||
|
if (error != 0) {
|
||||||
|
device_printf(dev,
|
||||||
|
"failed to send RESTORE_NO_STATE mailbox command: %d\n",
|
||||||
|
error);
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BCE_MB_TYPE(reply) != BCE_MB_RESTORE_NO_STATE) {
|
||||||
|
device_printf(dev,
|
||||||
|
"unexpected RESTORE_NO_STATE reply: type=%u val=0x%llx\n",
|
||||||
|
BCE_MB_TYPE(reply),
|
||||||
|
(unsigned long long)BCE_MB_VALUE(reply));
|
||||||
|
return (EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
error = bce_vhci_attach(sc);
|
||||||
|
if (error != 0) {
|
||||||
|
device_printf(dev, "failed to reattach VHCI after resume: %d\n",
|
||||||
|
error);
|
||||||
|
apple_bce_timestamp_start(sc, 0);
|
||||||
|
return (error);
|
||||||
|
}
|
||||||
|
|
||||||
|
apple_bce_timestamp_start(sc, 0);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
static device_method_t apple_bce_methods[] = {
|
static device_method_t apple_bce_methods[] = {
|
||||||
DEVMETHOD(device_probe, apple_bce_probe),
|
DEVMETHOD(device_probe, apple_bce_probe),
|
||||||
DEVMETHOD(device_attach, apple_bce_attach),
|
DEVMETHOD(device_attach, apple_bce_attach),
|
||||||
DEVMETHOD(device_detach, apple_bce_detach),
|
DEVMETHOD(device_detach, apple_bce_detach),
|
||||||
|
DEVMETHOD(device_suspend, apple_bce_suspend),
|
||||||
|
DEVMETHOD(device_resume, apple_bce_resume),
|
||||||
DEVMETHOD_END
|
DEVMETHOD_END
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
#define BCE_PCI_DEVICE_T2 0x1801
|
#define BCE_PCI_DEVICE_T2 0x1801
|
||||||
|
|
||||||
#define BCE_MAX_QUEUE_COUNT 0x100
|
#define BCE_MAX_QUEUE_COUNT 0x100
|
||||||
#define BCE_MAX_CQ_COUNT 16 /* Max completion queues tracked */
|
#define BCE_MAX_CQ_COUNT 64 /* Max completion queues tracked */
|
||||||
#define BCE_QUEUE_USER_MIN 2
|
#define BCE_QUEUE_USER_MIN 2
|
||||||
#define BCE_QUEUE_USER_MAX (BCE_MAX_QUEUE_COUNT - 1)
|
#define BCE_QUEUE_USER_MAX (BCE_MAX_QUEUE_COUNT - 1)
|
||||||
#define BCE_CMD_SIZE 0x40
|
#define BCE_CMD_SIZE 0x40
|
||||||
@@ -286,6 +286,7 @@ struct apple_bce_softc {
|
|||||||
struct mtx sc_queues_lock;
|
struct mtx sc_queues_lock;
|
||||||
struct bce_queue_cq *sc_cq_list[BCE_MAX_CQ_COUNT];
|
struct bce_queue_cq *sc_cq_list[BCE_MAX_CQ_COUNT];
|
||||||
struct bce_queue_sq *sc_int_sq_list[BCE_MAX_QUEUE_COUNT];
|
struct bce_queue_sq *sc_int_sq_list[BCE_MAX_QUEUE_COUNT];
|
||||||
|
device_t sc_vhci_dev;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Inline helpers */
|
/* Inline helpers */
|
||||||
|
|||||||
@@ -57,6 +57,11 @@ bce_mailbox_send(struct bce_mailbox *mb, uint64_t msg, uint64_t *recv,
|
|||||||
bus_write_4(mb->reg, BCE_REG_MBOX_OUT + 8, 0);
|
bus_write_4(mb->reg, BCE_REG_MBOX_OUT + 8, 0);
|
||||||
bus_write_4(mb->reg, BCE_REG_MBOX_OUT + 12, 0);
|
bus_write_4(mb->reg, BCE_REG_MBOX_OUT + 12, 0);
|
||||||
|
|
||||||
|
if (recv == NULL) {
|
||||||
|
atomic_store_int(&mb->status, 0);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
/* Wait for interrupt-driven reply */
|
/* Wait for interrupt-driven reply */
|
||||||
if (sema_timedwait(&mb->mb_cmpl, hz * timeout_ms / 1000) != 0) {
|
if (sema_timedwait(&mb->mb_cmpl, hz * timeout_ms / 1000) != 0) {
|
||||||
/* Timeout -- reset to idle */
|
/* Timeout -- reset to idle */
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,251 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 2026 Abdelkader Boudih <freebsd@seuros.com>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
*
|
||||||
|
* Apple T2 BCE Virtual USB Host Controller Interface (VHCI).
|
||||||
|
* Translates USB operations into BCE firmware messages over DMA queues.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _APPLE_BCE_VHCI_H_
|
||||||
|
#define _APPLE_BCE_VHCI_H_
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/bus.h>
|
||||||
|
#include <sys/lock.h>
|
||||||
|
#include <sys/mutex.h>
|
||||||
|
#include <sys/sx.h>
|
||||||
|
#include <sys/sema.h>
|
||||||
|
#include <sys/taskqueue.h>
|
||||||
|
|
||||||
|
#include "apple_bce.h"
|
||||||
|
|
||||||
|
/* Forward declaration -- full USB headers included only in .c file */
|
||||||
|
struct usb_bus;
|
||||||
|
struct usb_device;
|
||||||
|
struct usb_xfer;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* VHCI limits.
|
||||||
|
*/
|
||||||
|
#define BCE_VHCI_MAX_PORTS 16
|
||||||
|
#define BCE_VHCI_MAX_DEVICES 32
|
||||||
|
#define BCE_VHCI_MAX_ENDPOINTS 32
|
||||||
|
|
||||||
|
/* Queue element counts */
|
||||||
|
#define BCE_VHCI_MSG_QUEUE_EL 32
|
||||||
|
#define BCE_VHCI_EVT_QUEUE_EL 256
|
||||||
|
#define BCE_VHCI_EVT_PENDING 32
|
||||||
|
#define BCE_VHCI_TQ_EL 32 /* Transfer queue elements */
|
||||||
|
#define BCE_VHCI_XFER_BUFSZ 4096 /* DMA buffer per transfer queue */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* VHCI message format (16 bytes, matches firmware protocol).
|
||||||
|
*/
|
||||||
|
struct bce_vhci_message {
|
||||||
|
uint16_t cmd;
|
||||||
|
uint16_t status;
|
||||||
|
uint32_t param1;
|
||||||
|
uint64_t param2;
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* VHCI command IDs.
|
||||||
|
*/
|
||||||
|
enum bce_vhci_cmd_id {
|
||||||
|
/* Controller commands */
|
||||||
|
BCE_VHCI_CMD_CONTROLLER_ENABLE = 0x0001,
|
||||||
|
BCE_VHCI_CMD_CONTROLLER_DISABLE = 0x0002,
|
||||||
|
BCE_VHCI_CMD_CONTROLLER_START = 0x0003,
|
||||||
|
BCE_VHCI_CMD_CONTROLLER_PAUSE = 0x0004,
|
||||||
|
|
||||||
|
/* Port commands */
|
||||||
|
BCE_VHCI_CMD_PORT_POWER_ON = 0x0010,
|
||||||
|
BCE_VHCI_CMD_PORT_POWER_OFF = 0x0011,
|
||||||
|
BCE_VHCI_CMD_PORT_RESUME = 0x0012,
|
||||||
|
BCE_VHCI_CMD_PORT_SUSPEND = 0x0013,
|
||||||
|
BCE_VHCI_CMD_PORT_RESET = 0x0014,
|
||||||
|
BCE_VHCI_CMD_PORT_DISABLE = 0x0015,
|
||||||
|
BCE_VHCI_CMD_PORT_STATUS = 0x0016,
|
||||||
|
BCE_VHCI_CMD_PORT_STATUS_CHANGE = 0x0018,
|
||||||
|
|
||||||
|
/* Device commands */
|
||||||
|
BCE_VHCI_CMD_DEVICE_CREATE = 0x0030,
|
||||||
|
BCE_VHCI_CMD_DEVICE_DESTROY = 0x0031,
|
||||||
|
|
||||||
|
/* Endpoint commands */
|
||||||
|
BCE_VHCI_CMD_ENDPOINT_CREATE = 0x0040,
|
||||||
|
BCE_VHCI_CMD_ENDPOINT_DESTROY = 0x0041,
|
||||||
|
BCE_VHCI_CMD_ENDPOINT_SET_STATE = 0x0042,
|
||||||
|
BCE_VHCI_CMD_ENDPOINT_REQ_STATE = 0x0043,
|
||||||
|
BCE_VHCI_CMD_ENDPOINT_RESET = 0x0044,
|
||||||
|
|
||||||
|
/* Transfer commands */
|
||||||
|
BCE_VHCI_CMD_TRANSFER_REQUEST = 0x1000,
|
||||||
|
BCE_VHCI_CMD_CTRL_TRANSFER_STATUS = 0x1005,
|
||||||
|
|
||||||
|
/* Reply flag -- firmware replies have cmd | 0x8000 */
|
||||||
|
BCE_VHCI_CMD_REPLY_FLAG = 0x8000,
|
||||||
|
|
||||||
|
/* Cancel flag -- timeout sends cmd | 0x4000 */
|
||||||
|
BCE_VHCI_CMD_CANCEL_FLAG = 0x4000,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* VHCI message status codes.
|
||||||
|
*/
|
||||||
|
enum bce_vhci_msg_status {
|
||||||
|
BCE_VHCI_SUCCESS = 1,
|
||||||
|
BCE_VHCI_ERROR = 2,
|
||||||
|
BCE_VHCI_PIPE_STALL = 3,
|
||||||
|
BCE_VHCI_ABORT = 4,
|
||||||
|
BCE_VHCI_BAD_ARGUMENT = 5,
|
||||||
|
BCE_VHCI_OVERRUN = 6,
|
||||||
|
BCE_VHCI_INTERNAL_ERROR = 7,
|
||||||
|
BCE_VHCI_NO_POWER = 8,
|
||||||
|
BCE_VHCI_UNSUPPORTED = 9,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Endpoint states.
|
||||||
|
*/
|
||||||
|
enum bce_vhci_endpoint_state {
|
||||||
|
BCE_VHCI_ENDP_ACTIVE = 0,
|
||||||
|
BCE_VHCI_ENDP_PAUSED = 1,
|
||||||
|
BCE_VHCI_ENDP_STALLED = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Control transfer state machine.
|
||||||
|
*/
|
||||||
|
enum bce_vhci_ctrl_state {
|
||||||
|
BCE_VHCI_CTRL_IDLE = 0,
|
||||||
|
BCE_VHCI_CTRL_SETUP = 1, /* Awaiting setup XFER_REQ */
|
||||||
|
BCE_VHCI_CTRL_DATA = 2, /* Awaiting data XFER_REQ */
|
||||||
|
BCE_VHCI_CTRL_STATUS = 3, /* Awaiting CTRL_XFER_STATUS */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Pause sources (bitmask).
|
||||||
|
*/
|
||||||
|
#define BCE_VHCI_PAUSE_INTERNAL 0x01
|
||||||
|
#define BCE_VHCI_PAUSE_FIRMWARE 0x02
|
||||||
|
#define BCE_VHCI_PAUSE_SUSPEND 0x04
|
||||||
|
#define BCE_VHCI_PAUSE_SHUTDOWN 0x08
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Port status bit mapping (firmware -> USB).
|
||||||
|
* Firmware uses its own bit encoding; we translate in roothub_exec.
|
||||||
|
*/
|
||||||
|
#define BCE_VHCI_PORT_CONNECTED 0x0004
|
||||||
|
#define BCE_VHCI_PORT_ENABLED 0x0010
|
||||||
|
#define BCE_VHCI_PORT_SUSPENDED 0x0060
|
||||||
|
#define BCE_VHCI_PORT_OVERCURRENT 0x0002
|
||||||
|
#define BCE_VHCI_PORT_RESET 0x0008
|
||||||
|
#define BCE_VHCI_PORT_C_CONNECTION 0x40000
|
||||||
|
|
||||||
|
/*
|
||||||
|
* VHCI message queue (host -> device).
|
||||||
|
*/
|
||||||
|
struct bce_vhci_msg_queue {
|
||||||
|
struct bce_queue_cq *cq;
|
||||||
|
struct bce_queue_sq *sq;
|
||||||
|
bus_dma_tag_t dma_tag;
|
||||||
|
bus_dmamap_t dma_map;
|
||||||
|
bus_addr_t dma_addr;
|
||||||
|
struct bce_vhci_message *data;
|
||||||
|
uint32_t el_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* VHCI event queue (device -> host).
|
||||||
|
* Single contiguous DMA buffer for all receive slots.
|
||||||
|
*/
|
||||||
|
struct bce_vhci_evt_queue {
|
||||||
|
struct bce_queue_sq *sq;
|
||||||
|
bus_dma_tag_t dma_tag;
|
||||||
|
bus_dmamap_t dma_map;
|
||||||
|
bus_addr_t dma_addr;
|
||||||
|
struct bce_vhci_message *data;
|
||||||
|
uint32_t el_count;
|
||||||
|
void *userdata;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* VHCI command queue (synchronous command execution).
|
||||||
|
*/
|
||||||
|
struct bce_vhci_cmd_queue {
|
||||||
|
struct bce_vhci_msg_queue *msg;
|
||||||
|
struct sx exec_lock; /* Serialize callers */
|
||||||
|
struct mtx lock;
|
||||||
|
struct sema completion;
|
||||||
|
struct bce_vhci_message response;
|
||||||
|
volatile int pending;
|
||||||
|
uint16_t expected_cmd; /* Filter late replies */
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* VHCI transfer queue (per endpoint).
|
||||||
|
*
|
||||||
|
* Each endpoint gets a CQ + IN SQ + OUT SQ triplet registered with
|
||||||
|
* firmware as named DMA queues. The DMA buffer is used to shuttle
|
||||||
|
* USB payloads between the USB stack's frame buffers and firmware.
|
||||||
|
*/
|
||||||
|
struct bce_vhci_transfer_queue {
|
||||||
|
struct bce_vhci_softc *vhci;
|
||||||
|
uint8_t dev_addr; /* firmware device id */
|
||||||
|
uint8_t endp_addr; /* USB endpoint address */
|
||||||
|
struct mtx lock; /* Protects SQ submission */
|
||||||
|
struct bce_queue_cq *cq;
|
||||||
|
struct bce_queue_sq *sq_in; /* Device -> host */
|
||||||
|
struct bce_queue_sq *sq_out; /* Host -> device */
|
||||||
|
struct usb_xfer *active_xfer;
|
||||||
|
uint32_t paused_by;
|
||||||
|
int active; /* Queues created with FW */
|
||||||
|
int stalled;
|
||||||
|
int dma_inflight; /* DMA pending */
|
||||||
|
int create_pending; /* Deferred ep create */
|
||||||
|
struct usb_endpoint_descriptor *create_edesc;
|
||||||
|
struct usb_xfer *create_xfer; /* Deferred xfer */
|
||||||
|
|
||||||
|
/* DMA buffer for data transfer */
|
||||||
|
bus_dma_tag_t dma_tag;
|
||||||
|
bus_dmamap_t dma_map;
|
||||||
|
bus_addr_t dma_addr;
|
||||||
|
void *dma_buf;
|
||||||
|
|
||||||
|
/* Control transfer state machine */
|
||||||
|
enum bce_vhci_ctrl_state ctrl_state;
|
||||||
|
uint8_t ctrl_dir; /* UE_DIR_IN or UE_DIR_OUT */
|
||||||
|
uint32_t ctrl_data_len; /* Expected data phase length */
|
||||||
|
uint32_t ctrl_actual; /* Actual bytes transferred */
|
||||||
|
int ctrl_data_done; /* IN DMA completion seen */
|
||||||
|
int ctrl_status_pending; /* Deferred STATUS msg */
|
||||||
|
struct bce_vhci_message ctrl_status_msg; /* Saved STATUS for defer */
|
||||||
|
|
||||||
|
/* Queued transfer waiting for active_xfer to finish */
|
||||||
|
struct usb_xfer *pending_xfer;
|
||||||
|
|
||||||
|
/* Deferred firmware event (TRANSFER_REQUEST arrives before xfer) */
|
||||||
|
int evt_pending;
|
||||||
|
struct bce_vhci_message evt_saved;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* VHCI per-device state.
|
||||||
|
*/
|
||||||
|
struct bce_vhci_device {
|
||||||
|
int allocated; /* Device created with FW */
|
||||||
|
uint8_t fw_dev_id; /* Firmware device ID */
|
||||||
|
uint8_t port; /* Port number */
|
||||||
|
struct bce_vhci_transfer_queue tq[BCE_VHCI_MAX_ENDPOINTS];
|
||||||
|
};
|
||||||
|
|
||||||
|
/* VHCI softc is defined in apple_bce_vhci.c (depends on USB headers) */
|
||||||
|
struct bce_vhci_softc;
|
||||||
|
|
||||||
|
/* VHCI driver interface */
|
||||||
|
int bce_vhci_attach(struct apple_bce_softc *sc);
|
||||||
|
int bce_vhci_detach(struct apple_bce_softc *sc);
|
||||||
|
|
||||||
|
#endif /* _APPLE_BCE_VHCI_H_ */
|
||||||
@@ -135,6 +135,7 @@ DRIVER_MODULE(usbus, octusb, usb_driver, 0, 0);
|
|||||||
|
|
||||||
/* Dual Mode Drivers */
|
/* Dual Mode Drivers */
|
||||||
DRIVER_MODULE(usbus, dwcotg, usb_driver, 0, 0);
|
DRIVER_MODULE(usbus, dwcotg, usb_driver, 0, 0);
|
||||||
|
DRIVER_MODULE(usbus, bce_vhci, usb_driver, 0, 0);
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*
|
/*------------------------------------------------------------------------*
|
||||||
* usb_probe
|
* usb_probe
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
KMOD= apple_bce
|
KMOD= apple_bce
|
||||||
SRCS= apple_bce.c apple_bce_mailbox.c apple_bce_queue.c
|
SRCS= apple_bce.c apple_bce_mailbox.c apple_bce_queue.c
|
||||||
|
SRCS+= apple_bce_vhci.c
|
||||||
SRCS+= bus_if.h device_if.h pci_if.h
|
SRCS+= bus_if.h device_if.h pci_if.h
|
||||||
|
SRCS+= opt_usb.h opt_bus.h
|
||||||
|
|
||||||
.include <bsd.kmod.mk>
|
.include <bsd.kmod.mk>
|
||||||
|
|||||||
Reference in New Issue
Block a user