Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Linux/tools/usb/usbip/src/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 4 kB image not shown  

Quelle  usbip_bind.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (C) 2011 matt mooney <mfm@muteddisk.com>
 *               2005-2007 Takahiro Hirofuchi
 */


#include <libudev.h>

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <getopt.h>

#include "usbip_common.h"
#include "utils.h"
#include "usbip.h"
#include "sysfs_utils.h"

enum unbind_status {
 UNBIND_ST_OK,
 UNBIND_ST_USBIP_HOST,
 UNBIND_ST_FAILED
};

static const char usbip_bind_usage_string[] =
 "usbip bind \n"
 " -b, --busid= Bind " USBIP_HOST_DRV_NAME ".ko to device "
 "on \n";

void usbip_bind_usage(void)
{
 printf("usage: %s", usbip_bind_usage_string);
}

/* call at unbound state */
static int bind_usbip(char *busid)
{
 char attr_name[] = "bind";
 char bind_attr_path[SYSFS_PATH_MAX];
 int rc = -1;

 snprintf(bind_attr_path, sizeof(bind_attr_path), "%s/%s/%s/%s/%s/%s",
   SYSFS_MNT_PATH, SYSFS_BUS_NAME, SYSFS_BUS_TYPE,
   SYSFS_DRIVERS_NAME, USBIP_HOST_DRV_NAME, attr_name);

 rc = write_sysfs_attribute(bind_attr_path, busid, strlen(busid));
 if (rc < 0) {
  err("error binding device %s to driver: %s", busid,
      strerror(errno));
  return -1;
 }

 return 0;
}

/* buggy driver may cause dead lock */
static int unbind_other(char *busid)
{
 enum unbind_status status = UNBIND_ST_OK;

 char attr_name[] = "unbind";
 char unbind_attr_path[SYSFS_PATH_MAX];
 int rc = -1;

 struct udev *udev;
 struct udev_device *dev;
 const char *driver;
 const char *bDevClass;

 /* Create libudev context. */
 udev = udev_new();

 /* Get the device. */
 dev = udev_device_new_from_subsystem_sysname(udev, "usb", busid);
 if (!dev) {
  dbg("unable to find device with bus ID %s", busid);
  goto err_close_busid_dev;
 }

 /* Check what kind of device it is. */
 bDevClass  = udev_device_get_sysattr_value(dev, "bDeviceClass");
 if (!bDevClass) {
  dbg("unable to get bDevClass device attribute");
  goto err_close_busid_dev;
 }

 if (!strncmp(bDevClass, "09", strlen(bDevClass))) {
  dbg("skip unbinding of hub");
  goto err_close_busid_dev;
 }

 /* Get the device driver. */
 driver = udev_device_get_driver(dev);
 if (!driver) {
  /* No driver bound to this device. */
  goto out;
 }

 if (!strncmp(USBIP_HOST_DRV_NAME, driver,
    strlen(USBIP_HOST_DRV_NAME))) {
  /* Already bound to usbip-host. */
  status = UNBIND_ST_USBIP_HOST;
  goto out;
 }

 /* Unbind device from driver. */
 snprintf(unbind_attr_path, sizeof(unbind_attr_path), "%s/%s/%s/%s/%s/%s",
   SYSFS_MNT_PATH, SYSFS_BUS_NAME, SYSFS_BUS_TYPE,
   SYSFS_DRIVERS_NAME, driver, attr_name);

 rc = write_sysfs_attribute(unbind_attr_path, busid, strlen(busid));
 if (rc < 0) {
  err("error unbinding device %s from driver", busid);
  goto err_close_busid_dev;
 }

 goto out;

err_close_busid_dev:
 status = UNBIND_ST_FAILED;
out:
 udev_device_unref(dev);
 udev_unref(udev);

 return status;
}

static int bind_device(char *busid)
{
 int rc;
 struct udev *udev;
 struct udev_device *dev;
 const char *devpath;

 /* Check whether the device with this bus ID exists. */
 udev = udev_new();
 dev = udev_device_new_from_subsystem_sysname(udev, "usb", busid);
 if (!dev) {
  err("device with the specified bus ID does not exist");
  return -1;
 }
 devpath = udev_device_get_devpath(dev);
 udev_unref(udev);

 /* If the device is already attached to vhci_hcd - bail out */
 if (strstr(devpath, USBIP_VHCI_DRV_NAME)) {
  err("bind loop detected: device: %s is attached to %s\n",
      devpath, USBIP_VHCI_DRV_NAME);
  return -1;
 }

 rc = unbind_other(busid);
 if (rc == UNBIND_ST_FAILED) {
  err("could not unbind driver from device on busid %s", busid);
  return -1;
 } else if (rc == UNBIND_ST_USBIP_HOST) {
  err("device on busid %s is already bound to %s", busid,
      USBIP_HOST_DRV_NAME);
  return -1;
 }

 rc = modify_match_busid(busid, 1);
 if (rc < 0) {
  err("unable to bind device on %s", busid);
  return -1;
 }

 rc = bind_usbip(busid);
 if (rc < 0) {
  err("could not bind device to %s", USBIP_HOST_DRV_NAME);
  modify_match_busid(busid, 0);
  return -1;
 }

 info("bind device on busid %s: complete", busid);

 return 0;
}

int usbip_bind(int argc, char *argv[])
{
 static const struct option opts[] = {
  { "busid", required_argument, NULL, 'b' },
  { NULL,    0,                 NULL,  0  }
 };

 int opt;
 int ret = -1;

 for (;;) {
  opt = getopt_long(argc, argv, "b:", opts, NULL);

  if (opt == -1)
   break;

  switch (opt) {
  case 'b':
   ret = bind_device(optarg);
   goto out;
  default:
   goto err_out;
  }
 }

err_out:
 usbip_bind_usage();
out:
 return ret;
}

Messung V0.5
C=95 H=76 G=85

¤ Dauer der Verarbeitung: 0.4 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.