/*
 * 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.
 */

/** @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();
    }
}
