cregit-Linux how code gets into the kernel

Release 4.7 drivers/usb/usbip/vhci_sysfs.c

/*
 * Copyright (C) 2003-2008 Takahiro Hirofuchi
 *
 * This 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 is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
 * USA.
 */

#include <linux/kthread.h>
#include <linux/file.h>
#include <linux/net.h>

#include "usbip_common.h"
#include "vhci.h"

/* TODO: refine locking ?*/

/* Sysfs entry to show port status */

static ssize_t status_show(struct device *dev, struct device_attribute *attr, char *out) { char *s = out; int i = 0; unsigned long flags; BUG_ON(!the_controller || !out); spin_lock_irqsave(&the_controller->lock, flags); /* * output example: * prt sta spd dev socket local_busid * 000 004 000 000 c5a7bb80 1-2.3 * 001 004 000 000 d8cee980 2-3.4 * * IP address can be retrieved from a socket pointer address by looking * up /proc/net/{tcp,tcp6}. Also, a userland program may remember a * port number and its peer IP address. */ out += sprintf(out, "prt sta spd bus dev socket local_busid\n"); for (i = 0; i < VHCI_NPORTS; i++) { struct vhci_device *vdev = port_to_vdev(i); spin_lock(&vdev->ud.lock); out += sprintf(out, "%03u %03u ", i, vdev->ud.status); if (vdev->ud.status == VDEV_ST_USED) { out += sprintf(out, "%03u %08x ", vdev->speed, vdev->devid); out += sprintf(out, "%16p ", vdev->ud.tcp_socket); out += sprintf(out, "%s", dev_name(&vdev->udev->dev)); } else { out += sprintf(out, "000 000 000 0000000000000000 0-0"); } out += sprintf(out, "\n"); spin_unlock(&vdev->ud.lock); } spin_unlock_irqrestore(&the_controller->lock, flags); return out - s; }

Contributors

PersonTokensPropCommitsCommitProp
takahiro hirofuchitakahiro hirofuchi20490.67%114.29%
andrew goodbodyandrew goodbody104.44%114.29%
kay sieverskay sievers41.78%114.29%
stoyan gaydarovstoyan gaydarov31.33%114.29%
matt mooneymatt mooney20.89%114.29%
greg kroah-hartmangreg kroah-hartman10.44%114.29%
cedric cabessacedric cabessa10.44%114.29%
Total225100.00%7100.00%

