// 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 <ddk/driver.h>
#include <ddk/binding.h>
#include <driver/usb.h>
#include <zircon/assert.h>
#include <zircon/hw/usb.h>
#include <zircon/hw/usb-mass-storage.h>

#include <endian.h>
#include <stdio.h>
#include <string.h>

#include "usb-mass-storage.h"

// comment the next line if you don't want debug messages
#define DEBUG 0
#ifdef DEBUG
# define DEBUG_PRINT(x) printf x
#else
# define DEBUG_PRINT(x) do {} while (0)
#endif

static csw_status_t ums_verify_csw(ums_t* ums, iotxn_t* csw_request, uint32_t* out_residue);


static zx_status_t ums_reset(ums_t* ums) {
    // for all these control requests, data is null, length is 0 because nothing is passed back
    // value and index not used for first command, though index is supposed to be set to interface number
    // TODO: check interface number, see if index needs to be set
    DEBUG_PRINT(("UMS: performing reset recovery\n"));
    zx_status_t status = usb_control(&ums->usb, USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
                                     USB_REQ_RESET, 0x00, 0x00, NULL, 0, ZX_TIME_INFINITE);
    status = usb_control(&ums->usb, USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
                         USB_REQ_CLEAR_FEATURE, FS_ENDPOINT_HALT, ums->bulk_in_addr, NULL, 0,
                         ZX_TIME_INFINITE);
    status = usb_control(&ums->usb, USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
                         USB_REQ_CLEAR_FEATURE, FS_ENDPOINT_HALT, ums->bulk_out_addr, NULL, 0,
                         ZX_TIME_INFINITE);
    return status;
}

static void ums_queue_request(ums_t* ums, iotxn_t* txn) {
    iotxn_queue(ums->usb_mxdev, txn);
}

static void ums_txn_complete(iotxn_t* txn, void* cookie) {
    if (cookie) {
        completion_signal((completion_t *)cookie);
    }
}

static void ums_send_cbw(ums_t* ums, uint8_t lun, uint32_t transfer_length, uint8_t flags,
                         uint8_t command_len, void* command) {
    iotxn_t* txn = ums->cbw_iotxn;

    ums_cbw_t* cbw;
    iotxn_mmap(txn, (void **)&cbw);

    memset(cbw, 0, sizeof(*cbw));
    cbw->dCBWSignature = htole32(CBW_SIGNATURE);
    cbw->dCBWTag = htole32(ums->tag_send++);
    cbw->dCBWDataTransferLength = htole32(transfer_length);
    cbw->bmCBWFlags = flags;
    cbw->bCBWLUN = lun;
    cbw->bCBWCBLength = command_len;

    // copy command_len bytes from the command passed in into the command_len
    memcpy(cbw->CBWCB, command, command_len);

    completion_t completion = COMPLETION_INIT;
    txn->cookie = &completion;
    ums_queue_request(ums, txn);
    completion_wait(&completion, ZX_TIME_INFINITE);
}

static zx_status_t ums_read_csw(ums_t* ums, uint32_t* out_residue) {
    completion_t completion = COMPLETION_INIT;
    iotxn_t* csw_request = ums->csw_iotxn;
    csw_request->cookie = &completion;
    ums_queue_request(ums, csw_request);
    completion_wait(&completion, ZX_TIME_INFINITE);

    csw_status_t csw_error = ums_verify_csw(ums, csw_request, out_residue);

    if (csw_error == CSW_SUCCESS) {
        return ZX_OK;
    } else if (csw_error == CSW_FAILED) {
        return ZX_ERR_BAD_STATE;
    } else {
        // FIXME - best way to handle this?
        // print error and then reset device due to it
        DEBUG_PRINT(("UMS: CSW verify returned error. Check ums-hw.h csw_status_t for enum = %d\n", csw_error));
        ums_reset(ums);
        return ZX_ERR_INTERNAL;
    }
}

