Ejemplo n.º 1
0
BOOLEAN
VioScsiResetBus(
    IN PVOID DeviceExtension,
    IN ULONG PathId
    )
{
    UNREFERENCED_PARAMETER( PathId );

    return DeviceReset(DeviceExtension);
}
Ejemplo n.º 2
0
zx_status_t InputDevice::Init() {
    LTRACEF("Device %p\n", this);

    fbl::AutoLock lock(&lock_);

    // Reset the device and read configuration
    DeviceReset();

    SelectConfig(VIRTIO_INPUT_CFG_ID_NAME, 0);
    LTRACEF_LEVEL(2, "name %s\n", config_.u.string);

    SelectConfig(VIRTIO_INPUT_CFG_ID_SERIAL, 0);
    LTRACEF_LEVEL(2, "serial %s\n", config_.u.string);

    SelectConfig(VIRTIO_INPUT_CFG_ID_DEVIDS, 0);
    if (config_.size >= sizeof(virtio_input_devids_t)) {
        LTRACEF_LEVEL(2, "bustype %d\n", config_.u.ids.bustype);
        LTRACEF_LEVEL(2, "vendor %d\n", config_.u.ids.vendor);
        LTRACEF_LEVEL(2, "product %d\n", config_.u.ids.product);
        LTRACEF_LEVEL(2, "version %d\n", config_.u.ids.version);
    }

    SelectConfig(VIRTIO_INPUT_CFG_EV_BITS, VIRTIO_INPUT_EV_KEY);
    uint8_t cfg_key_size = config_.size;
    SelectConfig(VIRTIO_INPUT_CFG_EV_BITS, VIRTIO_INPUT_EV_REL);
    uint8_t cfg_rel_size = config_.size;
    SelectConfig(VIRTIO_INPUT_CFG_EV_BITS, VIRTIO_INPUT_EV_ABS);
    uint8_t cfg_abs_size = config_.size;

    // We only support one of pointer events or key events. In the advent that
    // the device is trying to present both to us we shall preference the
    // keyboard events as these are more useful to us.
    if (cfg_key_size > 0) {
        // Keyboard
        dev_class_ = HID_DEVICE_CLASS_KBD;
    } else if (cfg_rel_size > 0 || cfg_abs_size > 0) {
        // Pointer
        dev_class_ = HID_DEVICE_CLASS_POINTER;
    } else {
        return ZX_ERR_NOT_SUPPORTED;
    }

    DriverStatusAck();

    // Plan to clean up unless everything succeeds.
    auto cleanup = fbl::MakeAutoCall([this]() { Release(); });

    // Allocate the main vring
    zx_status_t status = vring_.Init(0, kEventCount);
    if (status != ZX_OK) {
        zxlogf(ERROR, "Failed to allocate vring: %s\n", zx_status_get_string(status));
        return status;
    }

    // Allocate event buffers for the ring.
    // TODO: Avoid multiple allocations, allocate enough for all buffers once.
    for (uint16_t id = 0; id < kEventCount; ++id) {
        static_assert(sizeof(virtio_input_event_t) <= PAGE_SIZE, "");
        status = io_buffer_init(&buffers_[id], bti_.get(), sizeof(virtio_input_event_t),
                                IO_BUFFER_RO | IO_BUFFER_CONTIG);
        if (status != ZX_OK) {
            zxlogf(ERROR, "Failed to allocate I/O buffers: %s\n", zx_status_get_string(status));
            return status;
        }
    }

    // Expose event buffers to the host
    vring_desc* desc = nullptr;
    uint16_t id;
    for (uint16_t i = 0; i < kEventCount; ++i) {
        desc = vring_.AllocDescChain(1, &id);
        if (desc == nullptr) {
            zxlogf(ERROR, "Failed to allocate descriptor chain\n");
            return ZX_ERR_NO_RESOURCES;
        }
        ZX_ASSERT(id < kEventCount);
        desc->addr = io_buffer_phys(&buffers_[id]);
        desc->len = sizeof(virtio_input_event_t);
        desc->flags |= VRING_DESC_F_WRITE;
        LTRACE_DO(virtio_dump_desc(desc));
        vring_.SubmitChain(id);
    }

    // Prepare the HID report buffer
    memset(&report_, 0, sizeof(report_));

    StartIrqThread();
    DriverStatusOk();

    device_ops_.release = virtio_input_release;

    hidbus_ops_.query = virtio_input_query;
    hidbus_ops_.start = virtio_input_start;
    hidbus_ops_.stop = virtio_input_stop;
    hidbus_ops_.get_descriptor = virtio_input_get_descriptor;
    hidbus_ops_.get_report = virtio_input_get_report;
    hidbus_ops_.set_report = virtio_input_set_report;
    hidbus_ops_.get_idle = virtio_input_get_idle;
    hidbus_ops_.set_idle = virtio_input_set_idle;
    hidbus_ops_.get_protocol = virtio_input_get_protocol;
    hidbus_ops_.set_protocol = virtio_input_set_protocol;

    hidbus_ifc_.ops = nullptr;

    device_add_args_t args = {};
    args.version = DEVICE_ADD_ARGS_VERSION;
    args.name = "virtio-input";
    args.ctx = this;
    args.ops = &device_ops_;
    args.proto_id = ZX_PROTOCOL_HIDBUS;
    args.proto_ops = &hidbus_ops_;

    status = device_add(bus_device_, &args, &device_);
    if (status != ZX_OK) {
        zxlogf(ERROR, "Failed to add device: %s\n", zx_status_get_string(status));
        device_ = nullptr;
        return status;
    }

    vring_.Kick();
    cleanup.cancel();
    return ZX_OK;
}
D3DDisplayManager::~D3DDisplayManager()
{
	DeviceReset();
	CleanupCache();
}