static DEVICE_ATTR_RO(status); /* Sysfs entry to shutdown a virtual connection */
static int vhci_port_disconnect(__u32 rhport) { struct vhci_device *vdev; unsigned long flags; usbip_dbg_vhci_sysfs("enter\n"); /* lock */ spin_lock_irqsave(&the_controller->lock, flags); vdev = port_to_vdev(rhport); spin_lock(&vdev->ud.lock); if (vdev->ud.status == VDEV_ST_NULL) { pr_err("not connected %d\n", vdev->ud.status); /* unlock */ spin_unlock(&vdev->ud.lock); spin_unlock_irqrestore(&the_controller->lock, flags); return -EINVAL; } /* unlock */ spin_unlock(&vdev->ud.lock); spin_unlock_irqrestore(&the_controller->lock, flags); usbip_event_add(&vdev->ud, VDEV_EVENT_DOWN); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
takahiro hirofuchitakahiro hirofuchi11888.72%125.00%
andrew goodbodyandrew goodbody139.77%125.00%
matt mooneymatt mooney10.75%125.00%
brian g. merrellbrian g. merrell10.75%125.00%
Total133100.00%4100.00%


static ssize_t store_detach(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int err; __u32 rhport = 0; if (sscanf(buf, "%u", &rhport) != 1) return -EINVAL; /* check rhport */ if (rhport >= VHCI_NPORTS) { dev_err(dev, "invalid port %u\n", rhport); return -EINVAL; } err = vhci_port_disconnect(rhport); if (err < 0) return -EINVAL; usbip_dbg_vhci_sysfs("Leave\n"); return count; }

Contributors

PersonTokensPropCommitsCommitProp
takahiro hirofuchitakahiro hirofuchi8486.60%125.00%
john de la garzajohn de la garza99.28%125.00%
matt mooneymatt mooney33.09%125.00%
brian g. merrellbrian g. merrell11.03%125.00%
Total97100.00%4100.00%

static DEVICE_ATTR(detach, S_IWUSR, NULL, store_detach); /* Sysfs entry to establish a virtual connection */
static int valid_args(__u32 rhport, enum usb_device_speed speed) { /* check rhport */ if (rhport >= VHCI_NPORTS) { pr_err("port %u\n", rhport); return -EINVAL; } /* check speed */ switch (speed) { case USB_SPEED_LOW: case USB_SPEED_FULL: case USB_SPEED_HIGH: case USB_SPEED_WIRELESS: break; default: pr_err("Failed attach request for unsupported USB speed: %s\n", usb_speed_string(speed)); return -EINVAL; } return 0; }

Contributors

PersonTokensPropCommitsCommitProp
takahiro hirofuchitakahiro hirofuchi6490.14%125.00%
shuah khanshuah khan45.63%125.00%
matt mooneymatt mooney22.82%125.00%
greg kroah-hartmangreg kroah-hartman11.41%125.00%
Total71100.00%4100.00%

/* * To start a new USB/IP attachment, a userland program needs to setup a TCP * connection and then write its socket descriptor with remote device * information into this sysfs file. * * A remote device is virtually attached to the root-hub port of @rhport with * @speed. @devid is embedded into a request to specify the remote device in a * server host. * * write() returns 0 on success, else negative errno. */
static ssize_t store_attach(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct vhci_device *vdev; struct socket *socket; int sockfd = 0; __u32 rhport = 0, devid = 0, speed = 0; int err; unsigned long flags; /* * @rhport: port number of vhci_hcd * @sockfd: socket descriptor of an established TCP connection * @devid: unique device identifier in a remote host * @speed: usb device speed in a remote host */ if (sscanf(buf, "%u %u %u %u", &rhport, &sockfd, &devid, &speed) != 4) return -EINVAL; usbip_dbg_vhci_sysfs("rhport(%u) sockfd(%u) devid(%u) speed(%u)\n", rhport, sockfd, devid, speed); /* check received parameters */ if (valid_args(rhport, speed) < 0) return -EINVAL; /* Extract socket from fd. */ socket = sockfd_lookup(sockfd, &err); if (!socket) return -EINVAL; /* now need lock until setting vdev status as used */ /* begin a lock */ spin_lock_irqsave(&the_controller->lock, flags); vdev = port_to_vdev(rhport); spin_lock(&vdev->ud.lock); if (vdev->ud.status != VDEV_ST_NULL) { /* end of the lock */ spin_unlock(&vdev->ud.lock); spin_unlock_irqrestore(&the_controller->lock, flags); sockfd_put(socket); dev_err(dev, "port %d already used\n", rhport); return -EINVAL; } dev_info(dev, "rhport(%u) sockfd(%d) devid(%u) speed(%u) speed_str(%s)\n", rhport, sockfd, devid, speed, usb_speed_string(speed)); vdev->devid = devid; vdev->speed = speed; vdev->ud.tcp_socket = socket; vdev->ud.status = VDEV_ST_NOTASSIGNED; spin_unlock(&vdev->ud.lock); spin_unlock_irqrestore(&the_controller->lock, flags); /* end the lock */ vdev->ud.tcp_rx = kthread_get_run(vhci_rx_loop, &vdev->ud, "vhci_rx"); vdev->ud.tcp_tx = kthread_get_run(vhci_tx_loop, &vdev->ud, "vhci_tx"); rh_port_connect(rhport, speed); return count; }

Contributors

PersonTokensPropCommitsCommitProp
takahiro hirofuchitakahiro hirofuchi24473.72%18.33%
max vozelermax vozeler288.46%18.33%
andrew goodbodyandrew goodbody133.93%18.33%
arnd bergmannarnd bergmann92.72%18.33%
al viroal viro82.42%18.33%
john de la garzajohn de la garza82.42%18.33%
shuah khanshuah khan72.11%216.67%
matt mooneymatt mooney61.81%18.33%
bernard blackhambernard blackham51.51%18.33%
oleg nesterovoleg nesterov20.60%18.33%
brian g. merrellbrian g. merrell10.30%18.33%
Total331100.00%12100.00%

static DEVICE_ATTR(attach, S_IWUSR, NULL, store_attach); static struct attribute *dev_attrs[] = { &dev_attr_status.attr, &dev_attr_detach.attr, &dev_attr_attach.attr, &dev_attr_usbip_debug.attr, NULL, }; const struct attribute_group dev_attr_group = { .attrs = dev_attrs, };

Overall Contributors

PersonTokensPropCommitsCommitProp
takahiro hirofuchitakahiro hirofuchi79783.81%14.76%
andrew goodbodyandrew goodbody363.79%14.76%
max vozelermax vozeler303.15%14.76%
matt mooneymatt mooney181.89%314.29%
john de la garzajohn de la garza171.79%14.76%
shuah khanshuah khan111.16%314.29%
arnd bergmannarnd bergmann90.95%14.76%
bernard blackhambernard blackham80.84%14.76%
al viroal viro80.84%14.76%
kay sieverskay sievers40.42%14.76%
brian g. merrellbrian g. merrell30.32%14.76%
stoyan gaydarovstoyan gaydarov30.32%14.76%
greg kroah-hartmangreg kroah-hartman30.32%29.52%
oleg nesterovoleg nesterov20.21%14.76%
cedric cabessacedric cabessa10.11%14.76%
marton nemethmarton nemeth10.11%14.76%
Total951100.00%21100.00%
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
{% endraw %}