static csw_status_t ums_verify_csw(ums_t* ums, iotxn_t* csw_request, uint32_t* out_residue) {
    ums_csw_t csw;
    iotxn_copyfrom(csw_request, &csw, sizeof(csw), 0);

    // check signature is "USBS"
    if (letoh32(csw.dCSWSignature) != CSW_SIGNATURE) {
        DEBUG_PRINT(("UMS:invalid csw sig: %08x \n", letoh32(csw.dCSWSignature)));
        return CSW_INVALID;
    }
    // check if tag matches the tag of last CBW
    if (letoh32(csw.dCSWTag) != ums->tag_receive++) {
        DEBUG_PRINT(("UMS:csw tag mismatch, expected:%08x got in csw:%08x \n", ums->tag_receive - 1,
                    letoh32(csw.dCSWTag)));
        return CSW_TAG_MISMATCH;
    }
    // check if success is true or not?
    if (csw.bmCSWStatus == CSW_FAILED) {
        return CSW_FAILED;
    } else if (csw.bmCSWStatus == CSW_PHASE_ERROR) {
        return CSW_PHASE_ERROR;
    }

    if (out_residue) {
        *out_residue = letoh32(csw.dCSWDataResidue);
    }
    return CSW_SUCCESS;
}

static void ums_queue_read(ums_t* ums, uint16_t transfer_length) {
    // read request sense response
    iotxn_t* read_request = ums->data_iotxn;
    read_request->length = transfer_length;
    read_request->cookie = NULL;
    ums_queue_request(ums, read_request);
}

static zx_status_t ums_inquiry(ums_t* ums, uint8_t lun, uint8_t* out_data) {
    // CBW Configuration
    scsi_command6_t command;
    memset(&command, 0, sizeof(command));
    command.opcode = UMS_INQUIRY;
    command.length = UMS_INQUIRY_TRANSFER_LENGTH;
    ums_send_cbw(ums, lun, UMS_INQUIRY_TRANSFER_LENGTH, USB_DIR_IN, sizeof(command), &command);

    // read inquiry response
    ums_queue_read(ums, UMS_INQUIRY_TRANSFER_LENGTH);

    // wait for CSW
    zx_status_t status = ums_read_csw(ums, NULL);
    if (status == ZX_OK) {
        iotxn_copyfrom(ums->data_iotxn, out_data, UMS_INQUIRY_TRANSFER_LENGTH, 0);
    }
    return status;
}

static zx_status_t ums_test_unit_ready(ums_t* ums, uint8_t lun) {
    // CBW Configuration
    scsi_command6_t command;
    memset(&command, 0, sizeof(command));
    command.opcode = UMS_TEST_UNIT_READY;
    ums_send_cbw(ums, lun, 0, USB_DIR_IN, sizeof(command), &command);

    // wait for CSW
    return ums_read_csw(ums, NULL);
}

static zx_status_t ums_request_sense(ums_t* ums, uint8_t lun, uint8_t* out_data) {
    // CBW Configuration
    scsi_command6_t command;
    memset(&command, 0, sizeof(command));
    command.opcode = UMS_REQUEST_SENSE;
    command.length = UMS_REQUEST_SENSE_TRANSFER_LENGTH;
    ums_send_cbw(ums, lun, UMS_REQUEST_SENSE_TRANSFER_LENGTH, USB_DIR_IN, sizeof(command), &command);

    // read request sense response
    ums_queue_read(ums, UMS_REQUEST_SENSE_TRANSFER_LENGTH);

    // wait for CSW
    zx_status_t status = ums_read_csw(ums, NULL);
    if (status == ZX_OK) {
        iotxn_copyfrom(ums->data_iotxn, out_data, UMS_REQUEST_SENSE_TRANSFER_LENGTH, 0);
    }
    return status;
}

