HelenOS sources

root/uspace/app/usbinfo/list.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. print_usb_device
  2. print_usb_bus
  3. list

/*
 * Copyright (c) 2010-2011 Vojtech Horky
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 * - The name of the author may not be used to endorse or promote products
 *   derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/** @addtogroup lsusb
 * @{
 */
/**
 * @file
 * Listing of USB host controllers.
 */

#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <str_error.h>
#include <stdbool.h>
#include <getopt.h>
#include <devman.h>
#include <loc.h>
#include <usb_iface.h>
#include <str.h>

#include "usbinfo.h"

#define MAX_PATH_LENGTH 1024

static void print_usb_device(devman_handle_t handle)
{
        char path[MAX_PATH_LENGTH];
        errno_t rc = devman_fun_get_path(handle, path, MAX_PATH_LENGTH);
        if (rc != EOK) {
                printf(NAME "Failed to get path for device %" PRIun "\n", handle);
                return;
        }
        printf("\tDevice %" PRIun ": %s\n", handle, path);
}

static void print_usb_bus(service_id_t svc)
{
        devman_handle_t hc_handle = 0;
        errno_t rc = devman_fun_sid_to_handle(svc, &hc_handle);
        if (rc != EOK) {
                printf(NAME ": Error resolving handle of HC with SID %"
                    PRIun ", skipping.\n", svc);
                return;
        }

        char path[MAX_PATH_LENGTH];
        rc = devman_fun_get_path(hc_handle, path, sizeof(path));
        if (rc != EOK) {
                printf(NAME ": Error resolving path of HC with SID %"
                    PRIun ", skipping.\n", svc);
                return;
        }
        printf("Bus %" PRIun ": %s\n", svc, path);

        /*
         * Construct device's path.
         * That's "hc function path" - ( '/' + "hc function name" )
         */
        // TODO replace this with something sane

        /* Get function name */
        char name[10];
        rc = devman_fun_get_name(hc_handle, name, sizeof(name));
        if (rc != EOK) {
                printf(NAME ": Error resolving name of HC with SID %"
                    PRIun ", skipping.\n", svc);
                return;
        }

        /* Get handle of parent device */
        devman_handle_t fh;
        path[str_size(path) - str_size(name) - 1] = '\0';
        rc = devman_fun_get_handle(path, &fh, IPC_FLAG_BLOCKING);
        if (rc != EOK) {
                printf(NAME ": Error resolving parent handle of HC with"
                    " SID %" PRIun ", skipping.\n", svc);
                return;
        }

        /* Get child handle */
        devman_handle_t dh;
        rc = devman_fun_get_child(fh, &dh);
        if (rc != EOK) {
                printf(NAME ": Error resolving parent handle of HC with"
                    " SID %" PRIun ", skipping.\n", svc);
                return;
        }

        devman_handle_t *fhs = 0;
        size_t count;
        rc = devman_dev_get_functions(dh, &fhs, &count);
        if (rc != EOK) {
                printf(NAME ": Error siblings of HC with"
                    " SID %" PRIun ", skipping.\n", svc);
                return;
        }

        for (size_t i = 0; i < count; ++i) {
                if (fhs[i] != hc_handle)
                        print_usb_device(fhs[i]);
        }
        free(fhs);
}

void list(void)
{
        category_id_t usbhc_cat;
        service_id_t *svcs;
        size_t count;
        errno_t rc;

        rc = loc_category_get_id(USB_HC_CATEGORY, &usbhc_cat, 0);
        if (rc != EOK) {
                printf(NAME ": Error resolving category '%s'",
                    USB_HC_CATEGORY);
                return;
        }

        rc = loc_category_get_svcs(usbhc_cat, &svcs, &count);
        if (rc != EOK) {
                printf(NAME ": Error getting list of host controllers.\n");
                return;
        }

        for (unsigned int i = 0; i < count; ++i) {
                print_usb_bus(svcs[i]);
        }

        free(svcs);
}

/** @}
 */

/* [<][>][^][v][top][bottom][index][help] */
HelenOS homepage, sources at GitHub