FreeBSD/sys/cam/ctl/ctl.c
/*
 * For known CDB types, parse the LBA and length.
 */
For known CDB types, parse the LBA and length.
For known CDB types parse the LBA and length .
static int
ctl_get_lba_len(union ctl_io *io, uint64_t *lba, uint64_t *len)
{
	if (io->io_hdr.io_type != CTL_IO_SCSI)
		return (1);
	switch (io->scsiio.cdb[0]) {
	case COMPARE_AND_WRITE: {
		struct scsi_compare_and_write *cdb;
		cdb = (struct scsi_compare_and_write *)io->scsiio.cdb;
		*lba = scsi_8btou64(cdb->addr);
		*len = cdb->length;
		break;
	}
	case READ_6:
	case WRITE_6: {
		struct scsi_rw_6 *cdb;
		cdb = (struct scsi_rw_6 *)io->scsiio.cdb;
		*lba = scsi_3btoul(cdb->addr);
		*lba &= 0x1fffff;
		*len = cdb->length;
		break;
	}
	case READ_10:
	case WRITE_10: {
		struct scsi_rw_10 *cdb;
		cdb = (struct scsi_rw_10 *)io->scsiio.cdb;
		*lba = scsi_4btoul(cdb->addr);
		*len = scsi_2btoul(cdb->length);
		break;
	}
	case WRITE_VERIFY_10: {
		struct scsi_write_verify_10 *cdb;
		cdb = (struct scsi_write_verify_10 *)io->scsiio.cdb;
		*lba = scsi_4btoul(cdb->addr);
		*len = scsi_2btoul(cdb->length);
		break;
	}
	case READ_12:
	case WRITE_12: {
		struct scsi_rw_12 *cdb;
		cdb = (struct scsi_rw_12 *)io->scsiio.cdb;
		*lba = scsi_4btoul(cdb->addr);
		*len = scsi_4btoul(cdb->length);
		break;
	}
	case WRITE_VERIFY_12: {
		struct scsi_write_verify_12 *cdb;
		cdb = (struct scsi_write_verify_12 *)io->scsiio.cdb;
		*lba = scsi_4btoul(cdb->addr);
		*len = scsi_4btoul(cdb->length);
		break;
	}
	case READ_16:
	case WRITE_16: {
		struct scsi_rw_16 *cdb;
		cdb = (struct scsi_rw_16 *)io->scsiio.cdb;
		*lba = scsi_8btou64(cdb->addr);
		*len = scsi_4btoul(cdb->length);
		break;
	}
	case WRITE_ATOMIC_16: {
		struct scsi_write_atomic_16 *cdb;
		cdb = (struct scsi_write_atomic_16 *)io->scsiio.cdb;
		*lba = scsi_8btou64(cdb->addr);
		*len = scsi_2btoul(cdb->length);
		break;
	}
	case WRITE_VERIFY_16: {
		struct scsi_write_verify_16 *cdb;
		cdb = (struct scsi_write_verify_16 *)io->scsiio.cdb;
		*lba = scsi_8btou64(cdb->addr);
		*len = scsi_4btoul(cdb->length);
		break;
	}
	case WRITE_SAME_10: {
		struct scsi_write_same_10 *cdb;
		cdb = (struct scsi_write_same_10 *)io->scsiio.cdb;
		*lba = scsi_4btoul(cdb->addr);
		*len = scsi_2btoul(cdb->length);
		break;
	}
	case WRITE_SAME_16: {
		struct scsi_write_same_16 *cdb;
		cdb = (struct scsi_write_same_16 *)io->scsiio.cdb;
		*lba = scsi_8btou64(cdb->addr);
		*len = scsi_4btoul(cdb->length);
		break;
	}
	case VERIFY_10: {
		struct scsi_verify_10 *cdb;
		cdb = (struct scsi_verify_10 *)io->scsiio.cdb;
		*lba = scsi_4btoul(cdb->addr);
		*len = scsi_2btoul(cdb->length);
		break;
	}
	case VERIFY_12: {
		struct scsi_verify_12 *cdb;
		cdb = (struct scsi_verify_12 *)io->scsiio.cdb;
		*lba = scsi_4btoul(cdb->addr);
		*len = scsi_4btoul(cdb->length);
		break;
	}
	case VERIFY_16: {
		struct scsi_verify_16 *cdb;
		cdb = (struct scsi_verify_16 *)io->scsiio.cdb;
		*lba = scsi_8btou64(cdb->addr);
		*len = scsi_4btoul(cdb->length);
		break;
	}
	case UNMAP: {
		*lba = 0;
		*len = UINT64_MAX;
		break;
	}
	case SERVICE_ACTION_IN: {	
		struct scsi_get_lba_status *cdb;
		cdb = (struct scsi_get_lba_status *)io->scsiio.cdb;
		*lba = scsi_8btou64(cdb->addr);
		*len = UINT32_MAX;
		break;
	}
	default:
		return (1);
		break; 
	}
	return (0);
}
static int ctl_get_lba_len ( union ctl_io * io , uint64_t * lba , uint64_t * len ) { if ( io -> io_hdr . io_type != CTL_IO_SCSI ) return ( 1 ) ; switch ( io -> scsiio . cdb [ 0 ] ) { case COMPARE_AND_WRITE : { struct scsi_compare_and_write * cdb ; cdb = ( struct scsi_compare_and_write * ) io -> scsiio . cdb ; * lba = scsi_8btou64 ( cdb -> addr ) ; * len = cdb -> length ; break ; } case READ_6 : case WRITE_6 : { struct scsi_rw_6 * cdb ; cdb = ( struct scsi_rw_6 * ) io -> scsiio . cdb ; * lba = scsi_3btoul ( cdb -> addr ) ; * lba &= 0x1fffff ; * len = cdb -> length ; break ; } case READ_10 : case WRITE_10 : { struct scsi_rw_10 * cdb ; cdb = ( struct scsi_rw_10 * ) io -> scsiio . cdb ; * lba = scsi_4btoul ( cdb -> addr ) ; * len = scsi_2btoul ( cdb -> length ) ; break ; } case WRITE_VERIFY_10 : { struct scsi_write_verify_10 * cdb ; cdb = ( struct scsi_write_verify_10 * ) io -> scsiio . cdb ; * lba = scsi_4btoul ( cdb -> addr ) ; * len = scsi_2btoul ( cdb -> length ) ; break ; } case READ_12 : case WRITE_12 : { struct scsi_rw_12 * cdb ; cdb = ( struct scsi_rw_12 * ) io -> scsiio . cdb ; * lba = scsi_4btoul ( cdb -> addr ) ; * len = scsi_4btoul ( cdb -> length ) ; break ; } case WRITE_VERIFY_12 : { struct scsi_write_verify_12 * cdb ; cdb = ( struct scsi_write_verify_12 * ) io -> scsiio . cdb ; * lba = scsi_4btoul ( cdb -> addr ) ; * len = scsi_4btoul ( cdb -> length ) ; break ; } case READ_16 : case WRITE_16 : { struct scsi_rw_16 * cdb ; cdb = ( struct scsi_rw_16 * ) io -> scsiio . cdb ; * lba = scsi_8btou64 ( cdb -> addr ) ; * len = scsi_4btoul ( cdb -> length ) ; break ; } case WRITE_ATOMIC_16 : { struct scsi_write_atomic_16 * cdb ; cdb = ( struct scsi_write_atomic_16 * ) io -> scsiio . cdb ; * lba = scsi_8btou64 ( cdb -> addr ) ; * len = scsi_2btoul ( cdb -> length ) ; break ; } case WRITE_VERIFY_16 : { struct scsi_write_verify_16 * cdb ; cdb = ( struct scsi_write_verify_16 * ) io -> scsiio . cdb ; * lba = scsi_8btou64 ( cdb -> addr ) ; * len = scsi_4btoul ( cdb -> length ) ; break ; } case WRITE_SAME_10 : { struct scsi_write_same_10 * cdb ; cdb = ( struct scsi_write_same_10 * ) io -> scsiio . cdb ; * lba = scsi_4btoul ( cdb -> addr ) ; * len = scsi_2btoul ( cdb -> length ) ; break ; } case WRITE_SAME_16 : { struct scsi_write_same_16 * cdb ; cdb = ( struct scsi_write_same_16 * ) io -> scsiio . cdb ; * lba = scsi_8btou64 ( cdb -> addr ) ; * len = scsi_4btoul ( cdb -> length ) ; break ; } case VERIFY_10 : { struct scsi_verify_10 * cdb ; cdb = ( struct scsi_verify_10 * ) io -> scsiio . cdb ; * lba = scsi_4btoul ( cdb -> addr ) ; * len = scsi_2btoul ( cdb -> length ) ; break ; } case VERIFY_12 : { struct scsi_verify_12 * cdb ; cdb = ( struct scsi_verify_12 * ) io -> scsiio . cdb ; * lba = scsi_4btoul ( cdb -> addr ) ; * len = scsi_4btoul ( cdb -> length ) ; break ; } case VERIFY_16 : { struct scsi_verify_16 * cdb ; cdb = ( struct scsi_verify_16 * ) io -> scsiio . cdb ; * lba = scsi_8btou64 ( cdb -> addr ) ; * len = scsi_4btoul ( cdb -> length ) ; break ; } case UNMAP : { * lba = 0 ; * len = UINT64_MAX ; break ; } case SERVICE_ACTION_IN : { struct scsi_get_lba_status * cdb ; cdb = ( struct scsi_get_lba_status * ) io -> scsiio . cdb ; * lba = scsi_8btou64 ( cdb -> addr ) ; * len = UINT32_MAX ; break ; } default : return ( 1 ) ; break ; } return ( 0 ) ; }
For known CDB types, parse the LBA and length.
For known CDB types parse the LBA and length .
/* only 5 bits are valid in the most significant address byte */ /* GET LBA STATUS */ /* NOTREACHED */