static zx_status_t ums_read_capacity10(ums_t* ums, uint8_t lun, scsi_read_capacity_10_t* out_data) {
    // CBW Configuration
    scsi_command10_t command;
    memset(&command, 0, sizeof(command));
    command.opcode = UMS_READ_CAPACITY10;
    ums_send_cbw(ums, lun, sizeof(*out_data), USB_DIR_IN, sizeof(command), &command);

    // read capacity10 response
    ums_queue_read(ums, sizeof(*out_data));

    zx_status_t status = ums_read_csw(ums, NULL);
    if (status == ZX_OK) {
        iotxn_copyfrom(ums->data_iotxn, out_data, sizeof(*out_data), 0);
    }
    return status;
}

static zx_status_t ums_read_capacity16(ums_t* ums, uint8_t lun, scsi_read_capacity_16_t* out_data) {
    // CBW Configuration
    scsi_command16_t command;
    memset(&command, 0, sizeof(command));
    command.opcode = UMS_READ_CAPACITY16;
    // service action = 10, not sure what that means
    command.misc = 0x10;
    command.length = sizeof(*out_data);
    ums_send_cbw(ums, lun, sizeof(*out_data), USB_DIR_IN, sizeof(command), &command);

    // read capacity16 response
    ums_queue_read(ums, sizeof(*out_data));

    zx_status_t status = ums_read_csw(ums, NULL);
    if (status == ZX_OK) {
        iotxn_copyfrom(ums->data_iotxn, out_data, sizeof(*out_data), 0);
    }
    return status;
}

static zx_status_t ums_mode_sense6(ums_t* ums, uint8_t lun, scsi_mode_sense_6_data_t* out_data) {
    // CBW Configuration
    scsi_mode_sense_6_command_t command;
    memset(&command, 0, sizeof(command));
    command.opcode = UMS_MODE_SENSE6;
    command.page = 0x3F;   // all pages, current values
    command.allocation_length = sizeof(*out_data);

    ums_send_cbw(ums, lun, sizeof(*out_data), USB_DIR_IN, sizeof(command), &command);

    // read mode sense response
    ums_queue_read(ums, sizeof(*out_data));

    zx_status_t status = ums_read_csw(ums, NULL);
    if (status == ZX_OK) {
        iotxn_copyfrom(ums->data_iotxn, out_data, sizeof(*out_data), 0);
    }
    return status;
}

static zx_status_t ums_data_transfer(ums_t* ums, iotxn_t* txn, zx_off_t offset, size_t length,
                                     uint8_t ep_address) {
    iotxn_t* clone = NULL;
    zx_status_t status = iotxn_clone_partial(txn, txn->vmo_offset + offset, length, &clone);
    if (status != ZX_OK) {
        return status;
    }
    clone->complete_cb = ums_txn_complete;

    usb_protocol_data_t* pdata = iotxn_pdata(clone, usb_protocol_data_t);
    memset(pdata, 0, sizeof(*pdata));
    pdata->ep_address = ep_address;

    completion_t completion = COMPLETION_INIT;
    clone->cookie = &completion;
    clone->protocol = ZX_PROTOCOL_USB;
    ums_queue_request(ums, clone);
    completion_wait(&completion, ZX_TIME_INFINITE);

    status = clone->status;
    if (status == ZX_OK && clone->actual != length) {
        status = ZX_ERR_IO;
    }

    iotxn_release(clone);
    return status;
}

