--- util.c +++ util.c @@ -1048,3 +1048,55 @@ h_hash_table_remove_all_true, NULL); } + +gfloat +h_sysfs_read_float(gchar *endpoint, gchar *entry) +{ + gchar *tmp, *buffer; + gfloat return_value = 0.0f; + + tmp = g_build_filename(endpoint, entry, NULL); + if (g_file_get_contents(tmp, &buffer, NULL, NULL)) + return_value = atof(buffer); + + g_free(tmp); + g_free(buffer); + + return return_value; +} + +gint +h_sysfs_read_int(gchar *endpoint, gchar *entry) +{ + gchar *tmp, *buffer; + gint return_value = 0.0f; + + tmp = g_build_filename(endpoint, entry, NULL); + if (g_file_get_contents(tmp, &buffer, NULL, NULL)) + return_value = atoi(buffer); + + g_free(tmp); + g_free(buffer); + + return return_value; +} + +gchar * +h_sysfs_read_string(gchar *endpoint, gchar *entry) +{ + gchar *tmp, *return_value; + + tmp = g_build_filename(endpoint, entry, NULL); + if (!g_file_get_contents(tmp, &return_value, NULL, NULL)) { + g_free(return_value); + + return_value = NULL; + } else { + return_value = g_strstrip(return_value); + } + + g_free(tmp); + + return return_value; +} + --- arch/linux/common/usb.h +++ arch/linux/common/usb.h @@ -15,7 +15,6 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - static gboolean remove_usb_devices(gpointer key, gpointer value, gpointer data) { @@ -23,8 +22,113 @@ } static gchar *usb_list = NULL; -void -__scan_usb(void) + +void __scan_usb_sysfs_add_device(gchar * endpoint, int n) +{ + gchar *manufacturer, *product, *mxpwr, *tmp, *strhash; + gint bus, classid, vendor, prodid; + gchar *version, *speed; + + classid = h_sysfs_read_int(endpoint, "bDeviceClass"); + vendor = h_sysfs_read_int(endpoint, "idVendor"); + prodid = h_sysfs_read_int(endpoint, "idProduct"); + bus = h_sysfs_read_int(endpoint, "busnum"); + if (!(speed = h_sysfs_read_string(endpoint, "speed"))) { + speed = g_strdup("12"); + } + + if (!(version = h_sysfs_read_string(endpoint, "version"))) { + version = g_strdup(" 1.0 "); + } + + if (!(mxpwr = h_sysfs_read_string(endpoint, "bMaxPower"))) { + mxpwr = g_strdup("0 mA"); + } + + if (!(manufacturer = h_sysfs_read_string(endpoint, "manufacturer"))) { + manufacturer = g_strdup("Unknown"); + } + + if (!(product = h_sysfs_read_string(endpoint, "product"))) { + if (classid == 9) { + product = g_strdup_printf("USB %.2f Hub", version); + } else { + product = g_strdup_printf("Unknown USB %.2f Device (class %d)", version, classid); + } + } + + const gchar *url = vendor_get_url(manufacturer); + if (url) { + tmp = g_strdup_printf("%s (%s)", vendor_get_name(manufacturer), url); + + g_free(manufacturer); + manufacturer = tmp; + } + + tmp = g_strdup_printf("USB%d", n); + usb_list = h_strdup_cprintf("$%s$%s=\n", usb_list, tmp, product); + + strhash = g_strdup_printf("[Device Information]\n" + "Product=%s\n" + "Manufacturer=%s\n" + "Speed=%sMbit/s\n" + "Max Current=%s\n" + "[Misc]\n" + "USB Version=%s\n" + "Class=0x%x\n" + "Vendor=0x%x\n" + "Product ID=0x%x\n" + "Bus=%d\n", + product, + manufacturer, + speed, + mxpwr, + version, classid, vendor, prodid, bus); + + g_hash_table_insert(moreinfo, tmp, strhash); + + g_free(manufacturer); + g_free(product); + g_free(mxpwr); + g_free(speed); + g_free(version); +} + +void __scan_usb_sysfs(void) +{ + GDir *sysfs; + gchar *filename; + const gchar *sysfs_path = "/sys/class/usb_endpoint"; + gint usb_device_number = 0; + + if (!(sysfs = g_dir_open(sysfs_path, 0, NULL))) { + return; + } + + if (usb_list) { + g_hash_table_foreach_remove(moreinfo, remove_usb_devices, NULL); + g_free(usb_list); + } + usb_list = g_strdup("[USB Devices]\n"); + + while ((filename = (gchar *) g_dir_read_name(sysfs))) { + gchar *endpoint = + g_build_filename(sysfs_path, filename, "device", NULL); + gchar *temp; + + temp = g_build_filename(endpoint, "idVendor", NULL); + if (g_file_test(temp, G_FILE_TEST_EXISTS)) { + __scan_usb_sysfs_add_device(endpoint, ++usb_device_number); + } + + g_free(temp); + g_free(endpoint); + } + + g_dir_close(sysfs); +} + +int __scan_usb_procfs(void) { FILE *dev; gchar buffer[128]; @@ -36,13 +140,13 @@ dev = fopen("/proc/bus/usb/devices", "r"); if (!dev) - return; + return 0; if (usb_list) { g_hash_table_foreach_remove(moreinfo, remove_usb_devices, NULL); g_free(usb_list); } - usb_list = g_strdup(""); + usb_list = g_strdup("[USB Devices]\n"); while (fgets(buffer, 128, dev)) { tmp = buffer; @@ -73,52 +177,60 @@ mxpwr = strstr(buffer, "MxPwr=") + 6; tmp = g_strdup_printf("USB%d", ++n); - + if (*product == '\0') { - g_free(product); - if (classid == 9) { - product = g_strdup_printf("USB %.2f Hub", ver); - } else { - product = g_strdup_printf("Unknown USB %.2f Device (class %d)", - ver, classid); - } + g_free(product); + if (classid == 9) { + product = g_strdup_printf("USB %.2f Hub", ver); + } else { + product = + g_strdup_printf + ("Unknown USB %.2f Device (class %d)", ver, + classid); + } } - + if (classid == 9) { /* hub */ - usb_list = h_strdup_cprintf("[%s#%d]\n", - usb_list, product, n); - } else { /* everything else */ - usb_list = h_strdup_cprintf("$%s$%s=\n", - usb_list, tmp, product); - - const gchar *url = vendor_get_url(manuf); - if (url) { - gchar *tmp = g_strdup_printf("%s (%s)", manuf, url); - g_free(manuf); - manuf = tmp; - } - - gchar *strhash = g_strdup_printf("[Device Information]\n" - "Product=%s\n" - "Manufacturer=%s\n" - "[Port #%d]\n" - "Speed=%.2fMbit/s\n" - "Max Current=%s\n" - "[Misc]\n" - "USB Version=%.2f\n" - "Revision=%.2f\n" - "Class=0x%x\n" - "Vendor=0x%x\n" - "Product ID=0x%x\n" - "Bus=%d\n" "Level=%d\n", - product, manuf, - port, speed, mxpwr, - ver, rev, classid, - vendor, prodid, bus, level); + usb_list = h_strdup_cprintf("[%s#%d]\n", + usb_list, product, n); + } else { /* everything else */ + usb_list = h_strdup_cprintf("$%s$%s=\n", + usb_list, tmp, product); + + const gchar *url = vendor_get_url(manuf); + if (url) { + gchar *tmp = + g_strdup_printf("%s (%s)", vendor_get_name(manuf), + url); + g_free(manuf); + manuf = tmp; + } + + gchar *strhash = g_strdup_printf("[Device Information]\n" + "Product=%s\n", + product); + if (manuf && strlen(manuf)) + strhash = h_strdup_cprintf("Manufacturer=%s\n", + strhash, manuf); + + strhash = h_strdup_cprintf("[Port #%d]\n" + "Speed=%.2fMbit/s\n" + "Max Current=%s\n" + "[Misc]\n" + "USB Version=%.2f\n" + "Revision=%.2f\n" + "Class=0x%x\n" + "Vendor=0x%x\n" + "Product ID=0x%x\n" + "Bus=%d\n" "Level=%d\n", + strhash, + port, speed, mxpwr, + ver, rev, classid, + vendor, prodid, bus, level); - g_hash_table_insert(moreinfo, tmp, strhash); - } + g_hash_table_insert(moreinfo, tmp, strhash); + } g_free(manuf); g_free(product); @@ -128,4 +240,12 @@ } fclose(dev); + + return n; +} + +void __scan_usb(void) +{ + if (!__scan_usb_procfs()) + __scan_usb_sysfs(); }