/*
 * Copyright (c) 2013-2015 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Rene de Jong
 */

/** @file
 * This is a simulation model for a UFS interface
 * The UFS interface consists of a host controller and (at least) one device.
 * The device can contain multiple logic units.
 * To make this interface as usefull as possible for future development, the
 * decision has been made to split the UFS functionality from the SCSI
 * functionality. The class UFS SCSIDevice can therefor be used as a starting
 * point for creating a more generic SCSI device. This has as a consequence
 * that the UFSHostDevice class contains functionality from both the host
 * controller and the device. The current UFS standard (1.1) allows only one
 * device, and up to 8 logic units. the logic units only handle the SCSI part
 * of the command, and the device mainly the UFS part. Yet the split between
 * the SCSIresume function and the SCSICMDHandle might seem a bit awkward.
 * The SCSICMDHandle function is in essence a SCSI reply generator, and it
 * distils the essential information from the command. A disktransfer cannot
 * be made from this position because the scatter gather list is not included
 * in the SCSI command, but in the Transfer Request descriptor. The device
 * needs to manage the data transfer. This file is build up as follows: first
 * the UFSSCSIDevice functions will be presented; then the UFSHostDevice
 * functions. The UFSHostDevice functions are split in three parts: UFS
 * transaction flow, data write transfer and data read transfer. The
 * functions are then ordered in the order in which a transfer takes place.
 */

/**
 * Reference material can be found at the JEDEC website:
 * UFS standard
 * http://www.jedec.org/standards-documents/results/jesd220
 * UFS HCI specification
 * http://www.jedec.org/standards-documents/results/jesd223
 */

#include "dev/arm/ufs_device.hh"

/**
 * Constructor and destructor functions of UFSHCM device
 */
UFSHostDevice::UFSSCSIDevice::UFSSCSIDevice(const UFSHostDeviceParams* p,
                             uint32_t lun_id, Callback *transfer_cb,
                             Callback *read_cb):
    SimObject(p),
    flashDisk(p->image[lun_id]),
    flashDevice(p->internalflash[lun_id]),
    blkSize(p->img_blk_size),
    lunAvail(p->image.size()),
    diskSize(flashDisk->size()),
    capacityLower((diskSize - 1) & 0xffffffff),
    capacityUpper((diskSize - SectorSize) >> 32),
    lunID(lun_id),
    transferCompleted(false),
    readCompleted(false),
    totalRead(0),
    totalWrite(0),
    amountOfWriteTransfers(0),
    amountOfReadTransfers(0)
{
    /**
     * These callbacks are used to communicate the events that are
     * triggered upstream; e.g. from the Memory Device to the UFS SCSI Device
     * or from the UFS SCSI device to the UFS host.
     */
    signalDone = transfer_cb;
    memReadCallback = new MakeCallback<UFSSCSIDevice,
        &UFSHostDevice::UFSSCSIDevice::readCallback>(this);
    deviceReadCallback = read_cb;
    memWriteCallback = new MakeCallback<UFSSCSIDevice,
        &UFSHostDevice::UFSSCSIDevice::SSDWriteDone>(this);

    /**
     * make ascii out of lun_id (and add more characters)
     * UFS allows up to 8 logic units, so the numbering should work out
     */
    uint32_t temp_id = ((lun_id | 0x30) << 24) | 0x3A4449;
    lunInfo.dWord0 = 0x02060000;   //data
    lunInfo.dWord1 = 0x0200001F;
    lunInfo.vendor0 = 0x484D5241;  //ARMH (HMRA)
    lunInfo.vendor1 = 0x424D4143;  //CAMB (BMAC)
    lunInfo.product0 = 0x356D6567; //gem5  (5meg)
    lunInfo.product1 = 0x4D534655; //UFSM (MSFU)
    lunInfo.product2 = 0x4C45444F; //ODEL (LEDO)
    lunInfo.product3 = temp_id;    // ID:"lun_id" ("lun_id":DI)
    lunInfo.productRevision = 0x01000000; //0x01

    DPRINTF(UFSHostDevice, "Logic unit %d assumes that %d logic units are"
            " present in the system\n", lunID, lunAvail);
    DPRINTF(UFSHostDevice,"The disksize of lun: %d should be %d blocks\n",
            lunID, diskSize);
    flashDevice->initializeMemory(diskSize, SectorSize);
}


/**
 * These pages are SCSI specific. For more information refer to:
 * Universal Flash Storage (UFS) JESD220 FEB 2011 (JEDEC)
 * http://www.jedec.org/standards-documents/results/jesd220
 */
const unsigned int UFSHostDevice::UFSSCSIDevice::controlPage[3] =
                                                {0x01400A0A, 0x00000000,
                                                 0x0000FFFF};
const unsigned int UFSHostDevice::UFSSCSIDevice::recoveryPage[3] =
                                                {0x03800A01, 0x00000000,
                                                 0xFFFF0003};
const unsigned int UFSHostDevice::UFSSCSIDevice::cachingPage[5] =
                                                {0x00011208, 0x00000000,
                                                 0x00000000, 0x00000020,
                                                 0x00000000};

UFSHostDevice::UFSSCSIDevice::~UFSSCSIDevice() {}

/**
 * UFS specific SCSI handling function.
 * The following attributes may still be added: SCSI format unit,
 * Send diagnostic and UNMAP;
 * Synchronize Cache and buffer read/write could not be tested yet
 * All parameters can be found in:
 * Universal Flash Storage (UFS) JESD220 FEB 2011 (JEDEC)
 * http://www.jedec.org/standards-documents/results/jesd220
 * (a JEDEC acount may be required {free of charge})
 */

