how to make /dev/mmcblk0 - linux

I'm trying to adapt an existing SD/MMC card driver to our SD controller hardware. I'm using Synopsys' dw_mmc code (in linux3.3) as a reference. I have a long way to go but at least it's compiled ok and the platform device and platform driver seems to have been registered. My question is how to make the /dev/mmcblk0 file appear in the system? I named our new device ald_sd and I can see ald_sd.0 under /sys/devices/platform. under /dev, I tried 'mknod mmcblk0 179 0' and I see mmcblk0 under /dev. Then I tried 'mount /dev/mmcblk0 /mnt/sd' (after making /mnt/sd) and it gives me message 'mount: mounting /dev/mmcblk0 on /mnt/sd failed: No such device or address'.
Please help. Thank you!
Chan

It's been several months since I sloved this problem. long story short, when the kernel reads the super block of the SD card, then the block access is ok. usually we make /dev/sd0 using mknod command.(not mmcblock0). (mmcblock0 file is made somewhere different maybe /sys.. I don't remember). Also beware, you can mis-type mknod like mkdir or mkdev, then you can have 'No such device or address' message too. Just for your information.

Related

Linux: writing to the i2c/SMBus

I have a problem with the i2c/SMBus on a Linux System with an Intel Apollo Lake processor. I am trying to read/write from/to an EEPROM but I face some issues. My EEPROM is located at the address 0x56, and I am able to watch the Bus with my Logic Analyzer.
When I try to read from the device via i2ctools (i2cget) the System behaves as expected. My issue occurs when I try to perform a write command via i2cset for example. i2cset ends with an error (Write failed). Because I am able to watch the Bus electrically I can also say that all lines stay HIGH and the Bus is not touched. I was able to activate the dev_dbg() functions in the i2c driver i2c_i801 and when I perform i2cset I am able to find (dmesg) the debug message:
[ 765.095591] [2753] i2c_i801:i801_check_post:433: i801_smbus 0000:00:1f.1: No response
When running my minimal I²C Python code using the smbus2 lib, I get the following error message and the above mentioned debug message:
from smbus2 import SMBus
bus = SMBus(0)
b = bus.read_byte_data(86,10) #<- This is performed
b = bus.write_byte_data(86,10,12) #<- This is not performed
bus.close()
Error:
File "usr/local/lib/python3.8/dist-packagers/smbus2-0.4.0-py3.8.egg/smbus/smbus2.py", line 455, in write_byte_data
ioctl(self.fd, I2C_SMBUS, msg)
OSERROR: [Errno 6] No such device or adress
A big hint for me is that I am not able to perform a write command in the address space form 0x50 to 0x57. My guess is that some driver locks the address space to prevent write command to that "dangerous" area.
My question is: "Does anyone know this kind of behavior and is there a solution so that I can write to my EEPROM at address 0x56? OR Is there a lock surrounding the i2c adress space from 0x50 to 0x57 and who is my opponent?"
I am kind of a newbie to the whole driver and kernel world so please be kind and it is quite possible that I made a beginner mistake.
I would appreciate hints and tips I can look after surrounding my problem.
It seems that I found the cause of my problem. In this Forum post is described that Intel changed a configuration Bit at the SMBus controller.
OK, I know what's going on.
Starting with the 8-Series/C220 chipsets, Intel introduced a new
configuration bit for the SMBus controller in register HOSTC (PCI
D31:F3 Address Offset 40h):
Bit 4 SPD Write Disable - R/WO.
0 = SPD write enabled.
1 = SPD write disabled. Writes to SMBus addresses 50h - 57h are
disabled.
This badly documented change in the configuration explains the issues.
One Challenge is, that to apply and enable changes to the SPD-write Bit the System needs to be rebooted. Unfortunately while rebooting the BIOS will change the Bit back to the default. The only solution seems to be an adaption in the BIOS.
For me, this issue is resolved. I just wanted to share this information in case someone faces the same issues.

Raspberry Pi Zero USB device emulation

I know that the Raspberry Pi Zero supports OTG and USB Peripheral protocols, and there's a lot of cool built in peripherals shown here: https://learn.adafruit.com/turning-your-raspberry-pi-zero-into-a-usb-gadget?view=all#other-modules
The problem is that I need to emulate a USB Peripheral device that does not appear on this list. I have a vendor ID and product ID for the device, and I'm trying to figure out how exactly to go about doing this. Do I need to modify the OTG USB drivers in the Raspbian kernel? Do I have to completely build my own kernel? Or is there a better option I don't even realize?
Thanks in advance!!
Do I need to modify the OTG USB drivers in the Raspbian kernel?
The answer to your first question is "it depends", but if your device
doesn't do anything too unusual this could be a No: you need not
modify source code for kernel modules nor the kernel.
You're fortunate that Raspbian supports a modern kernel with ConfigFS support. Once you are set up with dtoverlay=dwc2, you can open up a FunctionFS bulk endpoint as root like so:
modprobe libcomposite
modprobe usb_f_fs
cd /sys/kernel/config/usb_gadget
mkdir -p myperipheral; cd myperipheral
echo 0x1234 > idVendor # put actual vendor ID here
echo 0xabcd > idProduct # put actual product ID here
mkdir configs/c.1
mkdir configs/c.1/strings/0x409
echo "My Peripheral" > configs/c.1/strings/0x409/configuration
mkdir functions/ffs.my_func_name
ln -s functions/ffs.my_func_name configs/c.1/
mkdir -p /tmp/mount_point
mount my_func_name -t functionfs /tmp/mount_point
# compile ffs-test from source, then copy and run it from /tmp/mount_point
ls /sys/class/udc > UDC
If you need to emulate the other device more closely, it's up to you to set bcdDevice, bcdUSB, serial number, manufacturer, product string, max power, os_desc, and possibly other fields.
AFAIK FunctionFS does not support isochronous endpoints, interrupt transfers, nor out-of-the-ordinary control transfers. If you require this, you may need to start looking into extending existing gadget modules, with source code here.
Update: When I got home to test this, I encountered a severe caveat with Raspbian. It'll initially fail to create ffs.my_func_name because usb_f_fs is not enabled by default. Although you need not modify any kernel modules, you must recompile with an alternate configuration. make menuconfig -> Device Drivers -> USB support -> USB Gadget Support -> USB functions configurable through configfs / Function filesystem (FunctionFS) + some other modules to test. After uploading a new kernel/modules, I tested the above script on Raspbian 8. I would also recommend setting USB Gadget Drivers / Function Filesystem to (M) in case you resort to the simpler g_ffs legacy module in lieu of ConfigFS.

