Про USB Device (gadget) в linux.

В большинстве случаев платки с USB используются как usb-host. Как правило настройка usb-host сводится лишь к выставлению тех или иных галочек в make menuconfig.

Как настроить контроллер USB для работы в режиме USB-device (gadget).

Пример для микроконтроллера marvell 88F6282 (88F6283) семейства kirkwood.

В файл arch/arm/mach-kirkwood/common.c вносим следующие изменения:

/*****************************************************************************
 * EHCI0
 ****************************************************************************/
#include 

//static struct resource kirkwood_ehci_resources[] = {
static struct resource kirkwood_usb_resources[] = {
	{
		.start	= USB_PHYS_BASE,
		.end	= USB_PHYS_BASE + 0x0fff,
		.flags	= IORESOURCE_MEM,
	}, {
		.start	= IRQ_KIRKWOOD_USB,
		.end	= IRQ_KIRKWOOD_USB,
		.flags	= IORESOURCE_IRQ,
	},
};

static struct platform_device kirkwood_ehci = {
	.name		= "orion-ehci",
	.id		= 0,
	.dev		= {
		.dma_mask		= &ehci_dmamask,
		.coherent_dma_mask	= 0xffffffff,
		.platform_data		= &kirkwood_ehci_data,
	},
//	.resource	= kirkwood_ehci_resources,
//	.num_resources	= ARRAY_SIZE(kirkwood_ehci_resources),
    .resource	= kirkwood_usb_resources,
    .num_resources	= ARRAY_SIZE(kirkwood_usb_resources),
};

static struct fsl_usb2_platform_data kirkwood_otg_data = {
.operating_mode = FSL_USB2_DR_DEVICE,
.phy_mode       = FSL_USB2_PHY_UTMI,
};

static u64 otg_dmamask = DMA_BIT_MASK(32);

/* OTG gadget device */
struct platform_device kirkwood_otg = {
	.name		= "fsl-usb2-udc",
	.id		= -1,
	.dev		= {
		.dma_mask		= &otg_dmamask,
		.coherent_dma_mask	= DMA_BIT_MASK(32),
		.platform_data		= &kirkwood_otg_data,
	},
	.resource	= kirkwood_usb_resources,
	.num_resources	= ARRAY_SIZE(kirkwood_usb_resources),
};

void __init kirkwood_otg_init(void)
{
	kirkwood_clk_ctrl |= CGC_USB0;
	platform_device_register(&kirkwood_otg);
}

//void __init kirkwood_ehci_init(void)
//{
//	kirkwood_clk_ctrl |= CGC_USB0;
//	platform_device_register(&kirkwood_ehci);
//}
/*****************************************************************************
 * GE00
 ****************************************************************************/

В файл arch/arm/mach-kirkwood/db88f6281-bp-setup.c

static void __init db88f6281_init(void)
{
	/*
	 * Basic setup. Needs to be called early.
	 */

    kirkwood_init();
	….
   kirkwood_otg_init();
      …..
}

В файл drivers/usb/gadget/Kconfig

 config USB_GADGET_FSL_USB2
 	boolean "Freescale Highspeed USB DR Peripheral Controller"
	depends on FSL_SOC || ARCH_MXC || ARCH_KIRKWOOD
 	select USB_GADGET_DUALSPEED
 	help
 	   Some of Freescale PowerPC processors have a High Speed
–

Выставить в ядре:

->Device
    Drivers
        -> USB support (USB_SUPPORT [=y])
            -> USB Gadget Support (USB_GADGET [=y])

CONFIG_USB_MASS_STORAGE для того чтобы usb-device был как внешний накопитель.

После запуска ядра нужно воткнуть модуль передав при этом ему в качестве параметра файловую систему которая будет являться внешним накопителем. В моём случае файловая система представлена Ram-диском поэтому операция загрузки модуля выглядит так:

insmod  /lib/modules/2.6.36/kernel/drivers/usb/gadget/g_mass_storage.ko file=/ dev/ram0 
g_mass_storage gadget: Mass Storage Function, version: 2009/09/11 
g_mass_storage gadget: Number of LUNs=1 
 lun0: LUN: removable file: /dev/ram0 
g_mass_storage gadget: Mass Storage Gadget, version: 2009/09/11 
g_mass_storage gadget: g_mass_storage ready 
fsl-usb2-udc: bind to driver g_mass_storage 
# g_mass_storage gadget: high speed config #1: Linux File-Backed Storage 

