/*
 * 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;
    scsi_out.reset();

    /**
     * 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->setLE<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->getLE<uint8_t>();
        break;

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

      case 4:
        data = pkt->getLE<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();
    }
}
