예제 #1
0
파일: MassStorage.cs 프로젝트: rte-se/emul8
        void ReceiveCommandBlockWrapper(CommandBlockWrapper cbw, SCSI.CommandDescriptorBlock cdb, byte[] data)
        {
            this.DebugLog("Received Command Block Wrapper");
            var csw = new CommandStatusWrapper();
            var cdbData = new byte[cbw.Length];
            Array.Copy(data, 15, cdbData, 0, cbw.Length);
            cdb.Fill(cdbData);
            switch((SCSI.CommandDescriptorBlock.GroupCode)cdb.OperationCode)
            {
            case SCSI.CommandDescriptorBlock.GroupCode.Inquiry:
                csw.Tag = cbw.Tag;
                csw.DataResidue = 0x00;
                csw.Status = 0x00;
                transmissionQueue.Enqueue(inquiry.ToArray());
                //enqueue inquiry data 
                transmissionQueue.Enqueue(csw.ToArray());
                break;
            case SCSI.CommandDescriptorBlock.GroupCode.ModeSense:
                var msc = new SCSI.ModeSenseCommand();
                msc.Fill(cdbData);
                var retArr = new byte[192];
                retArr[0] = 0x03;
                //FIXME: probably it should return sth with more sense
                csw.Tag = cbw.Tag;
                csw.DataResidue = cbw.DataTransferLength - 0x03;
                csw.Status = 0x00;
                transmissionQueue.Enqueue(retArr);
                transmissionQueue.Enqueue(csw.ToArray());
                break;
            case SCSI.CommandDescriptorBlock.GroupCode.PreventAllowMediumRemoval:
                csw.Tag = cbw.Tag;
                csw.DataResidue = 0x00;
                csw.Status = 0x00;
                transmissionQueue.Enqueue(csw.ToArray());
                break;
            case SCSI.CommandDescriptorBlock.GroupCode.Read10:
                var dataRead = lbaBackend.Read((int)cdb.LogicalBlockAddress, (int)cdb.TransferLength);
                csw.Tag = cbw.Tag;
                csw.DataResidue = (uint)(cbw.DataTransferLength - dataRead.Length);
                csw.Status = 0x00;
                transmissionQueue.Enqueue(dataRead);
                transmissionQueue.Enqueue(csw.ToArray());
                break;
            case SCSI.CommandDescriptorBlock.GroupCode.Write10:
                writeFlag = true;
                //next write command could be data
                csw.Tag = cbw.Tag;
                csw.DataResidue = cbw.DataTransferLength;
                csw.Status = 0x00;
                writeCSW = csw;
                writeCDB = cdb;
                //transmissionQueue.Enqueue(csw.ToArray());
                break;
            case SCSI.CommandDescriptorBlock.GroupCode.ReadCapacity:
                var capData = new SCSI.CapacityDataStructure();
                capData.ReturnedLBA = (uint)lbaBackend.NumberOfBlocks - 1;
                capData.BlockLength = (uint)lbaBackend.BlockSize;
                csw.Tag = cbw.Tag;
                csw.DataResidue = 0x00;
                csw.Status = 0x00;
                transmissionQueue.Enqueue(capData.ToArray());
                transmissionQueue.Enqueue(csw.ToArray());
                break;
	    case SCSI.CommandDescriptorBlock.GroupCode.RequestSense:
		// TODO: this was copied from TestUnitReady. do a proper implementation
                csw.Tag = cbw.Tag;
                csw.DataResidue = 0x00;
                csw.Status = 0x00;
                transmissionQueue.Enqueue(csw.ToArray());
	    	break;
            case SCSI.CommandDescriptorBlock.GroupCode.TestUnitReady:
                csw.Tag = cbw.Tag;
                csw.DataResidue = 0x00;
                csw.Status = 0x00;
                transmissionQueue.Enqueue(csw.ToArray());
                break;
            default:
                this.Log(LogLevel.Warning, "Unsuported Command Code: 0x{0:X}", cdb.OperationCode);
                break;
            }
        }
