github.com/openebs/node-disk-manager@v1.9.1-0.20230225014141-4531f06ffa1e/pkg/smart/scsiinquirypage.go (about)

     1  /*
     2  Copyright 2018 The OpenEBS Authors.
     3  Licensed under the Apache License, Version 2.0 (the "License");
     4  you may not use this file except in compliance with the License.
     5  You may obtain a copy of the License at
     6      http://www.apache.org/licenses/LICENSE-2.0
     7  Unless required by applicable law or agreed to in writing, software
     8  distributed under the License is distributed on an "AS IS" BASIS,
     9  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    10  See the License for the specific language governing permissions and
    11  limitations under the License.
    12  */
    13  
    14  // SCSI command definitions.
    15  
    16  package smart
    17  
    18  import (
    19  	"bytes"
    20  	"encoding/binary"
    21  	"fmt"
    22  )
    23  
    24  // commands used to fetch various information of a disk from a set of defined
    25  // scsi pages
    26  const (
    27  	SCSIInquiry = 0x12 // inquiry command
    28  
    29  	// Minimum length of standard INQUIRY response
    30  	INQRespLen = 56
    31  )
    32  
    33  // scsiInquiry sends an INQUIRY command to a SCSI device and returns an
    34  // InquiryResponse struct.
    35  func (d *SCSIDev) scsiInquiry() (InquiryResponse, error) {
    36  	var response InquiryResponse
    37  	respBuf := make([]byte, INQRespLen)
    38  
    39  	// Use cdb6 to send scsi inquiry command
    40  	// TODO: Use cdb10 or cdb16 also as a fallthrough command to if
    41  	// cdb6 fails for a particular device
    42  	cdb := CDB6{SCSIInquiry}
    43  
    44  	binary.BigEndian.PutUint16(cdb[3:], uint16(len(respBuf)))
    45  
    46  	// return error if sending scsi cdb6 command fails
    47  	if err := d.sendSCSICDB(cdb[:], &respBuf); err != nil {
    48  		return response, err
    49  	}
    50  
    51  	err := binary.Read(bytes.NewBuffer(respBuf), NativeEndian, &response)
    52  	if err != nil {
    53  		return response, fmt.Errorf("error in reading data, Error: %+v", err)
    54  	}
    55  
    56  	return response, nil
    57  }
    58  
    59  // getValue returns the value of the attributes fetched using inquiry
    60  // command using Inquiry response struct
    61  func (inquiry InquiryResponse) getValue() map[string]string {
    62  	InqRespMap := make(map[string]string)
    63  
    64  	SPCVersionValue := fmt.Sprintf("%.d", (inquiry.Version - 0x02))
    65  
    66  	InqRespMap[Compliance] = "SPC-" + SPCVersionValue
    67  	InqRespMap[Vendor] = fmt.Sprintf("%.8s", inquiry.VendorID)
    68  	InqRespMap[ModelNumber] = fmt.Sprintf("%.16s", inquiry.ProductID)
    69  	InqRespMap[FirmwareRev] = fmt.Sprintf("%.4s", inquiry.ProductRev)
    70  	InqRespMap[SerialNumber] = fmt.Sprintf("%.20s", inquiry.SerialNumber)
    71  	return InqRespMap
    72  }