1. Android USB gadget
Android USB gadget source code locate under /kernel_imx/drivers/usb/gadget, it contains three files.
Android.c, f_adb.c, f_mass_storage.c
1.1 In f_mass_storage.c, macro MAX_LUNS (8) set max lun number, check the function below.
static int __init
fsg_function_bind(struct usb_configuration *c, struct usb_function *f)
{
...
dev_attr_file.attr.mode = 0644;
/* Find out how many LUNs there should be */
i = fsg->nluns;
if (i == 0)
i = 1;
if (i > MAX_LUNS) {
ERROR(fsg, "invalid number of LUNs: %d\n", i);
rc = -EINVAL;
goto out;
}
…
}
1.2 in /kernel_imx/arch/arm/mach-mx5/mx53_evk.c. Register Android USB device in function:
static void __initmxc_board_init(void)
{
...
mxc_register_device(&android_usb_device, &android_usb_pdata);
...
}
And then we check those two structures.
struct platform_device android_usb_device = {
.name = "android_usb",
.id = -1,
};
static struct android_usb_platform_data android_usb_pdata = {
.vendor_id = 0x0bb4,
.product_id = 0x0c01,
.adb_product_id = 0x0c02,
.version = 0x0100,
.product_name = "Android Phone",
.manufacturer_name = "Freescale",
.nluns = 3,
};
nluns = 3, MX53 EVK rev B has two SD card and one udisk support, and we need add extra udisk support, we change nlun = 4,
With the modification, we can find four lun0-lun3 under
/sys/devices/platform/fsl-usb2-udc/gadget
1.3 USB initialize
Register adb and mass storage in android.c
static int __init android_bind_config(struct usb_configuration *c)
{
struct android_dev *dev = _android_dev;
int ret;
printk(KERN_DEBUG "android_bind_config\n");
ret = mass_storage_function_add(dev->cdev, c, dev->nluns);
if (ret)
return ret;
return adb_function_add(dev->cdev, c);
}
1.4 Mount storage to host.
1.4.1 Manually Mount storage to host
Write storage device path”/dev/block/vold/major:minor” in /lun?/file
echo /dev/block/vold/179:1 > /sys/devices/platform/fsl-usb2-udc/gadget/lun0/file
echo /dev/block/vold/8:1 > /sys/devices/platform/fsl-usb2-udc/gadget/lun1/file
echo /dev/block/vold/8:17 > /sys/devices/platform/fsl-usb2-udc/gadget/lun2/file
echo /dev/block/vold/179:0 > /sys/devices/platform/fsl-usb2-udc/gadget/lun3/file
It will mount storage to host
1.4.2 Manually unmount storage from host.
echo “” > /sys/devices/platform/fsl-usb2-udc/gadget/lun0
1.4.3 Automatic mount storage to host
Froyo VOLD will handle vold.fstab under /devices/fsl/imx53_evk to mount storage. We can see mount example below.
“
dev_mount sdcard /mnt/sdcard auto /devices/platform/mxsdhci.0/mmc_host/mmc0
dev_mount extsd /mnt/extsd auto /devices/platform/mxsdhci.2/mmc_host/mmc1
dev_mount udisk /mnt/udisk auto /devices/platform/fsl-ehci.1/usb2/2-1/2-1.5
dev_mount extudisk /mnt/extudisk auto /devices/platform/fsl-ehci.1/usb2/2-1/2-1.4
“
2. Android VOLD
2.1 Parse vold.fstab file.
In /system/vold/main.cpp, open vold.fstab
static int process_config(VolumeManager *vm) {
...
if (!(fp = fopen("/etc/vold.fstab", "r"))) {
return -1;
}
...
if (!strcmp(part, "auto")) {
dv = new DirectVolume(vm, label, mount_point, -1);
} else {
dv = new DirectVolume(vm, label, mount_point, atoi(part));
}
...
}
In /system/vold/DirectVolume.cpp,
int DirectVolume::handleBlockEvent(NetlinkEvent *evt)
{
const char *dp = evt->findParam("DEVPATH");
PathCollection::iterator it;
for (it = mPaths->begin(); it != mPaths->end(); ++it) {
#ifdef PARTITION_DEBUG
SLOGD("dp:%s,*it:%s.", dp, *it);
#endif
if (!strncmp(dp, *it, strlen(*it))) {
/* We can handle this disk */
...
}
...
}
We print “DP” and “*it“ as below, we can see *it is path you set in vold.fstab, if DP match with *it, it will handle this disk.
D/DirectVolume( 2136): dp:/devices/platform/fsl-ehci.1/usb2/2-1/2-1.4/2-1.4:1.0/host2/target2:0:0/2:0:0:0/block/sda/sda1, *it:/devices/platform/mxsdhcimmc_host/mmc0.
D/DirectVolume( 2136): dp:/devices/platform/fsl-ehci.1/usb2/2-1/2-1.4/2-1.4:1.0/host2/target2:0:0/2:0:0:0/block/sda/sda1,*it:/devices/platform/mxsdhci.2/mmc_host/mmc1.
D/DirectVolume( 2136): dp:/devices/platform/fsl-ehci.1/usb2/2-1/2-1.4/2-1.4:1.0/host2/target2:0:0/2:0:0:0/block/sda/sda1,*it:/devices/platform/fsl-ehci.1/usb2/2-1/2-1.5.
TBD
Android USB gadget source code locate under /kernel_imx/drivers/usb/gadget, it contains three files.
Android.c, f_adb.c, f_mass_storage.c
1.1 In f_mass_storage.c, macro MAX_LUNS (8) set max lun number, check the function below.
static int __init
fsg_function_bind(struct usb_configuration *c, struct usb_function *f)
{
...
dev_attr_file.attr.mode = 0644;
/* Find out how many LUNs there should be */
i = fsg->nluns;
if (i == 0)
i = 1;
if (i > MAX_LUNS) {
ERROR(fsg, "invalid number of LUNs: %d\n", i);
rc = -EINVAL;
goto out;
}
…
}
1.2 in /kernel_imx/arch/arm/mach-mx5/mx53_evk.c. Register Android USB device in function:
static void __initmxc_board_init(void)
{
...
mxc_register_device(&android_usb_device, &android_usb_pdata);
...
}
And then we check those two structures.
struct platform_device android_usb_device = {
.name = "android_usb",
.id = -1,
};
static struct android_usb_platform_data android_usb_pdata = {
.vendor_id = 0x0bb4,
.product_id = 0x0c01,
.adb_product_id = 0x0c02,
.version = 0x0100,
.product_name = "Android Phone",
.manufacturer_name = "Freescale",
.nluns = 3,
};
nluns = 3, MX53 EVK rev B has two SD card and one udisk support, and we need add extra udisk support, we change nlun = 4,
With the modification, we can find four lun0-lun3 under
/sys/devices/platform/fsl-usb2-udc/gadget
1.3 USB initialize
Register adb and mass storage in android.c
static int __init android_bind_config(struct usb_configuration *c)
{
struct android_dev *dev = _android_dev;
int ret;
printk(KERN_DEBUG "android_bind_config\n");
ret = mass_storage_function_add(dev->cdev, c, dev->nluns);
if (ret)
return ret;
return adb_function_add(dev->cdev, c);
}
1.4 Mount storage to host.
1.4.1 Manually Mount storage to host
Write storage device path”/dev/block/vold/major:minor” in /lun?/file
echo /dev/block/vold/179:1 > /sys/devices/platform/fsl-usb2-udc/gadget/lun0/file
echo /dev/block/vold/8:1 > /sys/devices/platform/fsl-usb2-udc/gadget/lun1/file
echo /dev/block/vold/8:17 > /sys/devices/platform/fsl-usb2-udc/gadget/lun2/file
echo /dev/block/vold/179:0 > /sys/devices/platform/fsl-usb2-udc/gadget/lun3/file
It will mount storage to host
1.4.2 Manually unmount storage from host.
echo “” > /sys/devices/platform/fsl-usb2-udc/gadget/lun0
1.4.3 Automatic mount storage to host
Froyo VOLD will handle vold.fstab under /devices/fsl/imx53_evk to mount storage. We can see mount example below.
“
dev_mount sdcard /mnt/sdcard auto /devices/platform/mxsdhci.0/mmc_host/mmc0
dev_mount extsd /mnt/extsd auto /devices/platform/mxsdhci.2/mmc_host/mmc1
dev_mount udisk /mnt/udisk auto /devices/platform/fsl-ehci.1/usb2/2-1/2-1.5
dev_mount extudisk /mnt/extudisk auto /devices/platform/fsl-ehci.1/usb2/2-1/2-1.4
“
2. Android VOLD
2.1 Parse vold.fstab file.
In /system/vold/main.cpp, open vold.fstab
static int process_config(VolumeManager *vm) {
...
if (!(fp = fopen("/etc/vold.fstab", "r"))) {
return -1;
}
...
if (!strcmp(part, "auto")) {
dv = new DirectVolume(vm, label, mount_point, -1);
} else {
dv = new DirectVolume(vm, label, mount_point, atoi(part));
}
...
}
In /system/vold/DirectVolume.cpp,
int DirectVolume::handleBlockEvent(NetlinkEvent *evt)
{
const char *dp = evt->findParam("DEVPATH");
PathCollection::iterator it;
for (it = mPaths->begin(); it != mPaths->end(); ++it) {
#ifdef PARTITION_DEBUG
SLOGD("dp:%s,*it:%s.", dp, *it);
#endif
if (!strncmp(dp, *it, strlen(*it))) {
/* We can handle this disk */
...
}
...
}
We print “DP” and “*it“ as below, we can see *it is path you set in vold.fstab, if DP match with *it, it will handle this disk.
D/DirectVolume( 2136): dp:/devices/platform/fsl-ehci.1/usb2/2-1/2-1.4/2-1.4:1.0/host2/target2:0:0/2:0:0:0/block/sda/sda1, *it:/devices/platform/mxsdhcimmc_host/mmc0.
D/DirectVolume( 2136): dp:/devices/platform/fsl-ehci.1/usb2/2-1/2-1.4/2-1.4:1.0/host2/target2:0:0/2:0:0:0/block/sda/sda1,*it:/devices/platform/mxsdhci.2/mmc_host/mmc1.
D/DirectVolume( 2136): dp:/devices/platform/fsl-ehci.1/usb2/2-1/2-1.4/2-1.4:1.0/host2/target2:0:0/2:0:0:0/block/sda/sda1,*it:/devices/platform/fsl-ehci.1/usb2/2-1/2-1.5.
TBD