// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <efi/types.h>
#include <efi/protocol/device-path.h>
#include <efi/protocol/driver-binding.h>
#include <efi/protocol/usb-io.h>

#include <utils.h>
#include <stdio.h>

EFIAPI efi_status MyDriverSupported(
    efi_driver_binding_protocol* self, efi_handle ctlr,
    efi_device_path_protocol* path) {

    efi_usb_device_descriptor dev;
    efi_usb_io_protocol* usbio;
    efi_status r;

    r = gBS->OpenProtocol(ctlr, &UsbIoProtocol,
                          (void**)&usbio, self->DriverBindingHandle,
                          ctlr, EFI_OPEN_PROTOCOL_BY_DRIVER);

    if (r == 0) {
        if (usbio->UsbGetDeviceDescriptor(usbio, &dev)) {
            return EFI_UNSUPPORTED;
        }
        printf("Supported? ctlr=%p vid=%04x pid=%04x\n",
               ctlr, dev.IdVendor, dev.IdProduct);
        gBS->CloseProtocol(ctlr, &UsbIoProtocol,
                           self->DriverBindingHandle, ctlr);
        return EFI_SUCCESS;
    }
    return EFI_UNSUPPORTED;
}

EFIAPI efi_status MyDriverStart(
    efi_driver_binding_protocol* self, efi_handle ctlr,
    efi_device_path_protocol* path) {
    efi_status r;

    efi_usb_io_protocol* usbio;

    printf("Start! ctlr=%p\n", ctlr);

    r = gBS->OpenProtocol(ctlr, &UsbIoProtocol,
                          (void**)&usbio, self->DriverBindingHandle,
                          ctlr, EFI_OPEN_PROTOCOL_BY_DRIVER);

    // alloc device state, stash usbio with it
    // probably attached to a protocol installed on a child handle

    if (r) {
        printf("OpenProtocol Failed %lx\n", r);
        return EFI_DEVICE_ERROR;
    }
    return EFI_SUCCESS;
}

EFIAPI efi_status MyDriverStop(
    efi_driver_binding_protocol* self, efi_handle ctlr,
    size_t count, efi_handle* children) {

    printf("Stop! ctlr=%p\n", ctlr);

    // recover device state, tear down

    gBS->CloseProtocol(ctlr, &UsbIoProtocol,
                       self->DriverBindingHandle, ctlr);
    return EFI_SUCCESS;
}

static efi_driver_binding_protocol MyDriver = {
    .Supported = MyDriverSupported,
    .Start = MyDriverStart,
    .Stop = MyDriverStop,
    .Version = 32,
    .ImageHandle = NULL,
    .DriverBindingHandle = NULL,
};

void InstallMyDriver(efi_handle img, efi_system_table* sys) {
    efi_boot_services* bs = sys->BootServices;
    efi_handle* list;
    size_t count, i;
    efi_status r;

    MyDriver.ImageHandle = img;
    MyDriver.DriverBindingHandle = img;
    r = bs->InstallProtocolInterface(&img, &DriverBindingProtocol,
                                     EFI_NATIVE_INTERFACE, &MyDriver);
    if (r) {
        printf("DriverBinding failed %lx\n", r);
        return;
    }

    // For every Handle that supports UsbIoProtocol, try to connect the driver
    r = bs->LocateHandleBuffer(ByProtocol, &UsbIoProtocol, NULL, &count, &list);
    if (r == 0) {
        for (i = 0; i < count; i++) {
            r = bs->ConnectController(list[i], NULL, NULL, false);
        }
        bs->FreePool(list);
    }
}

void RemoveMyDriver(efi_handle img, efi_system_table* sys) {
    efi_boot_services* bs = sys->BootServices;
    efi_handle* list;
    size_t count, i;
    efi_status r;

    // Disconnect the driver
    r = bs->LocateHandleBuffer(ByProtocol, &UsbIoProtocol, NULL, &count, &list);
    if (r == 0) {
        for (i = 0; i < count; i++) {
            r = bs->DisconnectController(list[i], img, NULL);
        }
        bs->FreePool(list);
    }

    // Unregister so we can safely exit
    r = bs->UninstallProtocolInterface(img, &DriverBindingProtocol, &MyDriver);
    if (r)
        printf("UninstallProtocol failed %lx\n", r);
}

efi_status efi_main(efi_handle img, efi_system_table* sys) {
    InitGoodies(img, sys);

    printf("Hello, EFI World\n");

    InstallMyDriver(img, sys);

    // do stuff

    RemoveMyDriver(img, sys);

    WaitAnyKey();
    return EFI_SUCCESS;
}