struct UFSHostDevice::SCSIReply
UFSHostDevice::UFSSCSIDevice::SCSICMDHandle(uint32_t* SCSI_msg)
{
    struct SCSIReply scsi_out;
    memset(&scsi_out, 0, sizeof(struct SCSIReply));

    /**
     * Create the standard SCSI reponse information
     * These values might changes over the course of a transfer
     */
    scsi_out.message.header.dWord0 = UPIUHeaderDataIndWord0 |
        lunID << 16;
    scsi_out.message.header.dWord1 = UPIUHeaderDataIndWord1;
    scsi_out.message.header.dWord2 = UPIUHeaderDataIndWord2;
    statusCheck(SCSIGood, scsi_out.senseCode);
    scsi_out.senseSize = scsi_out.senseCode[0];
    scsi_out.LUN = lunID;
    scsi_out.status = SCSIGood;

    DPRINTF(UFSHostDevice, "SCSI command:%2x\n", SCSI_msg[4]);
    /**Determine what the message is and fill the response packet*/

    switch (SCSI_msg[4] & 0xFF) {

      case SCSIInquiry: {
          /**
           * SCSI inquiry: tell about this specific logic unit
           */
          scsi_out.msgSize = 36;
          scsi_out.message.dataMsg.resize(9);

          for (uint8_t count = 0; count < 9; count++)
              scsi_out.message.dataMsg[count] =
                  (reinterpret_cast<uint32_t*> (&lunInfo))[count];
      } break;

      case SCSIRead6: {
          /**
           * Read command. Number indicates the length of the command.
           */
          scsi_out.expectMore = 0x02;
          scsi_out.msgSize = 0;

          uint8_t* tempptr = reinterpret_cast<uint8_t*>(&SCSI_msg[4]);

          /**BE and not nicely aligned. Apart from that it only has
           * information in five bits of the first byte that is relevant
           * for this field.
           */
          uint32_t tmp = *reinterpret_cast<uint32_t*>(tempptr);
          uint64_t read_offset = betoh(tmp) & 0x1FFFFF;

          uint32_t read_size = tempptr[4];


          scsi_out.msgSize =  read_size * blkSize;
          scsi_out.offset = read_offset * blkSize;

          if ((read_offset + read_size) > diskSize)
              scsi_out.status = SCSIIllegalRequest;

          DPRINTF(UFSHostDevice, "Read6 offset: 0x%8x, for %d blocks\n",
                  read_offset, read_size);

          /**
           * Renew status check, for the request may have been illegal
           */
          statusCheck(scsi_out.status, scsi_out.senseCode);
          scsi_out.senseSize = scsi_out.senseCode[0];
          scsi_out.status = (scsi_out.status == SCSIGood) ? SCSIGood :
              SCSICheckCondition;

      } break;

      case SCSIRead10: {
          scsi_out.expectMore = 0x02;
          scsi_out.msgSize = 0;

          uint8_t* tempptr = reinterpret_cast<uint8_t*>(&SCSI_msg[4]);

          /**BE and not nicely aligned.*/
          uint32_t tmp = *reinterpret_cast<uint32_t*>(&tempptr[2]);
          uint64_t read_offset = betoh(tmp);

          uint16_t tmpsize = *reinterpret_cast<uint16_t*>(&tempptr[7]);
          uint32_t read_size = betoh(tmpsize);

          scsi_out.msgSize =  read_size * blkSize;
          scsi_out.offset = read_offset * blkSize;

          if ((read_offset + read_size) > diskSize)
              scsi_out.status = SCSIIllegalRequest;

          DPRINTF(UFSHostDevice, "Read10 offset: 0x%8x, for %d blocks\n",
                  read_offset, read_size);

          /**
           * Renew status check, for the request may have been illegal
           */
          statusCheck(scsi_out.status, scsi_out.senseCode);
          scsi_out.senseSize = scsi_out.senseCode[0];
          scsi_out.status = (scsi_out.status == SCSIGood) ? SCSIGood :
              SCSICheckCondition;

      } break;

      case SCSIRead16: {
          scsi_out.expectMore = 0x02;
          scsi_out.msgSize = 0;

          uint8_t* tempptr = reinterpret_cast<uint8_t*>(&SCSI_msg[4]);

          /**BE and not nicely aligned.*/
          uint32_t tmp = *reinterpret_cast<uint32_t*>(&tempptr[2]);
          uint64_t read_offset = betoh(tmp);

          tmp = *reinterpret_cast<uint32_t*>(&tempptr[6]);
          read_offset = (read_offset << 32) | betoh(tmp);

          tmp = *reinterpret_cast<uint32_t*>(&tempptr[10]);
          uint32_t read_size = betoh(tmp);

          scsi_out.msgSize =  read_size * blkSize;
          scsi_out.offset = read_offset * blkSize;

          if ((read_offset + read_size) > diskSize)
              scsi_out.status = SCSIIllegalRequest;

          DPRINTF(UFSHostDevice, "Read16 offset: 0x%8x, for %d blocks\n",
                  read_offset, read_size);

          /**
           * Renew status check, for the request may have been illegal
           */
          statusCheck(scsi_out.status, scsi_out.senseCode);
          scsi_out.senseSize = scsi_out.senseCode[0];
          scsi_out.status = (scsi_out.status == SCSIGood) ? SCSIGood :
              SCSICheckCondition;

      } break;

      case SCSIReadCapacity10: {
          /**
           * read the capacity of the device
           */
          scsi_out.msgSize = 8;
          scsi_out.message.dataMsg.resize(2);
          scsi_out.message.dataMsg[0] =
              betoh(capacityLower);//last block
          scsi_out.message.dataMsg[1] = betoh(blkSize);//blocksize

      } break;
      case SCSIReadCapacity16: {
          scsi_out.msgSize = 32;
          scsi_out.message.dataMsg.resize(8);
          scsi_out.message.dataMsg[0] =
              betoh(capacityUpper);//last block
          scsi_out.message.dataMsg[1] =
              betoh(capacityLower);//last block
          scsi_out.message.dataMsg[2] = betoh(blkSize);//blocksize
          scsi_out.message.dataMsg[3] = 0x00;//
          scsi_out.message.dataMsg[4] = 0x00;//reserved
          scsi_out.message.dataMsg[5] = 0x00;//reserved
          scsi_out.message.dataMsg[6] = 0x00;//reserved
          scsi_out.message.dataMsg[7] = 0x00;//reserved

      } break;

      case SCSIReportLUNs: {
          /**
           * Find out how many Logic Units this device has.
           */
          scsi_out.msgSize = (lunAvail * 8) + 8;//list + overhead
          scsi_out.message.dataMsg.resize(2 * lunAvail + 2);
          scsi_out.message.dataMsg[0] = (lunAvail * 8) << 24;//LUN listlength
          scsi_out.message.dataMsg[1] = 0x00;

          for (uint8_t count = 0; count < lunAvail; count++) {
              //LUN "count"
              scsi_out.message.dataMsg[2 + 2 * count] = (count & 0x7F) << 8;
              scsi_out.message.dataMsg[3 + 2 * count] = 0x00;
          }

      } break;

      case SCSIStartStop: {
          //Just acknowledge; not deemed relevant ATM
          scsi_out.msgSize = 0;

      } break;

      case SCSITestUnitReady: {
          //Just acknowledge; not deemed relevant ATM
          scsi_out.msgSize = 0;

      } break;

      case SCSIVerify10: {
          /**
           * See if the blocks that the host plans to request are in range of
           * the device.
           */
          scsi_out.msgSize = 0;

          uint8_t* tempptr = reinterpret_cast<uint8_t*>(&SCSI_msg[4]);

          /**BE and not nicely aligned.*/
          uint32_t tmp = *reinterpret_cast<uint32_t*>(&tempptr[2]);
          uint64_t read_offset = betoh(tmp);

          uint16_t tmpsize = *reinterpret_cast<uint16_t*>(&tempptr[7]);
          uint32_t read_size = betoh(tmpsize);

          if ((read_offset + read_size) > diskSize)
              scsi_out.status = SCSIIllegalRequest;

          /**
           * Renew status check, for the request may have been illegal
           */
          statusCheck(scsi_out.status, scsi_out.senseCode);
          scsi_out.senseSize = scsi_out.senseCode[0];
          scsi_out.status = (scsi_out.status == SCSIGood) ? SCSIGood :
              SCSICheckCondition;

      } break;

      case SCSIWrite6: {
          /**
           * Write command.
           */

          uint8_t* tempptr = reinterpret_cast<uint8_t*>(&SCSI_msg[4]);

          /**BE and not nicely aligned. Apart from that it only has
           * information in five bits of the first byte that is relevant
           * for this field.
           */
          uint32_t tmp = *reinterpret_cast<uint32_t*>(tempptr);
          uint64_t write_offset = betoh(tmp) & 0x1FFFFF;

          uint32_t write_size = tempptr[4];

          scsi_out.msgSize =  write_size * blkSize;
          scsi_out.offset = write_offset * blkSize;
          scsi_out.expectMore = 0x01;

          if ((write_offset + write_size) > diskSize)
              scsi_out.status = SCSIIllegalRequest;

          DPRINTF(UFSHostDevice, "Write6 offset: 0x%8x, for %d blocks\n",
                  write_offset, write_size);

          /**
           * Renew status check, for the request may have been illegal
           */
          statusCheck(scsi_out.status, scsi_out.senseCode);
          scsi_out.senseSize = scsi_out.senseCode[0];
          scsi_out.status = (scsi_out.status == SCSIGood) ? SCSIGood :
              SCSICheckCondition;

      } break;

      case SCSIWrite10: {
          uint8_t* tempptr = reinterpret_cast<uint8_t*>(&SCSI_msg[4]);

          /**BE and not nicely aligned.*/
          uint32_t tmp = *reinterpret_cast<uint32_t*>(&tempptr[2]);
          uint64_t write_offset = betoh(tmp);

          uint16_t tmpsize = *reinterpret_cast<uint16_t*>(&tempptr[7]);
          uint32_t write_size = betoh(tmpsize);

          scsi_out.msgSize =  write_size * blkSize;
          scsi_out.offset = write_offset * blkSize;
          scsi_out.expectMore = 0x01;

          if ((write_offset + write_size) > diskSize)
              scsi_out.status = SCSIIllegalRequest;

          DPRINTF(UFSHostDevice, "Write10 offset: 0x%8x, for %d blocks\n",
                  write_offset, write_size);

          /**
           * Renew status check, for the request may have been illegal
           */
          statusCheck(scsi_out.status, scsi_out.senseCode);
          scsi_out.senseSize = scsi_out.senseCode[0];
          scsi_out.status = (scsi_out.status == SCSIGood) ? SCSIGood :
              SCSICheckCondition;

      } break;

      case SCSIWrite16: {
          uint8_t* tempptr = reinterpret_cast<uint8_t*>(&SCSI_msg[4]);

          /**BE and not nicely aligned.*/
          uint32_t tmp = *reinterpret_cast<uint32_t*>(&tempptr[2]);
          uint64_t write_offset = betoh(tmp);

          tmp = *reinterpret_cast<uint32_t*>(&tempptr[6]);
          write_offset = (write_offset << 32) | betoh(tmp);

          tmp = *reinterpret_cast<uint32_t*>(&tempptr[10]);
          uint32_t write_size = betoh(tmp);

          scsi_out.msgSize = write_size * blkSize;
          scsi_out.offset = write_offset * blkSize;
          scsi_out.expectMore = 0x01;

          if ((write_offset + write_size) > diskSize)
              scsi_out.status = SCSIIllegalRequest;

          DPRINTF(UFSHostDevice, "Write16 offset: 0x%8x, for %d blocks\n",
                  write_offset, write_size);

          /**
           * Renew status check, for the request may have been illegal
           */
          statusCheck(scsi_out.status, scsi_out.senseCode);
          scsi_out.senseSize = scsi_out.senseCode[0];
          scsi_out.status = (scsi_out.status == SCSIGood) ? SCSIGood :
              SCSICheckCondition;

      } break;

      case SCSIFormatUnit: {//not yet verified
          scsi_out.msgSize = 0;
          scsi_out.expectMore = 0x01;

      } break;

      case SCSISendDiagnostic: {//not yet verified
          scsi_out.msgSize = 0;

      } break;

      case SCSISynchronizeCache: {
          //do we have cache (we don't have cache at this moment)
          //TODO: here will synchronization happen when cache is modelled
          scsi_out.msgSize = 0;

      } break;

        //UFS SCSI additional command set for full functionality
      case SCSIModeSelect10:
        //TODO:
        //scsi_out.expectMore = 0x01;//not supported due to modepage support
        //code isn't dead, code suggest what is to be done when implemented
        break;

      case SCSIModeSense6: case SCSIModeSense10: {
          /**
           * Get more discriptive information about the SCSI functionality
           * within this logic unit.
           */
          if ((SCSI_msg[4] & 0x3F0000) >> 16 == 0x0A) {//control page
              scsi_out.message.dataMsg.resize((sizeof(controlPage) >> 2) + 2);
              scsi_out.message.dataMsg[0] = 0x00000A00;//control page code
              scsi_out.message.dataMsg[1] = 0x00000000;//See JEDEC220 ch8

              for (uint8_t count = 0; count < 3; count++)
                  scsi_out.message.dataMsg[2 + count] = controlPage[count];

              scsi_out.msgSize = 20;
              DPRINTF(UFSHostDevice, "CONTROL page\n");

          } else if ((SCSI_msg[4] & 0x3F0000) >> 16 == 0x01) {//recovery page
              scsi_out.message.dataMsg.resize((sizeof(recoveryPage) >> 2)
                                              + 2);

              scsi_out.message.dataMsg[0] = 0x00000100;//recovery page code
              scsi_out.message.dataMsg[1] = 0x00000000;//See JEDEC220 ch8

              for (uint8_t count = 0; count < 3; count++)
                  scsi_out.message.dataMsg[2 + count] = recoveryPage[count];

              scsi_out.msgSize = 20;
              DPRINTF(UFSHostDevice, "RECOVERY page\n");

          } else if ((SCSI_msg[4] & 0x3F0000) >> 16 == 0x08) {//caching page

              scsi_out.message.dataMsg.resize((sizeof(cachingPage) >> 2) + 2);
              scsi_out.message.dataMsg[0] = 0x00001200;//caching page code
              scsi_out.message.dataMsg[1] = 0x00000000;//See JEDEC220 ch8

              for (uint8_t count = 0; count < 5; count++)
                  scsi_out.message.dataMsg[2 + count] = cachingPage[count];

              scsi_out.msgSize = 20;
              DPRINTF(UFSHostDevice, "CACHE page\n");

          } else if ((SCSI_msg[4] & 0x3F0000) >> 16 == 0x3F) {//ALL the pages!

              scsi_out.message.dataMsg.resize(((sizeof(controlPage) +
                                                sizeof(recoveryPage) +
                                                sizeof(cachingPage)) >> 2)
                                              + 2);
              scsi_out.message.dataMsg[0] = 0x00003200;//all page code
              scsi_out.message.dataMsg[1] = 0x00000000;//See JEDEC220 ch8

              for (uint8_t count = 0; count < 3; count++)
                  scsi_out.message.dataMsg[2 + count] = recoveryPage[count];

              for (uint8_t count = 0; count < 5; count++)
                  scsi_out.message.dataMsg[5 + count] = cachingPage[count];

              for (uint8_t count = 0; count < 3; count++)
                  scsi_out.message.dataMsg[10 + count] = controlPage[count];

              scsi_out.msgSize = 52;
              DPRINTF(UFSHostDevice, "Return ALL the pages!!!\n");

          } else inform("Wrong mode page requested\n");

          scsi_out.message.dataCount = scsi_out.msgSize << 24;
      } break;

      case SCSIRequestSense: {
          scsi_out.msgSize = 0;

      } break;

      case SCSIUnmap:break;//not yet verified

      case SCSIWriteBuffer: {
          scsi_out.expectMore = 0x01;

          uint8_t* tempptr = reinterpret_cast<uint8_t*>(&SCSI_msg[4]);

          /**BE and not nicely aligned.*/
          uint32_t tmp = *reinterpret_cast<uint32_t*>(&tempptr[2]);
          uint64_t write_offset = betoh(tmp) & 0xFFFFFF;

          tmp = *reinterpret_cast<uint32_t*>(&tempptr[5]);
          uint32_t write_size = betoh(tmp) & 0xFFFFFF;

          scsi_out.msgSize =  write_size;
          scsi_out.offset = write_offset;

      } break;

      case SCSIReadBuffer: {
          /**
           * less trivial than normal read. Size is in bytes instead
           * of blocks, and it is assumed (though not guaranteed) that
           * reading is from cache.
           */
          scsi_out.expectMore = 0x02;

          uint8_t* tempptr = reinterpret_cast<uint8_t*>(&SCSI_msg[4]);

          /**BE and not nicely aligned.*/
          uint32_t tmp = *reinterpret_cast<uint32_t*>(&tempptr[2]);
          uint64_t read_offset = betoh(tmp) & 0xFFFFFF;

          tmp = *reinterpret_cast<uint32_t*>(&tempptr[5]);
          uint32_t read_size = betoh(tmp) & 0xFFFFFF;

          scsi_out.msgSize = read_size;
          scsi_out.offset = read_offset;

          if ((read_offset + read_size) > capacityLower * blkSize)
              scsi_out.status = SCSIIllegalRequest;

          DPRINTF(UFSHostDevice, "Read buffer location: 0x%8x\n",
                  read_offset);
          DPRINTF(UFSHostDevice, "Number of bytes: 0x%8x\n", read_size);

          statusCheck(scsi_out.status, scsi_out.senseCode);
          scsi_out.senseSize = scsi_out.senseCode[0];
          scsi_out.status = (scsi_out.status == SCSIGood) ? SCSIGood :
              SCSICheckCondition;

      } break;

      case SCSIMaintenanceIn: {
          /**
           * linux sends this command three times from kernel 3.9 onwards,
           * UFS does not support it, nor does this model. Linux knows this,
           * but tries anyway (useful for some SD card types).
           * Lets make clear we don't want it and just ignore it.
           */
          DPRINTF(UFSHostDevice, "Ignoring Maintenance In command\n");
          statusCheck(SCSIIllegalRequest, scsi_out.senseCode);
          scsi_out.senseSize = scsi_out.senseCode[0];
          scsi_out.status = (scsi_out.status == SCSIGood) ? SCSIGood :
              SCSICheckCondition;
          scsi_out.msgSize = 0;
      } break;

      default: {
          statusCheck(SCSIIllegalRequest, scsi_out.senseCode);
          scsi_out.senseSize = scsi_out.senseCode[0];
          scsi_out.status = (scsi_out.status == SCSIGood) ? SCSIGood :
              SCSICheckCondition;
          scsi_out.msgSize = 0;
          inform("Unsupported scsi message type: %2x\n", SCSI_msg[4] & 0xFF);
          inform("0x%8x\n", SCSI_msg[0]);
          inform("0x%8x\n", SCSI_msg[1]);
          inform("0x%8x\n", SCSI_msg[2]);
          inform("0x%8x\n", SCSI_msg[3]);
          inform("0x%8x\n", SCSI_msg[4]);
      } break;
    }

    return scsi_out;
}

