mirror of https://gitee.com/openkylin/linux.git
95 lines
2.7 KiB
C
95 lines
2.7 KiB
C
/*
|
|
* Copyright (C) 2007 by Alan Stern
|
|
*
|
|
* 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 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
*/
|
|
|
|
/* this file is part of ehci-hcd.c */
|
|
|
|
|
|
/* Display the ports dedicated to the companion controller */
|
|
static ssize_t show_companion(struct device *dev,
|
|
struct device_attribute *attr,
|
|
char *buf)
|
|
{
|
|
struct ehci_hcd *ehci;
|
|
int nports, index, n;
|
|
int count = PAGE_SIZE;
|
|
char *ptr = buf;
|
|
|
|
ehci = hcd_to_ehci(bus_to_hcd(dev_get_drvdata(dev)));
|
|
nports = HCS_N_PORTS(ehci->hcs_params);
|
|
|
|
for (index = 0; index < nports; ++index) {
|
|
if (test_bit(index, &ehci->companion_ports)) {
|
|
n = scnprintf(ptr, count, "%d\n", index + 1);
|
|
ptr += n;
|
|
count -= n;
|
|
}
|
|
}
|
|
return ptr - buf;
|
|
}
|
|
|
|
/*
|
|
* Dedicate or undedicate a port to the companion controller.
|
|
* Syntax is "[-]portnum", where a leading '-' sign means
|
|
* return control of the port to the EHCI controller.
|
|
*/
|
|
static ssize_t store_companion(struct device *dev,
|
|
struct device_attribute *attr,
|
|
const char *buf, size_t count)
|
|
{
|
|
struct ehci_hcd *ehci;
|
|
int portnum, new_owner;
|
|
|
|
ehci = hcd_to_ehci(bus_to_hcd(dev_get_drvdata(dev)));
|
|
new_owner = PORT_OWNER; /* Owned by companion */
|
|
if (sscanf(buf, "%d", &portnum) != 1)
|
|
return -EINVAL;
|
|
if (portnum < 0) {
|
|
portnum = - portnum;
|
|
new_owner = 0; /* Owned by EHCI */
|
|
}
|
|
if (portnum <= 0 || portnum > HCS_N_PORTS(ehci->hcs_params))
|
|
return -ENOENT;
|
|
portnum--;
|
|
if (new_owner)
|
|
set_bit(portnum, &ehci->companion_ports);
|
|
else
|
|
clear_bit(portnum, &ehci->companion_ports);
|
|
set_owner(ehci, portnum, new_owner);
|
|
return count;
|
|
}
|
|
static DEVICE_ATTR(companion, 0644, show_companion, store_companion);
|
|
|
|
static inline int create_sysfs_files(struct ehci_hcd *ehci)
|
|
{
|
|
int i = 0;
|
|
|
|
/* with integrated TT there is no companion! */
|
|
if (!ehci_is_TDI(ehci))
|
|
i = device_create_file(ehci_to_hcd(ehci)->self.controller,
|
|
&dev_attr_companion);
|
|
return i;
|
|
}
|
|
|
|
static inline void remove_sysfs_files(struct ehci_hcd *ehci)
|
|
{
|
|
/* with integrated TT there is no companion! */
|
|
if (!ehci_is_TDI(ehci))
|
|
device_remove_file(ehci_to_hcd(ehci)->self.controller,
|
|
&dev_attr_companion);
|
|
}
|