Creating udev rule for USB DAC

Target:

Create a new udev rule which will:

Stop the Jack Daemon if DAC power off

Start the Jack Daemon if DAC power on

Identify USB DAC Card:

Power on USB DAC

Check the name of USB DAC

ls -l /proc/asound/
lrwxrwxrwx 1 root root 5 11月 22 17:55 AUDIO -> card2
dr-xr-xr-x 3 root root 0 11月 16 18:43 card0
dr-xr-xr-x 4 root root 0 11月 16 18:43 card1
dr-xr-xr-x 4 root root 0 11月 22 17:55 card2
-r–r–r– 1 root root 0 11月 16 16:36 cards
-r–r–r– 1 root root 0 11月 16 18:43 devices
lrwxrwxrwx 1 root root 5 11月 16 18:43 Generic -> card0
-r–r–r– 1 root root 0 11月 16 18:43 hwdep
-r–r–r– 1 root root 0 11月 16 18:43 modules
dr-xr-xr-x 2 root root 0 11月 16 18:43 oss
-r–r–r– 1 root root 0 11月 16 18:43 pcm

card2 is the name of DAC Card

ls  /sys/class/sound
card0  card2      controlC1  hwC0D0  pcmC0D3p  pcmC1D0p  pcmC2D0p
card1  controlC0  controlC2  hwC1D0  pcmC1D0c  pcmC2D0c  timer


Get the Attr List of card2

udevadm info /sys/class/sound/card2
P: /devices/pci0000:00/0000:00:12.0/usb2/2-4/2-4:1.0/sound/card2
L: 0
E: DEVPATH=/devices/pci0000:00/0000:00:12.0/usb2/2-4/2-4:1.0/sound/card2
E: SUBSYSTEM=sound
E: USEC_INITIALIZED=523137960408
E: ID_PATH=pci-0000:00:12.0-usb-0:4:1.0
E: ID_PATH_TAG=pci-0000_00_12_0-usb-0_4_1_0
E: ID_FOR_SEAT=sound-pci-0000_00_12_0-usb-0_4_1_0
E: SOUND_INITIALIZED=1
E: ID_VENDOR_FROM_DATABASE=Actions Semiconductor Co., Ltd
E: ID_VENDOR=ACTIONS
E: ID_VENDOR_ENC=ACTIONS
E: ID_VENDOR_ID=10d6
E: ID_MODEL=USB_AUDIO
E: ID_MODEL_ENC=USB\x20AUDIO
E: ID_MODEL_ID=dd01
E: ID_REVISION=0100
E: ID_SERIAL=ACTIONS_USB_AUDIO_4512482ADF0FEEEE
E: ID_SERIAL_SHORT=4512482ADF0FEEEE
E: ID_TYPE=audio
E: ID_BUS=usb
E: ID_USB_INTERFACES=:010100:010200:030000:
E: ID_USB_INTERFACE_NUM=00
E: ID_USB_DRIVER=snd-usb-audio
E: ID_ID=usb-ACTIONS_USB_AUDIO_4512482ADF0FEEEE-00
E: SYSTEMD_WANTS=sound.target
E: TAGS=:systemd:seat:
udevadm info --path=/sys/class/sound/card2 --attribute-walk

