#!/bin/ash
# GPL www.puppylinux.com
# DEVICE|TYPE|DESC

## MMC - SD cards
#  Some laptops with built in SD card readers report SD cards as /dev/sd* and usb
#    /sys/block/sdb -> ../devices/pci0000:00/0000:00:1d.7/usb1/1-8/1-8:1.0/host6/target6:0:0/6:0:0:0/block/sdb
#  Raspberry Pi
#    /sys/block/mmcblk0 -> ../devices/platform/soc/3f202000.sdhost/mmc_host/mmc0/mmc0:aaaa/block/mmcblk0


#PLUS_SIZE=yes # alternative format: DEVICE|TYPE|DESC|SIZE
#HDPARM=yes
SHOW_USBFLASH=yes
SHOW_EXTENDED_USB=yes
CARD_AS_USBFLASH=yes

device=${@##*/}

###############################################################

if [ "$device" ] ; then
	ALLDRVS=${device} #process cli argument
	CLI_ARG=1
else
	if [ -e /proc/ide ] ; then
		ALLDRVS="`ls -1 /sys/block | grep -E '^fd|^scd|^sd|^mmc|^sr' | tr '\n' ' '``ls -1 /proc/ide | grep '^hd' | tr '\n' ' '`"
	else
		ALLDRVS="`ls -1 /sys/block | grep -E '^fd|^scd|^sd|^mmc|^sr' | tr '\n' ' '`"
	fi
fi

###############################################################

for DRV in ${ALLDRVS} ; do

	if [ "$CLI_ARG" != "" ] ; then
		if [ ! -e /sys/block/${DRV} -a ! -e /proc/ide/${DRV} ] ; then
			echo "${DRV}: invalid drive" 1>&2
			continue
		fi
	fi

	vendor=""
	model=""
	size=""
	removable=""
	usb=""
	[ -f /sys/block/${DRV}/device/vendor ] && read -r vendor < /sys/block/${DRV}/device/vendor
	[ -f /sys/block/${DRV}/device/model ] && read -r model < /sys/block/${DRV}/device/model
	[ -f /sys/block/${DRV}/size ] && read -r size < /sys/block/${DRV}/size
	[ -f /sys/block/${DRV}/removable ] && read -r removable < /sys/block/${DRV}/removable
	info="$vendor $model"

	type=drive
	case $(readlink /sys/block/${DRV}) in *usb*) usb=yes ;; esac

	if [ -e /sys/block/${DRV}/device/type ] ; then
		# http://lxr.free-electrons.com/source/include/scsi/scsi.h?v=3.12
		case $(cat /sys/block/${DRV}/device/type) in
			0) #define TYPE_DISK 0x00
				type='drive'
				[ "$usb" = "yes" ] && type="usbdrv"
				;;
			5) #define TYPE_ROM 0x05
				type='optical' #see below
				;;
		esac
	fi

	case ${DRV} in
		fd*)  type=floppy  ;;
		scd*) type=optical ;; #old stuff
		mmc*)
			if [ "$SHOW_USBFLASH" = "yes" -a "$CARD_AS_USBFLASH" = "yes" ] ; then
				type=usbflash
			else
				type=card
			fi
			info="MMC/SD: $info"
			;;
	esac

	# -- legacy: /proc/ide - special case
	if [ -e /proc/ide ] ; then #legacy
		[ -f /proc/ide/${DRV}/model ] && read -r info < /proc/ide/${DRV}/model 
		[ -f /proc/ide/${DRV}/media ] && read -r media < /proc/ide/${DRV}/media
		case ${DRV} in
			sd*) # usb hd drives and usb flash drives appear as sdX
				usb=yes #will be used in the usbflash check
				type=usbdrv
				;;
			hd*) # somtimes optical drives appear as hdX... must check
				if [ "$media" = "cdrom" ] ; then
					type=optical # hard to tell what hdX drives are usb optical drives
				else
					[ "$removable" = "1" ] && usb=yes #not sure about this.. just in case
				fi
				;;
		esac
	fi
	# --

	## -- legacy: properly identify a floppy
	if [ "$type" = "usbdrv" ] ; then
		# find out if a usb floppy drive...
		[ "$size" = "2880" ] && type=floppy
		# if the floppy diskette not inserted, try this fallback test...
		# some examples: Vendor: NEC Model: USB UF000x Rev: 1.50, Sony USB Floppy Drive, rev 1.10/5.01,
		# MITUMI USB FDD, VenDor: TEAC Model: FD-05PUB, Vendor: COMPAQ Model: USB EXT FLOPPY
		case "$model" in *" FDD"*|*" UF000x"*|*"Floppy"*|*"USB-FDU"*|"FD-"*|*"FLOPPY"*) type=floppy ;; esac
	else
		# find out if it is a removable internal drive (zip, ls120, etc)...
		case ${DRV} in sd*) [ "$removable" = "1" ] && type=floppy ;; esac
	fi
	# might be a "fake" floppy device. have to check..
	[ "$type" = "floppy" -a "$model" = "" -a "$vendor" = "" ] && continue
	# --

	case $type in drive|usbdrive) # -hdparm
		if [ "$HDPARM" = "yes" -a "$removable" != "1" ] ; then
			modelx="$(hdparm -i /dev/${DRV} 2>/dev/null | grep Model | cut -f 1 -d ',' | cut -f 2 -d '=' | tr -s ' ')"
			[ "$modelx" != "" ] && info="$vendor $modelx"
		fi
	esac

	if [ "$usb" = "yes" ] ; then
		[ "$SHOW_USBFLASH" = "yes" -a "$type" = "usbdrv" -a "$removable" = "1" ] && type='usbflash'
		[ "$SHOW_EXTENDED_USB" = "yes" -a "$type" = "floppy" ] && type='usbfloppy'
		[ "$SHOW_EXTENDED_USB" = "yes" -a "$type" = "optical" ] && type='usboptical'
	fi

	# print results
	OUTPUT_STR="/dev/${DRV}|$type|$info"
	[ "$PLUS_SIZE" = "yes" ] && OUTPUT_STR="${OUTPUT_STR}|$size"
	echo "$OUTPUT_STR"
done

### END ###