/**
 * SCSI status check function. generic device test, creates sense codes
 * Future versions may include TODO: device checks, which is why this is
 * in a separate function.
 */

void
UFSHostDevice::UFSSCSIDevice::statusCheck(uint8_t status,
                                uint8_t* sensecodelist)
{
    for (uint8_t count = 0; count < 19; count++)
        sensecodelist[count] = 0;

    sensecodelist[0] = 18; //sense length
    sensecodelist[1] = 0x70; //we send a valid frame
    sensecodelist[3] = status & 0xF; //mask to be sure + sensecode
    sensecodelist[8] = 0x1F; //data length
}

/**
 * read from the flashdisk
 */

void
UFSHostDevice::UFSSCSIDevice::readFlash(uint8_t* readaddr, uint64_t offset,
                                   uint32_t size)
{
    /** read from image, and get to memory */
    for (int count = 0; count < (size / SectorSize); count++)
        flashDisk->read(&(readaddr[SectorSize*count]), (offset /
                                                        SectorSize) + count);
}

/**
 * Write to the flashdisk
 */

void
UFSHostDevice::UFSSCSIDevice::writeFlash(uint8_t* writeaddr, uint64_t offset,
                                    uint32_t size)
{
    /** Get from fifo and write to image*/
    for (int count = 0; count < (size / SectorSize); count++)
        flashDisk->write(&(writeaddr[SectorSize * count]),
                         (offset / SectorSize) + count);
}

/**
 * Constructor for the UFS Host device
 */

UFSHostDevice::UFSHostDevice(const UFSHostDeviceParams* p) :
    DmaDevice(p),
    pioAddr(p->pio_addr),
    pioSize(0x0FFF),
    pioDelay(p->pio_latency),
    intNum(p->int_num),
    gic(p->gic),
    lunAvail(p->image.size()),
    UFSSlots(p->ufs_slots - 1),
    readPendingNum(0),
    writePendingNum(0),
    activeDoorbells(0),
    pendingDoorbells(0),
    countInt(0),
    transferTrack(0),
    taskCommandTrack(0),
    idlePhaseStart(0),
    SCSIResumeEvent([this]{ SCSIStart(); }, name()),
    UTPEvent([this]{ finalUTP(); }, name())
{
    DPRINTF(UFSHostDevice, "The hostcontroller hosts %d Logic units\n",
            lunAvail);
    UFSDevice.resize(lunAvail);

    transferDoneCallback = new MakeCallback<UFSHostDevice,
        &UFSHostDevice::LUNSignal>(this);
    memReadCallback = new MakeCallback<UFSHostDevice,
        &UFSHostDevice::readCallback>(this);

    for (int count = 0; count < lunAvail; count++) {
        UFSDevice[count] = new UFSSCSIDevice(p, count, transferDoneCallback,
                                             memReadCallback);
    }

    if (UFSSlots > 31)
        warn("UFSSlots = %d, this will results in %d command slots",
             UFSSlots, (UFSSlots & 0x1F));

    if ((UFSSlots & 0x1F) == 0)
        fatal("Number of UFS command slots should be between 1 and 32.");

    setValues();
}

/**
 * Create the parameters of this device
 */

UFSHostDevice*
UFSHostDeviceParams::create()
{
    return new UFSHostDevice(this);
}


void
UFSHostDevice::regStats()
{
    DmaDevice::regStats();

    using namespace Stats;

    std::string UFSHost_name = name() + ".UFSDiskHost";

    // Register the stats
    /** Queue lengths */
    stats.currentSCSIQueue
        .name(UFSHost_name + ".currentSCSIQueue")
        .desc("Most up to date length of the command queue")
        .flags(none);
    stats.currentReadSSDQueue
        .name(UFSHost_name + ".currentReadSSDQueue")
        .desc("Most up to date length of the read SSD queue")
        .flags(none);
    stats.currentWriteSSDQueue
        .name(UFSHost_name + ".currentWriteSSDQueue")
        .desc("Most up to date length of the write SSD queue")
        .flags(none);

    /** Amount of data read/written */
    stats.totalReadSSD
        .name(UFSHost_name + ".totalReadSSD")
        .desc("Number of bytes read from SSD")
        .flags(none);

    stats.totalWrittenSSD
        .name(UFSHost_name + ".totalWrittenSSD")
        .desc("Number of bytes written to SSD")
        .flags(none);

    stats.totalReadDiskTransactions
        .name(UFSHost_name + ".totalReadDiskTransactions")
        .desc("Number of transactions from disk")
        .flags(none);
    stats.totalWriteDiskTransactions
        .name(UFSHost_name + ".totalWriteDiskTransactions")
        .desc("Number of transactions to disk")
        .flags(none);
    stats.totalReadUFSTransactions
        .name(UFSHost_name + ".totalReadUFSTransactions")
        .desc("Number of transactions from device")
        .flags(none);
    stats.totalWriteUFSTransactions
        .name(UFSHost_name + ".totalWriteUFSTransactions")
        .desc("Number of transactions to device")
        .flags(none);

    /** Average bandwidth for reads and writes */
    stats.averageReadSSDBW
        .name(UFSHost_name + ".averageReadSSDBandwidth")
        .desc("Average read bandwidth (bytes/s)")
        .flags(nozero);

    stats.averageReadSSDBW = stats.totalReadSSD / simSeconds;

    stats.averageWriteSSDBW
        .name(UFSHost_name + ".averageWriteSSDBandwidth")
        .desc("Average write bandwidth (bytes/s)")
        .flags(nozero);

    stats.averageWriteSSDBW = stats.totalWrittenSSD / simSeconds;

    stats.averageSCSIQueue
        .name(UFSHost_name + ".averageSCSIQueueLength")
        .desc("Average command queue length")
        .flags(nozero);
    stats.averageReadSSDQueue
        .name(UFSHost_name + ".averageReadSSDQueueLength")
        .desc("Average read queue length")
        .flags(nozero);
    stats.averageWriteSSDQueue
        .name(UFSHost_name + ".averageWriteSSDQueueLength")
        .desc("Average write queue length")
        .flags(nozero);

    /** Number of doorbells rung*/
    stats.curDoorbell
        .name(UFSHost_name + ".curDoorbell")
        .desc("Most up to date number of doorbells used")
        .flags(none);

    stats.curDoorbell = activeDoorbells;

    stats.maxDoorbell
        .name(UFSHost_name + ".maxDoorbell")
        .desc("Maximum number of doorbells utilized")
        .flags(none);
    stats.averageDoorbell
        .name(UFSHost_name + ".averageDoorbell")
        .desc("Average number of Doorbells used")
        .flags(nozero);

    /** Latency*/
    stats.transactionLatency
        .init(100)
        .name(UFSHost_name + ".transactionLatency")
        .desc("Histogram of transaction times")
        .flags(pdf);

    stats.idleTimes
        .init(100)
        .name(UFSHost_name + ".idlePeriods")
        .desc("Histogram of idle times")
        .flags(pdf);

}

