出错代码行如下:struct my_attribute val_attribute = __ATTR(val, 0666, val_show, val_store);
解决方法
是__ATTR宏的权限问题,将上述的0666改为0664,问题迎刃而解。
In file included from ./include/linux/bits.h:22, from ./include/linux/bitops.h:6, from ./include/linux/bitmap.h:8, from ./include/linux/ethtool.h:16, from drivers/net/phy/dp83867.c:7: ./include/linux/build_bug.h:16:51: error: negative width in bit-field ‘<anonymous>’ #define BUILD_BUG_ON_ZERO(e) ((int)(sizeof(struct { int:(-!!(e)); }))) ^ ./include/linux/kernel.h:531:3: note: in expansion of macro ‘BUILD_BUG_ON_ZERO’ BUILD_BUG_ON_ZERO((perms) & 2) + \ ^~~~~~~~~~~~~~~~~ ./include/linux/sysfs.h:103:12: note: in expansion of macro ‘VERIFY_OCTAL_PERMISSIONS’ .mode = VERIFY_OCTAL_PERMISSIONS(_mode) }, \ ^~~~~~~~~~~~~~~~~~~~~~~~ drivers/net/phy/dp83867.c:896:50: note: in expansion of macro ‘__ATTR’ static struct kobj_attribute dp83867_attribute = __ATTR(dp83867_value, 0666, dp83867_show, dp83867_store);
static int dp83867_value; static ssize_t dp83867_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { //sprintf(buf, "%d\n", hello_value); //MII_BMCR 0x00 /* Basic mode control register */ //MII_BMSR 0x01 /* Basic mode status register */ if (!g_phydev) return 0; u32 reg = phy_read(g_phydev,0x00); pr_err("BMCR %x \n",reg); reg = phy_read(g_phydev,0x01); pr_err("BMSR %x \n",reg); reg = phy_read_mmd(g_phydev, DP83867_DEVADDR, DP83867_RGMIICTL); pr_err("DP83867_RGMIICTL %x \n",reg); reg = phy_read_mmd(g_phydev, DP83867_DEVADDR, DP83867_RGMIIDCTL); pr_err("DP83867_RGMIIDCTL %x \n",reg); return 0; } static ssize_t dp83867_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count) { u32 reg_addr, reg_value; sscanf(buf, "%x,%x", ®_addr, ®_value); pr_err("reg add %x , reg value %x\n",reg_addr, reg_value); if(DP83867_RGMIIDCTL == reg_addr || DP83867_RGMIICTL == reg_addr) { phy_write_mmd(g_phydev, DP83867_DEVADDR, reg_addr, reg_value); } else if (0x00 == reg_addr) { phy_write(g_phydev,reg_addr,0x00); } return count; } static struct kobj_attribute dp83867_attribute = __ATTR(dp83867_value, 0664, dp83867_show, dp83867_store); static struct kobject *dp83867_kobj = NULL; static int dp83867_sys_init(void) { int retval; dp83867_kobj = kobject_create_and_add("dp83867", kernel_kobj); if (!dp83867_kobj) return -ENOMEM; retval = sysfs_create_file(dp83867_kobj, &dp83867_attribute.attr); if (retval) kobject_put(dp83867_kobj); return retval; } static void dp83867_remove(struct phy_device *phydev) { g_phydev = NULL; if (!dp83867_kobj) kobject_put(dp83867_kobj); }
sprintf和sscanf是对copy_from_user和copy_to_user函数的封装
# ls /sys/kernel/dp83867/ dp83867_value # ls /sys/kernel/dp83867/dp83867_value /sys/kernel/dp83867/dp83867_value # # cat /sys/kernel/dp83867/dp83867_value [ 101.698281] BMCR 1140 [ 101.701881] BMSR 796d [ 101.706221] DP83867_RGMIICTL d3 [ 101.711388] DP83867_RGMIIDCTL a8 # # echo '32,d3' > /sys/kernel/dp83867/dp83867_value # cat /sys/kernel/dp83867/dp83867_value [ 211.615714] BMCR 1140 [ 211.619518] BMSR 796d [ 211.624255] DP83867_RGMIICTL d3 [ 211.630225] DP83867_RGMIIDCTL a8 # # cat /sys/kernel/dp83867/dp83867_value # echo '86,77' > /sys/kernel/dp83867/dp83867_value [ 231.221858] reg add 86 , reg value 77 # # echo '86,77' > /sys/kernel/dp83867/dp83867_value # cat /sys/kernel/dp83867/dp83867_value [ 235.325542] BMCR 1140 [ 235.329554] BMSR 796d [ 235.334125] DP83867_RGMIICTL d3 [ 235.339593] DP83867_RGMIIDCTL 77 #