ata.go
func ataWrite(r *ATAArg, rs io.ReadSeeker) (*ATAArg, error) {
	// Only ATA writes allowed here
	if r.CmdStatus != ATACmdStatusWrite28Bit && r.CmdStatus != ATACmdStatusWrite48Bit {
		return nil, errATAAbort
	}

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

	// Verify that request data and sector count match up
	if sectors := len(r.Data) / sectorSize; sectors != int(r.SectorCount) {
		return nil, errATAAbort
	}

	// Determine if io.ReadSeeker is also an io.Writer, and if a write is
	// requested
	rws, ok := rs.(io.ReadWriteSeeker)
	if !ok {
		// A write was requested, but the io.ReadSeeker is not an io.Writer
		return nil, errATAAbort
	}

	// TODO(mdlayher): implement asynchronous writes

	// 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
	}

	// Write data to stream
	n, err := rws.Write(r.Data)
	if err != nil {
		return nil, err
	}

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

	return &ATAArg{
		CmdStatus: ATACmdStatusReadyStatus,
	}, nil
}
func ataWrite(r *ATAArg, rs io.ReadSeeker) (*ATAArg, error) {
	// Only ATA writes allowed here
	if r.CmdStatus != ATACmdStatusWrite28Bit && r.CmdStatus != ATACmdStatusWrite48Bit {
		return nil, errATAAbort
	}

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

	// Verify that request data and sector count match up
	if sectors := len(r.Data) / sectorSize; sectors != int(r.SectorCount) {
		return nil, errATAAbort
	}

	// Determine if io.ReadSeeker is also an io.Writer, and if a write is
	// requested
	rws, ok := rs.(io.ReadWriteSeeker)
	if !ok {
		// A write was requested, but the io.ReadSeeker is not an io.Writer
		return nil, errATAAbort
	}

	// TODO(mdlayher): implement asynchronous writes

	// 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
	}

	// Write data to stream
	n, err := rws.Write(r.Data)
	if err != nil {
		return nil, err
	}

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

	return &ATAArg{
		CmdStatus: ATACmdStatusReadyStatus,
	}, nil
}
func ataWrite ( r * ATAArg , rs io . ReadSeeker ) ( * ATAArg , error ) { // Only ATA writes allowed here if r . CmdStatus != ATACmdStatusWrite28Bit && r . CmdStatus != ATACmdStatusWrite48Bit { return nil , errATAAbort } // Write must be flagged as a write if ! r . FlagWrite { return nil , errATAAbort } // Verify that request data and sector count match up if sectors := len ( r . Data ) / sectorSize ; sectors != int ( r . SectorCount ) { return nil , errATAAbort } // Determine if io.ReadSeeker is also an io.Writer, and if a write is // requested rws , ok := rs . ( io . ReadWriteSeeker ) if ! ok { // A write was requested, but the io.ReadSeeker is not an io.Writer return nil , errATAAbort } // TODO(mdlayher): implement asynchronous writes // 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 } // Write data to stream n , err := rws . Write ( r . Data ) if err != nil { return nil , err } // Verify full sectors written to disk using sector count if sectors := n / sectorSize ; sectors != int ( r . SectorCount ) { return nil , errATAAbort } return & ATAArg { CmdStatus : ATACmdStatusReadyStatus , } , nil }
// ataWrite performs an ATA 28-bit or 48-bit write request on rs using the
// argument values in r.
ataWrite performs an ATA 28 - bit or 48 - bit write request on rs using the argument values in r .