inquiry page00h page80h page83h

This commit is contained in:
Le Zhang
2016-10-09 16:56:50 +08:00
parent c1b8beac68
commit a51a1d8d00
5 changed files with 281 additions and 89 deletions

View File

@@ -225,7 +225,7 @@ type SCSILuPhyAttribute struct {
VendorID string
ProductID string
ProductRev string
VersionDesction []uint16
VersionDesction [8]uint16
// Peripheral device type
DeviceType SCSIDeviceType
// Peripheral Qualifier

View File

@@ -47,6 +47,7 @@ func NewSCSILu(device_uuid uint64, path string, online bool) (*api.SCSILu, error
DeviceProtocol: sbc,
Storage: backing,
BlockShift: api.DefaultBlockShift,
UUID: device_uuid,
}
err = backing.Open(lu, backendPath)
@@ -69,6 +70,7 @@ func NewLUN0() *api.SCSILu {
DeviceProtocol: sbc,
Storage: backing,
BlockShift: api.DefaultBlockShift,
UUID: 0,
}
lu.Size = backing.Size(lu)

View File

@@ -25,6 +25,7 @@ import (
"github.com/golang/glog"
"github.com/gostor/gotgt/pkg/api"
"github.com/gostor/gotgt/pkg/util"
"github.com/gostor/gotgt/pkg/version"
)
const (
@@ -53,8 +54,9 @@ func (sbc SBCSCSIDeviceProtocol) InitLu(lu *api.SCSILu) error {
lu.Attrs.Readonly = false
lu.Attrs.SWP = false
lu.Attrs.SenseFormat = false
lu.Attrs.VendorID = "GOSTOR"
lu.Attrs.ProductID = "VIRTUAL-DISK"
lu.Attrs.VendorID = SCSI_VendorID
lu.Attrs.ProductID = SCSI_ProductID
lu.Attrs.ProductRev = version.SCSI_VERSION
/*
SCSIID for PAGE83 T10 VENDOR IDENTIFICATION field
@@ -73,10 +75,11 @@ func (sbc SBCSCSIDeviceProtocol) InitLu(lu *api.SCSILu) error {
*/
lu.Attrs.SCSISN = " "
lu.Attrs.VersionDesction = []uint16{
0x04C0, // SBC-3 no version claimed
0x0960, // iSCSI
0x0300, // SPC-3
lu.Attrs.VersionDesction = [8]uint16{
0x0320, // SBC-2 no version claimed
0x0960, // iSCSI no version claimed
0x0300, // SPC-3 no version claimed
0x0060, // SAM-3 no version claimed
}
if lu.BlockShift == 0 {
lu.BlockShift = api.DefaultBlockShift

View File

@@ -42,15 +42,17 @@ import (
*/
const (
PIV_FCP = iota
PIV_SPI
PIV_S3P
PIV_SBP
PIV_SRP
PIV_ISCSI
PIV_SAS
PIV_ADT
PIV_ATA
PIV_FCP = byte(0x00)
PIV_SPI = byte(0x01)
PIV_S3P = byte(0x02)
PIV_SBP = byte(0x03)
PIV_SRP = byte(0x04)
PIV_ISCSI = byte(0x05)
PIV_SAS = byte(0x06)
PIV_ADT = byte(0x07)
PIV_ATA = byte(0x08)
PIV_USB = byte(0x09)
PIV_SOP = byte(0x0A)
)
const (
@@ -67,12 +69,11 @@ const (
* 2 - Designator field contains ASCII printable chars
* 3 - Designaotor field contains UTF-8
*/
type CodeSet byte
var (
INQ_CODE_BIN CodeSet = 1
INQ_CODE_ASCII CodeSet = 2
INQ_CODE_UTF8 CodeSet = 3
const (
INQ_CODE_BIN = byte(1)
INQ_CODE_ASCII = byte(2)
INQ_CODE_UTF8 = byte(3)
)
/*
@@ -83,12 +84,11 @@ var (
* 10b - Associated with SCSI Target device
* 11b - Reserved
*/
type AssociationField byte
var (
ASS_LU AssociationField = 0
ASS_TGT_PORT AssociationField = 0x10
ASS_TGT_DEV AssociationField = 0x20
const (
ASS_LU = byte(0x00)
ASS_TGT_PORT = byte(0x01)
ASS_TGT_DEV = byte(0x02)
)
/*
@@ -112,10 +112,10 @@ var (
*/
const (
PQ_DEVICE_CONNECTED = byte(0x00)
PQ_DEVICE_NOT_CONNECT = byte(0x01)
PQ_RESERVED = byte(0x02)
PQ_NOT_SUPPORT = byte(0x03)
PQ_DEVICE_CONNECTED = byte(0x00 << 5)
PQ_DEVICE_NOT_CONNECT = byte(0x01 << 5)
PQ_RESERVED = byte(0x02 << 5)
PQ_NOT_SUPPORT = byte(0x03 << 5)
)
const (
@@ -132,6 +132,19 @@ const (
INQUIRY_NORM_ACA = byte(0x20)
INQUIRY_HISUP = byte(0x10)
INQUIRY_STANDARD_FORMAT = byte(0x02)
INQUIRY_ENCSERV = byte(0x40)
INQUIRY_VS0 = byte(0x20)
INQUIRY_MULTIP = byte(0x10)
INQUIRY_ADDR16 = byte(0x01)
INQUIRY_WBUS16 = byte(0x20)
INQUIRY_SYNC = byte(0x10)
INQUIRY_CMDQUE = byte(0x02)
INQUIRY_VS1 = byte(0x01)
INQUIRY_QAS = byte(0x02)
INQUIRY_IUS = byte(0x01)
)
const (
@@ -167,6 +180,18 @@ const (
DESG_SCSI
)
const (
NAA_IEEE_EXTD = byte(0x2)
NAA_LOCAL = byte(0x3)
NAA_IEEE_REGD = byte(0x5)
NAA_IEEE_REGD_EXTD = byte(0x6)
)
const (
SCSI_VendorID = "GOSTOR"
SCSI_ProductID = "GOTGT-VDISK"
)
func SPCIllegalOp(host int, cmd *api.SCSICommand) api.SAMStat {
return api.SAMStatGood
}
@@ -185,90 +210,251 @@ func SPCLuOnline(lu *api.SCSILu) error {
return nil
}
func InquiryPage0x00(host int, cmd *api.SCSICommand) (*bytes.Buffer, uint16) {
var (
buf = &bytes.Buffer{}
descBuf = &bytes.Buffer{}
data []byte = []byte{}
pageLength uint16 = 0
)
descBuf.WriteByte(0x00)
descBuf.WriteByte(0x80)
descBuf.WriteByte(0x83)
/*
TODO:
descBuf.WriteByte(0x86)
descBuf.WriteByte(0xB0)
descBuf.WriteByte(0xB2)
*/
data = descBuf.Bytes()
pageLength = uint16(len(data))
//byte 0
if cmd.Device.Attrs.Online {
buf.WriteByte(PQ_DEVICE_CONNECTED | byte(cmd.Device.Attrs.DeviceType))
} else {
buf.WriteByte(PQ_DEVICE_NOT_CONNECT | byte(cmd.Device.Attrs.DeviceType))
}
//byte 1
//PAGE CODE
buf.WriteByte(0x00)
//PAGE LENGTH
binary.Write(buf, binary.BigEndian, pageLength)
buf.Write(data)
return buf, pageLength
}
func InquiryPage0x80(host int, cmd *api.SCSICommand) (*bytes.Buffer, uint16) {
var (
buf = &bytes.Buffer{}
descBuf = &bytes.Buffer{}
data []byte = []byte{}
pageLength uint16 = 0
)
descBuf.WriteByte(0x20)
descBuf.WriteByte(0x20)
descBuf.WriteByte(0x20)
descBuf.WriteByte(0x20)
data = descBuf.Bytes()
pageLength = uint16(len(data))
//byte 0
if cmd.Device.Attrs.Online {
buf.WriteByte(PQ_DEVICE_CONNECTED | byte(cmd.Device.Attrs.DeviceType))
} else {
buf.WriteByte(PQ_DEVICE_NOT_CONNECT | byte(cmd.Device.Attrs.DeviceType))
}
//byte 1
//PAGE CODE
buf.WriteByte(0x80)
//PAGE LENGTH
binary.Write(buf, binary.BigEndian, pageLength)
buf.Write(data)
return buf, pageLength
}
func InquiryPage0x83(host int, cmd *api.SCSICommand) (*bytes.Buffer, uint16) {
var (
buf = &bytes.Buffer{}
descBuf = &bytes.Buffer{}
data []byte = []byte{}
pageLength uint16 = 0
)
//DESCRIPTOR 1 TARGET NAME
descBuf.WriteByte((PIV_ISCSI << 4) | INQ_CODE_ASCII)
descBuf.WriteByte(0x80 | ASS_TGT_PORT | DESG_VENDOR)
descBuf.WriteByte(0x00)
//length
descBuf.WriteByte(byte(len([]byte(cmd.Target.Name))))
//target name
descBuf.Write([]byte(cmd.Target.Name))
//DESCRIPTOR 2 NNA Locally
descBuf.WriteByte((PIV_ISCSI << 4) | INQ_CODE_BIN)
descBuf.WriteByte(0x80 | ASS_TGT_PORT | DESG_NAA)
descBuf.WriteByte(0x00)
//length
descBuf.WriteByte(0x08)
//NNA
binary.Write(descBuf, binary.BigEndian, (cmd.Device.UUID | (uint64(NAA_LOCAL) << 60)))
//TODO: Target Port Group(0x05), Relative Target port identifier(0x04)
/*
//DESCRIPTOR 3 TPG
descBuf.WriteByte((PIV_ISCSI << 4) | INQ_CODE_BIN)
descBuf.WriteByte(0x80 | ASS_TGT_PORT | DESG_REL_TGT_PORT)
descBuf.WriteByte(0x00)
//length
descBuf.WriteByte(0x08)
//TPG
binary.Write(descBuf, binary.BigEndian,)
//DESCRIPTOR 4 RTPI
descBuf.WriteByte((PIV_ISCSI << 4) | INQ_CODE_BIN)
descBuf.WriteByte(0x80 | ASS_TGT_PORT | DESG_NAA)
descBuf.WriteByte(0x00)
//length
descBuf.WriteByte(0x08)
//RTPGI
binary.Write(descBuf, binary.BigEndian,)
*/
data = descBuf.Bytes()
pageLength = uint16(len(data))
//byte 0
if cmd.Device.Attrs.Online {
buf.WriteByte(PQ_DEVICE_CONNECTED | byte(cmd.Device.Attrs.DeviceType))
} else {
buf.WriteByte(PQ_DEVICE_NOT_CONNECT | byte(cmd.Device.Attrs.DeviceType))
}
//byte 1
//PAGE CODE
buf.WriteByte(0x83)
//PAGE LENGTH
binary.Write(buf, binary.BigEndian, pageLength)
buf.Write(data)
return buf, pageLength
}
func SPCInquiry(host int, cmd *api.SCSICommand) api.SAMStat {
var (
buf = &bytes.Buffer{}
data []byte = []byte{}
b byte = 0x75
allocationLength uint16
pageLength uint16
additionLength byte
buf = &bytes.Buffer{}
data []byte = []byte{}
addBuf = &bytes.Buffer{}
addBufData []byte = []byte{}
//b byte = 0x75
scb []byte = cmd.SCB.Bytes()
pcode byte = scb[2]
evpd bool = false
vendorID = make([]byte, 8)
productID = make([]byte, 16)
productRev = make([]byte, 4)
)
allocationLength = util.GetUnalignedUint16(scb[3:5])
if scb[1]&0x01 > 0 {
evpd = true
}
if cmd.Device == nil {
b = (uint8(0) & 0x7) << 5
b |= uint8(0) & 0x1f
goto sense
}
if cmd.Device.Attrs.Online {
b = (byte(PQ_DEVICE_CONNECTED) << 5) | byte(cmd.Device.Attrs.DeviceType)
} else {
b = (byte(PQ_DEVICE_NOT_CONNECT) << 5) | byte(cmd.Device.Attrs.DeviceType)
}
if evpd {
if pcode == 0x0 {
buf.WriteByte(b)
b = 0
buf.WriteByte(b)
buf.WriteByte(b)
buf.WriteByte(b)
buf.WriteByte(b)
buf.WriteByte(b)
} else if pcode == 0xb0 {
buf.WriteByte(b)
buf.WriteByte(0xb0)
buf.WriteByte(0x00)
buf.WriteByte(0x3c)
buf.WriteByte(0x00)
buf.WriteByte(0x80)
switch pcode {
case 0x00:
buf, pageLength = InquiryPage0x00(host, cmd)
for i := 0; i < 58; i++ {
buf.WriteByte(0x00)
}
case 0x80:
buf, pageLength = InquiryPage0x80(host, cmd)
case 0x83:
buf, pageLength = InquiryPage0x83(host, cmd)
default:
goto sense
}
data = buf.Bytes()
if allocationLength < pageLength {
cmd.InSDBBuffer.Buffer = bytes.NewBuffer(data[0:allocationLength])
} else {
buf.WriteByte(b)
buf.WriteByte(0xb0)
buf.WriteByte(0x00)
buf.WriteByte(0x00)
buf.WriteByte(0x00)
cmd.InSDBBuffer.Buffer = bytes.NewBuffer(data[0:])
}
} else {
buf.WriteByte(b)
//byte 5
//SCCS(0) AAC(0) TPGS(0) 3PC(0) PROTECT(0)
addBuf.WriteByte(0x00)
//byte 6
//ENCSERV(0) VS(0) MULTIP(0) ADDR16(0)
addBuf.WriteByte(0x00)
//byte 7
//WBUS16(0) SYNC(0) CMDQUE(1) VS1(0)
addBuf.WriteByte(INQUIRY_CMDQUE)
copy(vendorID, []byte(cmd.Device.Attrs.VendorID))
addBuf.Write(vendorID)
copy(productID, []byte(cmd.Device.Attrs.ProductID))
addBuf.Write(productID)
copy(productRev, []byte(cmd.Device.Attrs.ProductRev))
addBuf.Write(productRev)
//Vendor specific(20 bytes)
for i := 0; i < 20; i++ {
addBuf.WriteByte(0x00)
}
//byte 56
addBuf.WriteByte(0x00)
//byte 57
addBuf.WriteByte(0x00)
//VERSION DESCRIPTOR 1 ~ 8
binary.Write(addBuf, binary.BigEndian, cmd.Device.Attrs.VersionDesction)
addBufData = addBuf.Bytes()
additionLength = byte(len(addBufData))
//Write header
//byte 0
//PERIPHERAL QUALIFIER, PERIPHERAL DEVICE TYPE
if cmd.Device.Attrs.Online {
buf.WriteByte(PQ_DEVICE_CONNECTED | byte(cmd.Device.Attrs.DeviceType))
} else {
buf.WriteByte(PQ_DEVICE_NOT_CONNECT | byte(cmd.Device.Attrs.DeviceType))
}
// byte 1
// RMB(0) LU_CONG(0)
buf.WriteByte(0x00)
// version byte
// byte 2
// VERSION
buf.WriteByte(VERSION_WITHDRAW_SPC3)
// byte 3
// Reserved, Reserved, NORMACA, HISUP, RESPONSE DATA FORMAT
buf.WriteByte(INQUIRY_HISUP | INQUIRY_STANDARD_FORMAT)
// byte 4
// ADDITIONAL LENGTH
buf.WriteByte(0x00)
// byte 5
/*
* SCCS(0) AAC(0) TPGS(0) 3PC(0) PROTECT(0)
*/
buf.WriteByte(0x00)
// byte 6
buf.WriteByte(0x00)
buf.WriteByte(0x02)
buf.Write([]byte{'1', '1', 'c', 'a', 'n', 's'})
buf.WriteByte(0x00)
buf.WriteByte(0x00)
buf.Write([]byte{'c', 'o', 'f', 'f', 'e', 'e'})
for i := 0; i < 10; i++ {
buf.WriteByte(0x00)
buf.WriteByte(additionLength)
buf.Write(addBufData)
data = buf.Bytes()
if allocationLength < uint16(additionLength) {
cmd.InSDBBuffer.Buffer = bytes.NewBuffer(data[0:allocationLength])
} else {
cmd.InSDBBuffer.Buffer = bytes.NewBuffer(data[0:])
}
buf.Write([]byte{'1', '.', '0'})
buf.WriteByte(0x00)
}
data = buf.Bytes()
data[4] = byte(len(data) - 4)
cmd.InSDBBuffer.Buffer = bytes.NewBuffer(data)
return api.SAMStatGood
sense:
BuildSenseData(cmd, ILLEGAL_REQUEST, ASC_INVALID_FIELD_IN_CDB)
@@ -302,7 +488,7 @@ func SPCReportLuns(host int, cmd *api.SCSICommand) api.SAMStat {
buf.Write(util.MarshalUint32(availLength))
cmd.InSDBBuffer.Resid = int32(actualLength)
// Skip through to byte 8, Reserved
// Skip through to byte 4, Reserved
for i := 0; i < 4; i++ {
buf.WriteByte(0x00)
}

View File

@@ -17,5 +17,6 @@ limitations under the License.
package version
const (
VERSION = "0.1"
VERSION = "0.1"
SCSI_VERSION = "0.1" /* SCSI version string MUST be shorter than 4 characters*/
)