From owner-svn-src-stable@freebsd.org Thu Oct 26 17:45:03 2017 Return-Path: Delivered-To: svn-src-stable@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 019C0E4F416; Thu, 26 Oct 2017 17:45:03 +0000 (UTC) (envelope-from tijl@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id D0E962FA8; Thu, 26 Oct 2017 17:45:02 +0000 (UTC) (envelope-from tijl@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id v9QHj1eP076378; Thu, 26 Oct 2017 17:45:01 GMT (envelope-from tijl@FreeBSD.org) Received: (from tijl@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id v9QHj1wP076375; Thu, 26 Oct 2017 17:45:01 GMT (envelope-from tijl@FreeBSD.org) Message-Id: <201710261745.v9QHj1wP076375@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: tijl set sender to tijl@FreeBSD.org using -f From: Tijl Coosemans Date: Thu, 26 Oct 2017 17:45:01 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r325015 - in stable/11/sys: compat/linsysfs compat/linux kern X-SVN-Group: stable-11 X-SVN-Commit-Author: tijl X-SVN-Commit-Paths: in stable/11/sys: compat/linsysfs compat/linux kern X-SVN-Commit-Revision: 325015 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 26 Oct 2017 17:45:03 -0000 Author: tijl Date: Thu Oct 26 17:45:01 2017 New Revision: 325015 URL: https://svnweb.freebsd.org/changeset/base/325015 Log: MFC r323692,r323710,r323714,r324628,r324629,r324635,r324636,r324637 Merge Linux emulation changes to support newer Linux libdrm. Modified: stable/11/sys/compat/linsysfs/linsysfs.c stable/11/sys/compat/linux/linux_util.c stable/11/sys/kern/vfs_lookup.c Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/compat/linsysfs/linsysfs.c ============================================================================== --- stable/11/sys/compat/linsysfs/linsysfs.c Thu Oct 26 16:36:27 2017 (r325014) +++ stable/11/sys/compat/linsysfs/linsysfs.c Thu Oct 26 17:45:01 2017 (r325015) @@ -133,20 +133,162 @@ linsysfs_link_scsi_host(PFS_FILL_ARGS) return (0); } +static int +linsysfs_fill_data(PFS_FILL_ARGS) +{ + sbuf_printf(sb, "%s", (char *)pn->pn_data); + return (0); +} + +static int +linsysfs_fill_vendor(PFS_FILL_ARGS) +{ + sbuf_printf(sb, "0x%04x\n", pci_get_vendor((device_t)pn->pn_data)); + return (0); +} + +static int +linsysfs_fill_device(PFS_FILL_ARGS) +{ + sbuf_printf(sb, "0x%04x\n", pci_get_device((device_t)pn->pn_data)); + return (0); +} + +static int +linsysfs_fill_subvendor(PFS_FILL_ARGS) +{ + sbuf_printf(sb, "0x%04x\n", pci_get_subvendor((device_t)pn->pn_data)); + return (0); +} + +static int +linsysfs_fill_subdevice(PFS_FILL_ARGS) +{ + sbuf_printf(sb, "0x%04x\n", pci_get_subdevice((device_t)pn->pn_data)); + return (0); +} + +static int +linsysfs_fill_revid(PFS_FILL_ARGS) +{ + sbuf_printf(sb, "0x%x\n", pci_get_revid((device_t)pn->pn_data)); + return (0); +} + +static int +linsysfs_fill_config(PFS_FILL_ARGS) +{ + uint8_t config[48]; + device_t dev; + uint32_t reg; + + dev = (device_t)pn->pn_data; + bzero(config, sizeof(config)); + reg = pci_get_vendor(dev); + config[0] = reg; + config[1] = reg >> 8; + reg = pci_get_device(dev); + config[2] = reg; + config[3] = reg >> 8; + reg = pci_get_revid(dev); + config[8] = reg; + reg = pci_get_subvendor(dev); + config[44] = reg; + config[45] = reg >> 8; + reg = pci_get_subdevice(dev); + config[46] = reg; + config[47] = reg >> 8; + sbuf_bcat(sb, config, sizeof(config)); + return (0); +} + +/* + * Filler function for PCI uevent file + */ +static int +linsysfs_fill_uevent_pci(PFS_FILL_ARGS) +{ + device_t dev; + + dev = (device_t)pn->pn_data; + sbuf_printf(sb, "DRIVER=%s\nPCI_CLASS=%X\nPCI_ID=%04X:%04X\n" + "PCI_SUBSYS_ID=%04X:%04X\nPCI_SLOT_NAME=%04d:%02x:%02x.%x\n", + linux_driver_get_name_dev(dev), pci_get_class(dev), + pci_get_vendor(dev), pci_get_device(dev), pci_get_subvendor(dev), + pci_get_subdevice(dev), pci_get_domain(dev), pci_get_bus(dev), + pci_get_slot(dev), pci_get_function(dev)); + return (0); +} + +/* + * Filler function for drm uevent file + */ +static int +linsysfs_fill_uevent_drm(PFS_FILL_ARGS) +{ + device_t dev; + int unit; + + dev = (device_t)pn->pn_data; + unit = device_get_unit(dev); + sbuf_printf(sb, + "MAJOR=226\nMINOR=%d\nDEVNAME=dri/card%d\nDEVTYPE=dri_minor\n", + unit, unit); + return (0); +} + +static char * +get_full_pfs_path(struct pfs_node *cur) +{ + char *temp, *path; + + temp = malloc(MAXPATHLEN, M_TEMP, M_WAITOK); + path = malloc(MAXPATHLEN, M_TEMP, M_WAITOK); + path[0] = '\0'; + + do { + snprintf(temp, MAXPATHLEN, "%s/%s", cur->pn_name, path); + strlcpy(path, temp, MAXPATHLEN); + cur = cur->pn_parent; + } while (cur->pn_parent != NULL); + + path[strlen(path) - 1] = '\0'; /* remove extra slash */ + free(temp, M_TEMP); + return (path); +} + +/* + * Filler function for symlink from drm char device to PCI device + */ +static int +linsysfs_fill_vgapci(PFS_FILL_ARGS) +{ + char *path; + + path = get_full_pfs_path((struct pfs_node*)pn->pn_data); + sbuf_printf(sb, "../../../%s", path); + free(path, M_TEMP); + return (0); +} + #define PCI_DEV "pci" +#define DRMN_DEV "drmn" static int -linsysfs_run_bus(device_t dev, struct pfs_node *dir, struct pfs_node *scsi, char *path, - char *prefix) +linsysfs_run_bus(device_t dev, struct pfs_node *dir, struct pfs_node *scsi, + struct pfs_node *chardev, struct pfs_node *drm, char *path, char *prefix) { struct scsi_host_queue *scsi_host; - struct pfs_node *sub_dir; - int i, nchildren; + struct pfs_node *sub_dir, *cur_file; + int i, nchildren, error; device_t *children, parent; devclass_t devclass; const char *name = NULL; struct pci_devinfo *dinfo; - char *device, *host, *new_path = path; + char *device, *host, *new_path, *devname; + new_path = path; + devname = malloc(16, M_TEMP, M_WAITOK); + parent = device_get_parent(dev); if (parent) { devclass = device_get_devclass(parent); @@ -171,6 +313,40 @@ linsysfs_run_bus(device_t dev, struct pfs_node *dir, s strcat(new_path, device); dir = pfs_create_dir(dir, device, NULL, NULL, NULL, 0); + cur_file = pfs_create_file(dir, "vendor", + &linsysfs_fill_vendor, NULL, NULL, NULL, + PFS_RD); + cur_file->pn_data = (void*)dev; + cur_file = pfs_create_file(dir, "device", + &linsysfs_fill_device, NULL, NULL, NULL, + PFS_RD); + cur_file->pn_data = (void*)dev; + cur_file = pfs_create_file(dir, + "subsystem_vendor", + &linsysfs_fill_subvendor, NULL, NULL, NULL, + PFS_RD); + cur_file->pn_data = (void*)dev; + cur_file = pfs_create_file(dir, + "subsystem_device", + &linsysfs_fill_subdevice, NULL, NULL, NULL, + PFS_RD); + cur_file->pn_data = (void*)dev; + cur_file = pfs_create_file(dir, "revision", + &linsysfs_fill_revid, NULL, NULL, NULL, + PFS_RD); + cur_file->pn_data = (void*)dev; + cur_file = pfs_create_file(dir, "config", + &linsysfs_fill_config, NULL, NULL, NULL, + PFS_RD); + cur_file->pn_data = (void*)dev; + cur_file = pfs_create_file(dir, "uevent", + &linsysfs_fill_uevent_pci, NULL, NULL, + NULL, PFS_RD); + cur_file->pn_data = (void*)dev; + cur_file = pfs_create_link(dir, "subsystem", + &linsysfs_fill_data, NULL, NULL, NULL, 0); + /* libdrm just checks that the link ends in "/pci" */ + cur_file->pn_data = "/sys/bus/pci"; if (dinfo->cfg.baseclass == PCIC_STORAGE) { /* DJA only make this if needed */ @@ -207,15 +383,51 @@ linsysfs_run_bus(device_t dev, struct pfs_node *dir, s free(host, M_TEMP); } } + + devclass = device_get_devclass(dev); + if (devclass != NULL) + name = devclass_get_name(devclass); + else + name = NULL; + if (name != NULL && strcmp(name, DRMN_DEV) == 0 && + device_get_unit(dev) >= 0) { + dinfo = device_get_ivars(parent); + if (dinfo != NULL && dinfo->cfg.baseclass == PCIC_DISPLAY) { + sprintf(devname, "226:%d", + device_get_unit(dev)); + sub_dir = pfs_create_dir(chardev, + devname, NULL, NULL, NULL, 0); + cur_file = pfs_create_link(sub_dir, + "device", &linsysfs_fill_vgapci, NULL, + NULL, NULL, PFS_RD); + cur_file->pn_data = (void*)dir; + cur_file = pfs_create_file(sub_dir, + "uevent", &linsysfs_fill_uevent_drm, NULL, + NULL, NULL, PFS_RD); + cur_file->pn_data = (void*)dev; + sprintf(devname, "card%d", + device_get_unit(dev)); + sub_dir = pfs_create_dir(drm, + devname, NULL, NULL, NULL, 0); + cur_file = pfs_create_link(sub_dir, + "device", &linsysfs_fill_vgapci, NULL, + NULL, NULL, PFS_RD); + cur_file->pn_data = (void*)dir; + } + } } - device_get_children(dev, &children, &nchildren); - for (i = 0; i < nchildren; i++) { - if (children[i]) - linsysfs_run_bus(children[i], dir, scsi, new_path, prefix); + error = device_get_children(dev, &children, &nchildren); + if (error == 0) { + for (i = 0; i < nchildren; i++) + if (children[i]) + linsysfs_run_bus(children[i], dir, scsi, + chardev, drm, new_path, prefix); + free(children, M_TEMP); } if (new_path != path) free(new_path, M_TEMP); + free(devname, M_TEMP); return (1); } @@ -276,9 +488,12 @@ static int linsysfs_init(PFS_INIT_ARGS) { struct pfs_node *root; + struct pfs_node *class; struct pfs_node *dir, *sys, *cpu; + struct pfs_node *drm; struct pfs_node *pci; struct pfs_node *scsi; + struct pfs_node *devdir, *chardev; devclass_t devclass; device_t dev; @@ -287,13 +502,16 @@ linsysfs_init(PFS_INIT_ARGS) root = pi->pi_root; /* /sys/class/... */ - scsi = pfs_create_dir(root, "class", NULL, NULL, NULL, 0); - scsi = pfs_create_dir(scsi, "scsi_host", NULL, NULL, NULL, 0); + class = pfs_create_dir(root, "class", NULL, NULL, NULL, 0); + scsi = pfs_create_dir(class, "scsi_host", NULL, NULL, NULL, 0); + drm = pfs_create_dir(class, "drm", NULL, NULL, NULL, 0); - /* /sys/devices */ - dir = pfs_create_dir(root, "devices", NULL, NULL, NULL, 0); + /* /sys/dev/... */ + devdir = pfs_create_dir(root, "dev", NULL, NULL, NULL, 0); + chardev = pfs_create_dir(devdir, "char", NULL, NULL, NULL, 0); - /* /sys/devices/pci0000:00 */ + /* /sys/devices/... */ + dir = pfs_create_dir(root, "devices", NULL, NULL, NULL, 0); pci = pfs_create_dir(dir, "pci0000:00", NULL, NULL, NULL, 0); devclass = devclass_find("root"); @@ -302,7 +520,7 @@ linsysfs_init(PFS_INIT_ARGS) } dev = devclass_get_device(devclass, 0); - linsysfs_run_bus(dev, pci, scsi, "/pci0000:00", "0000"); + linsysfs_run_bus(dev, pci, scsi, chardev, drm, "/pci0000:00", "0000"); /* /sys/devices/system */ sys = pfs_create_dir(dir, "system", NULL, NULL, NULL, 0); Modified: stable/11/sys/compat/linux/linux_util.c ============================================================================== --- stable/11/sys/compat/linux/linux_util.c Thu Oct 26 16:36:27 2017 (r325014) +++ stable/11/sys/compat/linux/linux_util.c Thu Oct 26 17:45:01 2017 (r325015) @@ -127,23 +127,51 @@ int linux_driver_get_major_minor(const char *node, int *major, int *minor) { struct device_element *de; + unsigned long devno; + size_t sz; if (node == NULL || major == NULL || minor == NULL) return 1; - if (strlen(node) > strlen("pts/") && - strncmp(node, "pts/", strlen("pts/")) == 0) { - unsigned long devno; - + sz = sizeof("pts/") - 1; + if (strncmp(node, "pts/", sz) == 0 && node[sz] != '\0') { /* * Linux checks major and minors of the slave device * to make sure it's a pty device, so let's make him * believe it is. */ - devno = strtoul(node + strlen("pts/"), NULL, 10); + devno = strtoul(node + sz, NULL, 10); *major = 136 + (devno / 256); *minor = devno % 256; + return (0); + } + sz = sizeof("dri/card") - 1; + if (strncmp(node, "dri/card", sz) == 0 && node[sz] != '\0') { + devno = strtoul(node + sz, NULL, 10); + *major = 226 + (devno / 256); + *minor = devno % 256; + return (0); + } + sz = sizeof("dri/controlD") - 1; + if (strncmp(node, "dri/controlD", sz) == 0 && node[sz] != '\0') { + devno = strtoul(node + sz, NULL, 10); + *major = 226 + (devno / 256); + *minor = devno % 256; + return (0); + } + sz = sizeof("dri/renderD") - 1; + if (strncmp(node, "dri/renderD", sz) == 0 && node[sz] != '\0') { + devno = strtoul(node + sz, NULL, 10); + *major = 226 + (devno / 256); + *minor = devno % 256; + return (0); + } + sz = sizeof("drm/") - 1; + if (strncmp(node, "drm/", sz) == 0 && node[sz] != '\0') { + devno = strtoul(node + sz, NULL, 10); + *major = 226 + (devno / 256); + *minor = devno % 256; return (0); } Modified: stable/11/sys/kern/vfs_lookup.c ============================================================================== --- stable/11/sys/kern/vfs_lookup.c Thu Oct 26 16:36:27 2017 (r325014) +++ stable/11/sys/kern/vfs_lookup.c Thu Oct 26 17:45:01 2017 (r325015) @@ -1390,13 +1390,13 @@ kern_alternate_path(struct thread *td, const char *pre for (cp = &ptr[len] - 1; *cp != '/'; cp--); *cp = '\0'; - NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, td); + NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, buf, td); error = namei(&nd); *cp = '/'; if (error != 0) goto keeporig; } else { - NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, buf, td); + NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, buf, td); error = namei(&nd); if (error != 0)