update ModeSense6 function
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
Copyright 2016 The GoStor Authors All rights reserved.
|
Copyright 2017 The GoStor Authors All rights reserved.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@@ -148,7 +148,7 @@ type SCSIDataBuffer struct {
|
|||||||
Buffer *bytes.Buffer
|
Buffer *bytes.Buffer
|
||||||
Length uint32
|
Length uint32
|
||||||
TransferLength uint32
|
TransferLength uint32
|
||||||
Resid int32
|
Resid uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
type SCSICommandState uint64
|
type SCSICommandState uint64
|
||||||
@@ -364,6 +364,7 @@ type ModePage struct {
|
|||||||
PageCode uint8
|
PageCode uint8
|
||||||
// Sub page code
|
// Sub page code
|
||||||
SubPageCode uint8
|
SubPageCode uint8
|
||||||
|
Size uint8
|
||||||
// Rest of mode page info
|
// Rest of mode page info
|
||||||
Data []byte
|
Data []byte
|
||||||
}
|
}
|
||||||
@@ -378,17 +379,18 @@ type SCSIReservation struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type SCSILu struct {
|
type SCSILu struct {
|
||||||
Address uint64
|
Address uint64
|
||||||
Size uint64
|
Size uint64
|
||||||
UUID uint64
|
UUID uint64
|
||||||
Path string
|
Path string
|
||||||
BsoFlags int
|
BsoFlags int
|
||||||
BlockShift uint
|
BlockShift uint
|
||||||
ReserveID uuid.UUID
|
ReserveID uuid.UUID
|
||||||
Attrs SCSILuPhyAttribute
|
Attrs SCSILuPhyAttribute
|
||||||
ModePages []ModePage
|
ModePages []ModePage
|
||||||
Storage BackingStore
|
Storage BackingStore
|
||||||
DeviceProtocol SCSIDeviceProtocol
|
DeviceProtocol SCSIDeviceProtocol
|
||||||
|
ModeBlockDescriptor []byte
|
||||||
|
|
||||||
PerformCommand CommandFunc
|
PerformCommand CommandFunc
|
||||||
FinishCommand func(*SCSITarget, *SCSICommand)
|
FinishCommand func(*SCSITarget, *SCSICommand)
|
||||||
|
|||||||
@@ -94,6 +94,7 @@ type ISCSICommand struct {
|
|||||||
TaskTag uint32
|
TaskTag uint32
|
||||||
ExpCmdSN, MaxCmdSN uint32
|
ExpCmdSN, MaxCmdSN uint32
|
||||||
AHSLen int
|
AHSLen int
|
||||||
|
Resid uint32
|
||||||
|
|
||||||
// Connection ID.
|
// Connection ID.
|
||||||
ConnID uint16
|
ConnID uint16
|
||||||
@@ -278,7 +279,11 @@ func (m *ISCSICommand) scsiCmdRespBytes() []byte {
|
|||||||
// rfc7143 11.4
|
// rfc7143 11.4
|
||||||
buf := &bytes.Buffer{}
|
buf := &bytes.Buffer{}
|
||||||
buf.WriteByte(byte(OpSCSIResp))
|
buf.WriteByte(byte(OpSCSIResp))
|
||||||
buf.WriteByte(0x80) // 11.4.1 = wtf
|
var flag byte = 0x80
|
||||||
|
if m.Resid > 0 {
|
||||||
|
flag |= 0x02
|
||||||
|
}
|
||||||
|
buf.WriteByte(flag)
|
||||||
buf.WriteByte(byte(m.SCSIResponse))
|
buf.WriteByte(byte(m.SCSIResponse))
|
||||||
buf.WriteByte(byte(m.Status))
|
buf.WriteByte(byte(m.Status))
|
||||||
|
|
||||||
@@ -295,9 +300,10 @@ func (m *ISCSICommand) scsiCmdRespBytes() []byte {
|
|||||||
buf.Write(util.MarshalUint64(uint64(m.StatSN))[4:])
|
buf.Write(util.MarshalUint64(uint64(m.StatSN))[4:])
|
||||||
buf.Write(util.MarshalUint64(uint64(m.ExpCmdSN))[4:])
|
buf.Write(util.MarshalUint64(uint64(m.ExpCmdSN))[4:])
|
||||||
buf.Write(util.MarshalUint64(uint64(m.MaxCmdSN))[4:])
|
buf.Write(util.MarshalUint64(uint64(m.MaxCmdSN))[4:])
|
||||||
for i := 0; i < 3*4; i++ {
|
for i := 0; i < 2*4; i++ {
|
||||||
buf.WriteByte(0x00)
|
buf.WriteByte(0x00)
|
||||||
}
|
}
|
||||||
|
buf.Write(util.MarshalUint64(uint64(m.Resid))[4:])
|
||||||
buf.Write(m.RawData)
|
buf.Write(m.RawData)
|
||||||
dl := len(m.RawData)
|
dl := len(m.RawData)
|
||||||
for dl%4 > 0 {
|
for dl%4 > 0 {
|
||||||
@@ -312,20 +318,22 @@ func (m *ISCSICommand) dataInBytes() []byte {
|
|||||||
// rfc7143 11.7
|
// rfc7143 11.7
|
||||||
buf := &bytes.Buffer{}
|
buf := &bytes.Buffer{}
|
||||||
buf.WriteByte(byte(OpSCSIIn))
|
buf.WriteByte(byte(OpSCSIIn))
|
||||||
var b byte
|
var flag byte
|
||||||
b = 0x0
|
|
||||||
if m.FinalInSeq || m.Final == true {
|
if m.FinalInSeq || m.Final == true {
|
||||||
b |= 0x80
|
flag |= 0x80
|
||||||
}
|
}
|
||||||
if m.HasStatus && m.Final == true {
|
if m.HasStatus && m.Final == true {
|
||||||
b |= 0x01
|
flag |= 0x01
|
||||||
}
|
}
|
||||||
buf.WriteByte(b)
|
if m.Resid > 0 {
|
||||||
|
flag |= 0x02
|
||||||
|
}
|
||||||
|
buf.WriteByte(flag)
|
||||||
buf.WriteByte(0x00)
|
buf.WriteByte(0x00)
|
||||||
if m.HasStatus && m.Final == true {
|
if m.HasStatus && m.Final == true {
|
||||||
b = byte(m.Status)
|
flag = byte(m.Status)
|
||||||
}
|
}
|
||||||
buf.WriteByte(b)
|
buf.WriteByte(flag)
|
||||||
|
|
||||||
buf.WriteByte(0x00) // 4
|
buf.WriteByte(0x00) // 4
|
||||||
|
|
||||||
@@ -344,9 +352,7 @@ func (m *ISCSICommand) dataInBytes() []byte {
|
|||||||
buf.Write(util.MarshalUint64(uint64(m.MaxCmdSN))[4:])
|
buf.Write(util.MarshalUint64(uint64(m.MaxCmdSN))[4:])
|
||||||
buf.Write(util.MarshalUint64(uint64(m.DataSN))[4:])
|
buf.Write(util.MarshalUint64(uint64(m.DataSN))[4:])
|
||||||
buf.Write(util.MarshalUint64(uint64(m.BufferOffset))[4:])
|
buf.Write(util.MarshalUint64(uint64(m.BufferOffset))[4:])
|
||||||
for i := 0; i < 4; i++ {
|
buf.Write(util.MarshalUint64(uint64(m.Resid))[4:])
|
||||||
buf.WriteByte(0x00)
|
|
||||||
}
|
|
||||||
buf.Write(m.RawData[m.BufferOffset : m.BufferOffset+uint32(m.DataLen)])
|
buf.Write(m.RawData[m.BufferOffset : m.BufferOffset+uint32(m.DataLen)])
|
||||||
dl := m.DataLen
|
dl := m.DataLen
|
||||||
for dl%4 > 0 {
|
for dl%4 > 0 {
|
||||||
|
|||||||
@@ -182,6 +182,7 @@ func (conn *iscsiConnection) buildRespPackage(oc OpCode, task *iscsiTask) error
|
|||||||
resp.RawData = append(length[2:4], scmd.SenseBuffer.Bytes()...)
|
resp.RawData = append(length[2:4], scmd.SenseBuffer.Bytes()...)
|
||||||
} else if scmd.Direction == api.SCSIDataRead || scmd.Direction == api.SCSIDataWrite {
|
} else if scmd.Direction == api.SCSIDataRead || scmd.Direction == api.SCSIDataWrite {
|
||||||
if scmd.InSDBBuffer.Buffer != nil {
|
if scmd.InSDBBuffer.Buffer != nil {
|
||||||
|
resp.Resid = scmd.InSDBBuffer.Resid
|
||||||
buf := scmd.InSDBBuffer.Buffer.Bytes()
|
buf := scmd.InSDBBuffer.Buffer.Bytes()
|
||||||
resp.RawData = buf
|
resp.RawData = buf
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -678,7 +678,7 @@ func (s *ISCSITargetDriver) iscsiTaskQueueHandler(task *iscsiTask) error {
|
|||||||
return s.iscsiExecTask(task)
|
return s.iscsiExecTask(task)
|
||||||
}
|
}
|
||||||
cmdsn := cmd.CmdSN
|
cmdsn := cmd.CmdSN
|
||||||
log.Debugf("CmdSN of command is %d, ExpCmdSN of session is %d", cmdsn, sess.ExpCmdSN)
|
log.Debugf("CmdSN of command is %d", cmdsn)
|
||||||
if cmdsn == sess.ExpCmdSN {
|
if cmdsn == sess.ExpCmdSN {
|
||||||
retry:
|
retry:
|
||||||
cmdsn += 1
|
cmdsn += 1
|
||||||
|
|||||||
@@ -96,20 +96,25 @@ func (sbc SBCSCSIDeviceProtocol) InitLu(lu *api.SCSILu) error {
|
|||||||
}
|
}
|
||||||
pages := []api.ModePage{}
|
pages := []api.ModePage{}
|
||||||
// Vendor uniq - However most apps seem to call for mode page 0
|
// Vendor uniq - However most apps seem to call for mode page 0
|
||||||
pages = append(pages, api.ModePage{0, 0, []byte{}})
|
//pages = append(pages, api.ModePage{0, 0, []byte{}})
|
||||||
// Disconnect page
|
// Disconnect page
|
||||||
pages = append(pages, api.ModePage{2, 0, []byte{0x80, 0x80, 0, 0xa, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}})
|
pages = append(pages, api.ModePage{2, 0, 14, []byte{0x80, 0x80, 0, 0xa, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}})
|
||||||
// Caching Page
|
// Caching Page
|
||||||
pages = append(pages, api.ModePage{8, 0, []byte{0x14, 0, 0xff, 0xff, 0, 0, 0xff, 0xff, 0xff, 0xff, 0x80, 0x14, 0, 0, 0, 0, 0, 0}})
|
pages = append(pages, api.ModePage{8, 0, 18, []byte{0x14, 0, 0xff, 0xff, 0, 0, 0xff, 0xff, 0xff, 0xff, 0x80, 0x14, 0, 0, 0, 0, 0, 0, 0x4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}})
|
||||||
|
|
||||||
// Control page
|
// Control page
|
||||||
pages = append(pages, api.ModePage{0x0a, 0, []byte{2, 0x10, 0, 0, 0, 0, 0, 0, 2, 0}})
|
pages = append(pages, api.ModePage{0x0a, 0, 10, []byte{2, 0x10, 0, 0, 0, 0, 0, 0, 2, 0, 0x08, 0, 0, 0, 0, 0, 0, 0}})
|
||||||
|
|
||||||
// Control Extensions mode page: TCMOS:1
|
// Control Extensions mode page: TCMOS:1
|
||||||
pages = append(pages, api.ModePage{0x0a, 1, []byte{0x04, 0x00, 0x00}})
|
pages = append(pages, api.ModePage{0x0a, 1, 0x1c, []byte{0x04, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}})
|
||||||
// Informational Exceptions Control page
|
// Informational Exceptions Control page
|
||||||
pages = append(pages, api.ModePage{0x1c, 0, []byte{8, 0, 0, 0, 0, 0, 0, 0, 0, 0}})
|
pages = append(pages, api.ModePage{0x1c, 0, 10, []byte{8, 0, 0, 0, 0, 0, 0, 0, 0, 0}})
|
||||||
lu.ModePages = pages
|
lu.ModePages = pages
|
||||||
|
mbd := util.MarshalUint32(uint32(0xffffffff))
|
||||||
|
if size := lu.Size >> lu.BlockShift; size>>32 == 0 {
|
||||||
|
mbd = util.MarshalUint32(uint32(size))
|
||||||
|
}
|
||||||
|
lu.ModeBlockDescriptor = append(mbd, util.MarshalUint32(uint32(1<<lu.BlockShift))...)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
106
pkg/scsi/spc.go
106
pkg/scsi/spc.go
@@ -354,7 +354,7 @@ func SPCReportLuns(host int, cmd *api.SCSICommand) api.SAMStat {
|
|||||||
|
|
||||||
// LUN list length
|
// LUN list length
|
||||||
buf.Write(util.MarshalUint32(availLength))
|
buf.Write(util.MarshalUint32(availLength))
|
||||||
cmd.InSDBBuffer.Resid = int32(actualLength)
|
cmd.InSDBBuffer.Resid = uint32(actualLength)
|
||||||
|
|
||||||
// Skip through to byte 4, Reserved
|
// Skip through to byte 4, Reserved
|
||||||
for i := 0; i < 4; i++ {
|
for i := 0; i < 4; i++ {
|
||||||
@@ -474,13 +474,17 @@ func SPCModeSense(host int, cmd *api.SCSICommand) api.SAMStat {
|
|||||||
var (
|
var (
|
||||||
scb = cmd.SCB.Bytes()
|
scb = cmd.SCB.Bytes()
|
||||||
mode6 = (scb[0] == 0x1a)
|
mode6 = (scb[0] == 0x1a)
|
||||||
dbd = scb[1] & 0x8 /* Disable Block Descriptors */
|
dbd = scb[1] & 0x8 // Disable Block Descriptors
|
||||||
pcode = scb[2] & 0x3f
|
pcode = scb[2] & 0x3f
|
||||||
pctrl = (scb[2] & 0xc0) >> 6
|
pctrl = (scb[2] & 0xc0) >> 6
|
||||||
subpcode = scb[3]
|
subpcode = scb[3]
|
||||||
blkDesctionLen = 0
|
blkDesctionLen = 0
|
||||||
key = ILLEGAL_REQUEST
|
key = ILLEGAL_REQUEST
|
||||||
asc = ASC_INVALID_FIELD_IN_CDB
|
asc = ASC_INVALID_FIELD_IN_CDB
|
||||||
|
data []byte
|
||||||
|
allocLen uint32
|
||||||
|
remainLen uint32
|
||||||
|
i uint32
|
||||||
)
|
)
|
||||||
if dbd == 0 {
|
if dbd == 0 {
|
||||||
blkDesctionLen = 8
|
blkDesctionLen = 8
|
||||||
@@ -489,11 +493,91 @@ func SPCModeSense(host int, cmd *api.SCSICommand) api.SAMStat {
|
|||||||
asc = ASC_SAVING_PARMS_UNSUP
|
asc = ASC_SAVING_PARMS_UNSUP
|
||||||
goto sense
|
goto sense
|
||||||
}
|
}
|
||||||
_ = dbd
|
if mode6 {
|
||||||
_ = pcode
|
allocLen = uint32(scb[4])
|
||||||
_ = subpcode
|
// set header
|
||||||
_ = mode6
|
for i = 0; i < 4 && i < allocLen; i++ {
|
||||||
_ = blkDesctionLen
|
data = append(data, 0x00)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
allocLen = uint32(util.GetUnalignedUint16(scb[7:9]))
|
||||||
|
// set header
|
||||||
|
for i = 0; i < 8 && i < allocLen; i++ {
|
||||||
|
data = append(data, 0x00)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
remainLen = allocLen - uint32(len(data))
|
||||||
|
if dbd == 0 && remainLen >= 8 {
|
||||||
|
data = append(data, cmd.Device.ModeBlockDescriptor...)
|
||||||
|
}
|
||||||
|
if pcode == 0x3f {
|
||||||
|
for _, pg := range cmd.Device.ModePages {
|
||||||
|
if pg.SubPageCode == 0 {
|
||||||
|
if remainLen < 2+uint32(pg.Size) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
data = append(data, pg.PageCode)
|
||||||
|
data = append(data, pg.Size)
|
||||||
|
} else {
|
||||||
|
if remainLen < 4+uint32(pg.Size) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
data = append(data, pg.PageCode|0x40)
|
||||||
|
data = append(data, pg.SubPageCode)
|
||||||
|
data = append(data, (pg.Size>>8)&0xff)
|
||||||
|
data = append(data, pg.Size&0xff)
|
||||||
|
}
|
||||||
|
if pctrl == 1 {
|
||||||
|
data = append(data, pg.Data[pg.Size:]...)
|
||||||
|
} else {
|
||||||
|
data = append(data, pg.Data[:pg.Size]...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var pg *api.ModePage
|
||||||
|
for _, p := range cmd.Device.ModePages {
|
||||||
|
if p.PageCode == pcode && p.SubPageCode == subpcode {
|
||||||
|
pg = &p
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if pg == nil {
|
||||||
|
goto sense
|
||||||
|
}
|
||||||
|
if remainLen >= 2+uint32(pg.Size) {
|
||||||
|
if pg.SubPageCode == 0 {
|
||||||
|
data = append(data, pg.PageCode)
|
||||||
|
data = append(data, pg.Size)
|
||||||
|
if pctrl == 1 {
|
||||||
|
data = append(data, pg.Data[pg.Size:]...)
|
||||||
|
} else {
|
||||||
|
data = append(data, pg.Data[:pg.Size]...)
|
||||||
|
}
|
||||||
|
} else if remainLen >= 4+uint32(pg.Size) {
|
||||||
|
data = append(data, pg.PageCode|0x40)
|
||||||
|
data = append(data, pg.SubPageCode)
|
||||||
|
data = append(data, (pg.Size>>8)&0xff)
|
||||||
|
data = append(data, pg.Size&0xff)
|
||||||
|
if pctrl == 1 {
|
||||||
|
data = append(data, pg.Data[pg.Size:]...)
|
||||||
|
} else {
|
||||||
|
data = append(data, pg.Data[:pg.Size]...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if mode6 {
|
||||||
|
data[0] = uint8(len(data) - 1)
|
||||||
|
data[3] = uint8(blkDesctionLen)
|
||||||
|
} else {
|
||||||
|
data[0] = uint8((len(data) - 2) >> 8)
|
||||||
|
data[1] = uint8(len(data) - 2)
|
||||||
|
data[6] = uint8(blkDesctionLen >> 8)
|
||||||
|
data[7] = uint8(blkDesctionLen)
|
||||||
|
}
|
||||||
|
cmd.InSDBBuffer.Resid = uint32(len(data))
|
||||||
|
cmd.InSDBBuffer.Buffer = bytes.NewBuffer(data)
|
||||||
return api.SAMStatGood
|
return api.SAMStatGood
|
||||||
sense:
|
sense:
|
||||||
BuildSenseData(cmd, key, asc)
|
BuildSenseData(cmd, key, asc)
|
||||||
@@ -660,7 +744,7 @@ func SPCPRReadKeys(host int, cmd *api.SCSICommand) api.SAMStat {
|
|||||||
cmd.InSDBBuffer.Buffer = bytes.NewBuffer(data)
|
cmd.InSDBBuffer.Buffer = bytes.NewBuffer(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.InSDBBuffer.Resid = int32(additionLength)
|
cmd.InSDBBuffer.Resid = uint32(additionLength)
|
||||||
return api.SAMStatGood
|
return api.SAMStatGood
|
||||||
sense:
|
sense:
|
||||||
cmd.InSDBBuffer.Resid = 0
|
cmd.InSDBBuffer.Resid = 0
|
||||||
@@ -715,7 +799,7 @@ func SPCPRReadReservation(host int, cmd *api.SCSICommand) api.SAMStat {
|
|||||||
cmd.InSDBBuffer.Buffer = bytes.NewBuffer(data)
|
cmd.InSDBBuffer.Buffer = bytes.NewBuffer(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.InSDBBuffer.Resid = int32(additionLength)
|
cmd.InSDBBuffer.Resid = uint32(additionLength)
|
||||||
return api.SAMStatGood
|
return api.SAMStatGood
|
||||||
|
|
||||||
sense:
|
sense:
|
||||||
@@ -760,7 +844,7 @@ func SPCPRReportCapabilities(host int, cmd *api.SCSICommand) api.SAMStat {
|
|||||||
} else {
|
} else {
|
||||||
actualLength = availLength
|
actualLength = availLength
|
||||||
}
|
}
|
||||||
cmd.InSDBBuffer.Resid = int32(actualLength)
|
cmd.InSDBBuffer.Resid = uint32(actualLength)
|
||||||
return api.SAMStatGood
|
return api.SAMStatGood
|
||||||
sense:
|
sense:
|
||||||
cmd.InSDBBuffer.Resid = 0
|
cmd.InSDBBuffer.Resid = 0
|
||||||
@@ -1257,7 +1341,7 @@ func SPCRequestSense(host int, cmd *api.SCSICommand) api.SAMStat {
|
|||||||
if cmd.SenseBuffer != nil {
|
if cmd.SenseBuffer != nil {
|
||||||
data.Write(cmd.SenseBuffer.Bytes()[:actualLength])
|
data.Write(cmd.SenseBuffer.Bytes()[:actualLength])
|
||||||
}
|
}
|
||||||
cmd.InSDBBuffer.Resid = int32(actualLength)
|
cmd.InSDBBuffer.Resid = uint32(actualLength)
|
||||||
cmd.InSDBBuffer.Buffer = data
|
cmd.InSDBBuffer.Buffer = data
|
||||||
|
|
||||||
// reset sense buffer in cmnd
|
// reset sense buffer in cmnd
|
||||||
|
|||||||
Reference in New Issue
Block a user