From 66dbc325afcef909043c30e90930a36823fc734c Mon Sep 17 00:00:00 2001 From: Mimi Zohar Date: Tue, 15 Mar 2011 16:12:09 -0400 Subject: evm: re-release EVM protects a file's security extended attributes(xattrs) against integrity attacks. This patchset provides the framework and an initial method. The initial method maintains an HMAC-sha1 value across the security extended attributes, storing the HMAC value as the extended attribute 'security.evm'. Other methods of validating the integrity of a file's metadata will be posted separately (eg. EVM-digital-signatures). While this patchset does authenticate the security xattrs, and cryptographically binds them to the inode, coming extensions will bind other directory and inode metadata for more complete protection. To help simplify the review and upstreaming process, each extension will be posted separately (eg. IMA-appraisal, IMA-appraisal-directory). For a general overview of the proposed Linux integrity subsystem, refer to Dave Safford's whitepaper: http://downloads.sf.net/project/linux-ima/linux-ima/Integrity_overview.pdf. EVM depends on the Kernel Key Retention System to provide it with a trusted/encrypted key for the HMAC-sha1 operation. The key is loaded onto the root's keyring using keyctl. Until EVM receives notification that the key has been successfully loaded onto the keyring (echo 1 > /evm), EVM can not create or validate the 'security.evm' xattr, but returns INTEGRITY_UNKNOWN. Loading the key and signaling EVM should be done as early as possible. Normally this is done in the initramfs, which has already been measured as part of the trusted boot. For more information on creating and loading existing trusted/encrypted keys, refer to Documentation/keys-trusted-encrypted.txt. A sample dracut patch, which loads the trusted/encrypted key and enables EVM, is available from http://linux-ima.sourceforge.net/#EVM. Based on the LSMs enabled, the set of EVM protected security xattrs is defined at compile. EVM adds the following three calls to the existing security hooks: evm_inode_setxattr(), evm_inode_post_setxattr(), and evm_inode_removexattr. To initialize and update the 'security.evm' extended attribute, EVM defines three calls: evm_inode_post_init(), evm_inode_post_setattr() and evm_inode_post_removexattr() hooks. To verify the integrity of a security xattr, EVM exports evm_verifyxattr(). Changelog v7: - Fixed URL in EVM ABI documentation Changelog v6: (based on Serge Hallyn's review) - fix URL in patch description - remove evm_hmac_size definition - use SHA1_DIGEST_SIZE (removed both MAX_DIGEST_SIZE and evm_hmac_size) - moved linux include before other includes - test for crypto_hash_setkey failure - fail earlier for invalid key - clear entire encrypted key, even on failure - check xattr name length before comparing xattr names Changelog: - locking based on i_mutex, remove evm_mutex - using trusted/encrypted keys for storing the EVM key used in the HMAC-sha1 operation. - replaced crypto hash with shash (Dmitry Kasatkin) - support for additional methods of verifying the security xattrs (Dmitry Kasatkin) - iint not allocated for all regular files, but only for those appraised - Use cap_sys_admin in lieu of cap_mac_admin - Use __vfs_setxattr_noperm(), without permission checks, from EVM Signed-off-by: Mimi Zohar Acked-by: Serge Hallyn --- Documentation/ABI/testing/evm | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 Documentation/ABI/testing/evm (limited to 'Documentation/ABI') diff --git a/Documentation/ABI/testing/evm b/Documentation/ABI/testing/evm new file mode 100644 index 000000000000..8374d4557e5d --- /dev/null +++ b/Documentation/ABI/testing/evm @@ -0,0 +1,23 @@ +What: security/evm +Date: March 2011 +Contact: Mimi Zohar +Description: + EVM protects a file's security extended attributes(xattrs) + against integrity attacks. The initial method maintains an + HMAC-sha1 value across the extended attributes, storing the + value as the extended attribute 'security.evm'. + + EVM depends on the Kernel Key Retention System to provide it + with a trusted/encrypted key for the HMAC-sha1 operation. + The key is loaded onto the root's keyring using keyctl. Until + EVM receives notification that the key has been successfully + loaded onto the keyring (echo 1 > /evm), EVM + can not create or validate the 'security.evm' xattr, but + returns INTEGRITY_UNKNOWN. Loading the key and signaling EVM + should be done as early as possible. Normally this is done + in the initramfs, which has already been measured as part + of the trusted boot. For more information on creating and + loading existing trusted/encrypted keys, refer to: + Documentation/keys-trusted-encrypted.txt. (A sample dracut + patch, which loads the trusted/encrypted key and enables + EVM, is available from http://linux-ima.sourceforge.net/#EVM.) -- cgit v1.2.3-55-g7522 From 18e10aba7f2a41767b9aa97911696c28d0f29083 Mon Sep 17 00:00:00 2001 From: Michal Malý Date: Thu, 4 Aug 2011 16:27:18 +0200 Subject: HID: lg4ff - Document sysfs interface for range setting Adds documentation of the sysfs interface used to set the wheel range. Signed-off-by: Michal Malý Signed-off-by: Simon Wood Signed-off-by: Jiri Kosina --- Documentation/ABI/testing/sysfs-driver-hid-logitech-lg4ff | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-driver-hid-logitech-lg4ff (limited to 'Documentation/ABI') diff --git a/Documentation/ABI/testing/sysfs-driver-hid-logitech-lg4ff b/Documentation/ABI/testing/sysfs-driver-hid-logitech-lg4ff new file mode 100644 index 000000000000..9aec8ef228b0 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-driver-hid-logitech-lg4ff @@ -0,0 +1,7 @@ +What: /sys/module/hid_logitech/drivers/hid:logitech//range. +Date: July 2011 +KernelVersion: 3.2 +Contact: Michal Malý +Description: Display minimum, maximum and current range of the steering + wheel. Writing a value within min and max boundaries sets the + range of the wheel. -- cgit v1.2.3-55-g7522 From e117d10d315970d0a3d4120c7f83b8337728ce1b Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Tue, 2 Aug 2011 00:53:09 +0200 Subject: Documentation/ABI/: update version number references from 2.6.x to 3.x Update the version number references from 2.6.x to 3.x Also correct spelling of "May" (was spelled "Mai"). Signed-off-by: Jesper Juhl Signed-off-by: Jiri Kosina --- Documentation/ABI/removed/o2cb | 2 +- Documentation/ABI/testing/sysfs-bus-bcma | 8 ++++---- .../ABI/testing/sysfs-class-backlight-driver-adp8870 | 16 ++++++++-------- 3 files changed, 13 insertions(+), 13 deletions(-) (limited to 'Documentation/ABI') diff --git a/Documentation/ABI/removed/o2cb b/Documentation/ABI/removed/o2cb index 7f5daa465093..20c91adca6d4 100644 --- a/Documentation/ABI/removed/o2cb +++ b/Documentation/ABI/removed/o2cb @@ -1,6 +1,6 @@ What: /sys/o2cb symlink Date: May 2011 -KernelVersion: 2.6.40 +KernelVersion: 3.0 Contact: ocfs2-devel@oss.oracle.com Description: This is a symlink: /sys/o2cb to /sys/fs/o2cb. The symlink is removed when new versions of ocfs2-tools which know to look diff --git a/Documentation/ABI/testing/sysfs-bus-bcma b/Documentation/ABI/testing/sysfs-bus-bcma index 06b62badddd1..721b4aea3020 100644 --- a/Documentation/ABI/testing/sysfs-bus-bcma +++ b/Documentation/ABI/testing/sysfs-bus-bcma @@ -1,6 +1,6 @@ What: /sys/bus/bcma/devices/.../manuf Date: May 2011 -KernelVersion: 2.6.40 +KernelVersion: 3.0 Contact: RafaÅ‚ MiÅ‚ecki Description: Each BCMA core has it's manufacturer id. See @@ -8,7 +8,7 @@ Description: What: /sys/bus/bcma/devices/.../id Date: May 2011 -KernelVersion: 2.6.40 +KernelVersion: 3.0 Contact: RafaÅ‚ MiÅ‚ecki Description: There are a few types of BCMA cores, they can be identified by @@ -16,7 +16,7 @@ Description: What: /sys/bus/bcma/devices/.../rev Date: May 2011 -KernelVersion: 2.6.40 +KernelVersion: 3.0 Contact: RafaÅ‚ MiÅ‚ecki Description: BCMA cores of the same type can still slightly differ depending @@ -24,7 +24,7 @@ Description: What: /sys/bus/bcma/devices/.../class Date: May 2011 -KernelVersion: 2.6.40 +KernelVersion: 3.0 Contact: RafaÅ‚ MiÅ‚ecki Description: Each BCMA core is identified by few fields, including class it diff --git a/Documentation/ABI/testing/sysfs-class-backlight-driver-adp8870 b/Documentation/ABI/testing/sysfs-class-backlight-driver-adp8870 index aa11dbdd794b..4a9c545bda4b 100644 --- a/Documentation/ABI/testing/sysfs-class-backlight-driver-adp8870 +++ b/Documentation/ABI/testing/sysfs-class-backlight-driver-adp8870 @@ -4,8 +4,8 @@ What: /sys/class/backlight//l2_bright_max What: /sys/class/backlight//l3_office_max What: /sys/class/backlight//l4_indoor_max What: /sys/class/backlight//l5_dark_max -Date: Mai 2011 -KernelVersion: 2.6.40 +Date: May 2011 +KernelVersion: 3.0 Contact: device-drivers-devel@blackfin.uclinux.org Description: Control the maximum brightness for @@ -18,8 +18,8 @@ What: /sys/class/backlight//l2_bright_dim What: /sys/class/backlight//l3_office_dim What: /sys/class/backlight//l4_indoor_dim What: /sys/class/backlight//l5_dark_dim -Date: Mai 2011 -KernelVersion: 2.6.40 +Date: May 2011 +KernelVersion: 3.0 Contact: device-drivers-devel@blackfin.uclinux.org Description: Control the dim brightness for @@ -29,8 +29,8 @@ Description: this . What: /sys/class/backlight//ambient_light_level -Date: Mai 2011 -KernelVersion: 2.6.40 +Date: May 2011 +KernelVersion: 3.0 Contact: device-drivers-devel@blackfin.uclinux.org Description: Get conversion value of the light sensor. @@ -39,8 +39,8 @@ Description: 8000 (max ambient brightness) What: /sys/class/backlight//ambient_light_zone -Date: Mai 2011 -KernelVersion: 2.6.40 +Date: May 2011 +KernelVersion: 3.0 Contact: device-drivers-devel@blackfin.uclinux.org Description: Get/Set current ambient light zone. Reading returns -- cgit v1.2.3-55-g7522 From f963d270cb7bbb8eeb57901d02b22a493e664fd2 Mon Sep 17 00:00:00 2001 From: Joe Handzik Date: Mon, 8 Aug 2011 11:40:17 +0200 Subject: cciss: add transport mode attribute to sys Signed-off-by: Joseph Handzik Acked-by: Stephen M. Cameron Signed-off-by: Jens Axboe --- Documentation/ABI/testing/sysfs-bus-pci-devices-cciss | 7 +++++++ drivers/block/cciss.c | 13 +++++++++++++ 2 files changed, 20 insertions(+) (limited to 'Documentation/ABI') diff --git a/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss b/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss index f5bb0a3bb8c0..53d99edd1d75 100644 --- a/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss +++ b/Documentation/ABI/testing/sysfs-bus-pci-devices-cciss @@ -71,3 +71,10 @@ Description: Value of 1 indicates the controller can honor the reset_devices a dump device, as kdump requires resetting the device in order to work reliably. +Where: /sys/bus/pci/devices//ccissX/transport_mode +Date: July 2011 +Kernel Version: 3.0 +Contact: iss_storagedev@hp.com +Description: Value of "simple" indicates that the controller has been placed + in "simple mode". Value of "performant" indicates that the + controller has been placed in "performant mode". diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 61f0b5b6a415..6da7edea700a 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -641,6 +641,18 @@ static ssize_t host_store_rescan(struct device *dev, } static DEVICE_ATTR(rescan, S_IWUSR, NULL, host_store_rescan); +static ssize_t host_show_transport_mode(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct ctlr_info *h = to_hba(dev); + + return snprintf(buf, 20, "%s\n", + h->transMethod & CFGTBL_Trans_Performant ? + "performant" : "simple"); +} +static DEVICE_ATTR(transport_mode, S_IRUGO, host_show_transport_mode, NULL); + static ssize_t dev_show_unique_id(struct device *dev, struct device_attribute *attr, char *buf) @@ -813,6 +825,7 @@ static DEVICE_ATTR(usage_count, S_IRUGO, cciss_show_usage_count, NULL); static struct attribute *cciss_host_attrs[] = { &dev_attr_rescan.attr, &dev_attr_resettable.attr, + &dev_attr_transport_mode.attr, NULL }; -- cgit v1.2.3-55-g7522 From 59b699cdee039d75915c354da06937102d1f9a84 Mon Sep 17 00:00:00 2001 From: Antonio Quartulli Date: Thu, 7 Jul 2011 15:35:36 +0200 Subject: batman-adv: implement AP-isolation on the receiver side When a node receives a unicast packet it checks if the source and the destination client can communicate or not due to the AP isolation Signed-off-by: Antonio Quartulli Signed-off-by: Marek Lindner --- Documentation/ABI/testing/sysfs-class-net-mesh | 8 +++++ net/batman-adv/bat_sysfs.c | 2 ++ net/batman-adv/soft-interface.c | 4 +++ net/batman-adv/translation-table.c | 42 ++++++++++++++++++++++++++ net/batman-adv/translation-table.h | 1 + net/batman-adv/types.h | 1 + 6 files changed, 58 insertions(+) (limited to 'Documentation/ABI') diff --git a/Documentation/ABI/testing/sysfs-class-net-mesh b/Documentation/ABI/testing/sysfs-class-net-mesh index 748fe1701d25..b02001488eef 100644 --- a/Documentation/ABI/testing/sysfs-class-net-mesh +++ b/Documentation/ABI/testing/sysfs-class-net-mesh @@ -22,6 +22,14 @@ Description: mesh will be fragmented or silently discarded if the packet size exceeds the outgoing interface MTU. +What: /sys/class/net//mesh/ap_isolation +Date: May 2011 +Contact: Antonio Quartulli +Description: + Indicates whether the data traffic going from a + wireless client to another wireless client will be + silently dropped. + What: /sys/class/net//mesh/gw_bandwidth Date: October 2010 Contact: Marek Lindner diff --git a/net/batman-adv/bat_sysfs.c b/net/batman-adv/bat_sysfs.c index cd15deba60a1..b8a7414c3571 100644 --- a/net/batman-adv/bat_sysfs.c +++ b/net/batman-adv/bat_sysfs.c @@ -380,6 +380,7 @@ static ssize_t store_gw_bwidth(struct kobject *kobj, struct attribute *attr, BAT_ATTR_BOOL(aggregated_ogms, S_IRUGO | S_IWUSR, NULL); BAT_ATTR_BOOL(bonding, S_IRUGO | S_IWUSR, NULL); BAT_ATTR_BOOL(fragmentation, S_IRUGO | S_IWUSR, update_min_mtu); +BAT_ATTR_BOOL(ap_isolation, S_IRUGO | S_IWUSR, NULL); static BAT_ATTR(vis_mode, S_IRUGO | S_IWUSR, show_vis_mode, store_vis_mode); static BAT_ATTR(gw_mode, S_IRUGO | S_IWUSR, show_gw_mode, store_gw_mode); BAT_ATTR_UINT(orig_interval, S_IRUGO | S_IWUSR, 2 * JITTER, INT_MAX, NULL); @@ -396,6 +397,7 @@ static struct bat_attribute *mesh_attrs[] = { &bat_attr_aggregated_ogms, &bat_attr_bonding, &bat_attr_fragmentation, + &bat_attr_ap_isolation, &bat_attr_vis_mode, &bat_attr_gw_mode, &bat_attr_orig_interval, diff --git a/net/batman-adv/soft-interface.c b/net/batman-adv/soft-interface.c index 6deed44a3703..9addbab52999 100644 --- a/net/batman-adv/soft-interface.c +++ b/net/batman-adv/soft-interface.c @@ -739,6 +739,9 @@ void interface_rx(struct net_device *soft_iface, soft_iface->last_rx = jiffies; + if (is_ap_isolated(bat_priv, ethhdr->h_source, ethhdr->h_dest)) + goto dropped; + netif_rx(skb); goto out; @@ -812,6 +815,7 @@ struct net_device *softif_create(const char *name) atomic_set(&bat_priv->aggregated_ogms, 1); atomic_set(&bat_priv->bonding, 0); + atomic_set(&bat_priv->ap_isolation, 0); atomic_set(&bat_priv->vis_mode, VIS_TYPE_CLIENT_UPDATE); atomic_set(&bat_priv->gw_mode, GW_MODE_OFF); atomic_set(&bat_priv->gw_sel_class, 20); diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index d6305645e08d..d0ed931ad2e7 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c @@ -781,6 +781,18 @@ static void tt_global_table_free(struct bat_priv *bat_priv) bat_priv->tt_global_hash = NULL; } +static bool _is_ap_isolated(struct tt_local_entry *tt_local_entry, + struct tt_global_entry *tt_global_entry) +{ + bool ret = false; + + if (tt_local_entry->flags & TT_CLIENT_WIFI && + tt_global_entry->flags & TT_CLIENT_WIFI) + ret = true; + + return ret; +} + struct orig_node *transtable_search(struct bat_priv *bat_priv, const uint8_t *addr) { @@ -1729,3 +1741,33 @@ void tt_commit_changes(struct bat_priv *bat_priv) atomic_inc(&bat_priv->ttvn); bat_priv->tt_poss_change = false; } + +bool is_ap_isolated(struct bat_priv *bat_priv, uint8_t *src, uint8_t *dst) +{ + struct tt_local_entry *tt_local_entry = NULL; + struct tt_global_entry *tt_global_entry = NULL; + bool ret = true; + + if (!atomic_read(&bat_priv->ap_isolation)) + return false; + + tt_local_entry = tt_local_hash_find(bat_priv, dst); + if (!tt_local_entry) + goto out; + + tt_global_entry = tt_global_hash_find(bat_priv, src); + if (!tt_global_entry) + goto out; + + if (_is_ap_isolated(tt_local_entry, tt_global_entry)) + goto out; + + ret = false; + +out: + if (tt_global_entry) + tt_global_entry_free_ref(tt_global_entry); + if (tt_local_entry) + tt_local_entry_free_ref(tt_local_entry); + return ret; +} diff --git a/net/batman-adv/translation-table.h b/net/batman-adv/translation-table.h index 4d1ca35c6818..f1d148ef0e36 100644 --- a/net/batman-adv/translation-table.h +++ b/net/batman-adv/translation-table.h @@ -63,5 +63,6 @@ void handle_tt_response(struct bat_priv *bat_priv, void send_roam_adv(struct bat_priv *bat_priv, uint8_t *client, struct orig_node *orig_node); void tt_commit_changes(struct bat_priv *bat_priv); +bool is_ap_isolated(struct bat_priv *bat_priv, uint8_t *src, uint8_t *dst); #endif /* _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ */ diff --git a/net/batman-adv/types.h b/net/batman-adv/types.h index bd0ced8a9a9e..1ae355750511 100644 --- a/net/batman-adv/types.h +++ b/net/batman-adv/types.h @@ -146,6 +146,7 @@ struct bat_priv { atomic_t aggregated_ogms; /* boolean */ atomic_t bonding; /* boolean */ atomic_t fragmentation; /* boolean */ + atomic_t ap_isolation; /* boolean */ atomic_t vis_mode; /* VIS_TYPE_* */ atomic_t gw_mode; /* GW_MODE_* */ atomic_t gw_sel_class; /* uint */ -- cgit v1.2.3-55-g7522 From 3a7bda830fad427768ed71c0ebf3448849c006b5 Mon Sep 17 00:00:00 2001 From: Dave Jiang Date: Fri, 29 Jul 2011 17:17:00 -0700 Subject: [SCSI] isci: Adding documentation to API change and fixup sysfs registration Adding API update for adding isci_id entry scsi_host sysfs entry. Also fixing up the sysfs registration to the scsi_host template Signed-off-by: Dave Jiang Signed-off-by: Dan Williams Signed-off-by: James Bottomley --- Documentation/ABI/testing/sysfs-class-scsi_host | 13 +++++++++ drivers/scsi/isci/init.c | 36 ++++++++++++------------- 2 files changed, 31 insertions(+), 18 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-class-scsi_host (limited to 'Documentation/ABI') diff --git a/Documentation/ABI/testing/sysfs-class-scsi_host b/Documentation/ABI/testing/sysfs-class-scsi_host new file mode 100644 index 000000000000..29a4f892e433 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-class-scsi_host @@ -0,0 +1,13 @@ +What: /sys/class/scsi_host/hostX/isci_id +Date: June 2011 +Contact: Dave Jiang +Description: + This file contains the enumerated host ID for the Intel + SCU controller. The Intel(R) C600 Series Chipset SATA/SAS + Storage Control Unit embeds up to two 4-port controllers in + a single PCI device. The controllers are enumerated in order + which usually means the lowest number scsi_host corresponds + with the first controller, but this association is not + guaranteed. The 'isci_id' attribute unambiguously identifies + the controller index: '0' for the first controller, + '1' for the second. diff --git a/drivers/scsi/isci/init.c b/drivers/scsi/isci/init.c index 61e0d09e2b57..e78320bbec4f 100644 --- a/drivers/scsi/isci/init.c +++ b/drivers/scsi/isci/init.c @@ -59,6 +59,7 @@ #include #include #include +#include #include "isci.h" #include "task.h" #include "probe_roms.h" @@ -113,6 +114,22 @@ unsigned char max_concurr_spinup = 1; module_param(max_concurr_spinup, byte, 0); MODULE_PARM_DESC(max_concurr_spinup, "Max concurrent device spinup"); +static ssize_t isci_show_id(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct Scsi_Host *shost = container_of(dev, typeof(*shost), shost_dev); + struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost); + struct isci_host *ihost = container_of(sas_ha, typeof(*ihost), sas_ha); + + return snprintf(buf, PAGE_SIZE, "%d\n", ihost->id); +} + +static DEVICE_ATTR(isci_id, S_IRUGO, isci_show_id, NULL); + +struct device_attribute *isci_host_attrs[] = { + &dev_attr_isci_id, + NULL +}; + static struct scsi_host_template isci_sht = { .module = THIS_MODULE, @@ -138,6 +155,7 @@ static struct scsi_host_template isci_sht = { .slave_alloc = sas_slave_alloc, .target_destroy = sas_target_destroy, .ioctl = sas_ioctl, + .shost_attrs = isci_host_attrs, }; static struct sas_domain_function_template isci_transport_ops = { @@ -232,17 +250,6 @@ static int isci_register_sas_ha(struct isci_host *isci_host) return 0; } -static ssize_t isci_show_id(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct Scsi_Host *shost = container_of(dev, typeof(*shost), shost_dev); - struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost); - struct isci_host *ihost = container_of(sas_ha, typeof(*ihost), sas_ha); - - return snprintf(buf, PAGE_SIZE, "%d\n", ihost->id); -} - -static DEVICE_ATTR(isci_id, S_IRUGO, isci_show_id, NULL); - static void isci_unregister(struct isci_host *isci_host) { struct Scsi_Host *shost; @@ -251,7 +258,6 @@ static void isci_unregister(struct isci_host *isci_host) return; shost = isci_host->shost; - device_remove_file(&shost->shost_dev, &dev_attr_isci_id); sas_unregister_ha(&isci_host->sas_ha); @@ -415,14 +421,8 @@ static struct isci_host *isci_host_alloc(struct pci_dev *pdev, int id) if (err) goto err_shost_remove; - err = device_create_file(&shost->shost_dev, &dev_attr_isci_id); - if (err) - goto err_unregister_ha; - return isci_host; - err_unregister_ha: - sas_unregister_ha(&(isci_host->sas_ha)); err_shost_remove: scsi_remove_host(shost); err_shost: -- cgit v1.2.3-55-g7522 From a72c5e5eb738033938ab30d6a634b74d1d060f10 Mon Sep 17 00:00:00 2001 From: Nao Nishijima Date: Thu, 25 Aug 2011 18:04:06 +0900 Subject: [SCSI] genhd: add a new attribute "alias" in gendisk This patch allows the user to set an "alias" of the disk via sysfs interface. This patch only adds a new attribute "alias" in gendisk structure. To show the alias instead of the device name in kernel messages, we need to revise printk messages and use alias_name() in them. Example: (current) printk("disk name is %s\n", disk->disk_name); (new) printk("disk name is %s\n", alias_name(disk)); Users can use alphabets, numbers, '-' and '_' in "alias" attribute. A disk can have an "alias" which length is up to 255 bytes. This attribute is write-once. Suggested-by: James Bottomley Suggested-by: Jon Masters Signed-off-by: Nao Nishijima Signed-off-by: James Bottomley --- Documentation/ABI/testing/sysfs-block | 13 +++++++ block/genhd.c | 71 +++++++++++++++++++++++++++++++++++ include/linux/genhd.h | 4 ++ 3 files changed, 88 insertions(+) (limited to 'Documentation/ABI') diff --git a/Documentation/ABI/testing/sysfs-block b/Documentation/ABI/testing/sysfs-block index c1eb41cb9876..2b5d56127fce 100644 --- a/Documentation/ABI/testing/sysfs-block +++ b/Documentation/ABI/testing/sysfs-block @@ -206,3 +206,16 @@ Description: when a discarded area is read the discard_zeroes_data parameter will be set to one. Otherwise it will be 0 and the result of reading a discarded area is undefined. +What: /sys/block//alias +Date: Aug 2011 +Contact: Nao Nishijima +Description: + A raw device name of a disk does not always point a same disk + each boot-up time. Therefore, users have to use persistent + device names, which udev creates when the kernel finds a disk, + instead of raw device name. However, kernel doesn't show those + persistent names on its messages (e.g. dmesg). + This file can store an alias of the disk and it would be + appeared in kernel messages if it is set. A disk can have an + alias which length is up to 255bytes. Users can use alphabets, + numbers, "-" and "_" in alias name. This file is writeonce. diff --git a/block/genhd.c b/block/genhd.c index e2f67902dd02..94855a9717de 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -19,6 +19,7 @@ #include #include #include +#include #include "blk.h" @@ -909,6 +910,74 @@ static int __init genhd_device_init(void) subsys_initcall(genhd_device_init); +static ssize_t alias_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct gendisk *disk = dev_to_disk(dev); + ssize_t ret = 0; + + if (disk->alias) + ret = snprintf(buf, ALIAS_LEN, "%s\n", disk->alias); + return ret; +} + +static ssize_t alias_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct gendisk *disk = dev_to_disk(dev); + char *alias; + char *envp[] = { NULL, NULL }; + unsigned char c; + int i; + ssize_t ret = count; + + if (!count) + return -EINVAL; + + if (count >= ALIAS_LEN) { + printk(KERN_ERR "alias: alias is too long\n"); + return -EINVAL; + } + + /* Validation check */ + for (i = 0; i < count; i++) { + c = buf[i]; + if (i == count - 1 && c == '\n') + break; + if (!isalnum(c) && c != '_' && c != '-') { + printk(KERN_ERR "alias: invalid alias\n"); + return -EINVAL; + } + } + + if (disk->alias) { + printk(KERN_INFO "alias: %s is already assigned (%s)\n", + disk->disk_name, disk->alias); + return -EINVAL; + } + + alias = kasprintf(GFP_KERNEL, "%s", buf); + if (!alias) + return -ENOMEM; + + if (alias[count - 1] == '\n') + alias[count - 1] = '\0'; + + envp[0] = kasprintf(GFP_KERNEL, "ALIAS=%s", alias); + if (!envp[0]) { + kfree(alias); + return -ENOMEM; + } + + disk->alias = alias; + printk(KERN_INFO "alias: assigned %s to %s\n", alias, disk->disk_name); + + kobject_uevent_env(&dev->kobj, KOBJ_ADD, envp); + + kfree(envp[0]); + return ret; +} + static ssize_t disk_range_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -968,6 +1037,7 @@ static ssize_t disk_discard_alignment_show(struct device *dev, return sprintf(buf, "%d\n", queue_discard_alignment(disk->queue)); } +static DEVICE_ATTR(alias, S_IRUGO|S_IWUSR, alias_show, alias_store); static DEVICE_ATTR(range, S_IRUGO, disk_range_show, NULL); static DEVICE_ATTR(ext_range, S_IRUGO, disk_ext_range_show, NULL); static DEVICE_ATTR(removable, S_IRUGO, disk_removable_show, NULL); @@ -990,6 +1060,7 @@ static struct device_attribute dev_attr_fail_timeout = #endif static struct attribute *disk_attrs[] = { + &dev_attr_alias.attr, &dev_attr_range.attr, &dev_attr_ext_range.attr, &dev_attr_removable.attr, diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 02fa4697a0e5..6957350e122f 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -21,6 +21,8 @@ #define dev_to_part(device) container_of((device), struct hd_struct, __dev) #define disk_to_dev(disk) (&(disk)->part0.__dev) #define part_to_dev(part) (&((part)->__dev)) +#define alias_name(disk) ((disk)->alias ? (disk)->alias : \ + (disk)->disk_name) extern struct device_type part_type; extern struct kobject *block_depr; @@ -58,6 +60,7 @@ enum { #define DISK_MAX_PARTS 256 #define DISK_NAME_LEN 32 +#define ALIAS_LEN 256 #include #include @@ -162,6 +165,7 @@ struct gendisk { * disks that can't be partitioned. */ char disk_name[DISK_NAME_LEN]; /* name of major driver */ + char *alias; /* alias name of disk */ char *(*devnode)(struct gendisk *gd, mode_t *mode); unsigned int events; /* supported events */ -- cgit v1.2.3-55-g7522 From 25aa55488c3644b19e33ba79c564191b8e33f477 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 14 Sep 2011 12:33:16 -0400 Subject: USB: document ehci-hcd's "companion" sysfs attribute This patch (as1484) adds documentation for ehci-hcd's "companion" sysfs attribute, which was added to the kernel over four years ago but never documented. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- .../ABI/testing/sysfs-bus-pci-drivers-ehci_hcd | 46 ++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-bus-pci-drivers-ehci_hcd (limited to 'Documentation/ABI') diff --git a/Documentation/ABI/testing/sysfs-bus-pci-drivers-ehci_hcd b/Documentation/ABI/testing/sysfs-bus-pci-drivers-ehci_hcd new file mode 100644 index 000000000000..60c60fa624b2 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-pci-drivers-ehci_hcd @@ -0,0 +1,46 @@ +What: /sys/bus/pci/drivers/ehci_hcd/.../companion + /sys/bus/usb/devices/usbN/../companion +Date: January 2007 +KernelVersion: 2.6.21 +Contact: Alan Stern +Description: + PCI-based EHCI USB controllers (i.e., high-speed USB-2.0 + controllers) are often implemented along with a set of + "companion" full/low-speed USB-1.1 controllers. When a + high-speed device is plugged in, the connection is routed + to the EHCI controller; when a full- or low-speed device + is plugged in, the connection is routed to the companion + controller. + + Sometimes you want to force a high-speed device to connect + at full speed, which can be accomplished by forcing the + connection to be routed to the companion controller. + That's what this file does. Writing a port number to the + file causes connections on that port to be routed to the + companion controller, and writing the negative of a port + number returns the port to normal operation. + + For example: To force the high-speed device attached to + port 4 on bus 2 to run at full speed: + + echo 4 >/sys/bus/usb/devices/usb2/../companion + + To return the port to high-speed operation: + + echo -4 >/sys/bus/usb/devices/usb2/../companion + + Reading the file gives the list of ports currently forced + to the companion controller. + + Note: Some EHCI controllers do not have companions; they + may contain an internal "transaction translator" or they + may be attached directly to a "rate-matching hub". This + mechanism will not work with such controllers. Also, it + cannot be used to force a port on a high-speed hub to + connect at full speed. + + Note: When this file was first added, it appeared in a + different sysfs directory. The location given above is + correct for 2.6.35 (and probably several earlier kernel + versions as well). + -- cgit v1.2.3-55-g7522 From c1045e87b2cd293d53dff19779ea46b19195d593 Mon Sep 17 00:00:00 2001 From: Andiry Xu Date: Fri, 23 Sep 2011 14:19:53 -0700 Subject: usbcore: add sysfs support to xHCI usb2 hardware LPM This patch adds sysfs support to xHCI usb2 hardware LPM, so developer can enable and disable usb2 hardware LPM manually for test purpose. Signed-off-by: Andiry Xu Signed-off-by: Sarah Sharp Signed-off-by: Greg Kroah-Hartman --- Documentation/ABI/testing/sysfs-bus-usb | 15 +++++++++ Documentation/usb/power-management.txt | 26 +++++++++++++++ drivers/usb/core/sysfs.c | 59 ++++++++++++++++++++++++++++++++- 3 files changed, 99 insertions(+), 1 deletion(-) (limited to 'Documentation/ABI') diff --git a/Documentation/ABI/testing/sysfs-bus-usb b/Documentation/ABI/testing/sysfs-bus-usb index 294aa864a60a..e647378e9e88 100644 --- a/Documentation/ABI/testing/sysfs-bus-usb +++ b/Documentation/ABI/testing/sysfs-bus-usb @@ -142,3 +142,18 @@ Description: such devices. Users: usb_modeswitch + +What: /sys/bus/usb/devices/.../power/usb2_hardware_lpm +Date: September 2011 +Contact: Andiry Xu +Description: + If CONFIG_USB_SUSPEND is set and a USB 2.0 lpm-capable device + is plugged in to a xHCI host which support link PM, it will + perform a LPM test; if the test is passed and host supports + USB2 hardware LPM (xHCI 1.0 feature), USB2 hardware LPM will + be enabled for the device and the USB device directory will + contain a file named power/usb2_hardware_lpm. The file holds + a string value (enable or disable) indicating whether or not + USB2 hardware LPM is enabled for the device. Developer can + write y/Y/1 or n/N/0 to the file to enable/disable the + feature. diff --git a/Documentation/usb/power-management.txt b/Documentation/usb/power-management.txt index c9ffa9ced7ee..9d85d96ec6e0 100644 --- a/Documentation/usb/power-management.txt +++ b/Documentation/usb/power-management.txt @@ -487,3 +487,29 @@ succeed, it may still remain active and thus cause the system to resume as soon as the system suspend is complete. Or the remote wakeup may fail and get lost. Which outcome occurs depends on timing and on the hardware and firmware design. + + + xHCI hardware link PM + --------------------- + +xHCI host controller provides hardware link power management to usb2.0 +(xHCI 1.0 feature) and usb3.0 devices which support link PM. By +enabling hardware LPM, the host can automatically put the device into +lower power state(L1 for usb2.0 devices, or U1/U2 for usb3.0 devices), +which state device can enter and resume very quickly. + +The user interface for controlling USB2 hardware LPM is located in the +power/ subdirectory of each USB device's sysfs directory, that is, in +/sys/bus/usb/devices/.../power/ where "..." is the device's ID. The +relevant attribute files is usb2_hardware_lpm. + + power/usb2_hardware_lpm + + When a USB2 device which support LPM is plugged to a + xHCI host root hub which support software LPM, the + host will run a software LPM test for it; if the device + enters L1 state and resume successfully and the host + supports USB2 hardware LPM, this file will show up and + driver will enable hardware LPM for the device. You + can write y/Y/1 or n/N/0 to the file to enable/disable + USB2 hardware LPM manually. This is for test purpose mainly. diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index cf05b97693ea..662c0cf3a3e1 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c @@ -412,6 +412,56 @@ set_level(struct device *dev, struct device_attribute *attr, static DEVICE_ATTR(level, S_IRUGO | S_IWUSR, show_level, set_level); +static ssize_t +show_usb2_hardware_lpm(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct usb_device *udev = to_usb_device(dev); + const char *p; + + if (udev->usb2_hw_lpm_enabled == 1) + p = "enabled"; + else + p = "disabled"; + + return sprintf(buf, "%s\n", p); +} + +static ssize_t +set_usb2_hardware_lpm(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct usb_device *udev = to_usb_device(dev); + bool value; + int ret; + + usb_lock_device(udev); + + ret = strtobool(buf, &value); + + if (!ret) + ret = usb_set_usb2_hardware_lpm(udev, value); + + usb_unlock_device(udev); + + if (!ret) + return count; + + return ret; +} + +static DEVICE_ATTR(usb2_hardware_lpm, S_IRUGO | S_IWUSR, show_usb2_hardware_lpm, + set_usb2_hardware_lpm); + +static struct attribute *usb2_hardware_lpm_attr[] = { + &dev_attr_usb2_hardware_lpm.attr, + NULL, +}; +static struct attribute_group usb2_hardware_lpm_attr_group = { + .name = power_group_name, + .attrs = usb2_hardware_lpm_attr, +}; + static struct attribute *power_attrs[] = { &dev_attr_autosuspend.attr, &dev_attr_level.attr, @@ -428,13 +478,20 @@ static int add_power_attributes(struct device *dev) { int rc = 0; - if (is_usb_device(dev)) + if (is_usb_device(dev)) { + struct usb_device *udev = to_usb_device(dev); rc = sysfs_merge_group(&dev->kobj, &power_attr_group); + if (udev->usb2_hw_lpm_capable == 1) + rc = sysfs_merge_group(&dev->kobj, + &usb2_hardware_lpm_attr_group); + } + return rc; } static void remove_power_attributes(struct device *dev) { + sysfs_unmerge_group(&dev->kobj, &usb2_hardware_lpm_attr_group); sysfs_unmerge_group(&dev->kobj, &power_attr_group); } -- cgit v1.2.3-55-g7522 From 6ffe1ffb074d2152db5fbecab815915f657306bb Mon Sep 17 00:00:00 2001 From: Sean M. Collins Date: Wed, 14 Sep 2011 21:35:52 -0400 Subject: doc: raw1394: Trivial typo fix Signed-off-by: Sean M. Collins Signed-off-by: Jiri Kosina --- Documentation/ABI/removed/raw1394 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Documentation/ABI') diff --git a/Documentation/ABI/removed/raw1394 b/Documentation/ABI/removed/raw1394 index 490aa1efc4ae..ec333e676322 100644 --- a/Documentation/ABI/removed/raw1394 +++ b/Documentation/ABI/removed/raw1394 @@ -5,7 +5,7 @@ Description: /dev/raw1394 was a character device file that allowed low-level access to FireWire buses. Its major drawbacks were its inability to implement sensible device security policies, and its low level - of abstraction that required userspace clients do duplicate much + of abstraction that required userspace clients to duplicate much of the kernel's ieee1394 core functionality. Replaced by /dev/fw*, i.e. the ABI of firewire-core. -- cgit v1.2.3-55-g7522 From 9005b65099ee4f14b6be691c4574612fe947531a Mon Sep 17 00:00:00 2001 From: MyungJoo Ham Date: Sun, 2 Oct 2011 00:19:28 +0200 Subject: PM / devfreq: Add common sysfs interfaces Device specific sysfs interface /sys/devices/.../power/devfreq_* - governor R: name of governor - cur_freq R: current frequency - polling_interval R: polling interval in ms given with devfreq profile W: update polling interval. - central_polling R: 1 if polling is managed by devfreq framework Signed-off-by: MyungJoo Ham Signed-off-by: Kyungmin Park Reviewed-by: Mike Turquette Acked-by: Kevin Hilman Signed-off-by: Rafael J. Wysocki -- Documentation/ABI/testing/sysfs-class-devfreq | 44 ++++++++++++++++ drivers/devfreq/devfreq.c | 69 ++++++++++++++++++++++++++ 2 files changed, 113 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-class-devfreq --- Documentation/ABI/testing/sysfs-class-devfreq | 44 +++++++++++++++++ drivers/devfreq/devfreq.c | 69 +++++++++++++++++++++++++++ 2 files changed, 113 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-class-devfreq (limited to 'Documentation/ABI') diff --git a/Documentation/ABI/testing/sysfs-class-devfreq b/Documentation/ABI/testing/sysfs-class-devfreq new file mode 100644 index 000000000000..0ec855f479ce --- /dev/null +++ b/Documentation/ABI/testing/sysfs-class-devfreq @@ -0,0 +1,44 @@ +What: /sys/class/devfreq/.../ +Date: September 2011 +Contact: MyungJoo Ham +Description: + Provide a place in sysfs for the devfreq objects. + This allows accessing various devfreq specific variables. + The name of devfreq object denoted as ... is same as the + name of device using devfreq. + +What: /sys/class/devfreq/.../governor +Date: September 2011 +Contact: MyungJoo Ham +Description: + The /sys/class/devfreq/.../governor shows the name of the + governor used by the corresponding devfreq object. + +What: /sys/class/devfreq/.../cur_freq +Date: September 2011 +Contact: MyungJoo Ham +Description: + The /sys/class/devfreq/.../cur_freq shows the current + frequency of the corresponding devfreq object. + +What: /sys/class/devfreq/.../central_polling +Date: September 2011 +Contact: MyungJoo Ham +Description: + The /sys/class/devfreq/.../central_polling shows whether + the devfreq ojbect is using devfreq-provided central + polling mechanism or not. + +What: /sys/class/devfreq/.../polling_interval +Date: September 2011 +Contact: MyungJoo Ham +Description: + The /sys/class/devfreq/.../polling_interval shows and sets + the requested polling interval of the corresponding devfreq + object. The values are represented in ms. If the value is + less than 1 jiffy, it is considered to be 0, which means + no polling. This value is meaningless if the governor is + not polling; thus. If the governor is not using + devfreq-provided central polling + (/sys/class/devfreq/.../central_polling is 0), this value + may be useless. diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index f3100b19f798..5d15b812377b 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -437,6 +437,74 @@ int devfreq_remove_device(struct devfreq *devfreq) return 0; } +static ssize_t show_governor(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%s\n", to_devfreq(dev)->governor->name); +} + +static ssize_t show_freq(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%lu\n", to_devfreq(dev)->previous_freq); +} + +static ssize_t show_polling_interval(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", to_devfreq(dev)->profile->polling_ms); +} + +static ssize_t store_polling_interval(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct devfreq *df = to_devfreq(dev); + unsigned int value; + int ret; + + ret = sscanf(buf, "%u", &value); + if (ret != 1) + goto out; + + mutex_lock(&df->lock); + df->profile->polling_ms = value; + df->next_polling = df->polling_jiffies + = msecs_to_jiffies(value); + mutex_unlock(&df->lock); + + ret = count; + + if (df->governor->no_central_polling) + goto out; + + mutex_lock(&devfreq_list_lock); + if (df->next_polling > 0 && !polling) { + polling = true; + queue_delayed_work(devfreq_wq, &devfreq_work, + df->next_polling); + } + mutex_unlock(&devfreq_list_lock); +out: + return ret; +} + +static ssize_t show_central_polling(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", + !to_devfreq(dev)->governor->no_central_polling); +} + +static struct device_attribute devfreq_attrs[] = { + __ATTR(governor, S_IRUGO, show_governor, NULL), + __ATTR(cur_freq, S_IRUGO, show_freq, NULL), + __ATTR(central_polling, S_IRUGO, show_central_polling, NULL), + __ATTR(polling_interval, S_IRUGO | S_IWUSR, show_polling_interval, + store_polling_interval), + { }, +}; + /** * devfreq_start_polling() - Initialize data structure for devfreq framework and * start polling registered devfreq devices. @@ -461,6 +529,7 @@ static int __init devfreq_init(void) pr_err("%s: couldn't create class\n", __FILE__); return PTR_ERR(devfreq_class); } + devfreq_class->dev_attrs = devfreq_attrs; return 0; } subsys_initcall(devfreq_init); -- cgit v1.2.3-55-g7522 From ce26c5bb9569d8b826f01b8620fc16d8da6821e9 Mon Sep 17 00:00:00 2001 From: MyungJoo Ham Date: Sun, 2 Oct 2011 00:19:34 +0200 Subject: PM / devfreq: Add basic governors Four cpufreq-like governors are provided as examples. powersave: use the lowest frequency possible. The user (device) should set the polling_ms as 0 because polling is useless for this governor. performance: use the highest freqeuncy possible. The user (device) should set the polling_ms as 0 because polling is useless for this governor. userspace: use the user specified frequency stored at devfreq.user_set_freq. With sysfs support in the following patch, a user may set the value with the sysfs interface. simple_ondemand: simplified version of cpufreq's ondemand governor. When a user updates OPP entries (enable/disable/add), OPP framework automatically notifies devfreq to update operating frequency accordingly. Thus, devfreq users (device drivers) do not need to update devfreq manually with OPP entry updates or set polling_ms for powersave , performance, userspace, or any other "static" governors. Note that these are given only as basic examples for governors and any devices with devfreq may implement their own governors with the drivers and use them. Signed-off-by: MyungJoo Ham Signed-off-by: Kyungmin Park Reviewed-by: Mike Turquette Acked-by: Kevin Hilman Signed-off-by: Rafael J. Wysocki --- Documentation/ABI/testing/sysfs-class-devfreq | 8 ++ drivers/devfreq/Kconfig | 36 ++++++++ drivers/devfreq/Makefile | 4 + drivers/devfreq/governor_performance.c | 29 +++++++ drivers/devfreq/governor_powersave.c | 29 +++++++ drivers/devfreq/governor_simpleondemand.c | 88 +++++++++++++++++++ drivers/devfreq/governor_userspace.c | 116 ++++++++++++++++++++++++++ include/linux/devfreq.h | 35 ++++++++ 8 files changed, 345 insertions(+) create mode 100644 drivers/devfreq/governor_performance.c create mode 100644 drivers/devfreq/governor_powersave.c create mode 100644 drivers/devfreq/governor_simpleondemand.c create mode 100644 drivers/devfreq/governor_userspace.c (limited to 'Documentation/ABI') diff --git a/Documentation/ABI/testing/sysfs-class-devfreq b/Documentation/ABI/testing/sysfs-class-devfreq index 0ec855f479ce..23d78b5aab11 100644 --- a/Documentation/ABI/testing/sysfs-class-devfreq +++ b/Documentation/ABI/testing/sysfs-class-devfreq @@ -42,3 +42,11 @@ Description: devfreq-provided central polling (/sys/class/devfreq/.../central_polling is 0), this value may be useless. + +What: /sys/class/devfreq/.../userspace/set_freq +Date: September 2011 +Contact: MyungJoo Ham +Description: + The /sys/class/devfreq/.../userspace/set_freq shows and + sets the requested frequency for the devfreq object if + userspace governor is in effect. diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig index 1fb42de4f420..643b055ed3cd 100644 --- a/drivers/devfreq/Kconfig +++ b/drivers/devfreq/Kconfig @@ -34,6 +34,42 @@ menuconfig PM_DEVFREQ if PM_DEVFREQ +comment "DEVFREQ Governors" + +config DEVFREQ_GOV_SIMPLE_ONDEMAND + bool "Simple Ondemand" + help + Chooses frequency based on the recent load on the device. Works + similar as ONDEMAND governor of CPUFREQ does. A device with + Simple-Ondemand should be able to provide busy/total counter + values that imply the usage rate. A device may provide tuned + values to the governor with data field at devfreq_add_device(). + +config DEVFREQ_GOV_PERFORMANCE + bool "Performance" + help + Sets the frequency at the maximum available frequency. + This governor always returns UINT_MAX as frequency so that + the DEVFREQ framework returns the highest frequency available + at any time. + +config DEVFREQ_GOV_POWERSAVE + bool "Powersave" + help + Sets the frequency at the minimum available frequency. + This governor always returns 0 as frequency so that + the DEVFREQ framework returns the lowest frequency available + at any time. + +config DEVFREQ_GOV_USERSPACE + bool "Userspace" + help + Sets the frequency at the user specified one. + This governor returns the user configured frequency if there + has been an input to /sys/devices/.../power/devfreq_set_freq. + Otherwise, the governor does not change the frequnecy + given at the initialization. + comment "DEVFREQ Drivers" endif # PM_DEVFREQ diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile index 168934a12b38..4564a89e970a 100644 --- a/drivers/devfreq/Makefile +++ b/drivers/devfreq/Makefile @@ -1 +1,5 @@ obj-$(CONFIG_PM_DEVFREQ) += devfreq.o +obj-$(CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND) += governor_simpleondemand.o +obj-$(CONFIG_DEVFREQ_GOV_PERFORMANCE) += governor_performance.o +obj-$(CONFIG_DEVFREQ_GOV_POWERSAVE) += governor_powersave.o +obj-$(CONFIG_DEVFREQ_GOV_USERSPACE) += governor_userspace.o diff --git a/drivers/devfreq/governor_performance.c b/drivers/devfreq/governor_performance.c new file mode 100644 index 000000000000..c0596b291761 --- /dev/null +++ b/drivers/devfreq/governor_performance.c @@ -0,0 +1,29 @@ +/* + * linux/drivers/devfreq/governor_performance.c + * + * Copyright (C) 2011 Samsung Electronics + * MyungJoo Ham + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include + +static int devfreq_performance_func(struct devfreq *df, + unsigned long *freq) +{ + /* + * target callback should be able to get floor value as + * said in devfreq.h + */ + *freq = UINT_MAX; + return 0; +} + +const struct devfreq_governor devfreq_performance = { + .name = "performance", + .get_target_freq = devfreq_performance_func, + .no_central_polling = true, +}; diff --git a/drivers/devfreq/governor_powersave.c b/drivers/devfreq/governor_powersave.c new file mode 100644 index 000000000000..2483a85a266f --- /dev/null +++ b/drivers/devfreq/governor_powersave.c @@ -0,0 +1,29 @@ +/* + * linux/drivers/devfreq/governor_powersave.c + * + * Copyright (C) 2011 Samsung Electronics + * MyungJoo Ham + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include + +static int devfreq_powersave_func(struct devfreq *df, + unsigned long *freq) +{ + /* + * target callback should be able to get ceiling value as + * said in devfreq.h + */ + *freq = 0; + return 0; +} + +const struct devfreq_governor devfreq_powersave = { + .name = "powersave", + .get_target_freq = devfreq_powersave_func, + .no_central_polling = true, +}; diff --git a/drivers/devfreq/governor_simpleondemand.c b/drivers/devfreq/governor_simpleondemand.c new file mode 100644 index 000000000000..efad8dcf9028 --- /dev/null +++ b/drivers/devfreq/governor_simpleondemand.c @@ -0,0 +1,88 @@ +/* + * linux/drivers/devfreq/governor_simpleondemand.c + * + * Copyright (C) 2011 Samsung Electronics + * MyungJoo Ham + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include + +/* Default constants for DevFreq-Simple-Ondemand (DFSO) */ +#define DFSO_UPTHRESHOLD (90) +#define DFSO_DOWNDIFFERENCTIAL (5) +static int devfreq_simple_ondemand_func(struct devfreq *df, + unsigned long *freq) +{ + struct devfreq_dev_status stat; + int err = df->profile->get_dev_status(df->dev.parent, &stat); + unsigned long long a, b; + unsigned int dfso_upthreshold = DFSO_UPTHRESHOLD; + unsigned int dfso_downdifferential = DFSO_DOWNDIFFERENCTIAL; + struct devfreq_simple_ondemand_data *data = df->data; + + if (err) + return err; + + if (data) { + if (data->upthreshold) + dfso_upthreshold = data->upthreshold; + if (data->downdifferential) + dfso_downdifferential = data->downdifferential; + } + if (dfso_upthreshold > 100 || + dfso_upthreshold < dfso_downdifferential) + return -EINVAL; + + /* Assume MAX if it is going to be divided by zero */ + if (stat.total_time == 0) { + *freq = UINT_MAX; + return 0; + } + + /* Prevent overflow */ + if (stat.busy_time >= (1 << 24) || stat.total_time >= (1 << 24)) { + stat.busy_time >>= 7; + stat.total_time >>= 7; + } + + /* Set MAX if it's busy enough */ + if (stat.busy_time * 100 > + stat.total_time * dfso_upthreshold) { + *freq = UINT_MAX; + return 0; + } + + /* Set MAX if we do not know the initial frequency */ + if (stat.current_frequency == 0) { + *freq = UINT_MAX; + return 0; + } + + /* Keep the current frequency */ + if (stat.busy_time * 100 > + stat.total_time * (dfso_upthreshold - dfso_downdifferential)) { + *freq = stat.current_frequency; + return 0; + } + + /* Set the desired frequency based on the load */ + a = stat.busy_time; + a *= stat.current_frequency; + b = div_u64(a, stat.total_time); + b *= 100; + b = div_u64(b, (dfso_upthreshold - dfso_downdifferential / 2)); + *freq = (unsigned long) b; + + return 0; +} + +const struct devfreq_governor devfreq_simple_ondemand = { + .name = "simple_ondemand", + .get_target_freq = devfreq_simple_ondemand_func, +}; diff --git a/drivers/devfreq/governor_userspace.c b/drivers/devfreq/governor_userspace.c new file mode 100644 index 000000000000..4f8b563da782 --- /dev/null +++ b/drivers/devfreq/governor_userspace.c @@ -0,0 +1,116 @@ +/* + * linux/drivers/devfreq/governor_simpleondemand.c + * + * Copyright (C) 2011 Samsung Electronics + * MyungJoo Ham + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include "governor.h" + +struct userspace_data { + unsigned long user_frequency; + bool valid; +}; + +static int devfreq_userspace_func(struct devfreq *df, unsigned long *freq) +{ + struct userspace_data *data = df->data; + + if (!data->valid) + *freq = df->previous_freq; /* No user freq specified yet */ + else + *freq = data->user_frequency; + return 0; +} + +static ssize_t store_freq(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct devfreq *devfreq = to_devfreq(dev); + struct userspace_data *data; + unsigned long wanted; + int err = 0; + + + mutex_lock(&devfreq->lock); + data = devfreq->data; + + sscanf(buf, "%lu", &wanted); + data->user_frequency = wanted; + data->valid = true; + err = update_devfreq(devfreq); + if (err == 0) + err = count; + mutex_unlock(&devfreq->lock); + return err; +} + +static ssize_t show_freq(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct devfreq *devfreq = to_devfreq(dev); + struct userspace_data *data; + int err = 0; + + mutex_lock(&devfreq->lock); + data = devfreq->data; + + if (data->valid) + err = sprintf(buf, "%lu\n", data->user_frequency); + else + err = sprintf(buf, "undefined\n"); + mutex_unlock(&devfreq->lock); + return err; +} + +static DEVICE_ATTR(set_freq, 0644, show_freq, store_freq); +static struct attribute *dev_entries[] = { + &dev_attr_set_freq.attr, + NULL, +}; +static struct attribute_group dev_attr_group = { + .name = "userspace", + .attrs = dev_entries, +}; + +static int userspace_init(struct devfreq *devfreq) +{ + int err = 0; + struct userspace_data *data = kzalloc(sizeof(struct userspace_data), + GFP_KERNEL); + + if (!data) { + err = -ENOMEM; + goto out; + } + data->valid = false; + devfreq->data = data; + + err = sysfs_create_group(&devfreq->dev.kobj, &dev_attr_group); +out: + return err; +} + +static void userspace_exit(struct devfreq *devfreq) +{ + sysfs_remove_group(&devfreq->dev.kobj, &dev_attr_group); + kfree(devfreq->data); + devfreq->data = NULL; +} + +const struct devfreq_governor devfreq_userspace = { + .name = "userspace", + .get_target_freq = devfreq_userspace_func, + .init = userspace_init, + .exit = userspace_exit, + .no_central_polling = true, +}; diff --git a/include/linux/devfreq.h b/include/linux/devfreq.h index b3be3d3cbaa7..afb94583960c 100644 --- a/include/linux/devfreq.h +++ b/include/linux/devfreq.h @@ -166,6 +166,36 @@ extern int devfreq_register_opp_notifier(struct device *dev, extern int devfreq_unregister_opp_notifier(struct device *dev, struct devfreq *devfreq); +#ifdef CONFIG_DEVFREQ_GOV_POWERSAVE +extern const struct devfreq_governor devfreq_powersave; +#endif +#ifdef CONFIG_DEVFREQ_GOV_PERFORMANCE +extern const struct devfreq_governor devfreq_performance; +#endif +#ifdef CONFIG_DEVFREQ_GOV_USERSPACE +extern const struct devfreq_governor devfreq_userspace; +#endif +#ifdef CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND +extern const struct devfreq_governor devfreq_simple_ondemand; +/** + * struct devfreq_simple_ondemand_data - void *data fed to struct devfreq + * and devfreq_add_device + * @ upthreshold If the load is over this value, the frequency jumps. + * Specify 0 to use the default. Valid value = 0 to 100. + * @ downdifferential If the load is under upthreshold - downdifferential, + * the governor may consider slowing the frequency down. + * Specify 0 to use the default. Valid value = 0 to 100. + * downdifferential < upthreshold must hold. + * + * If the fed devfreq_simple_ondemand_data pointer is NULL to the governor, + * the governor uses the default values. + */ +struct devfreq_simple_ondemand_data { + unsigned int upthreshold; + unsigned int downdifferential; +}; +#endif + #else /* !CONFIG_PM_DEVFREQ */ static struct devfreq *devfreq_add_device(struct device *dev, struct devfreq_dev_profile *profile, @@ -198,6 +228,11 @@ static int devfreq_unregister_opp_notifier(struct device *dev, return -EINVAL; } +#define devfreq_powersave NULL +#define devfreq_performance NULL +#define devfreq_userspace NULL +#define devfreq_simple_ondemand NULL + #endif /* CONFIG_PM_DEVFREQ */ #endif /* __LINUX_DEVFREQ_H__ */ -- cgit v1.2.3-55-g7522 From 773e3206e6a8b4c81826dc76057a96ba3cc96672 Mon Sep 17 00:00:00 2001 From: Ike Panhc Date: Tue, 6 Sep 2011 02:32:52 +0800 Subject: ideapad: add debugfs support Add two nodes in debugfs which shows cfg value and its meaning, and status info read from VPC2004. Signed-off-by: Ike Panhc Signed-off-by: Matthew Garrett --- Documentation/ABI/testing/debugfs-ideapad | 19 ++++ drivers/platform/x86/ideapad-laptop.c | 152 ++++++++++++++++++++++++++++++ 2 files changed, 171 insertions(+) create mode 100644 Documentation/ABI/testing/debugfs-ideapad (limited to 'Documentation/ABI') diff --git a/Documentation/ABI/testing/debugfs-ideapad b/Documentation/ABI/testing/debugfs-ideapad new file mode 100644 index 000000000000..7079c0b21030 --- /dev/null +++ b/Documentation/ABI/testing/debugfs-ideapad @@ -0,0 +1,19 @@ +What: /sys/kernel/debug/ideapad/cfg +Date: Sep 2011 +KernelVersion: 3.2 +Contact: Ike Panhc +Description: + +cfg shows the return value of _CFG method in VPC2004 device. It tells machine +capability and what graphic component within the machine. + + +What: /sys/kernel/debug/ideapad/status +Date: Sep 2011 +KernelVersion: 3.2 +Contact: Ike Panhc +Description: + +status shows infos we can read and tells its meaning and value. + + diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index 39a72a8aeb8c..1c8b5065f34c 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c @@ -34,6 +34,8 @@ #include #include #include +#include +#include #define IDEAPAD_RFKILL_DEV_NUM (3) @@ -71,10 +73,12 @@ struct ideapad_private { struct platform_device *platform_device; struct input_dev *inputdev; struct backlight_device *blightdev; + struct dentry *debug; unsigned long cfg; }; static acpi_handle ideapad_handle; +static struct ideapad_private *ideapad_priv; static bool no_bt_rfkill; module_param(no_bt_rfkill, bool, 0444); MODULE_PARM_DESC(no_bt_rfkill, "No rfkill for bluetooth."); @@ -187,6 +191,146 @@ static int write_ec_cmd(acpi_handle handle, int cmd, unsigned long data) return -1; } +/* + * debugfs + */ +#define DEBUGFS_EVENT_LEN (4096) +static int debugfs_status_show(struct seq_file *s, void *data) +{ + unsigned long value; + + if (!read_ec_data(ideapad_handle, VPCCMD_R_BL_MAX, &value)) + seq_printf(s, "Backlight max:\t%lu\n", value); + if (!read_ec_data(ideapad_handle, VPCCMD_R_BL, &value)) + seq_printf(s, "Backlight now:\t%lu\n", value); + if (!read_ec_data(ideapad_handle, VPCCMD_R_BL_POWER, &value)) + seq_printf(s, "BL power value:\t%s\n", value ? "On" : "Off"); + seq_printf(s, "=====================\n"); + + if (!read_ec_data(ideapad_handle, VPCCMD_R_RF, &value)) + seq_printf(s, "Radio status:\t%s(%lu)\n", + value ? "On" : "Off", value); + if (!read_ec_data(ideapad_handle, VPCCMD_R_WIFI, &value)) + seq_printf(s, "Wifi status:\t%s(%lu)\n", + value ? "On" : "Off", value); + if (!read_ec_data(ideapad_handle, VPCCMD_R_BT, &value)) + seq_printf(s, "BT status:\t%s(%lu)\n", + value ? "On" : "Off", value); + if (!read_ec_data(ideapad_handle, VPCCMD_R_3G, &value)) + seq_printf(s, "3G status:\t%s(%lu)\n", + value ? "On" : "Off", value); + seq_printf(s, "=====================\n"); + + if (!read_ec_data(ideapad_handle, VPCCMD_R_TOUCHPAD, &value)) + seq_printf(s, "Touchpad status:%s(%lu)\n", + value ? "On" : "Off", value); + if (!read_ec_data(ideapad_handle, VPCCMD_R_CAMERA, &value)) + seq_printf(s, "Camera status:\t%s(%lu)\n", + value ? "On" : "Off", value); + + return 0; +} + +static int debugfs_status_open(struct inode *inode, struct file *file) +{ + return single_open(file, debugfs_status_show, NULL); +} + +static const struct file_operations debugfs_status_fops = { + .owner = THIS_MODULE, + .open = debugfs_status_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int debugfs_cfg_show(struct seq_file *s, void *data) +{ + if (!ideapad_priv) { + seq_printf(s, "cfg: N/A\n"); + } else { + seq_printf(s, "cfg: 0x%.8lX\n\nCapability: ", + ideapad_priv->cfg); + if (test_bit(CFG_BT_BIT, &ideapad_priv->cfg)) + seq_printf(s, "Bluetooth "); + if (test_bit(CFG_3G_BIT, &ideapad_priv->cfg)) + seq_printf(s, "3G "); + if (test_bit(CFG_WIFI_BIT, &ideapad_priv->cfg)) + seq_printf(s, "Wireless "); + if (test_bit(CFG_CAMERA_BIT, &ideapad_priv->cfg)) + seq_printf(s, "Camera "); + seq_printf(s, "\nGraphic: "); + switch ((ideapad_priv->cfg)&0x700) { + case 0x100: + seq_printf(s, "Intel"); + break; + case 0x200: + seq_printf(s, "ATI"); + break; + case 0x300: + seq_printf(s, "Nvidia"); + break; + case 0x400: + seq_printf(s, "Intel and ATI"); + break; + case 0x500: + seq_printf(s, "Intel and Nvidia"); + break; + } + seq_printf(s, "\n"); + } + return 0; +} + +static int debugfs_cfg_open(struct inode *inode, struct file *file) +{ + return single_open(file, debugfs_cfg_show, NULL); +} + +static const struct file_operations debugfs_cfg_fops = { + .owner = THIS_MODULE, + .open = debugfs_cfg_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static int __devinit ideapad_debugfs_init(struct ideapad_private *priv) +{ + struct dentry *node; + + priv->debug = debugfs_create_dir("ideapad", NULL); + if (priv->debug == NULL) { + pr_err("failed to create debugfs directory"); + goto errout; + } + + node = debugfs_create_file("cfg", S_IRUGO, priv->debug, NULL, + &debugfs_cfg_fops); + if (!node) { + pr_err("failed to create cfg in debugfs"); + goto errout; + } + + node = debugfs_create_file("status", S_IRUGO, priv->debug, NULL, + &debugfs_status_fops); + if (!node) { + pr_err("failed to create event in debugfs"); + goto errout; + } + + return 0; + +errout: + return -ENOMEM; +} + +static void ideapad_debugfs_exit(struct ideapad_private *priv) +{ + debugfs_remove_recursive(priv->debug); + priv->debug = NULL; +} + /* * sysfs */ @@ -573,6 +717,7 @@ static int __devinit ideapad_acpi_add(struct acpi_device *adevice) if (!priv) return -ENOMEM; dev_set_drvdata(&adevice->dev, priv); + ideapad_priv = priv; ideapad_handle = adevice->handle; priv->cfg = cfg; @@ -580,6 +725,10 @@ static int __devinit ideapad_acpi_add(struct acpi_device *adevice) if (ret) goto platform_failed; + ret = ideapad_debugfs_init(priv); + if (ret) + goto debugfs_failed; + ret = ideapad_input_init(priv); if (ret) goto input_failed; @@ -605,6 +754,8 @@ backlight_failed: ideapad_unregister_rfkill(adevice, i); ideapad_input_exit(priv); input_failed: + ideapad_debugfs_exit(priv); +debugfs_failed: ideapad_platform_exit(priv); platform_failed: kfree(priv); @@ -620,6 +771,7 @@ static int __devexit ideapad_acpi_remove(struct acpi_device *adevice, int type) for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) ideapad_unregister_rfkill(adevice, i); ideapad_input_exit(priv); + ideapad_debugfs_exit(priv); ideapad_platform_exit(priv); dev_set_drvdata(&adevice->dev, NULL); kfree(priv); -- cgit v1.2.3-55-g7522 From 349d594be45bdc7a86a08385f2f4f49d08ab68dd Mon Sep 17 00:00:00 2001 From: Ike Panhc Date: Tue, 6 Sep 2011 02:33:00 +0800 Subject: ideapad: remove sysfs node for cfg Replaced by the one in debugfs. Signed-off-by: Ike Panhc Signed-off-by: Matthew Garrett --- Documentation/ABI/testing/sysfs-platform-ideapad-laptop | 15 --------------- drivers/platform/x86/ideapad-laptop.c | 12 ------------ 2 files changed, 27 deletions(-) (limited to 'Documentation/ABI') diff --git a/Documentation/ABI/testing/sysfs-platform-ideapad-laptop b/Documentation/ABI/testing/sysfs-platform-ideapad-laptop index ff53183c3848..814b01354c41 100644 --- a/Documentation/ABI/testing/sysfs-platform-ideapad-laptop +++ b/Documentation/ABI/testing/sysfs-platform-ideapad-laptop @@ -5,19 +5,4 @@ Contact: "Ike Panhc " Description: Control the power of camera module. 1 means on, 0 means off. -What: /sys/devices/platform/ideapad/cfg -Date: Jun 2011 -KernelVersion: 3.1 -Contact: "Ike Panhc " -Description: - Ideapad capability bits. - Bit 8-10: 1 - Intel graphic only - 2 - ATI graphic only - 3 - Nvidia graphic only - 4 - Intel and ATI graphic - 5 - Intel and Nvidia graphic - Bit 16: Bluetooth exist (1 for exist) - Bit 17: 3G exist (1 for exist) - Bit 18: Wifi exist (1 for exist) - Bit 19: Camera exist (1 for exist) diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index 1c8b5065f34c..a36addf106a0 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c @@ -363,20 +363,8 @@ static ssize_t store_ideapad_cam(struct device *dev, static DEVICE_ATTR(camera_power, 0644, show_ideapad_cam, store_ideapad_cam); -static ssize_t show_ideapad_cfg(struct device *dev, - struct device_attribute *attr, - char *buf) -{ - struct ideapad_private *priv = dev_get_drvdata(dev); - - return sprintf(buf, "0x%.8lX\n", priv->cfg); -} - -static DEVICE_ATTR(cfg, 0444, show_ideapad_cfg, NULL); - static struct attribute *ideapad_attributes[] = { &dev_attr_camera_power.attr, - &dev_attr_cfg.attr, NULL }; -- cgit v1.2.3-55-g7522 From 362b646062b2073bd5c38efb42171d86e4f717e6 Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Fri, 4 Nov 2011 03:33:46 +0100 Subject: ACPI: Export FADT pm_profile integer value to userspace There are a lot userspace approaches to detect the usage of the platform (laptop, workstation, server, ...) and adjust kernel tunables accordingly (io/process scheduler, power management, ...). These approaches need constant maintaining and are ugly to implement (detect PCMCIA controller -> laptop, does not work on recent systems anymore, ...) On ACPI systems there is an easy and reliable way (if implemented in BIOS and most recent platforms have this value set). -> export it to userspace. Signed-off-by: Thomas Renninger Acked-by: Rafael J. Wysocki Signed-off-by: Len Brown --- Documentation/ABI/stable/sysfs-acpi-pmprofile | 22 ++++++++++++++++++++++ drivers/acpi/sysfs.c | 14 +++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 Documentation/ABI/stable/sysfs-acpi-pmprofile (limited to 'Documentation/ABI') diff --git a/Documentation/ABI/stable/sysfs-acpi-pmprofile b/Documentation/ABI/stable/sysfs-acpi-pmprofile new file mode 100644 index 000000000000..964c7a8afb26 --- /dev/null +++ b/Documentation/ABI/stable/sysfs-acpi-pmprofile @@ -0,0 +1,22 @@ +What: /sys/firmware/acpi/pm_profile +Date: 03-Nov-2011 +KernelVersion: v3.2 +Contact: linux-acpi@vger.kernel.org +Description: The ACPI pm_profile sysfs interface exports the platform + power management (and performance) requirement expectations + as provided by BIOS. The integer value is directly passed as + retrieved from the FADT ACPI table. +Values: For possible values see ACPI specification: + 5.2.9 Fixed ACPI Description Table (FADT) + Field: Preferred_PM_Profile + + Currently these values are defined by spec: + 0 Unspecified + 1 Desktop + 2 Mobile + 3 Workstation + 4 Enterprise Server + 5 SOHO Server + 6 Appliance PC + 7 Performance Server + >7 Reserved diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index c538d0ef10ff..9f66181c814e 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c @@ -706,11 +706,23 @@ static void __exit interrupt_stats_exit(void) return; } +static ssize_t +acpi_show_profile(struct device *dev, struct device_attribute *attr, + char *buf) +{ + return sprintf(buf, "%d\n", acpi_gbl_FADT.preferred_profile); +} + +static const struct device_attribute pm_profile_attr = + __ATTR(pm_profile, S_IRUGO, acpi_show_profile, NULL); + int __init acpi_sysfs_init(void) { int result; result = acpi_tables_sysfs_init(); - + if (result) + return result; + result = sysfs_create_file(acpi_kobj, &pm_profile_attr.attr); return result; } -- cgit v1.2.3-55-g7522 From d0985394e7fee6b25a7cc8335d45bc1c1a8ab2d3 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 10 Nov 2011 09:03:55 +0100 Subject: block: Revert "[SCSI] genhd: add a new attribute "alias" in gendisk" This reverts commit a72c5e5eb738033938ab30d6a634b74d1d060f10. The commit introduced alias for block devices which is intended to be used during logging although actual usage hasn't been committed yet. This approach adds very limited benefit (raw log might be easier to follow) which can be trivially implemented in userland but has a lot of problems. It is much worse than netif renames because it doesn't rename the actual device but just adds conveninence name which isn't used universally or enforced. Everything internal including device lookup and sysfs still uses the internal name and nothing prevents two devices from using conflicting alias - ie. sda can have sdb as its alias. This has been nacked by people working on device driver core, block layer and kernel-userland interface and shouldn't have been upstreamed. Revert it. http://thread.gmane.org/gmane.linux.kernel/1155104 http://thread.gmane.org/gmane.linux.scsi/68632 http://thread.gmane.org/gmane.linux.scsi/69776 Signed-off-by: Tejun Heo Acked-by: Greg Kroah-Hartman Acked-by: Kay Sievers Cc: "James E.J. Bottomley" Cc: Nao Nishijima Cc: Alan Cox Cc: Al Viro Signed-off-by: Jens Axboe --- Documentation/ABI/testing/sysfs-block | 13 ------- block/genhd.c | 71 ----------------------------------- include/linux/genhd.h | 4 -- 3 files changed, 88 deletions(-) (limited to 'Documentation/ABI') diff --git a/Documentation/ABI/testing/sysfs-block b/Documentation/ABI/testing/sysfs-block index 2b5d56127fce..c1eb41cb9876 100644 --- a/Documentation/ABI/testing/sysfs-block +++ b/Documentation/ABI/testing/sysfs-block @@ -206,16 +206,3 @@ Description: when a discarded area is read the discard_zeroes_data parameter will be set to one. Otherwise it will be 0 and the result of reading a discarded area is undefined. -What: /sys/block//alias -Date: Aug 2011 -Contact: Nao Nishijima -Description: - A raw device name of a disk does not always point a same disk - each boot-up time. Therefore, users have to use persistent - device names, which udev creates when the kernel finds a disk, - instead of raw device name. However, kernel doesn't show those - persistent names on its messages (e.g. dmesg). - This file can store an alias of the disk and it would be - appeared in kernel messages if it is set. A disk can have an - alias which length is up to 255bytes. Users can use alphabets, - numbers, "-" and "_" in alias name. This file is writeonce. diff --git a/block/genhd.c b/block/genhd.c index 9253839714ff..02e9fca80825 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -19,7 +19,6 @@ #include #include #include -#include #include "blk.h" @@ -916,74 +915,6 @@ static int __init genhd_device_init(void) subsys_initcall(genhd_device_init); -static ssize_t alias_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - struct gendisk *disk = dev_to_disk(dev); - ssize_t ret = 0; - - if (disk->alias) - ret = snprintf(buf, ALIAS_LEN, "%s\n", disk->alias); - return ret; -} - -static ssize_t alias_store(struct device *dev, struct device_attribute *attr, - const char *buf, size_t count) -{ - struct gendisk *disk = dev_to_disk(dev); - char *alias; - char *envp[] = { NULL, NULL }; - unsigned char c; - int i; - ssize_t ret = count; - - if (!count) - return -EINVAL; - - if (count >= ALIAS_LEN) { - printk(KERN_ERR "alias: alias is too long\n"); - return -EINVAL; - } - - /* Validation check */ - for (i = 0; i < count; i++) { - c = buf[i]; - if (i == count - 1 && c == '\n') - break; - if (!isalnum(c) && c != '_' && c != '-') { - printk(KERN_ERR "alias: invalid alias\n"); - return -EINVAL; - } - } - - if (disk->alias) { - printk(KERN_INFO "alias: %s is already assigned (%s)\n", - disk->disk_name, disk->alias); - return -EINVAL; - } - - alias = kasprintf(GFP_KERNEL, "%s", buf); - if (!alias) - return -ENOMEM; - - if (alias[count - 1] == '\n') - alias[count - 1] = '\0'; - - envp[0] = kasprintf(GFP_KERNEL, "ALIAS=%s", alias); - if (!envp[0]) { - kfree(alias); - return -ENOMEM; - } - - disk->alias = alias; - printk(KERN_INFO "alias: assigned %s to %s\n", alias, disk->disk_name); - - kobject_uevent_env(&dev->kobj, KOBJ_ADD, envp); - - kfree(envp[0]); - return ret; -} - static ssize_t disk_range_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -1043,7 +974,6 @@ static ssize_t disk_discard_alignment_show(struct device *dev, return sprintf(buf, "%d\n", queue_discard_alignment(disk->queue)); } -static DEVICE_ATTR(alias, S_IRUGO|S_IWUSR, alias_show, alias_store); static DEVICE_ATTR(range, S_IRUGO, disk_range_show, NULL); static DEVICE_ATTR(ext_range, S_IRUGO, disk_ext_range_show, NULL); static DEVICE_ATTR(removable, S_IRUGO, disk_removable_show, NULL); @@ -1066,7 +996,6 @@ static struct device_attribute dev_attr_fail_timeout = #endif static struct attribute *disk_attrs[] = { - &dev_attr_alias.attr, &dev_attr_range.attr, &dev_attr_ext_range.attr, &dev_attr_removable.attr, diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 9de31bc98c88..6d18f3531f18 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -21,8 +21,6 @@ #define dev_to_part(device) container_of((device), struct hd_struct, __dev) #define disk_to_dev(disk) (&(disk)->part0.__dev) #define part_to_dev(part) (&((part)->__dev)) -#define alias_name(disk) ((disk)->alias ? (disk)->alias : \ - (disk)->disk_name) extern struct device_type part_type; extern struct kobject *block_depr; @@ -60,7 +58,6 @@ enum { #define DISK_MAX_PARTS 256 #define DISK_NAME_LEN 32 -#define ALIAS_LEN 256 #include #include @@ -166,7 +163,6 @@ struct gendisk { * disks that can't be partitioned. */ char disk_name[DISK_NAME_LEN]; /* name of major driver */ - char *alias; /* alias name of disk */ char *(*devnode)(struct gendisk *gd, mode_t *mode); unsigned int events; /* supported events */ -- cgit v1.2.3-55-g7522 From 246835fccdc0dadeda20cd51f7ec868031fa8142 Mon Sep 17 00:00:00 2001 From: Jason Gerecke Date: Mon, 12 Dec 2011 00:12:04 -0800 Subject: Input: wacom - add LED support for Cintiq 24HD The Cintiq 24HD has three LEDs on the left side of the tablet and three LEDs on the right side of the tablet. Switching to LED 0, 1, or 2 will enable the top, middle, or bottom LED for the respective side. Switching to LED 3 turns off the LEDs on the respective side. Signed-off-by: Jason Gerecke Reviewed-by: Ping Cheng Signed-off-by: Dmitry Torokhov --- Documentation/ABI/testing/sysfs-driver-wacom | 17 +++++++++-------- drivers/input/tablet/wacom_sys.c | 5 ++++- 2 files changed, 13 insertions(+), 9 deletions(-) (limited to 'Documentation/ABI') diff --git a/Documentation/ABI/testing/sysfs-driver-wacom b/Documentation/ABI/testing/sysfs-driver-wacom index 82d4df136444..0130d6683c14 100644 --- a/Documentation/ABI/testing/sysfs-driver-wacom +++ b/Documentation/ABI/testing/sysfs-driver-wacom @@ -15,9 +15,9 @@ Contact: linux-input@vger.kernel.org Description: Attribute group for control of the status LEDs and the OLEDs. This attribute group is only available for Intuos 4 M, L, - and XL (with LEDs and OLEDs) and Cintiq 21UX2 (LEDs only). - Therefore its presence implicitly signifies the presence of - said LEDs and OLEDs on the tablet device. + and XL (with LEDs and OLEDs) and Cintiq 21UX2 and Cintiq 24HD + (LEDs only). Therefore its presence implicitly signifies the + presence of said LEDs and OLEDs on the tablet device. What: /sys/bus/usb/devices/-:./wacom_led/status0_luminance Date: August 2011 @@ -41,16 +41,17 @@ Date: August 2011 Contact: linux-input@vger.kernel.org Description: Writing to this file sets which one of the four (for Intuos 4) - or of the right four (for Cintiq 21UX2) status LEDs is active (0..3). - The other three LEDs on the same side are always inactive. + or of the right four (for Cintiq 21UX2 and Cintiq 24HD) status + LEDs is active (0..3). The other three LEDs on the same side are + always inactive. What: /sys/bus/usb/devices/-:./wacom_led/status_led1_select Date: September 2011 Contact: linux-input@vger.kernel.org Description: - Writing to this file sets which one of the left four (for Cintiq 21UX2) - status LEDs is active (0..3). The other three LEDs on the left are always - inactive. + Writing to this file sets which one of the left four (for Cintiq 21UX2 + and Cintiq 24HD) status LEDs is active (0..3). The other three LEDs on + the left are always inactive. What: /sys/bus/usb/devices/-:./wacom_led/buttons_luminance Date: August 2011 diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c index 2fe21d1a18b7..7e63183a6c68 100644 --- a/drivers/input/tablet/wacom_sys.c +++ b/drivers/input/tablet/wacom_sys.c @@ -563,7 +563,8 @@ static int wacom_led_control(struct wacom *wacom) if (!buf) return -ENOMEM; - if (wacom->wacom_wac.features.type == WACOM_21UX2) + if (wacom->wacom_wac.features.type == WACOM_21UX2 || + wacom->wacom_wac.features.type == WACOM_24HD) led = (wacom->led.select[1] << 4) | 0x40; led |= wacom->led.select[0] | 0x4; @@ -782,6 +783,7 @@ static int wacom_initialize_leds(struct wacom *wacom) &intuos4_led_attr_group); break; + case WACOM_24HD: case WACOM_21UX2: wacom->led.select[0] = 0; wacom->led.select[1] = 0; @@ -816,6 +818,7 @@ static void wacom_destroy_leds(struct wacom *wacom) &intuos4_led_attr_group); break; + case WACOM_24HD: case WACOM_21UX2: sysfs_remove_group(&wacom->intf->dev.kobj, &cintiq_led_attr_group); -- cgit v1.2.3-55-g7522