static ssize_t ums_read(ums_block_t* dev, iotxn_t* txn) {
    ums_t* ums = block_to_ums(dev);

    uint64_t lba = txn->offset / dev->block_size;
    if (lba > dev->total_blocks) {
        return ZX_ERR_OUT_OF_RANGE;
    }
    uint32_t num_blocks = txn->length / dev->block_size;
    if (lba + num_blocks >= dev->total_blocks) {
        num_blocks = dev->total_blocks - lba;
        if (num_blocks == 0) {
            return 0;
        }
    }

    size_t blocks_transferred = 0;
    size_t max_blocks = ums->max_transfer / dev->block_size;
    zx_status_t status = ZX_OK;

    while (status == ZX_OK && blocks_transferred < num_blocks) {
        size_t blocks = num_blocks - blocks_transferred;
        if (blocks > max_blocks) {
            blocks = max_blocks;
        }
        size_t length = blocks * dev->block_size;

        // CBW Configuration
        // Need to use UMS_READ16 if block addresses are greater than 32 bit
        if (dev->total_blocks > UINT32_MAX) {
            scsi_command16_t command;
            memset(&command, 0, sizeof(command));
            command.opcode = UMS_READ16;
            command.lba = htobe64(lba + blocks_transferred);
            command.length = htobe32(blocks);
            ums_send_cbw(ums, dev->lun, length, USB_DIR_IN, sizeof(command), &command);
        } else if (blocks <= UINT16_MAX) {
            scsi_command10_t command;
            memset(&command, 0, sizeof(command));
            command.opcode = UMS_READ10;
            command.lba = htobe32(lba + blocks_transferred);
            command.length_hi = blocks >> 8;
            command.length_lo = blocks & 0xFF;
            ums_send_cbw(ums, dev->lun, length, USB_DIR_IN, sizeof(command), &command);
        } else {
            scsi_command12_t command;
            memset(&command, 0, sizeof(command));
            command.opcode = UMS_READ12;
            command.lba = htobe32(lba + blocks_transferred);
            command.length = htobe32(blocks);
            ums_send_cbw(ums, dev->lun, length, USB_DIR_IN, sizeof(command), &command);
        }

        status = ums_data_transfer(ums, txn, blocks_transferred * dev->block_size, length,
                                   ums->bulk_in_addr);
        blocks_transferred += blocks;

        // receive CSW
        uint32_t residue;
        status = ums_read_csw(ums, &residue);
        if (status == ZX_OK && residue) {
            printf("unexpected residue in ums_read\n");
            status = ZX_ERR_IO;
        }
    }

    if (status == ZX_OK) {
        return num_blocks * dev->block_size;
    } else {
        return status;
    }
}

static ssize_t ums_write(ums_block_t* dev, iotxn_t* txn) {
    ums_t* ums = block_to_ums(dev);

    uint64_t lba = txn->offset / dev->block_size;
    if (lba > dev->total_blocks) {
        return ZX_ERR_OUT_OF_RANGE;
    }
    uint32_t num_blocks = txn->length / dev->block_size;
    if (lba + num_blocks >= dev->total_blocks) {
        num_blocks = dev->total_blocks - lba;
        if (num_blocks == 0) {
            return 0;
        }
    }

    size_t blocks_transferred = 0;
    size_t max_blocks = ums->max_transfer / dev->block_size;
    zx_status_t status = ZX_OK;

    while (status == ZX_OK && blocks_transferred < num_blocks) {
        size_t blocks = num_blocks - blocks_transferred;
        if (blocks > max_blocks) {
            blocks = max_blocks;
        }
        size_t length = blocks * dev->block_size;

        // Need to use UMS_WRITE16 if block addresses are greater than 32 bit
        if (dev->total_blocks > UINT32_MAX) {
            scsi_command16_t command;
            memset(&command, 0, sizeof(command));
            command.opcode = UMS_WRITE16;
            command.lba = htobe64(lba + blocks_transferred);
            command.length = htobe32(blocks);
            ums_send_cbw(ums, dev->lun, length, USB_DIR_OUT, sizeof(command), &command);
        } else if (blocks <= UINT16_MAX) {
            scsi_command10_t command;
            memset(&command, 0, sizeof(command));
            command.opcode = UMS_WRITE10;
            command.lba = htobe32(lba + blocks_transferred);
            command.length_hi = blocks >> 8;
            command.length_lo = blocks & 0xFF;
            ums_send_cbw(ums, dev->lun, length, USB_DIR_OUT, sizeof(command), &command);
        } else {
            scsi_command12_t command;
            memset(&command, 0, sizeof(command));
            command.opcode = UMS_WRITE12;
            command.lba = htobe32(lba + blocks_transferred);
            command.length = htobe32(blocks);
            ums_send_cbw(ums, dev->lun, length, USB_DIR_OUT, sizeof(command), &command);
        }

        status = ums_data_transfer(ums, txn, blocks_transferred * dev->block_size, length,
                                   ums->bulk_out_addr);
        blocks_transferred += blocks;

        // receive CSW
        uint32_t residue;
        status = ums_read_csw(ums, &residue);
        if (status == ZX_OK && residue) {
            printf("unexpected residue in ums_write\n");
            status = ZX_ERR_IO;
        }
    }

    if (status == ZX_OK) {
        return num_blocks * dev->block_size;
    } else {
        return status;
    }
}

