Training courses

Kernel and Embedded Linux

Bootlin training courses

Embedded Linux, kernel,
Yocto Project, Buildroot, real-time,
graphics, boot time, debugging...

Bootlin logo

Elixir Cross Referencer

#!/bin/sh
#
# $FreeBSD$
#

# PROVIDE: cfumass
# REQUIRE: var
# KEYWORD: nojail

. /etc/rc.subr

name="cfumass"
desc="Configure the LUN for device mode USB mass storage"
rcvar="cfumass_enable"

start_cmd="${name}_start"
stop_cmd="${name}_stop"

extra_commands="reload"
reload_cmd="${name}_start"

: ${cfumass_dir:=/var/cfumass}
: ${cfumass_image:=/var/tmp/cfumass.img}
: ${cfumass_vendor:="FreeBSD"}
: ${cfumass_product:="cfumass(4)"}

remove_luns()
{
	local _lun _luns

	_luns=`ctladm devlist -b block -v | awk '

	$1 ~ /^[0-9]+$/ {
		lun = $1
	}

	$1 == "file='"${cfumass_image}"'" {
		print lun
	}'`

	for _lun in ${_luns}; do
		ctladm remove -b block -l "${_lun}" > /dev/null
	done
}

cfumass_start()
{
	local err _files _template _new_template

	if [ ! -d "${cfumass_dir}" ]; then
		warn "${cfumass_dir} does not exist"
		return 1
	fi

	_files=`find "${cfumass_dir}" -newer "${cfumass_image}" -print 2> /dev/null`
	if [ ! -e "${cfumass_image}" -o -n "${_files}" ]; then
		# The image doesn't exist or is out of date.
		makefs -t cd9660 -o label="${cfumass_vendor}" \
		    -o rockridge "${cfumass_image}" "${cfumass_dir}"
		err=$?
		if [ "${err}" -ne 0 ]; then
			warn "unable to create ${cfumass_image}"
			return "${err}"
		fi
	fi

	remove_luns

	ctladm create -b block -o file="${cfumass_image}" -o readonly=on \
	    -o vendor="${cfumass_vendor}" -o product="${cfumass_product}" \
	    -S 0 > /dev/null
	err=$?
	if [ "${err}" -ne 0 ]; then
		warn "unable to create CTL LUN"
		return "${err}"
	fi

	load_kld -e cfumass cfumass

	# If the template is already switched to Mass Storage, then reset
	# it to -1 to force the host to reenumerate it; otherwise it might
	# not notice the new LUN.
	_template=`sysctl -n hw.usb.template`
	if [ "${_template}" -eq 0 ]; then
		sysctl hw.usb.template=-1 > /dev/null
		err=$?
		if [ "${err}" -ne 0 ]; then
			warn "unable to set hw.usb.template sysctl"
			return "${err}"
		fi
	fi

	# Set the template number based on the current one.
	_template=`sysctl -n hw.usb.template`
	case "${_template}" in
	-1)
		_new_template="0"
		;;
	8)
		_new_template="10"
		;;
	*)
		warn "hw.usb.template sysctl set to neither -1 nor 8; not changing"
		_new_template=""
		;;
	esac
		
	if [ -n "${_new_template}" ]; then
		sysctl hw.usb.template="${_new_template}" > /dev/null
		err=$?
		if [ "${err}" -ne 0 ]; then
			warn "unable to set hw.usb.template sysctl to ${_new_template}"
			return "${err}"
		fi
	fi
}

cfumass_stop()
{
	local err _template _new_template

	remove_luns

	_template=`sysctl -n hw.usb.template`
	case "${_template}" in
	0)
		_new_template="-1"
		;;
	10)
		_new_template="8"
		;;
	*)
		warn "hw.usb.template sysctl set to neither 0 nor 10; not changing"
		_new_template=""
		;;
	esac
		
	if [ -n "${_new_template}" ]; then
		sysctl hw.usb.template="${_new_template}" > /dev/null
		err=$?
		if [ "${err}" -ne 0 ]; then
			warn "unable to set hw.usb.template sysctl to ${_new_template}"
			return "${err}"
		fi
	fi
}

load_rc_config $name
run_rc_command "$1"