/**
 * Register init
 */
void UFSHostDevice::setValues()
{
    /**
     * The capability register is built up as follows:
     * 31-29 RES; Testmode support; O3 delivery; 64 bit addr;
     * 23-19 RES; 18-16 #TM Req slots; 15-5 RES;4-0 # TR slots
     */
    UFSHCIMem.HCCAP = 0x06070000 | (UFSSlots & 0x1F);
    UFSHCIMem.HCversion = 0x00010000; //version is 1.0
    UFSHCIMem.HCHCDDID = 0xAA003C3C;// Arbitrary number
    UFSHCIMem.HCHCPMID = 0x41524D48; //ARMH (not an official MIPI number)
    UFSHCIMem.TRUTRLDBR = 0x00;
    UFSHCIMem.TMUTMRLDBR = 0x00;
    UFSHCIMem.CMDUICCMDR = 0x00;
    // We can process CMD, TM, TR, device present
    UFSHCIMem.ORHostControllerStatus = 0x08;
    UFSHCIMem.TRUTRLBA = 0x00;
    UFSHCIMem.TRUTRLBAU = 0x00;
    UFSHCIMem.TMUTMRLBA = 0x00;
    UFSHCIMem.TMUTMRLBAU = 0x00;
}

/**
 * Determine address ranges
 */

AddrRangeList
UFSHostDevice::getAddrRanges() const
{
    AddrRangeList ranges;
    ranges.push_back(RangeSize(pioAddr, pioSize));
    return ranges;
}

/**
 * UFSHCD read register. This function allows the system to read the
 * register entries
 */

Tick
UFSHostDevice::read(PacketPtr pkt)
{
    uint32_t data = 0;

    switch (pkt->getAddr() & 0xFF)
    {

      case regControllerCapabilities:
        data = UFSHCIMem.HCCAP;
        break;

      case regUFSVersion:
        data = UFSHCIMem.HCversion;
        break;

      case regControllerDEVID:
        data = UFSHCIMem.HCHCDDID;
        break;

      case regControllerPRODID:
        data = UFSHCIMem.HCHCPMID;
        break;

      case regInterruptStatus:
        data = UFSHCIMem.ORInterruptStatus;
        UFSHCIMem.ORInterruptStatus = 0x00;
        //TODO: Revise and extend
        clearInterrupt();
        break;

      case regInterruptEnable:
        data = UFSHCIMem.ORInterruptEnable;
        break;

      case regControllerStatus:
        data = UFSHCIMem.ORHostControllerStatus;
        break;

      case regControllerEnable:
        data = UFSHCIMem.ORHostControllerEnable;
        break;

      case regUICErrorCodePHYAdapterLayer:
        data = UFSHCIMem.ORUECPA;
        break;

      case regUICErrorCodeDataLinkLayer:
        data = UFSHCIMem.ORUECDL;
        break;

      case regUICErrorCodeNetworkLayer:
        data = UFSHCIMem.ORUECN;
        break;

      case regUICErrorCodeTransportLayer:
        data = UFSHCIMem.ORUECT;
        break;

      case regUICErrorCodeDME:
        data = UFSHCIMem.ORUECDME;
        break;

      case regUTPTransferREQINTAGGControl:
        data = UFSHCIMem.ORUTRIACR;
        break;

      case regUTPTransferREQListBaseL:
        data = UFSHCIMem.TRUTRLBA;
        break;

      case regUTPTransferREQListBaseH:
        data = UFSHCIMem.TRUTRLBAU;
        break;

      case regUTPTransferREQDoorbell:
        data = UFSHCIMem.TRUTRLDBR;
        break;

      case regUTPTransferREQListClear:
        data = UFSHCIMem.TRUTRLCLR;
        break;

      case regUTPTransferREQListRunStop:
        data = UFSHCIMem.TRUTRLRSR;
        break;

      case regUTPTaskREQListBaseL:
        data = UFSHCIMem.TMUTMRLBA;
        break;

      case regUTPTaskREQListBaseH:
        data = UFSHCIMem.TMUTMRLBAU;
        break;

      case regUTPTaskREQDoorbell:
        data = UFSHCIMem.TMUTMRLDBR;
        break;

      case regUTPTaskREQListClear:
        data = UFSHCIMem.TMUTMRLCLR;
        break;

      case regUTPTaskREQListRunStop:
        data = UFSHCIMem.TMUTMRLRSR;
        break;

      case regUICCommand:
        data = UFSHCIMem.CMDUICCMDR;
        break;

      case regUICCommandArg1:
        data = UFSHCIMem.CMDUCMDARG1;
        break;

      case regUICCommandArg2:
        data = UFSHCIMem.CMDUCMDARG2;
        break;

      case regUICCommandArg3:
        data = UFSHCIMem.CMDUCMDARG3;
        break;

      default:
        data = 0x00;
        break;
    }

    pkt->set<uint32_t>(data);
    pkt->makeResponse();
    return pioDelay;
}

/**
 * UFSHCD write function. This function allows access to the writeable
 * registers. If any function attempts to write value to an unwriteable
 * register entry, then the value will not be written.
 */
Tick
UFSHostDevice::write(PacketPtr pkt)
{
    uint32_t data = 0;

    switch (pkt->getSize()) {

      case 1:
        data = pkt->get<uint8_t>();
        break;

      case 2:
        data = pkt->get<uint16_t>();
        break;

      case 4:
        data = pkt->get<uint32_t>();
        break;

      default:
        panic("Undefined UFSHCD controller write size!\n");
        break;
    }

    switch (pkt->getAddr() & 0xFF)
    {
      case regControllerCapabilities://you shall not write to this
        break;

      case regUFSVersion://you shall not write to this
        break;

      case regControllerDEVID://you shall not write to this
        break;

      case regControllerPRODID://you shall not write to this
        break;

      case regInterruptStatus://you shall not write to this
        break;

      case regInterruptEnable:
        UFSHCIMem.ORInterruptEnable = data;
        break;

      case regControllerStatus:
        UFSHCIMem.ORHostControllerStatus = data;
        break;

      case regControllerEnable:
        UFSHCIMem.ORHostControllerEnable = data;
        break;

      case regUICErrorCodePHYAdapterLayer:
        UFSHCIMem.ORUECPA = data;
        break;

      case regUICErrorCodeDataLinkLayer:
        UFSHCIMem.ORUECDL = data;
        break;

      case regUICErrorCodeNetworkLayer:
        UFSHCIMem.ORUECN = data;
        break;

      case regUICErrorCodeTransportLayer:
        UFSHCIMem.ORUECT = data;
        break;

      case regUICErrorCodeDME:
        UFSHCIMem.ORUECDME = data;
        break;

      case regUTPTransferREQINTAGGControl:
        UFSHCIMem.ORUTRIACR = data;
        break;

      case regUTPTransferREQListBaseL:
        UFSHCIMem.TRUTRLBA = data;
        if (((UFSHCIMem.TRUTRLBA | UFSHCIMem.TRUTRLBAU) != 0x00) &&
            ((UFSHCIMem.TMUTMRLBA | UFSHCIMem.TMUTMRLBAU)!= 0x00))
            UFSHCIMem.ORHostControllerStatus |= UICCommandReady;
        break;

      case regUTPTransferREQListBaseH:
        UFSHCIMem.TRUTRLBAU = data;
        if (((UFSHCIMem.TRUTRLBA | UFSHCIMem.TRUTRLBAU) != 0x00) &&
            ((UFSHCIMem.TMUTMRLBA | UFSHCIMem.TMUTMRLBAU) != 0x00))
            UFSHCIMem.ORHostControllerStatus |= UICCommandReady;
        break;

      case regUTPTransferREQDoorbell:
        if (!(UFSHCIMem.TRUTRLDBR) && data)
            stats.idleTimes.sample(curTick() - idlePhaseStart);
        UFSHCIMem.TRUTRLDBR |= data;
        requestHandler();
        break;

      case regUTPTransferREQListClear:
        UFSHCIMem.TRUTRLCLR = data;
        break;

      case regUTPTransferREQListRunStop:
        UFSHCIMem.TRUTRLRSR = data;
        break;

      case regUTPTaskREQListBaseL:
        UFSHCIMem.TMUTMRLBA = data;
        if (((UFSHCIMem.TRUTRLBA | UFSHCIMem.TRUTRLBAU) != 0x00) &&
            ((UFSHCIMem.TMUTMRLBA | UFSHCIMem.TMUTMRLBAU) != 0x00))
            UFSHCIMem.ORHostControllerStatus |= UICCommandReady;
        break;

      case regUTPTaskREQListBaseH:
        UFSHCIMem.TMUTMRLBAU = data;
        if (((UFSHCIMem.TRUTRLBA | UFSHCIMem.TRUTRLBAU) != 0x00) &&
            ((UFSHCIMem.TMUTMRLBA | UFSHCIMem.TMUTMRLBAU) != 0x00))
            UFSHCIMem.ORHostControllerStatus |= UICCommandReady;
        break;

      case regUTPTaskREQDoorbell:
        UFSHCIMem.TMUTMRLDBR |= data;
        requestHandler();
        break;

      case regUTPTaskREQListClear:
        UFSHCIMem.TMUTMRLCLR = data;
        break;

      case regUTPTaskREQListRunStop:
        UFSHCIMem.TMUTMRLRSR = data;
        break;

      case regUICCommand:
        UFSHCIMem.CMDUICCMDR = data;
        requestHandler();
        break;

      case regUICCommandArg1:
        UFSHCIMem.CMDUCMDARG1 = data;
        break;

      case regUICCommandArg2:
        UFSHCIMem.CMDUCMDARG2 = data;
        break;

      case regUICCommandArg3:
        UFSHCIMem.CMDUCMDARG3 = data;
        break;

      default:break;//nothing happens, you try to access a register that
                    //does not exist

    }

    pkt->makeResponse();
    return pioDelay;
}