static void ums_unbind(void* ctx) {
    ums_t* ums = ctx;

    // terminate our worker thread
    mtx_lock(&ums->iotxn_lock);
    ums->dead = true;
    mtx_unlock(&ums->iotxn_lock);
    completion_signal(&ums->iotxn_completion);

    // wait for worker thread to finish before removing devices
    thrd_join(ums->worker_thread, NULL);

    for (uint8_t lun = 0; lun <= ums->max_lun; lun++) {
        ums_block_t* dev = &ums->block_devs[lun];

        if (dev->device_added) {
            device_remove(dev->mxdev);
        }
    }

    // remove our root device
    device_remove(ums->mxdev);
}

static void ums_release(void* ctx) {
    ums_t* ums = ctx;

    if (ums->cbw_iotxn) {
        iotxn_release(ums->cbw_iotxn);
    }
    if (ums->data_iotxn) {
        iotxn_release(ums->data_iotxn);
    }
    if (ums->csw_iotxn) {
        iotxn_release(ums->csw_iotxn);
    }

    free(ums);
}

static zx_status_t ums_add_block_device(ums_block_t* dev) {
    ums_t* ums = block_to_ums(dev);
    uint8_t lun = dev->lun;

    scsi_read_capacity_10_t data;
    zx_status_t status = ums_read_capacity10(ums, lun, &data);
    if (status < 0) {
        printf("read_capacity10 failed: %d\n", status);
        return status;
    }

    dev->total_blocks = betoh32(data.lba);
    dev->block_size = betoh32(data.block_length);

    if (dev->total_blocks == 0xFFFFFFFF) {
        scsi_read_capacity_16_t data;
        status = ums_read_capacity16(ums, lun, &data);
        if (status < 0) {
            printf("read_capacity16 failed: %d\n", status);
            return status;
        }

        dev->total_blocks = betoh64(data.lba);
        dev->block_size = betoh32(data.block_length);
    }
    if (dev->block_size == 0) {
        printf("UMS zero block size\n");
        return ZX_ERR_INVALID_ARGS;
    }

    // +1 because this returns the address of the final block, and blocks are zero indexed
    dev->total_blocks++;

    // determine if LUN is read-only
    scsi_mode_sense_6_data_t ms_data;
    status = ums_mode_sense6(ums, lun, &ms_data);
    if (status != ZX_OK) {
        printf("ums_mode_sense6 failed: %d\n", status);
        return status;
    }

    if (ms_data.device_specific_param & MODE_SENSE_DSP_RO) {
        dev->flags |= BLOCK_FLAG_READONLY;
    } else {
        dev->flags &= ~BLOCK_FLAG_READONLY;
    }

    DEBUG_PRINT(("UMS: block size is: 0x%08x\n", dev->block_size));
    DEBUG_PRINT(("UMS: total blocks is: %" PRId64 "\n", dev->total_blocks));
    DEBUG_PRINT(("UMS: total size is: %" PRId64 "\n", dev->total_blocks * dev->block_size));
    DEBUG_PRINT(("UMS: read-only: %d removable: %d\n", !!(dev->flags & BLOCK_FLAG_READONLY),
                                                       !!(dev->flags & BLOCK_FLAG_REMOVABLE)));

    return ums_block_add_device(ums, dev);
}

