BOOLEAN VioScsiResetBus( IN PVOID DeviceExtension, IN ULONG PathId ) { UNREFERENCED_PARAMETER( PathId ); return DeviceReset(DeviceExtension); }
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(); }