На компе при этом мы в dmesg можем увидеть вот такой лог:

Apr 23 21:02:21 ubunta kernel: [47718.452228] usb 2-1.3.1: new high-speed USB device number 76 using ehci_hcd 
Apr 23 21:02:21 ubunta kernel: [47718.571196] usb 2-1.3.1: New USB device found, idVendor=0525, idProduct=a4a5 
Apr 23 21:02:21 ubunta kernel: [47718.571201] usb 2-1.3.1: New USB device strings: Mfr=1, Product=2, SerialNumber=0 
Apr 23 21:02:21 ubunta kernel: [47718.571204] usb 2-1.3.1: Product: Mass Storage Gadget 
Apr 23 21:02:21 ubunta kernel: [47718.571207] usb 2-1.3.1: Manufacturer: Linux 2.6.36 with fsl-usb2-udc 
Apr 23 21:02:21 ubunta mtp-probe: checking bus 2, device 76: "/sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.3/2-1.3.1" 
Apr 23 21:02:21 ubunta mtp-probe: bus: 2, device: 76 was not an MTP device 
Apr 23 21:02:21 ubunta kernel: [47718.582534] usb-storage 2-1.3.1:1.0: Quirks match for vid 0525 pid a4a5: 10000 
Apr 23 21:02:21 ubunta kernel: [47718.582606] scsi14 : usb-storage 2-1.3.1:1.0 
Apr 23 21:02:22 ubunta kernel: [47719.581749] scsi 14:0:0:0: Direct-Access     Linux    File-CD Gadget   0319 PQ: 0 ANSI: 2 
Apr 23 21:02:22 ubunta kernel: [47719.582773] sd 14:0:0:0: Attached scsi generic sg3 type 0 
Apr 23 21:02:22 ubunta kernel: [47719.587731] sd 14:0:0:0: [sdc] 245760 512-byte logical blocks: (125 MB/120 MiB) 
Apr 23 21:02:22 ubunta kernel: [47719.690417] sd 14:0:0:0: [sdc] Write Protect is off 
Apr 23 21:02:22 ubunta kernel: [47719.690422] sd 14:0:0:0: [sdc] Mode Sense: 0f 00 00 00 
Apr 23 21:02:22 ubunta kernel: [47719.800337] sd 14:0:0:0: [sdc] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA 
Apr 23 21:02:23 ubunta kernel: [47720.025344]  sdc: unknown partition table 
Apr 23 21:02:23 ubunta kernel: [47720.250131] sd 14:0:0:0: [sdc] Attached SCSI removable disk 
Apr 23 21:02:23 ubunta kernel: [47720.569987] EXT2-fs (sdc): warning: mounting unchecked fs, running e2fsck is recommended 
Apr 23 21:02:23 ubunta udisksd[2136]: Mounted /dev/sdc at /media/dima/733ee7cf-c6e8-4ab6-bd6a-24f8192b491c on behalf of uid 1000 

Если автомонтирование включено то откроется стандартное окошко наутилуса в юбунте в котором будет доступна вся файловая система процессора 88F6282

Ошибка в причине которой не разбирался. При первом запуске была вот такая проблема:

# insmod /lib/modules/2.6.36/kernel/drivers/usb/gadget/g_mass_storage.ko 
g_mass_storage gadget: adding config #1 'Linux File-Backed Storage'/bf007068 
g_mass_storage gadget: Mass Storage Function, version: 2009/09/11 
g_mass_storage gadget: Number of LUNs=1 
 lun0: LUN: removable file: (no medium) 
g_mass_storage gadget: I/O thread pid: 557 
g_mass_storage gadget: adding 'Mass Storage Function'/df9a9960 to config 'Linux File-Backed Storage'/bf007068 
g_mass_storage gadget: cfg 1/bf007068 speeds: high full 
g_mass_storage gadget:   interface 0 = Mass Storage Function/df9a9960 
g_mass_storage gadget: Mass Storage Gadget, version: 2009/09/11 
g_mass_storage gadget: g_mass_storage ready 
fsl-usb2-udc: bind to driver g_mass_storage 
g_mass_storage gadget: suspend 
# g_mass_storage gadget: resume 
g_mass_storage gadget: suspend 
g_mass_storage gadget: resume 
g_mass_storage gadget: suspend 
g_mass_storage gadget: resume 
g_mass_storage gadget: suspend 
g_mass_storage gadget: resume 
…..

решилось простым аппаратным переподключением usb.