예제 #2
0
        void ReceiveCommandBlockWrapper(CommandBlockWrapper cbw, SCSI.CommandDescriptorBlock cdb, byte[] data)
        {
            this.DebugLog("Received Command Block Wrapper");
            var csw     = new CommandStatusWrapper();
            var cdbData = new byte[cbw.Length];

            Array.Copy(data, 15, cdbData, 0, cbw.Length);
            cdb.Fill(cdbData);
            switch ((SCSI.CommandDescriptorBlock.GroupCode)cdb.OperationCode)
            {
            case SCSI.CommandDescriptorBlock.GroupCode.Inquiry:
                csw.Tag         = cbw.Tag;
                csw.DataResidue = 0x00;
                csw.Status      = 0x00;
                transmissionQueue.Enqueue(inquiry.ToArray());
                //enqueue inquiry data
                transmissionQueue.Enqueue(csw.ToArray());
                break;

            case SCSI.CommandDescriptorBlock.GroupCode.ModeSense:
                var msc = new SCSI.ModeSenseCommand();
                msc.Fill(cdbData);
                var retArr = new byte[192];
                retArr[0] = 0x03;
                //FIXME: probably it should return sth with more sense
                csw.Tag         = cbw.Tag;
                csw.DataResidue = cbw.DataTransferLength - 0x03;
                csw.Status      = 0x00;
                transmissionQueue.Enqueue(retArr);
                transmissionQueue.Enqueue(csw.ToArray());
                break;

            case SCSI.CommandDescriptorBlock.GroupCode.PreventAllowMediumRemoval:
                csw.Tag         = cbw.Tag;
                csw.DataResidue = 0x00;
                csw.Status      = 0x00;
                transmissionQueue.Enqueue(csw.ToArray());
                break;

            case SCSI.CommandDescriptorBlock.GroupCode.Read10:
                var dataRead = lbaBackend.Read((int)cdb.LogicalBlockAddress, (int)cdb.TransferLength);
                csw.Tag         = cbw.Tag;
                csw.DataResidue = (uint)(cbw.DataTransferLength - dataRead.Length);
                csw.Status      = 0x00;
                transmissionQueue.Enqueue(dataRead);
                transmissionQueue.Enqueue(csw.ToArray());
                break;

            case SCSI.CommandDescriptorBlock.GroupCode.Write10:
                writeFlag = true;
                //next write command could be data
                csw.Tag         = cbw.Tag;
                csw.DataResidue = cbw.DataTransferLength;
                csw.Status      = 0x00;
                writeCSW        = csw;
                writeCDB        = cdb;
                //transmissionQueue.Enqueue(csw.ToArray());
                break;

            case SCSI.CommandDescriptorBlock.GroupCode.ReadCapacity:
                var capData = new SCSI.CapacityDataStructure();
                capData.ReturnedLBA = (uint)lbaBackend.NumberOfBlocks - 1;
                capData.BlockLength = (uint)lbaBackend.BlockSize;
                csw.Tag             = cbw.Tag;
                csw.DataResidue     = 0x00;
                csw.Status          = 0x00;
                transmissionQueue.Enqueue(capData.ToArray());
                transmissionQueue.Enqueue(csw.ToArray());
                break;

            case SCSI.CommandDescriptorBlock.GroupCode.RequestSense:
                // TODO: this was copied from TestUnitReady. do a proper implementation
                csw.Tag         = cbw.Tag;
                csw.DataResidue = 0x00;
                csw.Status      = 0x00;
                transmissionQueue.Enqueue(csw.ToArray());
                break;

            case SCSI.CommandDescriptorBlock.GroupCode.TestUnitReady:
                csw.Tag         = cbw.Tag;
                csw.DataResidue = 0x00;
                csw.Status      = 0x00;
                transmissionQueue.Enqueue(csw.ToArray());
                break;

            default:
                this.Log(LogLevel.Warning, "Unsuported Command Code: 0x{0:X}", cdb.OperationCode);
                break;
            }
        }