sys/dev/scsi/sd.c
/*
 * Write `len' bytes from address `addr' to drive and partition in `dev',
 * at block blkoff from the beginning of the partition.  The address is
 * either kernel virtual or physical (some machines may never use one or
 * the other, but we need it in the protocol to stay machine-independent).
 */
Write `len' bytes from address `addr' to drive and partition in `dev',
at block blkoff from the beginning of the partition.  The address is
either kernel virtual or physical (some machines may never use one or
the other, but we need it in the protocol to stay machine-independent).
Write ` len ' bytes from address ` addr ' to drive and partition in ` dev ' at block blkoff from the beginning of the partition . The address is either kernel virtual or physical ( some machines may never use one or the other but we need it in the protocol to stay machine - independent ) .
int
sddump(dev_t dev, daddr_t blkoff, caddr_t addr, int len)
{
	register struct sd_softc *sc;
	register struct partition *p;
	register daddr_t bn, n, nblks;
	register struct hba_softc *hba;
	register int stat, unit;
	struct scsi_cdb cdb;
	unit = sdunit(dev);
	if (unit >= sdcd.cd_ndevs || (sc = sdcd.cd_devs[unit]) == NULL ||
	    (sc->sc_flags & SDF_ALIVE) == 0)
		return (ENXIO);
	p = &sc->sc_dk.dk_label.d_partitions[sdpart(dev)];
	n = (len + sc->sc_blksize - 1) >> DEV_BSHIFT;
	if (blkoff < 0 || blkoff >= p->p_size || blkoff + n > p->p_size)
		return (EINVAL);
	bn = blkoff + p->p_offset;
	bn >>= sc->sc_bshift;
	hba = sc->sc_unit.u_hba;
	if (hba->hba_head) {
		(*hba->hba_driver->hd_reset)(hba, 0);
		printf("[reset %s] ", sc->sc_dk.dk_dev.dv_xname);
	}
	CDB10(&cdb)->cdb_cmd = CMD_WRITE10;
	CDB10(&cdb)->cdb_lun_rel = sc->sc_unit.u_unit << 5;
	CDB10(&cdb)->cdb_xxx = 0;
	CDB10(&cdb)->cdb_ctrl = 0;
#define	DUMP_MAX	(32 * 1024)	/* no more than 32k per write */
	for (;;) {
		if ((n = len) > DUMP_MAX)
			n = DUMP_MAX;
		CDB10(&cdb)->cdb_lbah = bn >> 24;
		CDB10(&cdb)->cdb_lbahm = bn >> 16;
		CDB10(&cdb)->cdb_lbalm = bn >> 8;
		CDB10(&cdb)->cdb_lbal = bn;
		nblks = n >> (DEV_BSHIFT + sc->sc_bshift);
		CDB10(&cdb)->cdb_lenh = nblks >> 8;
		CDB10(&cdb)->cdb_lenl = nblks;
		stat = hba->hba_driver->hd_dump(hba, sc->sc_unit.u_targ,
		    &cdb, addr, n);
		if ((stat & STS_MASK) != STS_GOOD) {
			printf("%s: scsi write error 0x%x\ndump ",
			    sc->sc_dk.dk_dev.dv_xname, stat);
			return (EIO);
		}
		if ((len -= n) == 0)
			return (0);
		addr += n;
		bn += nblks;
	}
}
int sddump ( dev_t dev , daddr_t blkoff , caddr_t addr , int len ) { register struct sd_softc * sc ; register struct partition * p ; register daddr_t bn , n , nblks ; register struct hba_softc * hba ; register int stat , unit ; struct scsi_cdb cdb ; unit = sdunit ( dev ) ; if ( unit >= sdcd . cd_ndevs || ( sc = sdcd . cd_devs [ unit ] ) == NULL || ( sc -> sc_flags & SDF_ALIVE ) == 0 ) return ( ENXIO ) ; p = & sc -> sc_dk . dk_label . d_partitions [ sdpart ( dev ) ] ; n = ( len + sc -> sc_blksize - 1 ) >> DEV_BSHIFT ; if ( blkoff < 0 || blkoff >= p -> p_size || blkoff + n > p -> p_size ) return ( EINVAL ) ; bn = blkoff + p -> p_offset ; bn >>= sc -> sc_bshift ; hba = sc -> sc_unit . u_hba ; if ( hba -> hba_head ) { ( * hba -> hba_driver -> hd_reset ) ( hba , 0 ) ; printf ( " " , sc -> sc_dk . dk_dev . dv_xname ) ; } CDB10 ( & cdb ) -> cdb_cmd = CMD_WRITE10 ; CDB10 ( & cdb ) -> cdb_lun_rel = sc -> sc_unit . u_unit << 5 ; CDB10 ( & cdb ) -> cdb_xxx = 0 ; CDB10 ( & cdb ) -> cdb_ctrl = 0 ; #define DUMP_MAX 	(32 * 1024)	/* no more than 32k per write */ for ( ; ; ) { if ( ( n = len ) > DUMP_MAX ) n = DUMP_MAX ; CDB10 ( & cdb ) -> cdb_lbah = bn >> 24 ; CDB10 ( & cdb ) -> cdb_lbahm = bn >> 16 ; CDB10 ( & cdb ) -> cdb_lbalm = bn >> 8 ; CDB10 ( & cdb ) -> cdb_lbal = bn ; nblks = n >> ( DEV_BSHIFT + sc -> sc_bshift ) ; CDB10 ( & cdb ) -> cdb_lenh = nblks >> 8 ; CDB10 ( & cdb ) -> cdb_lenl = nblks ; stat = hba -> hba_driver -> hd_dump ( hba , sc -> sc_unit . u_targ , & cdb , addr , n ) ; if ( ( stat & STS_MASK ) != STS_GOOD ) { printf ( " \n " , sc -> sc_dk . dk_dev . dv_xname , stat ) ; return ( EIO ) ; } if ( ( len -= n ) == 0 ) return ( 0 ) ; addr += n ; bn += nblks ; } }
Write `len' bytes from address `addr' to drive and partition in `dev',
 at block blkoff from the beginning of the partition.
Write ` len ' bytes from address ` addr ' to drive and partition in ` dev ' at block blkoff from the beginning of the partition .
/* drive ok? */ /* blocks in range? */ /* scsi bus idle? */