1/* 2 * This file is part of the zfcp device driver for 3 * FCP adapters for IBM System z9 and zSeries. 4 * 5 * (C) Copyright IBM Corp. 2002, 2006 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2, or (at your option) 10 * any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 */ 21 22#include "zfcp_ext.h" 23 24#define ZFCP_LOG_AREA ZFCP_LOG_AREA_CONFIG 25 26/** 27 * ZFCP_DEFINE_DRIVER_ATTR - define for all loglevels sysfs attributes 28 * @_name: name of attribute 29 * @_define: name of ZFCP loglevel define 30 * 31 * Generates store function for a sysfs loglevel attribute of zfcp driver. 32 */ 33#define ZFCP_DEFINE_DRIVER_ATTR(_name, _define) \ 34static ssize_t zfcp_sysfs_loglevel_##_name##_store(struct device_driver *drv, \ 35 const char *buf, \ 36 size_t count) \ 37{ \ 38 unsigned int loglevel; \ 39 unsigned int new_loglevel; \ 40 char *endp; \ 41 \ 42 new_loglevel = simple_strtoul(buf, &endp, 0); \ 43 if ((endp + 1) < (buf + count)) \ 44 return -EINVAL; \ 45 if (new_loglevel > 3) \ 46 return -EINVAL; \ 47 down(&zfcp_data.config_sema); \ 48 loglevel = atomic_read(&zfcp_data.loglevel); \ 49 loglevel &= ~((unsigned int) 0xf << (ZFCP_LOG_AREA_##_define << 2)); \ 50 loglevel |= new_loglevel << (ZFCP_LOG_AREA_##_define << 2); \ 51 atomic_set(&zfcp_data.loglevel, loglevel); \ 52 up(&zfcp_data.config_sema); \ 53 return count; \ 54} \ 55 \ 56static ssize_t zfcp_sysfs_loglevel_##_name##_show(struct device_driver *dev, \ 57 char *buf) \ 58{ \ 59 return sprintf(buf,"%d\n", (unsigned int) \ 60 ZFCP_GET_LOG_VALUE(ZFCP_LOG_AREA_##_define)); \ 61} \ 62 \ 63static DRIVER_ATTR(loglevel_##_name, S_IWUSR | S_IRUGO, \ 64 zfcp_sysfs_loglevel_##_name##_show, \ 65 zfcp_sysfs_loglevel_##_name##_store); 66 67ZFCP_DEFINE_DRIVER_ATTR(other, OTHER); 68ZFCP_DEFINE_DRIVER_ATTR(scsi, SCSI); 69ZFCP_DEFINE_DRIVER_ATTR(fsf, FSF); 70ZFCP_DEFINE_DRIVER_ATTR(config, CONFIG); 71ZFCP_DEFINE_DRIVER_ATTR(cio, CIO); 72ZFCP_DEFINE_DRIVER_ATTR(qdio, QDIO); 73ZFCP_DEFINE_DRIVER_ATTR(erp, ERP); 74ZFCP_DEFINE_DRIVER_ATTR(fc, FC); 75 76static ssize_t zfcp_sysfs_version_show(struct device_driver *dev, 77 char *buf) 78{ 79 return sprintf(buf, "%s\n", zfcp_data.driver_version); 80} 81 82static DRIVER_ATTR(version, S_IRUGO, zfcp_sysfs_version_show, NULL); 83 84static struct attribute *zfcp_driver_attrs[] = { 85 &driver_attr_loglevel_other.attr, 86 &driver_attr_loglevel_scsi.attr, 87 &driver_attr_loglevel_fsf.attr, 88 &driver_attr_loglevel_config.attr, 89 &driver_attr_loglevel_cio.attr, 90 &driver_attr_loglevel_qdio.attr, 91 &driver_attr_loglevel_erp.attr, 92 &driver_attr_loglevel_fc.attr, 93 &driver_attr_version.attr, 94 NULL 95}; 96 97static struct attribute_group zfcp_driver_attr_group = { 98 .attrs = zfcp_driver_attrs, 99}; 100 101/** 102 * zfcp_sysfs_create_driver_files - create sysfs driver files 103 * @dev: pointer to belonging device 104 * 105 * Create all sysfs attributes of the zfcp device driver 106 */ 107int 108zfcp_sysfs_driver_create_files(struct device_driver *drv) 109{ 110 return sysfs_create_group(&drv->kobj, &zfcp_driver_attr_group); 111} 112 113/** 114 * zfcp_sysfs_remove_driver_files - remove sysfs driver files 115 * @dev: pointer to belonging device 116 * 117 * Remove all sysfs attributes of the zfcp device driver 118 */ 119void 120zfcp_sysfs_driver_remove_files(struct device_driver *drv) 121{ 122 sysfs_remove_group(&drv->kobj, &zfcp_driver_attr_group); 123} 124 125#undef ZFCP_LOG_AREA 126