looking at device '/devices/pci0000:00/0000:00:12.0/usb2/2-4/2-4:1.0/sound/card2':
    KERNEL=="card2"
    SUBSYSTEM=="sound"
    DRIVER==""
    ATTR{number}=="2"
    ATTR{id}=="AUDIO"

  looking at parent device '/devices/pci0000:00/0000:00:12.0/usb2/2-4/2-4:1.0':
    KERNELS=="2-4:1.0"
    SUBSYSTEMS=="usb"
    DRIVERS=="snd-usb-audio"
    ATTRS{supports_autosuspend}=="1"
    ATTRS{bInterfaceProtocol}=="00"
    ATTRS{authorized}=="1"
    ATTRS{bNumEndpoints}=="00"
    ATTRS{bInterfaceClass}=="01"
    ATTRS{bInterfaceNumber}=="00"
    ATTRS{bInterfaceSubClass}=="01"
    ATTRS{bAlternateSetting}==" 0"

  looking at parent device '/devices/pci0000:00/0000:00:12.0/usb2/2-4':
    KERNELS=="2-4"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{devpath}=="4"
    ATTRS{bDeviceProtocol}=="00"
    ATTRS{bmAttributes}=="c0"
    ATTRS{quirks}=="0x0"
    ATTRS{tx_lanes}=="1"
    ATTRS{product}=="USB AUDIO"
    ATTRS{busnum}=="2"
    ATTRS{bcdDevice}=="0100"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{manufacturer}=="ACTIONS"
    ATTRS{bNumInterfaces}==" 4"
    ATTRS{bDeviceClass}=="00"
    ATTRS{configuration}==""
    ATTRS{maxchild}=="0"
    ATTRS{devnum}=="20"
    ATTRS{serial}=="4512482ADF0FEEEE"
    ATTRS{bMaxPower}=="300mA"
    ATTRS{idVendor}=="10d6"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{urbnum}=="25748"
    ATTRS{idProduct}=="dd01"
    ATTRS{version}==" 1.00"
    ATTRS{removable}=="unknown"
    ATTRS{authorized}=="1"
    ATTRS{bMaxPacketSize0}=="64"
    ATTRS{speed}=="12"
    ATTRS{rx_lanes}=="1"
    ATTRS{lATTRS{avoid_reset_quirk}=="0"
    ATTRS{bConfigurationValue}=="1"

  looking at parent device '/devices/pci0000:00/0000:00:12.0/usb2':
    KERNELS=="usb2"
    SUBSYSTEMS=="usb"DRIVERS=="usb"
    ATTRS{configuration}==""
    ATTRS{idProduct}=="0001"
    ATTRS{version}==" 1.10"
    ATTRS{tx_lanes}=="1"
    ATTRS{bNumInterfaces}==" 1"
    ATTRS{bDeviceClass}=="09"
    ATTRS{removable}=="unknown"
    ATTRS{authorized_default}=="1"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{interface_authorized_default}=="1"
    ATTRS{busnum}=="2"
    ATTRS{bDeviceProtocol}=="00"
    ATTRS{bMaxPower}=="0mA"
    ATTRS{quirks}=="0x0"
    ATTRS{speed}=="12"
    ATTRS{bcdDevice}=="0419"
    ATTRS{maxchild}=="5"
    ATTRS{idVendor}=="1d6b"
    ATTRS{devpath}=="0"
    ATTRS{manufacturer}=="Linux 4.19.0-9-amd64 ohci_hcd"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{bMaxPacketSize0}=="64"
    ATTRS{rx_lanes}=="1"
    ATTRS{bmAttributes}=="e0"
    ATTRS{urbnum}=="511"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{product}=="OHCI PCI host controller"
    ATTRS{serial}=="0000:00:12.0"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{ltm_capable}=="no"
    ATTRS{devnum}=="1"
    ATTRS{authorized}=="1"

    
# Get kernel prop
udevadm monitor --kernel --property --subsystem-match=usb
monitor will print the received events for:
KERNEL - the kernel uevent

KERNEL[1083.319560] add      /devices/pci0000:00/0000:00:12.0/usb2/2-4 (usb)
ACTION=add
DEVPATH=/devices/pci0000:00/0000:00:12.0/usb2/2-4
SUBSYSTEM=usb
DEVNAME=/dev/bus/usb/002/002
DEVTYPE=usb_device
PRODUCT=10d6/dd01/100
TYPE=0/0/0
BUSNUM=002
DEVNUM=002
SEQNUM=2112
MAJOR=189
MINOR=129

Write your udev rule based on selected attrs

cat /opt/local/libexec/udev/rules.d/99-AD-86d.rules

ACTION=="add",SUBSYSTEM=="sound",ATTR{id}=="AUDIO",RUN+="/opt/local/bin/add_ad_86d.sh"
ACTION=="remove",SUBSYSTEM=="usb",ATTRS{idVendor}=="10d6",ATTRS{idProduct}=="dd01",RUN+="/opt/local/bin/remove_ad_86d.sh"

Config NUT for CyberPower VAL600 UPS with TrueNAS Core 12.0-U6

     Master NAS,   PC/TrueNAS Core attached with UPS USB Cable

  • Step 1:   Power on the Cyberpower VAL600 & plug the USB cable into TrueNas system

  • Step 2:   Find out UPS port information, say ugen3.0

TrueNAS Web Gui / System/Advance/Show Console Message

  • Step 3:   Config with the UPS

TrueNAS Web Gui / Services/UPS

UPS Mode:  Master

Remote Monitor:    Enable

Monitor User:      upsmon

Monitor Password:   Your Passwrod

Driver:  Cyber Power System ups2 Value 600E USB

Port or Hostname:   /dev/ugen0.3auto

Shutdown Command:  shutdown -h now

  • Step 4:  Check with command upsc ups@localhost

TrueNAS Web Gui / Shell

  • Step 5:   Verify shutdown command is working by turn off the AC power supplier of UPS

     Slave NAS:    PC/TrueNAS Core not  attached with UPS USB Cable

  • Step 6:Config TrueNAS PC as NUT Salve

UPS Mode:     Slave

Remote Host:   IP of Master NAS

Remote Port:    3493

Port or Hostname:  auto

Monitor User:     upsmon

Monitor Password:    Same as Master UPS

Shutdown command:     shutdown -h now

     Slave Linux:    PC/Linux not  attached with UPS USB Cable

  • Step 7: Config Linux PC as NUT slave

Install NUT

Config upsmon as following

POWERDOWNFLAG /etc/nut/killpower
               MONITOR ups@MASTER_UPS_IP 1  upsmon YOUR_PASSWORD  slave
               MINSUPPLIES 1
               SHUTDOWNCMD “/sbin/shutdown -h +0”

               POLLFREQ 5
               POLLFREQALERT 5
               HOSTSYNC 15
               DEADTIME 15
               RBWARNTIME 43200
               NOCOMMWARNTIME 300
               FINALDELAY 5

Launch upsmon service

Note:

TrueNAS Core only support  UPS On Battery Action

Understanding Flash: Unpredictable Write Performance

https://flashdba.com/2014/12/10/understanding-flash-unpredictable-write-performance/

fast-page-slow-page

I’ve spent a lot of time in this blog series talking about the challenges involved in using flash, such as the way that pages have to be erased before they are written and the restriction that erase operations take place on a whole block. I also described the problem of erase operations being slow in comparison to reads and writes – and the resulting processes we have to put in place to manage that problem (i.e. garbage collection) . And most recently I covered the way that garbage collection can result in unpredictable performance.

But so far we’ve always worked under the assumption that reads and writes to NAND flash have the same predictably low latency. This post is all about bursting that particular bubble…

Programming NAND Flash: A Quick Recap

You might remember from my post on the subject of SLC, MLC and TLC that I used the analogy of electrons in a bucket to explain the programming of NAND flash cells:

slc-mlc-tlc-buckets

I’d now like to change that analogy slightly, so I’m asking you to consider that you have an empty bucket and a powerful hose pipe. You can turn the hose on and off whenever you want to fill the bucket up, but you cannot empty water out of the bucket unless you completely empty it. Ok, now we’re ready.

For SLC we simply say that an empty bucket denotes a binary value of 1 and a full bucket denotes binary 0. Thus when you want to program an SLC bucket you simply let rip with your hose pipe until it’s full. No need to measure whether the water line is above or below the halfway point (the threshold), just go crazy. Blam! That was quick, wasn’t it?

For MLC however, we have three thresholds – and again we start with the bucket empty (denoting binary 11). Now, if I want to program the binary values of 01 or 10 in the above diagram I need to be careful, because if I overfill I cannot go backwards. bucketI therefore have to fill a little, test, fill some more, test and so on. It’s actually kind of tricky – and it’s one of the reasons that MLC is both slower than SLC and has a lower wear limit. But here’s the thing… if I want to program my MLC to have a value of binary 00 in the above diagram, I have no such problems because (as with SLC) I can just open the hose up on full power and hit it.

What we’ve demonstrated here is that programming a full charge value to an MLC cell is faster than programming any of the other available values. With a little more thought you can probably see that TLC has this problem to an even worse degree – imagine how accurate you need to be with that hose when you have seven thresholds to consider!

One final thought. We read and write (program) to NAND flash at the page level, which means we are accessing a large collection of cells as if they are one single unit. What are the chances that when we write a page we will want every cell to be programmed to full charge? I’d say extremely low. So even if some cells are programmed “the fast way”, just one “slow” program operation to a non-full-charge threshold will slow the whole program operation down. In other words, I can hardly ever take advantage of the faster latency experienced by full charge operations.

Fast Pages and Slow Pages

The majority of flash seen in the data centre today is MLC, which contains two bits per cell. Is there a way to program MLC in order that, at least sometimes, I can program at the faster speeds of a full-charge operation?

mlc-bucket-msb-lsbLet’s take my MLC bucket diagram from above and remap the binary values like the diagram on the left. What have I changed? Well most importantly I’ve reordered the binary values that correspond to each voltage level; empty charge still represents 11 but now full charge represents 10. Why did I do that?

The clue is the dotted line separating the most significant bit (MSB) and the least significant bit (LSB) of each value. Let’s consider two NAND flash pages, each comprising many cells. Now, instead of having both bits from each MLC cell used for a single page, I will put all of the MSB values into one page and call that the slow page. Then I’ll take all of the LSB values and put that into the other page and call that the fast page.

Why did I do this? Well, consider what happens when I want to program my fast page: in the diagram you can see that it’s possible to turn the LSB value from one to zero by programming it to either of the two higher thresholds… including the full charge threshold. In fact, if you forget about the MSB side for a second, the LSB side very similar to an SLC cell – and therefore performs like one.

The slow page, meanwhile, has to be programmed just like we discussed previously and therefore sees no benefit from this configuration. What’s more, if I want to program the fast page in this way I can’t store data in the corresponding slow page (the one with the matching MSBs) because every time I program a full charge to this cell the MSB ends up with a value of one. Also, when I want to program the slow page I have to erase the whole block first and then program both pages together (slowly!).

It’s kind of complicated… but potentially we now have the option to program certain MLC pages using a faster operation, with the trade-off that other pages will be affected as a result.

Getting To The Point

I should point out here that this is pretty low-level stuff which requires direct access to NAND flash (rather than via an SSD for example). It may also require a working relationship with the flash manufacturer. So why am I mentioning it here?

Well first of all I want to show you that NAND flash is actually a difficult and unpredictable medium on which to store data – unless you truly understand how it works and make allowances for its behaviour. NAND-flashThis is one of the reasons why so many flash products exist on the market with completely differing performance characteristics.

When you look at the datasheet for an MLC flash product and you see write / program times shown as, for example, 1.4 milliseconds it’s important to realise that this is the average of its bi-modal behaviour. Fast (LSB) pages may well have program times of 300 microseconds, while slow (MSB) pages might take up to 2.5 milliseconds.

Secondly, I want to point out that direct access to the flash (instead of via an SSD) brings certain benefits. What if, in my all flash array, I send all inbound user writes to fast pages but then, later on during garbage collection, I move data to be stored in slow pages? If I could do that, I’d effectively be hiding much of the slower performance of MLC writes from my users. And that would be a wonderful thing…

…which is why, at Violin, we’ve been doing it for years

Install dd-wrt onto wndr3700 v4

Hardware:                       2.4G/5G Wifi,  USB,  128MB RAM/128B NAND

Version Installed:             DD-WRT v24-sp2 (01/04/15) std – build 25760

Feature Integrated:

FreeRadius,                   PPPoE Server / Relay
PPTP Server / Client,     OpenVPN Server / Client
USB:                               Printer,  Storage,     USB Over IP
FTP Server,                    DLNA Server,          Samba Server
SIP Proxy,                       Http Server (Lighttpd)
Mikrotik MAC Telnet,      IP over DNS Tunneling (nstx)
SNMP,                            VNC Repeat,          Zabbix client

 

Add 32G USB key with following partition setting:

Part1 LABEL=”EXEC”   SIZE=2G   TYPE=”ext4″ With Journal

Part2  LABEL=”DATA”   SIZE=30G  TYPE=”ext4″ Without Journal

 

SSH into the route and execute:

umount /dev/sda1
umount /dev/sda2
mkdir /mnt/exec
mkdir /mnt/data
mount /dev/sda1 /mnt/exec
mount /dev/sda2 /mnt/data
cp -r -p  /opt /mnt/exec/
cp -r -p  /etc /mnt/exec/
cp -r -p /www /mnt/exec/
cp -r -p /jffs /mnt/exec/

Startup Script:
umount /dev/sda1
umount /dev/sda2
cp -r -p /tmp /tmp/mnt
mkdir /mnt/exec
mkdir /mnt/data
mount /dev/sda1 /mnt/exec
mount /dev/sda2 /mnt/data
mount –bind /mnt/exec/www /www
mount –bind /mnt/exec/opt /opt
mount –bind /mnt/exec/etc /etc
mount –bind /mnt/exec/jffs /jffs
mv /tmp/mnt/tmp /mnt/exec/
mount –bind /mnt/exec/tmp /tmp

usbip

http://sourceforge.net/projects/usbip/

http://usbip.sourceforge.net/

https://www.usenix.org/legacy/events/usenix05/tech/freenix/hirofuchi/hirofuchi.pdf

http://wiki.openwrt.org/doc/howto/usb.iptunnel

https://github.com/spurious/usbip-windows-mirror/blob/master/driver/README

 http://www.xrdp.org/index.php?option=com_content&view=article&id=15:usb-redirection&catid=2:documents&Itemid=7

 https://www.kernel.org/doc/readme/tools-usb-usbip-README

 

 

Open Source OS

https://reactos.org/

 

Not open source

https://www.virtualhere.com/

http://www.virtual-serial-port.org/products/usb-over-network/

http://www.usb-over-network.com/usb-over-network.html