/**
 * Request handler. Determines where the request comes from and initiates the
 * appropriate actions accordingly.
 */

void
UFSHostDevice::requestHandler()
{
    Addr address = 0x00;
    int mask = 0x01;
    int size;
    int count = 0;
    struct taskStart task_info;
    struct transferStart transferstart_info;
    transferstart_info.done = 0;

    /**
     * step1 determine what called us
     * step2 determine where to get it
     * Look for any request of which we where not yet aware
     */
    while (((UFSHCIMem.CMDUICCMDR > 0x00) |
            ((UFSHCIMem.TMUTMRLDBR ^ taskCommandTrack) > 0x00) |
            ((UFSHCIMem.TRUTRLDBR ^ transferTrack) > 0x00)) ) {

        if (UFSHCIMem.CMDUICCMDR > 0x00) {
            /**
             * Command; general control of the Host controller.
             * no DMA transfer needed
             */
            commandHandler();
            UFSHCIMem.ORInterruptStatus |= UICCommandCOMPL;
            generateInterrupt();
            UFSHCIMem.CMDUICCMDR = 0x00;
            return; //command, nothing more we can do

        } else if ((UFSHCIMem.TMUTMRLDBR ^ taskCommandTrack) > 0x00) {
            /**
             * Task; flow control, meant for the device/Logic unit
             * DMA transfer is needed, flash will not be approached
             */
            size = sizeof(UTPUPIUTaskReq);
            /**Find the position that is not handled yet*/
            count = findLsbSet((UFSHCIMem.TMUTMRLDBR ^ taskCommandTrack));
            address = UFSHCIMem.TMUTMRLBAU;
            //<-64 bit
            address = (count * size) + (address << 32) +
                UFSHCIMem.TMUTMRLBA;
            taskCommandTrack |= mask << count;

            inform("UFSmodel received a task from the system; this might"
                   " lead to untested behaviour.\n");

            task_info.mask = mask << count;
            task_info.address = address;
            task_info.size = size;
            task_info.done = UFSHCIMem.TMUTMRLDBR;
            taskInfo.push_back(task_info);
            taskEventQueue.push_back(
                EventFunctionWrapper([this]{ taskStart(); }, name()));
            writeDevice(&taskEventQueue.back(), false, address, size,
                        reinterpret_cast<uint8_t*>
                        (&taskInfo.back().destination), 0, 0);

        } else if ((UFSHCIMem.TRUTRLDBR ^ transferTrack) > 0x00) {
            /**
             * Transfer; Data transfer from or to the disk. There will be DMA
             * transfers, and the flash might be approached. Further
             * commands, are needed to specify the exact command.
             */
            size = sizeof(UTPTransferReqDesc);
            /**Find the position that is not handled yet*/
            count = findLsbSet((UFSHCIMem.TRUTRLDBR ^ transferTrack));
            address = UFSHCIMem.TRUTRLBAU;
            //<-64 bit
            address = (count * size) + (address << 32) + UFSHCIMem.TRUTRLBA;

            transferTrack |= mask << count;
            DPRINTF(UFSHostDevice, "Doorbell register: 0x%8x select #:"
                    " 0x%8x completion info: 0x%8x\n", UFSHCIMem.TRUTRLDBR,
                    count, transferstart_info.done);

            transferstart_info.done = UFSHCIMem.TRUTRLDBR;

            /**stats**/
            transactionStart[count] = curTick(); //note the start time
            ++activeDoorbells;
            stats.maxDoorbell = (stats.maxDoorbell.value() < activeDoorbells)
                ? activeDoorbells : stats.maxDoorbell.value();
            stats.averageDoorbell = stats.maxDoorbell.value();

            /**
             * step3 start transfer
             * step4 register information; allowing the host to respond in
             * the end
             */
            transferstart_info.mask = mask << count;
            transferstart_info.address = address;
            transferstart_info.size = size;
            transferstart_info.done = UFSHCIMem.TRUTRLDBR;
            transferStartInfo.push_back(transferstart_info);

            /**Deleted in readDone, queued in finalUTP*/
            transferStartInfo.back().destination = new struct
                UTPTransferReqDesc;
            DPRINTF(UFSHostDevice, "Initial transfer start: 0x%8x\n",
                    transferstart_info.done);
            transferEventQueue.push_back(
                EventFunctionWrapper([this]{ transferStart(); }, name()));

            if (transferEventQueue.size() < 2) {
                writeDevice(&transferEventQueue.front(), false,
                            address, size, reinterpret_cast<uint8_t*>
                            (transferStartInfo.front().destination),0, 0);
                DPRINTF(UFSHostDevice, "Transfer scheduled\n");
            }
        }
    }
}

/**
 * Task start event
 */

void
UFSHostDevice::taskStart()
{
    DPRINTF(UFSHostDevice, "Task start");
    taskHandler(&taskInfo.front().destination, taskInfo.front().mask,
                taskInfo.front().address, taskInfo.front().size);
    taskInfo.pop_front();
    taskEventQueue.pop_front();
}

/**
 * Transfer start event
 */

void
UFSHostDevice::transferStart()
{
    DPRINTF(UFSHostDevice, "Enter transfer event\n");
    transferHandler(transferStartInfo.front().destination,
                    transferStartInfo.front().mask,
                    transferStartInfo.front().address,
                    transferStartInfo.front().size,
                    transferStartInfo.front().done);

    transferStartInfo.pop_front();
    DPRINTF(UFSHostDevice, "Transfer queue size at end of event: "
            "0x%8x\n", transferEventQueue.size());
}

/**
 * Handles the commands that are given. At this point in time, not many
 * commands have been implemented in the driver.
 */

void
UFSHostDevice::commandHandler()
{
    if (UFSHCIMem.CMDUICCMDR == 0x16) {
        UFSHCIMem.ORHostControllerStatus |= 0x0F;//link startup
    }

}

/**
 * Handles the tasks that are given. At this point in time, not many tasks
 * have been implemented in the driver.
 */

void
UFSHostDevice::taskHandler(struct UTPUPIUTaskReq* request_in,
                           uint32_t req_pos, Addr finaladdress, uint32_t
                           finalsize)
{
    /**
     * For now, just unpack and acknowledge the task without doing anything.
     * TODO Implement UFS tasks.
     */
    inform("taskHandler\n");
    inform("%8x\n", request_in->header.dWord0);
    inform("%8x\n", request_in->header.dWord1);
    inform("%8x\n", request_in->header.dWord2);

    request_in->header.dWord2 &= 0xffffff00;

    UFSHCIMem.TMUTMRLDBR &= ~(req_pos);
    taskCommandTrack &= ~(req_pos);
    UFSHCIMem.ORInterruptStatus |= UTPTaskREQCOMPL;

    readDevice(true, finaladdress, finalsize, reinterpret_cast<uint8_t*>
               (request_in), true, NULL);

}

/**
 * Obtains the SCSI command (if any)
 * Two possibilities: if it contains a SCSI command, then it is a usable
 * message; if it doesnt contain a SCSI message, then it can't be handeld
 * by this code.
 * This is the second stage of the transfer. We have the information about
 * where the next command can be found and what the type of command is. The
 * actions that are needed from the device its side are: get the information
 * and store the information such that we can reply.
 */

void
UFSHostDevice::transferHandler(struct UTPTransferReqDesc* request_in,
                               int req_pos, Addr finaladdress, uint32_t
                               finalsize, uint32_t done)
{

    Addr cmd_desc_addr = 0x00;


    //acknowledge handling of the message
    DPRINTF(UFSHostDevice, "SCSI message detected\n");
    request_in->header.dWord2 &= 0xffffff00;
    SCSIInfo.RequestIn = request_in;
    SCSIInfo.reqPos = req_pos;
    SCSIInfo.finalAddress = finaladdress;
    SCSIInfo.finalSize = finalsize;
    SCSIInfo.destination.resize(request_in->PRDTableOffset * 4
        + request_in->PRDTableLength * sizeof(UFSHCDSGEntry));
    SCSIInfo.done = done;

    assert(!SCSIResumeEvent.scheduled());
    /**
     *Get the UTP command that has the SCSI command
     */
    cmd_desc_addr = request_in->commandDescBaseAddrHi;
    cmd_desc_addr = (cmd_desc_addr << 32) |
        (request_in->commandDescBaseAddrLo & 0xffffffff);

    writeDevice(&SCSIResumeEvent, false, cmd_desc_addr,
                SCSIInfo.destination.size(), &SCSIInfo.destination[0],0, 0);

    DPRINTF(UFSHostDevice, "SCSI scheduled\n");

    transferEventQueue.pop_front();
}

/**
 * Obtain LUN and put it in the right LUN queue. Each LUN has its own queue
 * of commands that need to be executed. This is the first instance where it
 * can be determined which Logic unit should handle the transfer. Then check
 * wether it should wait and queue or if it can continue.
 */