static zx_status_t ums_check_luns_ready(ums_t* ums) {
    zx_status_t status = ZX_OK;

    for (uint8_t lun = 0; lun <= ums->max_lun && status == ZX_OK; lun++) {
        ums_block_t* dev = &ums->block_devs[lun];
        bool ready;

        status = ums_test_unit_ready(ums, lun);
        if (status == ZX_OK) {
            ready = true;
        } if (status == ZX_ERR_BAD_STATE) {
            ready = false;
            // command returned CSW_FAILED. device is there but media is not ready.
            uint8_t request_sense_data[UMS_REQUEST_SENSE_TRANSFER_LENGTH];
            status = ums_request_sense(ums, lun, request_sense_data);
        }
        if (status != ZX_OK) {
            break;
        }

        if (ready && !dev->device_added) {
            // this will set ums_block_t.device_added if it succeeds
            status = ums_add_block_device(dev);
            if (status == ZX_OK) {
                dev->device_added = true;
            } else {
                printf("UMS: device_add for block device failed %d\n", status);
            }
        } else if (!ready && dev->device_added) {
            device_remove(dev->mxdev);
            dev->device_added = false;
        }
    }

    return status;
}

static zx_protocol_device_t ums_device_proto = {
    .version = DEVICE_OPS_VERSION,
    .unbind = ums_unbind,
    .release = ums_release,
};

static int ums_worker_thread(void* arg) {
    ums_t* ums = (ums_t*)arg;
    zx_status_t status = ZX_OK;

    for (uint8_t lun = 0; lun <= ums->max_lun; lun++) {
        uint8_t inquiry_data[UMS_INQUIRY_TRANSFER_LENGTH];
        status = ums_inquiry(ums, lun, inquiry_data);
        if (status < 0) {
            printf("ums_inquiry failed for lun %d status: %d\n", lun, status);
            goto fail;
        }
        uint8_t rmb = inquiry_data[1] & 0x80;   // Removable Media Bit
        if (rmb) {
            ums->block_devs[lun].flags |= BLOCK_FLAG_REMOVABLE;
        }
    }

    // Add root device, which will contain block devices for logical units
    device_add_args_t args = {
        .version = DEVICE_ADD_ARGS_VERSION,
        .name = "ums",
        .ctx = ums,
        .ops = &ums_device_proto,
        .flags = DEVICE_ADD_NON_BINDABLE,
    };

    status = device_add(ums->usb_mxdev, &args, &ums->mxdev);
    if (status != ZX_OK) {
        goto fail;
    }

    bool wait = true;
    while (1) {
        if (wait) {
            status = completion_wait(&ums->iotxn_completion, ZX_SEC(1));
            if (status == ZX_ERR_TIMED_OUT) {
                if (ums_check_luns_ready(ums) != ZX_OK) {
                    return status;
                }
                continue;
            }
            completion_reset(&ums->iotxn_completion);
        }

        mtx_lock(&ums->iotxn_lock);
        if (ums->dead) {
            mtx_unlock(&ums->iotxn_lock);
            break;
        }
        iotxn_t* txn = list_remove_head_type(&ums->queued_iotxns, iotxn_t, node);
        if (txn == NULL) {
            mtx_unlock(&ums->iotxn_lock);
            wait = true;
            continue;
        }
        ums->curr_txn = txn;
        mtx_unlock(&ums->iotxn_lock);

        ums_block_t* dev = txn->context;

        zx_status_t status;
        if (txn->opcode == IOTXN_OP_READ) {
            status = ums_read(dev, txn);
        }else if (txn->opcode == IOTXN_OP_WRITE) {
            status = ums_write(dev, txn);
        } else {
            status = ZX_ERR_INVALID_ARGS;
        }

        mtx_lock(&ums->iotxn_lock);
        // unblock calls to IOCTL_DEVICE_SYNC that are waiting for curr_txn to complete
        ums_sync_node_t* sync_node;
        ums_sync_node_t* temp;
        list_for_every_entry_safe(&ums->sync_nodes, sync_node, temp, ums_sync_node_t, node) {
            if (sync_node->iotxn == txn) {
                list_delete(&sync_node->node);
                completion_signal(&sync_node->completion);
            }
        }
        ums->curr_txn = NULL;
        // make sure we have processed all queued transactions before waiting again
        wait = list_is_empty(&ums->queued_iotxns);
        mtx_unlock(&ums->iotxn_lock);

        if (status >= 0) {
            iotxn_complete(txn, ZX_OK, txn->length);
        } else {
            iotxn_complete(txn, status, 0);
        }
    }

    // complete any pending txns
    list_node_t txns = LIST_INITIAL_VALUE(txns);
    mtx_lock(&ums->iotxn_lock);
    list_move(&ums->queued_iotxns, &txns);
    mtx_unlock(&ums->iotxn_lock);

    iotxn_t* txn;
    while ((txn = list_remove_head_type(&ums->queued_iotxns, iotxn_t, node)) != NULL) {
        iotxn_complete(txn, ZX_ERR_IO_NOT_PRESENT, 0);
    }

    return ZX_OK;

fail:
    printf("ums_worker_thread failed\n");
    ums_release(ums);
    return status;
}

