ata.go
func ataRead(r *ATAArg, rs io.ReadSeeker) (*ATAArg, error) {
	// Only ATA reads allowed here
	if r.CmdStatus != ATACmdStatusRead28Bit && r.CmdStatus != ATACmdStatusRead48Bit {
		return nil, errATAAbort
	}

	// Read must not be flagged as a write
	if r.FlagWrite {
		return nil, errATAAbort
	}

	// Convert LBA to byte offset and seek to correct location
	offset := calculateLBA(r.LBA, r.FlagLBA48Extended) * sectorSize
	if _, err := rs.Seek(offset, os.SEEK_SET); err != nil {
		return nil, err
	}

	// Allocate buffer and read exact (sector count * sector size) bytes from
	// stream
	//
	// TODO(mdlayher): use r.Data instead of allocating?
	b := make([]byte, int(r.SectorCount)*sectorSize)
	n, err := rs.Read(b)
	if err != nil {
		return nil, err
	}

	// Verify sector count
	if sectors := n / sectorSize; sectors != int(r.SectorCount) {
		return nil, errATAAbort
	}

	return &ATAArg{
		CmdStatus: ATACmdStatusReadyStatus,
		Data:      b,
	}, nil
}
func ataRead(r *ATAArg, rs io.ReadSeeker) (*ATAArg, error) {
	// Only ATA reads allowed here
	if r.CmdStatus != ATACmdStatusRead28Bit && r.CmdStatus != ATACmdStatusRead48Bit {
		return nil, errATAAbort
	}

	// Read must not be flagged as a write
	if r.FlagWrite {
		return nil, errATAAbort
	}

	// Convert LBA to byte offset and seek to correct location
	offset := calculateLBA(r.LBA, r.FlagLBA48Extended) * sectorSize
	if _, err := rs.Seek(offset, os.SEEK_SET); err != nil {
		return nil, err
	}

	// Allocate buffer and read exact (sector count * sector size) bytes from
	// stream
	//
	// TODO(mdlayher): use r.Data instead of allocating?
	b := make([]byte, int(r.SectorCount)*sectorSize)
	n, err := rs.Read(b)
	if err != nil {
		return nil, err
	}

	// Verify sector count
	if sectors := n / sectorSize; sectors != int(r.SectorCount) {
		return nil, errATAAbort
	}

	return &ATAArg{
		CmdStatus: ATACmdStatusReadyStatus,
		Data:      b,
	}, nil
}
// ataRead performs an ATA 28-bit or 48-bit read request on rs using the
// argument values in r.