2

I started by asking this question: How do I initialize the attribute group correctly for a platform driver?

And came to the conclusion that function calling device_show_int() was doing so with the wrong function prototype.

The code problem starts by defining the struct dev_ext_attribute structure using the DEVICE_INT_ATTR() macro. The [struct device_attribute][1] structure has the show field defined as pointer to a function taking three (3) arguments:

struct device_attribute {
    struct attribute        attr;
    ssize_t (*show)(struct device *dev, struct device_attribute *attr,
                    char *buf);
    ssize_t (*store)(struct device *dev, struct device_attribute *attr,
                     const char *buf, size_t count);
};

Yet in my call stack (please the question referenced above) the dereferenced function is being called with only two (2) arguments from drv_attr_show():

if (drv_attr->show)
        ret = drv_attr->show(drv_priv->driver, buf);

This seems pretty egregious, is it a bug or have I somehow managed to screw up the kernel build? (ARM, Kernel 3.12)

Community
  • 1
  • 1
Jamie
  • 7,075
  • 12
  • 56
  • 86
  • What's the value of `drv_attr->show`? :-) C isn't typesafe (especially not hardcore kernel C), so you cannot argue about correctness based on types. Correctness depends on *values*. – Kerrek SB Jul 08 '14 at 00:36
  • @KerrekSB But the *value* doesn't tell the compiler how to format the call stack, the *type* or *cast* does. Somehow, since no errors are thrown in compiling the kernel, I'm guessing I've mixed my types up somehow because the between defining the structure and invoking the function pointer, the `show` field goes from 3 to 2 arguments. Nonetheless, to answer your question, `drv_attr->show` = `device_show_int`: a function with three (3) parameters (see: callstack from other question). – Jamie Jul 08 '14 at 00:58

1 Answers1

5

You're confusing device_attribute and driver_attribute. The function drv_attr_show() works on a struct driver_attribute, which is defined as:

struct driver_attribute {
    struct attribute attr;
    ssize_t (*show)(struct device_driver *driver, char *buf);
    ssize_t (*store)(struct device_driver *driver, const char *buf,
                     size_t count);
};

So no bug here.

pdw
  • 8,359
  • 2
  • 29
  • 41