static zx_status_t ums_bind(void* ctx, zx_device_t* device, void** cookie) {
    usb_protocol_t usb;
    if (device_get_protocol(device, ZX_PROTOCOL_USB, &usb)) {
        return 0;
    }

    // find our endpoints
    usb_desc_iter_t iter;
    zx_status_t result = usb_desc_iter_init(&usb, &iter);
    if (result < 0) return result;

    usb_interface_descriptor_t* intf = usb_desc_iter_next_interface(&iter, true);
    if (!intf) {
        usb_desc_iter_release(&iter);
        return ZX_ERR_NOT_SUPPORTED;
    }
    if (intf->bNumEndpoints < 2) {
        DEBUG_PRINT(("UMS:ums_bind wrong number of endpoints: %d\n", intf->bNumEndpoints));
        usb_desc_iter_release(&iter);
        return ZX_ERR_NOT_SUPPORTED;
    }

    uint8_t bulk_in_addr = 0;
    uint8_t bulk_out_addr = 0;
    size_t bulk_in_max_packet = 0;
    size_t bulk_out_max_packet = 0;

   usb_endpoint_descriptor_t* endp = usb_desc_iter_next_endpoint(&iter);
    while (endp) {
        if (usb_ep_direction(endp) == USB_ENDPOINT_OUT) {
            if (usb_ep_type(endp) == USB_ENDPOINT_BULK) {
                bulk_out_addr = endp->bEndpointAddress;
                bulk_out_max_packet = usb_ep_max_packet(endp);
            }
        } else {
            if (usb_ep_type(endp) == USB_ENDPOINT_BULK) {
                bulk_in_addr = endp->bEndpointAddress;
                bulk_in_max_packet = usb_ep_max_packet(endp);
            }
        }
        endp = usb_desc_iter_next_endpoint(&iter);
    }
    usb_desc_iter_release(&iter);

    if (!bulk_in_addr || !bulk_out_addr) {
        DEBUG_PRINT(("UMS:ums_bind could not find endpoints\n"));
        return ZX_ERR_NOT_SUPPORTED;
    }

    uint8_t max_lun;
    zx_status_t status = usb_control(&usb, USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
                                     USB_REQ_GET_MAX_LUN, 0x00, 0x00, &max_lun, sizeof(max_lun),
                                     ZX_TIME_INFINITE);
    if (status != sizeof(max_lun)) {
        return status;
    }

    ums_t* ums = calloc(1, sizeof(ums_t) + (max_lun + 1) * sizeof(ums_block_t));
    if (!ums) {
        DEBUG_PRINT(("UMS:Not enough memory for ums_t\n"));
        return ZX_ERR_NO_MEMORY;
    }

    DEBUG_PRINT(("UMS:Max lun is: %u\n", max_lun));
    ums->max_lun = max_lun;

    for (uint8_t lun = 0; lun <= max_lun; lun++) {
        ums_block_t* dev = &ums->block_devs[lun];
        dev->lun = lun;
    }

    list_initialize(&ums->queued_iotxns);
    list_initialize(&ums->sync_nodes);
    completion_reset(&ums->iotxn_completion);
    mtx_init(&ums->iotxn_lock, mtx_plain);

    ums->usb_mxdev = device;
    memcpy(&ums->usb, &usb, sizeof(ums->usb));
    ums->bulk_in_addr = bulk_in_addr;
    ums->bulk_out_addr = bulk_out_addr;
    ums->bulk_in_max_packet = bulk_in_max_packet;
    ums->bulk_out_max_packet = bulk_out_max_packet;

    size_t max_in = usb_get_max_transfer_size(&usb, bulk_in_addr);
    size_t max_out = usb_get_max_transfer_size(&usb, bulk_out_addr);
    ums->max_transfer = (max_in < max_out ? max_in : max_out);

    ums->cbw_iotxn = usb_alloc_iotxn(bulk_out_addr, sizeof(ums_cbw_t));
    if (!ums->cbw_iotxn) {
        status = ZX_ERR_NO_MEMORY;
        goto fail;
    }
    ums->data_iotxn = usb_alloc_iotxn(bulk_in_addr, PAGE_SIZE);
    if (!ums->data_iotxn) {
        status = ZX_ERR_NO_MEMORY;
        goto fail;
    }
    ums->csw_iotxn = usb_alloc_iotxn(bulk_in_addr, sizeof(ums_csw_t));
    if (!ums->csw_iotxn) {
        status = ZX_ERR_NO_MEMORY;
        goto fail;
    }

    ums->cbw_iotxn->length = sizeof(ums_cbw_t);
    ums->csw_iotxn->length = sizeof(ums_csw_t);
    ums->cbw_iotxn->complete_cb = ums_txn_complete;
    ums->data_iotxn->complete_cb = ums_txn_complete;
    ums->csw_iotxn->complete_cb = ums_txn_complete;

    ums->tag_send = ums->tag_receive = 8;

    thrd_create_with_name(&ums->worker_thread, ums_worker_thread, ums, "ums_worker_thread");

    return status;

fail:
    printf("ums_bind failed: %d\n", status);
    ums_release(ums);
    return status;
}

static zx_driver_ops_t usb_mass_storage_driver_ops = {
    .version = DRIVER_OPS_VERSION,
    .bind = ums_bind,
};

ZIRCON_DRIVER_BEGIN(usb_mass_storage, usb_mass_storage_driver_ops, "zircon", "0.1", 4)
    BI_ABORT_IF(NE, BIND_PROTOCOL, ZX_PROTOCOL_USB),
    BI_ABORT_IF(NE, BIND_USB_CLASS, USB_CLASS_MSC),
    BI_ABORT_IF(NE, BIND_USB_SUBCLASS, USB_SUBCLASS_MSC_SCSI),
    BI_MATCH_IF(EQ, BIND_USB_PROTOCOL, USB_PROTOCOL_MSC_BULK_ONLY),
ZIRCON_DRIVER_END(usb_mass_storage)
