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 VendorID string
ProductID string ProductID string
ProductRev string ProductRev string
VersionDesction []uint16 VersionDesction [8]uint16
// Peripheral device type // Peripheral device type
DeviceType SCSIDeviceType DeviceType SCSIDeviceType
// Peripheral Qualifier // Peripheral Qualifier

View File

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

View File

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

View File

@@ -42,15 +42,17 @@ import (
*/ */
const ( const (
PIV_FCP = iota PIV_FCP = byte(0x00)
PIV_SPI PIV_SPI = byte(0x01)
PIV_S3P PIV_S3P = byte(0x02)
PIV_SBP PIV_SBP = byte(0x03)
PIV_SRP PIV_SRP = byte(0x04)
PIV_ISCSI PIV_ISCSI = byte(0x05)
PIV_SAS PIV_SAS = byte(0x06)
PIV_ADT PIV_ADT = byte(0x07)
PIV_ATA PIV_ATA = byte(0x08)
PIV_USB = byte(0x09)
PIV_SOP = byte(0x0A)
) )
const ( const (
@@ -67,12 +69,11 @@ const (
* 2 - Designator field contains ASCII printable chars * 2 - Designator field contains ASCII printable chars
* 3 - Designaotor field contains UTF-8 * 3 - Designaotor field contains UTF-8
*/ */
type CodeSet byte
var ( const (
INQ_CODE_BIN CodeSet = 1 INQ_CODE_BIN = byte(1)
INQ_CODE_ASCII CodeSet = 2 INQ_CODE_ASCII = byte(2)
INQ_CODE_UTF8 CodeSet = 3 INQ_CODE_UTF8 = byte(3)
) )
/* /*
@@ -83,12 +84,11 @@ var (
* 10b - Associated with SCSI Target device * 10b - Associated with SCSI Target device
* 11b - Reserved * 11b - Reserved
*/ */
type AssociationField byte
var ( const (
ASS_LU AssociationField = 0 ASS_LU = byte(0x00)
ASS_TGT_PORT AssociationField = 0x10 ASS_TGT_PORT = byte(0x01)
ASS_TGT_DEV AssociationField = 0x20 ASS_TGT_DEV = byte(0x02)
) )
/* /*
@@ -112,10 +112,10 @@ var (
*/ */
const ( const (
PQ_DEVICE_CONNECTED = byte(0x00) PQ_DEVICE_CONNECTED = byte(0x00 << 5)
PQ_DEVICE_NOT_CONNECT = byte(0x01) PQ_DEVICE_NOT_CONNECT = byte(0x01 << 5)
PQ_RESERVED = byte(0x02) PQ_RESERVED = byte(0x02 << 5)
PQ_NOT_SUPPORT = byte(0x03) PQ_NOT_SUPPORT = byte(0x03 << 5)
) )
const ( const (
@@ -132,6 +132,19 @@ const (
INQUIRY_NORM_ACA = byte(0x20) INQUIRY_NORM_ACA = byte(0x20)
INQUIRY_HISUP = byte(0x10) INQUIRY_HISUP = byte(0x10)
INQUIRY_STANDARD_FORMAT = byte(0x02) 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 ( const (
@@ -167,6 +180,18 @@ const (
DESG_SCSI 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 { func SPCIllegalOp(host int, cmd *api.SCSICommand) api.SAMStat {
return api.SAMStatGood return api.SAMStatGood
} }
@@ -185,90 +210,251 @@ func SPCLuOnline(lu *api.SCSILu) error {
return nil 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 { func SPCInquiry(host int, cmd *api.SCSICommand) api.SAMStat {
var ( var (
buf = &bytes.Buffer{} allocationLength uint16
data []byte = []byte{} pageLength uint16
b byte = 0x75 additionLength byte
buf = &bytes.Buffer{}
data []byte = []byte{}
addBuf = &bytes.Buffer{}
addBufData []byte = []byte{}
//b byte = 0x75
scb []byte = cmd.SCB.Bytes() scb []byte = cmd.SCB.Bytes()
pcode byte = scb[2] pcode byte = scb[2]
evpd bool = false 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 { if scb[1]&0x01 > 0 {
evpd = true evpd = true
} }
if cmd.Device == nil { if cmd.Device == nil {
b = (uint8(0) & 0x7) << 5
b |= uint8(0) & 0x1f
goto sense 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 evpd {
if pcode == 0x0 { switch pcode {
buf.WriteByte(b) case 0x00:
b = 0 buf, pageLength = InquiryPage0x00(host, cmd)
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)
for i := 0; i < 58; i++ { case 0x80:
buf.WriteByte(0x00) 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 { } else {
buf.WriteByte(b) cmd.InSDBBuffer.Buffer = bytes.NewBuffer(data[0:])
buf.WriteByte(0xb0)
buf.WriteByte(0x00)
buf.WriteByte(0x00)
buf.WriteByte(0x00)
} }
} else { } 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) // RMB(0) LU_CONG(0)
buf.WriteByte(0x00) buf.WriteByte(0x00)
// version byte // byte 2
// VERSION
buf.WriteByte(VERSION_WITHDRAW_SPC3) buf.WriteByte(VERSION_WITHDRAW_SPC3)
// byte 3
// Reserved, Reserved, NORMACA, HISUP, RESPONSE DATA FORMAT // Reserved, Reserved, NORMACA, HISUP, RESPONSE DATA FORMAT
buf.WriteByte(INQUIRY_HISUP | INQUIRY_STANDARD_FORMAT) buf.WriteByte(INQUIRY_HISUP | INQUIRY_STANDARD_FORMAT)
// byte 4
// ADDITIONAL LENGTH // ADDITIONAL LENGTH
buf.WriteByte(0x00) buf.WriteByte(additionLength)
// byte 5
/* buf.Write(addBufData)
* SCCS(0) AAC(0) TPGS(0) 3PC(0) PROTECT(0) data = buf.Bytes()
*/ if allocationLength < uint16(additionLength) {
buf.WriteByte(0x00) cmd.InSDBBuffer.Buffer = bytes.NewBuffer(data[0:allocationLength])
// byte 6 } else {
buf.WriteByte(0x00) cmd.InSDBBuffer.Buffer = bytes.NewBuffer(data[0:])
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.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 return api.SAMStatGood
sense: sense:
BuildSenseData(cmd, ILLEGAL_REQUEST, ASC_INVALID_FIELD_IN_CDB) 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)) buf.Write(util.MarshalUint32(availLength))
cmd.InSDBBuffer.Resid = int32(actualLength) cmd.InSDBBuffer.Resid = int32(actualLength)
// Skip through to byte 8, Reserved // Skip through to byte 4, Reserved
for i := 0; i < 4; i++ { for i := 0; i < 4; i++ {
buf.WriteByte(0x00) buf.WriteByte(0x00)
} }

View File

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