root/drivers/rapidio/rio-sysfs.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. routes_show
  2. lprev_show
  3. lnext_show
  4. modalias_show
  5. rio_read_config
  6. rio_write_config
  7. rio_dev_is_attr_visible
  8. scan_store
  9. port_destid_show
  10. sys_size_show

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * RapidIO sysfs attributes and support
   4  *
   5  * Copyright 2005 MontaVista Software, Inc.
   6  * Matt Porter <mporter@kernel.crashing.org>
   7  */
   8 
   9 #include <linux/kernel.h>
  10 #include <linux/rio.h>
  11 #include <linux/rio_drv.h>
  12 #include <linux/stat.h>
  13 #include <linux/capability.h>
  14 
  15 #include "rio.h"
  16 
  17 /* Sysfs support */
  18 #define rio_config_attr(field, format_string)                                   \
  19 static ssize_t                                                          \
  20 field##_show(struct device *dev, struct device_attribute *attr, char *buf)                      \
  21 {                                                                       \
  22         struct rio_dev *rdev = to_rio_dev(dev);                         \
  23                                                                         \
  24         return sprintf(buf, format_string, rdev->field);                \
  25 }                                                                       \
  26 static DEVICE_ATTR_RO(field);
  27 
  28 rio_config_attr(did, "0x%04x\n");
  29 rio_config_attr(vid, "0x%04x\n");
  30 rio_config_attr(device_rev, "0x%08x\n");
  31 rio_config_attr(asm_did, "0x%04x\n");
  32 rio_config_attr(asm_vid, "0x%04x\n");
  33 rio_config_attr(asm_rev, "0x%04x\n");
  34 rio_config_attr(destid, "0x%04x\n");
  35 rio_config_attr(hopcount, "0x%02x\n");
  36 
  37 static ssize_t routes_show(struct device *dev, struct device_attribute *attr, char *buf)
  38 {
  39         struct rio_dev *rdev = to_rio_dev(dev);
  40         char *str = buf;
  41         int i;
  42 
  43         for (i = 0; i < RIO_MAX_ROUTE_ENTRIES(rdev->net->hport->sys_size);
  44                         i++) {
  45                 if (rdev->rswitch->route_table[i] == RIO_INVALID_ROUTE)
  46                         continue;
  47                 str +=
  48                     sprintf(str, "%04x %02x\n", i,
  49                             rdev->rswitch->route_table[i]);
  50         }
  51 
  52         return (str - buf);
  53 }
  54 static DEVICE_ATTR_RO(routes);
  55 
  56 static ssize_t lprev_show(struct device *dev,
  57                           struct device_attribute *attr, char *buf)
  58 {
  59         struct rio_dev *rdev = to_rio_dev(dev);
  60 
  61         return sprintf(buf, "%s\n",
  62                         (rdev->prev) ? rio_name(rdev->prev) : "root");
  63 }
  64 static DEVICE_ATTR_RO(lprev);
  65 
  66 static ssize_t lnext_show(struct device *dev,
  67                           struct device_attribute *attr, char *buf)
  68 {
  69         struct rio_dev *rdev = to_rio_dev(dev);
  70         char *str = buf;
  71         int i;
  72 
  73         if (rdev->pef & RIO_PEF_SWITCH) {
  74                 for (i = 0; i < RIO_GET_TOTAL_PORTS(rdev->swpinfo); i++) {
  75                         if (rdev->rswitch->nextdev[i])
  76                                 str += sprintf(str, "%s\n",
  77                                         rio_name(rdev->rswitch->nextdev[i]));
  78                         else
  79                                 str += sprintf(str, "null\n");
  80                 }
  81         }
  82 
  83         return str - buf;
  84 }
  85 static DEVICE_ATTR_RO(lnext);
  86 
  87 static ssize_t modalias_show(struct device *dev,
  88                              struct device_attribute *attr, char *buf)
  89 {
  90         struct rio_dev *rdev = to_rio_dev(dev);
  91 
  92         return sprintf(buf, "rapidio:v%04Xd%04Xav%04Xad%04X\n",
  93                        rdev->vid, rdev->did, rdev->asm_vid, rdev->asm_did);
  94 }
  95 static DEVICE_ATTR_RO(modalias);
  96 
  97 static struct attribute *rio_dev_attrs[] = {
  98         &dev_attr_did.attr,
  99         &dev_attr_vid.attr,
 100         &dev_attr_device_rev.attr,
 101         &dev_attr_asm_did.attr,
 102         &dev_attr_asm_vid.attr,
 103         &dev_attr_asm_rev.attr,
 104         &dev_attr_lprev.attr,
 105         &dev_attr_destid.attr,
 106         &dev_attr_modalias.attr,
 107 
 108         /* Switch-only attributes */
 109         &dev_attr_routes.attr,
 110         &dev_attr_lnext.attr,
 111         &dev_attr_hopcount.attr,
 112         NULL,
 113 };
 114 
 115 static ssize_t
 116 rio_read_config(struct file *filp, struct kobject *kobj,
 117                 struct bin_attribute *bin_attr,
 118                 char *buf, loff_t off, size_t count)
 119 {
 120         struct rio_dev *dev = to_rio_dev(kobj_to_dev(kobj));
 121         unsigned int size = 0x100;
 122         loff_t init_off = off;
 123         u8 *data = (u8 *) buf;
 124 
 125         /* Several chips lock up trying to read undefined config space */
 126         if (capable(CAP_SYS_ADMIN))
 127                 size = RIO_MAINT_SPACE_SZ;
 128 
 129         if (off >= size)
 130                 return 0;
 131         if (off + count > size) {
 132                 size -= off;
 133                 count = size;
 134         } else {
 135                 size = count;
 136         }
 137 
 138         if ((off & 1) && size) {
 139                 u8 val;
 140                 rio_read_config_8(dev, off, &val);
 141                 data[off - init_off] = val;
 142                 off++;
 143                 size--;
 144         }
 145 
 146         if ((off & 3) && size > 2) {
 147                 u16 val;
 148                 rio_read_config_16(dev, off, &val);
 149                 data[off - init_off] = (val >> 8) & 0xff;
 150                 data[off - init_off + 1] = val & 0xff;
 151                 off += 2;
 152                 size -= 2;
 153         }
 154 
 155         while (size > 3) {
 156                 u32 val;
 157                 rio_read_config_32(dev, off, &val);
 158                 data[off - init_off] = (val >> 24) & 0xff;
 159                 data[off - init_off + 1] = (val >> 16) & 0xff;
 160                 data[off - init_off + 2] = (val >> 8) & 0xff;
 161                 data[off - init_off + 3] = val & 0xff;
 162                 off += 4;
 163                 size -= 4;
 164         }
 165 
 166         if (size >= 2) {
 167                 u16 val;
 168                 rio_read_config_16(dev, off, &val);
 169                 data[off - init_off] = (val >> 8) & 0xff;
 170                 data[off - init_off + 1] = val & 0xff;
 171                 off += 2;
 172                 size -= 2;
 173         }
 174 
 175         if (size > 0) {
 176                 u8 val;
 177                 rio_read_config_8(dev, off, &val);
 178                 data[off - init_off] = val;
 179                 off++;
 180                 --size;
 181         }
 182 
 183         return count;
 184 }
 185 
 186 static ssize_t
 187 rio_write_config(struct file *filp, struct kobject *kobj,
 188                  struct bin_attribute *bin_attr,
 189                  char *buf, loff_t off, size_t count)
 190 {
 191         struct rio_dev *dev = to_rio_dev(kobj_to_dev(kobj));
 192         unsigned int size = count;
 193         loff_t init_off = off;
 194         u8 *data = (u8 *) buf;
 195 
 196         if (off >= RIO_MAINT_SPACE_SZ)
 197                 return 0;
 198         if (off + count > RIO_MAINT_SPACE_SZ) {
 199                 size = RIO_MAINT_SPACE_SZ - off;
 200                 count = size;
 201         }
 202 
 203         if ((off & 1) && size) {
 204                 rio_write_config_8(dev, off, data[off - init_off]);
 205                 off++;
 206                 size--;
 207         }
 208 
 209         if ((off & 3) && (size > 2)) {
 210                 u16 val = data[off - init_off + 1];
 211                 val |= (u16) data[off - init_off] << 8;
 212                 rio_write_config_16(dev, off, val);
 213                 off += 2;
 214                 size -= 2;
 215         }
 216 
 217         while (size > 3) {
 218                 u32 val = data[off - init_off + 3];
 219                 val |= (u32) data[off - init_off + 2] << 8;
 220                 val |= (u32) data[off - init_off + 1] << 16;
 221                 val |= (u32) data[off - init_off] << 24;
 222                 rio_write_config_32(dev, off, val);
 223                 off += 4;
 224                 size -= 4;
 225         }
 226 
 227         if (size >= 2) {
 228                 u16 val = data[off - init_off + 1];
 229                 val |= (u16) data[off - init_off] << 8;
 230                 rio_write_config_16(dev, off, val);
 231                 off += 2;
 232                 size -= 2;
 233         }
 234 
 235         if (size) {
 236                 rio_write_config_8(dev, off, data[off - init_off]);
 237                 off++;
 238                 --size;
 239         }
 240 
 241         return count;
 242 }
 243 
 244 static struct bin_attribute rio_config_attr = {
 245         .attr = {
 246                  .name = "config",
 247                  .mode = S_IRUGO | S_IWUSR,
 248                  },
 249         .size = RIO_MAINT_SPACE_SZ,
 250         .read = rio_read_config,
 251         .write = rio_write_config,
 252 };
 253 
 254 static struct bin_attribute *rio_dev_bin_attrs[] = {
 255         &rio_config_attr,
 256         NULL,
 257 };
 258 
 259 static umode_t rio_dev_is_attr_visible(struct kobject *kobj,
 260                                        struct attribute *attr, int n)
 261 {
 262         struct rio_dev *rdev = to_rio_dev(kobj_to_dev(kobj));
 263         umode_t mode = attr->mode;
 264 
 265         if (!(rdev->pef & RIO_PEF_SWITCH) &&
 266             (attr == &dev_attr_routes.attr ||
 267              attr == &dev_attr_lnext.attr ||
 268              attr == &dev_attr_hopcount.attr)) {
 269                 /*
 270                  * Hide switch-specific attributes for a non-switch device.
 271                  */
 272                 mode = 0;
 273         }
 274 
 275         return mode;
 276 }
 277 
 278 static const struct attribute_group rio_dev_group = {
 279         .attrs          = rio_dev_attrs,
 280         .is_visible     = rio_dev_is_attr_visible,
 281         .bin_attrs      = rio_dev_bin_attrs,
 282 };
 283 
 284 const struct attribute_group *rio_dev_groups[] = {
 285         &rio_dev_group,
 286         NULL,
 287 };
 288 
 289 static ssize_t scan_store(struct bus_type *bus, const char *buf, size_t count)
 290 {
 291         long val;
 292         int rc;
 293 
 294         if (kstrtol(buf, 0, &val) < 0)
 295                 return -EINVAL;
 296 
 297         if (val == RIO_MPORT_ANY) {
 298                 rc = rio_init_mports();
 299                 goto exit;
 300         }
 301 
 302         if (val < 0 || val >= RIO_MAX_MPORTS)
 303                 return -EINVAL;
 304 
 305         rc = rio_mport_scan((int)val);
 306 exit:
 307         if (!rc)
 308                 rc = count;
 309 
 310         return rc;
 311 }
 312 static BUS_ATTR_WO(scan);
 313 
 314 static struct attribute *rio_bus_attrs[] = {
 315         &bus_attr_scan.attr,
 316         NULL,
 317 };
 318 
 319 static const struct attribute_group rio_bus_group = {
 320         .attrs = rio_bus_attrs,
 321 };
 322 
 323 const struct attribute_group *rio_bus_groups[] = {
 324         &rio_bus_group,
 325         NULL,
 326 };
 327 
 328 static ssize_t
 329 port_destid_show(struct device *dev, struct device_attribute *attr,
 330                  char *buf)
 331 {
 332         struct rio_mport *mport = to_rio_mport(dev);
 333 
 334         if (mport)
 335                 return sprintf(buf, "0x%04x\n", mport->host_deviceid);
 336         else
 337                 return -ENODEV;
 338 }
 339 static DEVICE_ATTR_RO(port_destid);
 340 
 341 static ssize_t sys_size_show(struct device *dev, struct device_attribute *attr,
 342                            char *buf)
 343 {
 344         struct rio_mport *mport = to_rio_mport(dev);
 345 
 346         if (mport)
 347                 return sprintf(buf, "%u\n", mport->sys_size);
 348         else
 349                 return -ENODEV;
 350 }
 351 static DEVICE_ATTR_RO(sys_size);
 352 
 353 static struct attribute *rio_mport_attrs[] = {
 354         &dev_attr_port_destid.attr,
 355         &dev_attr_sys_size.attr,
 356         NULL,
 357 };
 358 
 359 static const struct attribute_group rio_mport_group = {
 360         .attrs = rio_mport_attrs,
 361 };
 362 
 363 const struct attribute_group *rio_mport_groups[] = {
 364         &rio_mport_group,
 365         NULL,
 366 };

/* [<][>][^][v][top][bottom][index][help] */