void
UFSHostDevice::SCSIStart()
{
    DPRINTF(UFSHostDevice, "SCSI message on hold until ready\n");
    uint32_t LUN = SCSIInfo.destination[2];
    UFSDevice[LUN]->SCSIInfoQueue.push_back(SCSIInfo);

    DPRINTF(UFSHostDevice, "SCSI queue %d has %d elements\n", LUN,
            UFSDevice[LUN]->SCSIInfoQueue.size());

    /**There are 32 doorbells, so at max there can be 32 transactions*/
    if (UFSDevice[LUN]->SCSIInfoQueue.size() < 2) //LUN is available
        SCSIResume(LUN);

    else if (UFSDevice[LUN]->SCSIInfoQueue.size() > 32)
        panic("SCSI queue is getting too big %d\n", UFSDevice[LUN]->
              SCSIInfoQueue.size());

    /**
     * First transfer is done, fetch the next;
     * At this point, the device is busy, not the HC
     */
    if (!transferEventQueue.empty()) {

        /**
         * loading next data packet in case Another LUN
         * is approached in the mean time
         */
        writeDevice(&transferEventQueue.front(), false,
                    transferStartInfo.front().address,
                    transferStartInfo.front().size, reinterpret_cast<uint8_t*>
                    (transferStartInfo.front().destination), 0, 0);

        DPRINTF(UFSHostDevice, "Transfer scheduled");
    }
}

/**
 * Handles the transfer requests that are given.
 * There can be three types of transfer. SCSI specific, Reads and writes
 * apart from the data transfer, this also generates its own reply (UPIU
 * response). Information for this reply is stored in transferInfo and will
 * be used in transferDone
 */

void
UFSHostDevice::SCSIResume(uint32_t lun_id)
{
    DPRINTF(UFSHostDevice, "SCSIresume\n");
    if (UFSDevice[lun_id]->SCSIInfoQueue.empty())
        panic("No SCSI message scheduled lun:%d Doorbell: 0x%8x", lun_id,
              UFSHCIMem.TRUTRLDBR);

    /**old info, lets form it such that we can understand it*/
    struct UTPTransferReqDesc* request_in = UFSDevice[lun_id]->
        SCSIInfoQueue.front().RequestIn;

    uint32_t req_pos = UFSDevice[lun_id]->SCSIInfoQueue.front().reqPos;

    Addr finaladdress = UFSDevice[lun_id]->SCSIInfoQueue.front().
        finalAddress;

    uint32_t finalsize = UFSDevice[lun_id]->SCSIInfoQueue.front().finalSize;

    uint32_t* transfercommand = reinterpret_cast<uint32_t*>
        (&(UFSDevice[lun_id]->SCSIInfoQueue.front().destination[0]));

    DPRINTF(UFSHostDevice, "Task tag: 0x%8x\n", transfercommand[0]>>24);
    /**call logic unit to handle SCSI command*/
    request_out_datain = UFSDevice[(transfercommand[0] & 0xFF0000) >> 16]->
        SCSICMDHandle(transfercommand);

    DPRINTF(UFSHostDevice, "LUN: %d\n", request_out_datain.LUN);

    /**
     * build response stating that it was succesful
     * command completion, Logic unit number, and Task tag
     */
    request_in->header.dWord0 = ((request_in->header.dWord0 >> 24) == 0x21)
        ? 0x36 : 0x21;
    UFSDevice[lun_id]->transferInfo.requestOut.header.dWord0 =
        request_in->header.dWord0 | (request_out_datain.LUN << 8)
        | (transfercommand[0] & 0xFF000000);
    /**SCSI status reply*/
    UFSDevice[lun_id]->transferInfo.requestOut.header.dWord1 = 0x00000000 |
        (request_out_datain.status << 24);
    /**segment size + EHS length (see UFS standard ch7)*/
    UFSDevice[lun_id]->transferInfo.requestOut.header.dWord2 = 0x00000000 |
        ((request_out_datain.senseSize + 2) << 24) | 0x05;
    /**amount of data that will follow*/
    UFSDevice[lun_id]->transferInfo.requestOut.senseDataLen =
        request_out_datain.senseSize;

    //data
    for (uint8_t count = 0; count<request_out_datain.senseSize; count++) {
        UFSDevice[lun_id]->transferInfo.requestOut.senseData[count] =
            request_out_datain.senseCode[count + 1];
    }

    /*
     * At position defined by "request_in->PRDTableOffset" (counting 32 bit
     * words) in array "transfercommand" we have a scatter gather list, which
     * is usefull to us if we interpreted it as a UFSHCDSGEntry structure.
     */
    struct UFSHCDSGEntry* sglist =  reinterpret_cast<UFSHCDSGEntry*>
        (&(transfercommand[(request_in->PRDTableOffset)]));

    uint32_t length = request_in->PRDTableLength;
    DPRINTF(UFSHostDevice, "# PRDT entries: %d\n", length);

    Addr response_addr = request_in->commandDescBaseAddrHi;
    response_addr = (response_addr << 32) |
        ((request_in->commandDescBaseAddrLo +
          (request_in->responseUPIULength << 2)) & 0xffffffff);

    /**transferdone information packet filling*/
    UFSDevice[lun_id]->transferInfo.responseStartAddr = response_addr;
    UFSDevice[lun_id]->transferInfo.reqPos = req_pos;
    UFSDevice[lun_id]->transferInfo.size = finalsize;
    UFSDevice[lun_id]->transferInfo.address = finaladdress;
    UFSDevice[lun_id]->transferInfo.destination = reinterpret_cast<uint8_t*>
        (UFSDevice[lun_id]->SCSIInfoQueue.front().RequestIn);
    UFSDevice[lun_id]->transferInfo.finished = true;
    UFSDevice[lun_id]->transferInfo.lunID = request_out_datain.LUN;

    /**
     * In this part the data that needs to be transfered will be initiated
     * and the chain of DMA (and potentially) disk transactions will be
     * started.
     */
    if (request_out_datain.expectMore == 0x01) {
        /**write transfer*/
        manageWriteTransfer(request_out_datain.LUN, request_out_datain.offset,
                            length, sglist);

    } else if (request_out_datain.expectMore == 0x02) {
        /**read transfer*/
        manageReadTransfer(request_out_datain.msgSize, request_out_datain.LUN,
                           request_out_datain.offset, length, sglist);

    } else {
        /**not disk related transfer, SCSI maintanance*/
        uint32_t count = 0;
        uint32_t size_accum = 0;
        DPRINTF(UFSHostDevice, "Data DMA size: 0x%8x\n",
                request_out_datain.msgSize);

        /**Transport the SCSI reponse data according to the SG list*/
        while ((length > count) && size_accum
               < (request_out_datain.msgSize - 1) &&
               (request_out_datain.msgSize != 0x00)) {
            Addr SCSI_start = sglist[count].upperAddr;
            SCSI_start = (SCSI_start << 32) |
                (sglist[count].baseAddr & 0xFFFFFFFF);
            DPRINTF(UFSHostDevice, "Data DMA start: 0x%8x\n", SCSI_start);
            DPRINTF(UFSHostDevice, "Data DMA size: 0x%8x\n",
                    (sglist[count].size + 1));
            /**
             * safetynet; it has been shown that sg list may be optimistic in
             * the amount of data allocated, which can potentially lead to
             * some garbage data being send over. Hence this construction
             * that finds the least amount of data that needs to be
             * transfered.
             */
            uint32_t size_to_send = sglist[count].size + 1;

            if (request_out_datain.msgSize < (size_to_send + size_accum))
                size_to_send = request_out_datain.msgSize - size_accum;

            readDevice(false, SCSI_start, size_to_send,
                       reinterpret_cast<uint8_t*>
                       (&(request_out_datain.message.dataMsg[size_accum])),
                       false, NULL);

            size_accum += size_to_send;
            DPRINTF(UFSHostDevice, "Total remaining: 0x%8x,accumulated so far"
                    " : 0x%8x\n", (request_out_datain.msgSize - size_accum),
                    size_accum);

            ++count;
            DPRINTF(UFSHostDevice, "Transfer #: %d\n", count);
        }

        /**Go to the next stage of the answering process*/
        transferDone(response_addr, req_pos, UFSDevice[lun_id]->
                     transferInfo.requestOut, finalsize, finaladdress,
                     reinterpret_cast<uint8_t*>(request_in), true, lun_id);
    }

    DPRINTF(UFSHostDevice, "SCSI resume done\n");
}

/**
 * Find finished transfer. Callback function. One of the LUNs is done with
 * the disk transfer and reports back to the controller. This function finds
 * out who it was, and calls transferDone.
 */
void
UFSHostDevice::LUNSignal()
{
    uint8_t this_lun = 0;

    //while we haven't found the right lun, keep searching
    while ((this_lun < lunAvail) && !UFSDevice[this_lun]->finishedCommand())
        ++this_lun;

    if (this_lun < lunAvail) {
        //Clear signal.
        UFSDevice[this_lun]->clearSignal();
        //found it; call transferDone
        transferDone(UFSDevice[this_lun]->transferInfo.responseStartAddr,
                     UFSDevice[this_lun]->transferInfo.reqPos,
                     UFSDevice[this_lun]->transferInfo.requestOut,
                     UFSDevice[this_lun]->transferInfo.size,
                     UFSDevice[this_lun]->transferInfo.address,
                     UFSDevice[this_lun]->transferInfo.destination,
                     UFSDevice[this_lun]->transferInfo.finished,
                     UFSDevice[this_lun]->transferInfo.lunID);
    }

    else
        panic("no LUN finished in tick %d\n", curTick());
}

/**
 * Transfer done. When the data transfer is done, this function ensures
 * that the application is notified.
 */

void
UFSHostDevice::transferDone(Addr responseStartAddr, uint32_t req_pos,
                            struct UTPUPIURSP request_out, uint32_t size,
                            Addr address, uint8_t* destination,
                            bool finished, uint32_t lun_id)
{
    /**Test whether SCSI queue hasn't popped prematurely*/
    if (UFSDevice[lun_id]->SCSIInfoQueue.empty())
        panic("No SCSI message scheduled lun:%d Doorbell: 0x%8x", lun_id,
              UFSHCIMem.TRUTRLDBR);

    DPRINTF(UFSHostDevice, "DMA start: 0x%8x; DMA size: 0x%8x\n",
            responseStartAddr, sizeof(request_out));

    struct transferStart lastinfo;
    lastinfo.mask = req_pos;
    lastinfo.done = finished;
    lastinfo.address = address;
    lastinfo.size = size;
    lastinfo.destination = reinterpret_cast<UTPTransferReqDesc*>
        (destination);
    lastinfo.lun_id = lun_id;

    transferEnd.push_back(lastinfo);

    DPRINTF(UFSHostDevice, "Transfer done start\n");

    readDevice(false, responseStartAddr, sizeof(request_out),
               reinterpret_cast<uint8_t*>
               (&(UFSDevice[lun_id]->transferInfo.requestOut)),
               true, &UTPEvent);
}

