Re: What about the patch for USB gadgets?

On Wed, 2011-05-11 at 15:11 +0200, W. Martin Borgert wrote:
> Hi,
> there was a patch sent to the list in February:
> However, I can't find any reaction on the list, neither
> approval nor rejection. Can someone comment on the patch
> or point me to existing comments, please? TIA!

A quick question on these, are they properly represented in sysfs or are
they "virtual" devices?  Given that they are USB connected it would seem
they should be properly presented, even in the case of platform drivers
since there has to be a USB tree in sysfs to root things in...  One
thing you can do is grab the attached lsudev.c tool and run that like
"lsudev net" when the device is present, and that'll give me more
information about the sysfs layout that I can use to answer my question.

gcc -o lsudev `pkg-config --libs --cflags glib-2.0 gudev-1.0` lsudev.c

/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 * Copyright (C) 2009 Red Hat, Inc.

#include <glib.h>
#include <gudev/gudev.h>

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <signal.h>

static GMainLoop *loop = NULL;

static void
signal_handler (int signo)
	if (signo == SIGINT || signo == SIGTERM) {
		g_message ("Caught signal %d, shutting down...", signo);
		g_main_loop_quit (loop);

static void
setup_signals (void)
	struct sigaction action;
	sigset_t mask;

	sigemptyset (&mask);
	action.sa_handler = signal_handler;
	action.sa_mask = mask;
	action.sa_flags = 0;
	sigaction (SIGTERM,  &action, NULL);
	sigaction (SIGINT,  &action, NULL);

static void
println (guint indent, const char *fmt, ...)
	va_list args;
	GString *output;
	int i;

	g_return_if_fail (fmt != NULL);

	output = g_string_sized_new (250);

	for (i = 0; i < indent; i++)
		g_string_append_c (output, ' ');

	va_start (args, fmt);
	g_string_append_vprintf (output, fmt, args);
	va_end (args);

	g_print ("%s\n", output->str);
	g_string_free (output, TRUE);

static void
dump_device_and_parent (GUdevDevice *device, guint indent)
	const char **list, **iter;
	GUdevDevice *parent;
	char propstr[500];
	guint32 namelen = 0, i;

	println (indent, "------------------------------------------------------");
	println (indent, "Name:     %s", g_udev_device_get_name (device));
	println (indent, "Type:     %s", g_udev_device_get_devtype (device));
	println (indent, "Subsys:   %s", g_udev_device_get_subsystem (device));
	println (indent, "Number:   %s", g_udev_device_get_number (device));
	println (indent, "Path:     %s", g_udev_device_get_sysfs_path (device));
	println (indent, "Driver:   %s", g_udev_device_get_driver (device));
	println (indent, "Action:   %s", g_udev_device_get_action (device));
	println (indent, "Seq Num:  %lu", g_udev_device_get_seqnum (device));
	println (indent, "Dev File: %s", g_udev_device_get_device_file (device));

	println (indent, "");
	println (indent, "Properties:");

	/* Get longest property name length for alignment */
	list = (const char **) g_udev_device_get_property_keys (device);
	for (iter = list; iter && *iter; iter++) {
		if (strlen (*iter) > namelen)
			namelen = strlen (*iter);

	for (iter = list; iter && *iter; iter++) {
		strcpy (propstr, *iter);
		strcat (propstr, ":");
		for (i = 0; i < namelen - strlen (*iter); i++)
			strcat (propstr, " ");
		strcat (propstr, g_udev_device_get_property (device, *iter));
		println (indent + 2, "%s", propstr);

	println (indent, "");

	parent = g_udev_device_get_parent (device);
	if (parent) {
		dump_device_and_parent (parent, indent + 4);
		g_object_unref (parent);

static void
handle_uevent (GUdevClient *client,
               const char *action,
               GUdevDevice *device,
               gpointer user_data)
	const char *expected_subsys = user_data;
	const char *subsys;

	g_return_if_fail (client != NULL);
	g_return_if_fail (action != NULL);
	g_return_if_fail (device != NULL);

	/* A bit paranoid */
	subsys = g_udev_device_get_subsystem (device);
	g_return_if_fail (subsys != NULL);

	g_return_if_fail (!strcmp (subsys, expected_subsys));

	g_print ("---- (EVENT: %s) ----\n", action);
	dump_device_and_parent (device, 0);
	g_print ("\n");

main (int argc, char *argv[])
	GUdevClient *client;	
	const char *subsys[2] = { NULL, NULL };
	GList *list, *iter;

	if (argc != 2) {
		g_warning ("Usage: %s [subsystem]", argv[0]);
		return 1;

	g_type_init ();

	loop = g_main_loop_new (NULL, FALSE);

	setup_signals ();

	subsys[0] = argv[1];
	client = g_udev_client_new (subsys);
	g_signal_connect (client, "uevent", G_CALLBACK (handle_uevent), (gpointer) subsys[0]);

	list = g_udev_client_query_by_subsystem (client, subsys[0]);
	for (iter = list; iter; iter = g_list_next (iter)) {
		dump_device_and_parent (G_UDEV_DEVICE (iter->data), 0);
		g_print ("\n");
		g_object_unref (G_UDEV_DEVICE (iter->data));

	g_main_loop_run (loop);

	return 0;

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]