what does "usb start" command do exactly?

I am facing a problem when i try to read from usb device at u-boot.
When i do
fatls usb 0:1
it says bad device. But as soon as i do
usb start
fatls usb 0:1
then it shows me correcly the fat partition in USB.
I was looking to add both commands in the common/main.c so that whenever the board boots it looks for the fat partition of USB.
It is tough but i need to do it.
Anybody has a clue??
As has been said in the comments, "usb start" is what initializes the USB subsystem and scans attached devices for things U-Boot can deal with (USB sticks, ethernet, etc). Unlike some buses such as MMC that we will do an initial scan on prior to starting the shell, for USB you must run the start command first if you expect to use devices that are attached.
Now, you don't add things to common/main.c, you add things to the bootcmd environment variable (and this can be changed in the boards config.h file so that the default environment is changed, if you are working on a board where you cannot do 'saveenv' to save your changes in a persistent way). So what you would want to do is:
=> setenv bootcmd 'usb start;fatls usb 0:1'
or whatever commands you wish to do with the files present on the USB stick.

i2cdetect doesn't find anything on goodix chip

I have a goodix chip for the touchscreen on my tablet PC and even though I compiled the latest kernel module for it, things are not working.
I am using exactly this kernel version with the patched driver:
https://github.com/NimbleX/kernel
For starters, the picture of the said chip is the following:
The DSDT tables contain information regarding the touchscreen.
From what I understand the touchscreen is connected via an I2C serial interface but lshw shows that *-serial is UNCLAIMED.
Nevertheless I can see that the i2c_i801 module for the SMBus controller is loaded.
With the help of Aleksei I was able to determine that the toucscreen is connected to i2c-1 buss and that the controller must use 0x14 or 0x5d address.
Unfortunatelly, i2cdetect doesn't find anything, as it can be seen here.
I created a lengthy gist with the output of the following:
dmesg
DSDT.dsl
lshw
lspci
lsusb
/proc/bus/input/devices
xinput
I know that some of these are redundant and that others are useless but nevertheless it's better to have where to search than to miss something out.
I measured with a multimeter and the chip is powered both when running Windows and Linux so this rules out that I need to somehow tell Linux to power this thing out.
So, what do do next in order to debug this thing?
Hi can you check where pin 5,6 are connected specifically 6 which is reset ic so if that may be reseting the ic. just a posiblity.

Linux: calling open() on a USB device which may not be present

I have a device attached to a Raspberry Pi. The Pi is running ARCH Linux. The device communicates with the Pi via USB. The device has to be switched on and off via a pulse and I have control, from the Pi, of a relay which causes this pulse. However I can never be sure whether the device is initially on or off.
In my code I toggle the relay and then speculatively call open() on the device (with flags O_RDWR | O_NOCTTY). The problem is that if I am doing this when the device is off the open() call hangs. I have tried waiting for 1 second after the toggle, for things to settle, but that hasn't helped. I have tried calling stat() before the open() call but this always returns zero (so the device is there as far as stat() is concerned). I have tried specifying O_NON_BLOCK in the open() call but that causes it to always fail.
Can anyone suggest either (a) what I'm doing wrong or (b) a reliable way forward?
You can be certain that the device has powered if it has USB enumerated. You can use libudev to find the list of USB enumerated devices and check whether your device is on that list.
The command line "lsusb" does that. So if you need an example of how to use libudev then you can read the lsusb source code (https://github.com/gregkh/lsusb).
If you can be sure that the device will eventually turn up, the blocking open() ("hangs") may actually be what you want! The call to open() will return, hopefully with success, when your device turns up.
The stat() call simply checks if the device special file is there. It can't tell you if there is anything listening.
One possible way forward, would be to open() with O_NONBLOCK in an exponential back-off loop.
Depending on what you mean with "communicates via USB", you may want to use libusb. If it's just a USB serial port, wrapping open() yourself is probably the easiest though.
It's not clear what you have done to get a device file that survives disconnect.
The usual approach is to use hotplug+udev to create (and remove) the device symlinks, then the special file would only be there when the device is plugged in.
Courtesy of all the helpful people below, the quick answer was to include in my .rules file a "remove" action to go with the existing "add" action. So in the file where I have:
ACTION=="add", ATTRS{interface}=="Pololu Orangutan X2 Serial Adapter", MODE="7777", SYMLINK+="OrangutanUSB"
...to give me a /dev/OrangutanUSB device, I have included a new line:
ACTION=="remove", ATTRS{interface}=="Pololu Orangutan X2 Serial Adapter", MODE="7777", SYMLINK-="OrangutanUSB"
...to cause the operating system to remove the /dev/OrangutanUSB device when it has been powered off. This way the open() call fails correctly when the device has gone, rather than hanging.
Ultimately, what I should do is check that the device is enumerated, rather than expecting open() to fail, but that can wait until I have the time. For now my code works as originally intended.

Resources