/**
 * finalUTP. Second part of the transfer done event.
 * this sends the final response: the UTP response. After this transaction
 * the doorbell shall be cleared, and the interupt shall be set.
 */

void
UFSHostDevice::finalUTP()
{
    uint32_t lun_id = transferEnd.front().lun_id;

    UFSDevice[lun_id]->SCSIInfoQueue.pop_front();
    DPRINTF(UFSHostDevice, "SCSIInfoQueue size: %d, lun: %d\n",
            UFSDevice[lun_id]->SCSIInfoQueue.size(), lun_id);

    /**stats**/
    if (UFSHCIMem.TRUTRLDBR & transferEnd.front().mask) {
        uint8_t count = 0;
        while (!(transferEnd.front().mask & (0x1 << count)))
            ++count;
        stats.transactionLatency.sample(curTick() -
                                        transactionStart[count]);
    }

    /**Last message that will be transfered*/
    readDevice(true, transferEnd.front().address,
               transferEnd.front().size, reinterpret_cast<uint8_t*>
               (transferEnd.front().destination), true, NULL);

    /**clean and ensure that the tracker is updated*/
    transferTrack &= ~(transferEnd.front().mask);
    --activeDoorbells;
    ++pendingDoorbells;
    garbage.push_back(transferEnd.front().destination);
    transferEnd.pop_front();
    DPRINTF(UFSHostDevice, "UTP handled\n");

    /**stats**/
    stats.averageDoorbell = stats.maxDoorbell.value();

    DPRINTF(UFSHostDevice, "activeDoorbells: %d, pendingDoorbells: %d,"
            " garbage: %d, TransferEvent: %d\n", activeDoorbells,
            pendingDoorbells, garbage.size(), transferEventQueue.size());

    /**This is the moment that the device is available again*/
    if (!UFSDevice[lun_id]->SCSIInfoQueue.empty())
        SCSIResume(lun_id);
}

/**
 * Read done handling function, is only initiated at the end of a transaction
 */
void
UFSHostDevice::readDone()
{
    DPRINTF(UFSHostDevice, "Read done start\n");
    --readPendingNum;

    /**Garbage collection; sort out the allocated UTP descriptor*/
    if (garbage.size() > 0) {
        delete garbage.front();
        garbage.pop_front();
        }

    /**done, generate interrupt if we havent got one already*/
    if (!(UFSHCIMem.ORInterruptStatus & 0x01)) {
        UFSHCIMem.ORInterruptStatus |= UTPTransferREQCOMPL;
        generateInterrupt();
    }


    if (!readDoneEvent.empty()) {
        readDoneEvent.pop_front();
    }
}

/**
 * set interrupt and sort out the doorbell register.
 */

void
UFSHostDevice::generateInterrupt()
{
    /**just to keep track of the transactions*/
    countInt++;

    /**step5 clear doorbell*/
    UFSHCIMem.TRUTRLDBR &= transferTrack;
    pendingDoorbells = 0;
    DPRINTF(UFSHostDevice, "Clear doorbell %X\n", UFSHCIMem.TRUTRLDBR);

    checkDrain();

    /**step6 raise interrupt*/
    gic->sendInt(intNum);
    DPRINTF(UFSHostDevice, "Send interrupt @ transaction: 0x%8x!\n",
            countInt);
}

/**
 * Clear interrupt
 */

void
UFSHostDevice::clearInterrupt()
{
    gic->clearInt(intNum);
    DPRINTF(UFSHostDevice, "Clear interrupt: 0x%8x!\n", countInt);

    checkDrain();

    if (!(UFSHCIMem.TRUTRLDBR)) {
        idlePhaseStart = curTick();
    }
    /**end of a transaction*/
}

/**
 * Important to understand about the transfer flow:
 * We have basically three stages, The "system memory" stage, the "device
 * buffer" stage and the "disk" stage. In this model we assume an infinite
 * buffer, or a buffer that is big enough to store all the data in the
 * biggest transaction. Between the three stages are two queues. Those queues
 * store the messages to simulate their transaction from one stage to the
 * next. The manage{Action} function fills up one of the queues and triggers
 * the first event, which causes a chain reaction of events executed once
 * they pass through their queues. For a write action the stages are ordered
 * "system memory", "device buffer" and "disk", whereas the read transfers
 * happen "disk", "device buffer" and "system memory". The dma action in the
 * dma device is written from a bus perspective whereas this model is written
 * from a device perspective. To avoid confusion, the translation between the
 * two has been made in the writeDevice and readDevice funtions.
 */


/**
 * Dma transaction function: write device. Note that the dma action is
 * from a device perspective, while this function is from an initiator
 * perspective
 */

void
UFSHostDevice::writeDevice(Event* additional_action, bool toDisk, Addr
                           start, int size, uint8_t* destination, uint64_t
                           SCSIDiskOffset, uint32_t lun_id)
{
    DPRINTF(UFSHostDevice, "Write transaction Start: 0x%8x; Size: %d\n",
            start, size);

    /**check whether transfer is all the way to the flash*/
    if (toDisk) {
        ++writePendingNum;

        while (!writeDoneEvent.empty() && (writeDoneEvent.front().when()
                                          < curTick()))
            writeDoneEvent.pop_front();

        writeDoneEvent.push_back(
            EventFunctionWrapper([this]{ writeDone(); },
                                 name()));
        assert(!writeDoneEvent.back().scheduled());

        /**destination is an offset here since we are writing to a disk*/
        struct transferInfo new_transfer;
        new_transfer.offset = SCSIDiskOffset;
        new_transfer.size = size;
        new_transfer.lunID = lun_id;
        new_transfer.filePointer = 0;
        SSDWriteinfo.push_back(new_transfer);

        /**allocate appropriate buffer*/
        SSDWriteinfo.back().buffer.resize(size);

        /**transaction*/
        dmaPort.dmaAction(MemCmd::ReadReq, start, size,
                          &writeDoneEvent.back(),
                          &SSDWriteinfo.back().buffer[0], 0);
        //yes, a readreq at a write device function is correct.
        DPRINTF(UFSHostDevice, "Write to disk scheduled\n");

    } else {
        assert(!additional_action->scheduled());
        dmaPort.dmaAction(MemCmd::ReadReq, start, size,
                          additional_action, destination, 0);
        DPRINTF(UFSHostDevice, "Write scheduled\n");
    }
}

/**
 * Manage write transfer. Manages correct transfer flow and makes sure that
 * the queues are filled on time
 */

void
UFSHostDevice::manageWriteTransfer(uint8_t LUN, uint64_t offset, uint32_t
                                   sg_table_length, struct UFSHCDSGEntry*
                                   sglist)
{
    struct writeToDiskBurst next_packet;

    next_packet.SCSIDiskOffset = offset;

    UFSDevice[LUN]->setTotalWrite(sg_table_length);

    /**
     * Break-up the transactions into actions defined by the scatter gather
     * list.
     */
    for (uint32_t count = 0; count < sg_table_length; count++) {
        next_packet.start = sglist[count].upperAddr;
        next_packet.start = (next_packet.start << 32) |
            (sglist[count].baseAddr & 0xFFFFFFFF);
        next_packet.LUN = LUN;
        DPRINTF(UFSHostDevice, "Write data DMA start: 0x%8x\n",
                next_packet.start);
        DPRINTF(UFSHostDevice, "Write data DMA size: 0x%8x\n",
                (sglist[count].size + 1));
        assert(sglist[count].size > 0);

        if (count != 0)
            next_packet.SCSIDiskOffset = next_packet.SCSIDiskOffset +
                (sglist[count - 1].size + 1);

        next_packet.size = sglist[count].size + 1;

        /**If the queue is empty, the transaction should be initiated*/
        if (dmaWriteInfo.empty())
            writeDevice(NULL, true, next_packet.start, next_packet.size,
                        NULL, next_packet.SCSIDiskOffset, next_packet.LUN);
        else
            DPRINTF(UFSHostDevice, "Write not initiated queue: %d\n",
                    dmaWriteInfo.size());

        dmaWriteInfo.push_back(next_packet);
        DPRINTF(UFSHostDevice, "Write Location: 0x%8x\n",
                next_packet.SCSIDiskOffset);

        DPRINTF(UFSHostDevice, "Write transfer #: 0x%8x\n", count + 1);

        /** stats **/
        stats.totalWrittenSSD += (sglist[count].size + 1);
    }

    /**stats**/
    ++stats.totalWriteUFSTransactions;
}

/**
 * Write done handling function. Is only initiated when the flash is directly
 * approached
 */

void
UFSHostDevice::writeDone()
{
    /**DMA is done, information no longer needed*/
    assert(dmaWriteInfo.size() > 0);
    dmaWriteInfo.pop_front();
    assert(SSDWriteinfo.size() > 0);
    uint32_t lun = SSDWriteinfo.front().lunID;

    /**If there is nothing on the way, we need to start the events*/
    DPRINTF(UFSHostDevice, "Write done entered, queue: %d\n",
            UFSDevice[lun]->SSDWriteDoneInfo.size());
    /**Write the disk*/
    UFSDevice[lun]->writeFlash(&SSDWriteinfo.front().buffer[0],
                               SSDWriteinfo.front().offset,
                               SSDWriteinfo.front().size);

    /**
     * Move to the second queue, enter the logic unit
     * This is where the disk is approached and the flash transaction is
     * handled SSDWriteDone will take care of the timing
     */
    UFSDevice[lun]->SSDWriteDoneInfo.push_back(SSDWriteinfo.front());
    SSDWriteinfo.pop_front();

    --writePendingNum;
    /**so far, only the DMA part has been handled, lets do the disk delay*/
    UFSDevice[lun]->SSDWriteStart();

    /** stats **/
    stats.currentWriteSSDQueue = UFSDevice[lun]->SSDWriteDoneInfo.size();
    stats.averageWriteSSDQueue = UFSDevice[lun]->SSDWriteDoneInfo.size();
    ++stats.totalWriteDiskTransactions;

    /**initiate the next dma action (if any)*/
    if (!dmaWriteInfo.empty())
        writeDevice(NULL, true, dmaWriteInfo.front().start,
                    dmaWriteInfo.front().size,  NULL,
                    dmaWriteInfo.front().SCSIDiskOffset,
                    dmaWriteInfo.front().LUN);
    DPRINTF(UFSHostDevice, "Write done end\n");
}

