func (t *Target) handleVPD(s *Session, m, resp *packet.Message) { lun := int(m.LUN) alloc := int(packet.ParseUint(m.CDB[3:5])) vpd, err := t.LUNs[lun].VitalProductData(m.CDB[2]) if err != nil { resp.Status = 0x02 resp.SCSIResponse = 0x01 return } resp.RawData = vpd if len(vpd) >= alloc { resp.RawData = resp.RawData[:alloc] } }
func (t *Target) handleSCSICmd(s *Session, m *packet.Message) (err error) { opCode := m.CDB[0] lun := int(m.LUN) resp := &packet.Message{ OpCode: packet.OpSCSIResp, Final: true, StatSN: m.ExpStatSN, TaskTag: m.TaskTag, ExpCmdSN: m.CmdSN + 1, MaxCmdSN: m.CmdSN + 10, } defer func() { if err == nil { err = s.Send(resp) } }() switch opCode { case 0x00: ready, err := t.LUNs[lun].TestUnitReady() if err != nil { resp.Status = 0x02 resp.SCSIResponse = 0x01 } if !ready { resp.Status = 0x08 resp.SCSIResponse = 0x01 } return s.Send(resp) case 0x25: resp.OpCode = packet.OpSCSIIn resp.HasStatus = true var data []byte pmi := m.CDB[8]&0x01 == 0x01 lba := uint32(packet.ParseUint(m.CDB[2:6])) rlba, blocksize, err := t.LUNs[lun].ReadCapacity10(pmi, lba) if err != nil { resp.Status = 0x02 resp.SCSIResponse = 0x01 break } data = append(data, packet.MarshalUint64(uint64(rlba))[4:]...) data = append(data, packet.MarshalUint64(uint64(blocksize))[4:]...) resp.RawData = data case 0x9e: resp.OpCode = packet.OpSCSIIn resp.HasStatus = true sa := m.CDB[1] & 0x1f switch sa { case 0x10: pmi := m.CDB[14]&0x01 == 0x01 lba := packet.ParseUint(m.CDB[2:10]) capacity, err := t.LUNs[lun].ReadCapacity16(pmi, lba) if err != nil { resp.Status = 0x02 resp.SCSIResponse = 0x01 break } resp.RawData = capacity.bytes() } case 0x12: resp.OpCode = packet.OpSCSIIn resp.HasStatus = true alloc := int(packet.ParseUint(m.CDB[3:5])) evpd := m.CDB[1]&0x01 == 0x01 if evpd { t.handleVPD(s, m, resp) return } inq, err := t.LUNs[lun].Inquiry() if err != nil { resp.Status = 0x02 resp.SCSIResponse = 0x01 break } resp.RawData = inq.bytes()[:alloc] default: setError(resp, ErrUnsupportedCommand) } return }