/**
 * SSD write start. Starts the write action in the timing model
 */
void
UFSHostDevice::UFSSCSIDevice::SSDWriteStart()
{
    assert(SSDWriteDoneInfo.size() > 0);
    flashDevice->writeMemory(
        SSDWriteDoneInfo.front().offset,
        SSDWriteDoneInfo.front().size, memWriteCallback);

    SSDWriteDoneInfo.pop_front();

    DPRINTF(UFSHostDevice, "Write is started; left in queue: %d\n",
            SSDWriteDoneInfo.size());
}


/**
 * SSDisk write done
 */

void
UFSHostDevice::UFSSCSIDevice::SSDWriteDone()
{
    DPRINTF(UFSHostDevice, "Write disk, aiming for %d messages, %d so far\n",
            totalWrite, amountOfWriteTransfers);

    //we have done one extra transfer
    ++amountOfWriteTransfers;

    /**test whether call was correct*/
    assert(totalWrite >= amountOfWriteTransfers && totalWrite != 0);

    /**are we there yet? (did we do everything)*/
    if (totalWrite == amountOfWriteTransfers) {
        DPRINTF(UFSHostDevice, "Write transactions finished\n");
        totalWrite = 0;
        amountOfWriteTransfers = 0;

        //Callback UFS Host
        setSignal();
        signalDone->process();
    }

}

/**
 * Dma transaction function: read device. Notice that the dma action is from
 * a device perspective, while this function is from an initiator perspective
 */

void
UFSHostDevice::readDevice(bool lastTransfer, Addr start, uint32_t size,
                          uint8_t* destination, bool no_cache, Event*
                          additional_action)
{
    DPRINTF(UFSHostDevice, "Read start: 0x%8x; Size: %d, data[0]: 0x%8x\n",
            start, size, (reinterpret_cast<uint32_t *>(destination))[0]);

    /** check wether interrupt is needed */
    if (lastTransfer) {
        ++readPendingNum;
        readDoneEvent.push_back(
            EventFunctionWrapper([this]{ readDone(); },
                                 name()));
        assert(!readDoneEvent.back().scheduled());
        dmaPort.dmaAction(MemCmd::WriteReq, start, size,
                          &readDoneEvent.back(), destination, 0);
        //yes, a writereq at a read device function is correct.

    } else {
        if (additional_action != NULL)
            assert(!additional_action->scheduled());

        dmaPort.dmaAction(MemCmd::WriteReq, start, size,
                          additional_action, destination, 0);

    }

}

/**
 * Manage read transfer. Manages correct transfer flow and makes sure that
 * the queues are filled on time
 */

void
UFSHostDevice::manageReadTransfer(uint32_t size, uint32_t LUN, uint64_t
                                  offset, uint32_t sg_table_length,
                                  struct UFSHCDSGEntry* sglist)
{
    uint32_t size_accum = 0;

    DPRINTF(UFSHostDevice, "Data READ size: %d\n", size);

    /**
     * Break-up the transactions into actions defined by the scatter gather
     * list.
     */
    for (uint32_t count = 0; count < sg_table_length; count++) {
        struct transferInfo new_transfer;
        new_transfer.offset = sglist[count].upperAddr;
        new_transfer.offset = (new_transfer.offset << 32) |
            (sglist[count].baseAddr & 0xFFFFFFFF);
        new_transfer.filePointer = offset + size_accum;
        new_transfer.size = (sglist[count].size + 1);
        new_transfer.lunID = LUN;

        DPRINTF(UFSHostDevice, "Data READ start: 0x%8x; size: %d\n",
                new_transfer.offset, new_transfer.size);

        UFSDevice[LUN]->SSDReadInfo.push_back(new_transfer);
        UFSDevice[LUN]->SSDReadInfo.back().buffer.resize(sglist[count].size
                                                         + 1);

        /**
         * The disk image is read here; but the action is simultated later
         * You can see this as the preparation stage, whereas later is the
         * simulation phase.
         */
        UFSDevice[LUN]->readFlash(&UFSDevice[LUN]->
                                  SSDReadInfo.back().buffer[0],
                                  offset + size_accum,
                                  sglist[count].size + 1);

        size_accum += (sglist[count].size + 1);

        DPRINTF(UFSHostDevice, "Transfer %d; Remaining: 0x%8x, Accumulated:"
                " 0x%8x\n", (count + 1), (size-size_accum), size_accum);

        /** stats **/
        stats.totalReadSSD += (sglist[count].size + 1);
        stats.currentReadSSDQueue = UFSDevice[LUN]->SSDReadInfo.size();
        stats.averageReadSSDQueue = UFSDevice[LUN]->SSDReadInfo.size();
    }

    UFSDevice[LUN]->SSDReadStart(sg_table_length);

    /** stats **/
    ++stats.totalReadUFSTransactions;

}



/**
 * SSDisk start read; this function was created to keep the interfaces
 * between the layers simpler. Without this function UFSHost would need to
 * know about the flashdevice.
 */

void
UFSHostDevice::UFSSCSIDevice::SSDReadStart(uint32_t total_read)
{
    totalRead = total_read;
    for (uint32_t number_handled = 0; number_handled < SSDReadInfo.size();
         number_handled++) {
        /**
         * Load all the read request to the Memory device.
         * It will call back when done.
         */
        flashDevice->readMemory(SSDReadInfo.front().filePointer,
                                SSDReadInfo.front().size, memReadCallback);
    }

}


/**
 * SSDisk read done
 */

void
UFSHostDevice::UFSSCSIDevice::SSDReadDone()
{
    DPRINTF(UFSHostDevice, "SSD read done at lun %d, Aiming for %d messages,"
            " %d so far\n", lunID, totalRead, amountOfReadTransfers);

    if (totalRead == amountOfReadTransfers) {
        totalRead = 0;
        amountOfReadTransfers = 0;

        /**Callback: transferdone*/
        setSignal();
        signalDone->process();
    }

}

/**
 * Read callback, on the way from the disk to the DMA. Called by the flash
 * layer. Intermediate step to the host layer
 */
void
UFSHostDevice::UFSSCSIDevice::readCallback()
{
    ++amountOfReadTransfers;

    /**Callback; make sure data is transfered upstream:
     * UFSHostDevice::readCallback
     */
    setReadSignal();
    deviceReadCallback->process();

    //Are we done yet?
    SSDReadDone();
}

/**
 * Read callback, on the way from the disk to the DMA. Called by the UFSSCSI
 * layer.
 */

void
UFSHostDevice::readCallback()
{
    DPRINTF(UFSHostDevice, "Read Callback\n");
    uint8_t this_lun = 0;

    //while we haven't found the right lun, keep searching
    while ((this_lun < lunAvail) && !UFSDevice[this_lun]->finishedRead())
        ++this_lun;

    DPRINTF(UFSHostDevice, "Found LUN %d messages pending for clean: %d\n",
            this_lun, SSDReadPending.size());

    if (this_lun < lunAvail) {
        //Clear signal.
        UFSDevice[this_lun]->clearReadSignal();
        SSDReadPending.push_back(UFSDevice[this_lun]->SSDReadInfo.front());
        UFSDevice[this_lun]->SSDReadInfo.pop_front();
        readGarbageEventQueue.push_back(
            EventFunctionWrapper([this]{ readGarbage(); }, name()));

        //make sure the queue is popped a the end of the dma transaction
        readDevice(false, SSDReadPending.front().offset,
                   SSDReadPending.front().size,
                   &SSDReadPending.front().buffer[0], false,
                   &readGarbageEventQueue.back());

        /**stats*/
        ++stats.totalReadDiskTransactions;
    }
    else
        panic("no read finished in tick %d\n", curTick());
}

/**
 * After a disk read DMA transfer, the structure needs to be freed. This is
 * done in this function.
 */
void
UFSHostDevice::readGarbage()
{
    DPRINTF(UFSHostDevice, "Clean read data, %d\n", SSDReadPending.size());
    SSDReadPending.pop_front();
    readGarbageEventQueue.pop_front();
}

/**
 * Serialize; needed to make checkpoints
 */

void
UFSHostDevice::serialize(CheckpointOut &cp) const
{
    DmaDevice::serialize(cp);

    const uint8_t* temp_HCI_mem = reinterpret_cast<const uint8_t*>(&UFSHCIMem);
    SERIALIZE_ARRAY(temp_HCI_mem, sizeof(HCIMem));

    uint32_t lun_avail = lunAvail;
    SERIALIZE_SCALAR(lun_avail);
}


/**
 * Unserialize; needed to restore from checkpoints
 */

void
UFSHostDevice::unserialize(CheckpointIn &cp)
{
    DmaDevice::unserialize(cp);
    uint8_t* temp_HCI_mem = reinterpret_cast<uint8_t*>(&UFSHCIMem);
    UNSERIALIZE_ARRAY(temp_HCI_mem, sizeof(HCIMem));

    uint32_t lun_avail;
    UNSERIALIZE_SCALAR(lun_avail);
    assert(lunAvail == lun_avail);
}


/**
 * Drain; needed to enable checkpoints
 */

DrainState
UFSHostDevice::drain()
{
    if (UFSHCIMem.TRUTRLDBR) {
        DPRINTF(UFSHostDevice, "UFSDevice is draining...\n");
        return DrainState::Draining;
    } else {
        DPRINTF(UFSHostDevice, "UFSDevice drained\n");
        return DrainState::Drained;
    }
}

/**
 * Checkdrain; needed to enable checkpoints
 */

void
UFSHostDevice::checkDrain()
{
    if (drainState() != DrainState::Draining)
        return;

    if (UFSHCIMem.TRUTRLDBR) {
        DPRINTF(UFSHostDevice, "UFSDevice is still draining; with %d active"
            " doorbells\n", activeDoorbells);
    } else {
        DPRINTF(UFSHostDevice, "UFSDevice is done draining\n");
        signalDrainDone();
    }
}
