linux-old/arch/ia64/sn/io/hwgdfs/hcl.c
<<
>>
Prefs
   1/*
   2 * This file is subject to the terms and conditions of the GNU General Public
   3 * License.  See the file "COPYING" in the main directory of this archive
   4 * for more details.
   5 *
   6 *  hcl - SGI's Hardware Graph compatibility layer.
   7 *
   8 * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
   9 */
  10
  11#include <linux/types.h>
  12#include <linux/config.h>
  13#include <linux/slab.h>
  14#include <linux/ctype.h>
  15#include <linux/module.h>
  16#include <linux/init.h>
  17#include <asm/sn/sgi.h>
  18#include <linux/devfs_fs.h>
  19#include <linux/devfs_fs_kernel.h>
  20#include <asm/io.h>
  21#include <asm/sn/iograph.h>
  22#include <asm/sn/invent.h>
  23#include <asm/sn/hcl.h>
  24#include <asm/sn/labelcl.h>
  25#include <asm/sn/simulator.h>
  26
  27#define HCL_NAME "SGI-HWGRAPH COMPATIBILITY DRIVER"
  28#define HCL_TEMP_NAME "HCL_TEMP_NAME_USED_FOR_HWGRAPH_VERTEX_CREATE"
  29#define HCL_TEMP_NAME_LEN 44 
  30#define HCL_VERSION "1.0"
  31vertex_hdl_t hwgraph_root;
  32vertex_hdl_t linux_busnum;
  33
  34extern void pci_bus_cvlink_init(void);
  35
  36/*
  37 * Debug flag definition.
  38 */
  39#define OPTION_NONE             0x00
  40#define HCL_DEBUG_NONE 0x00000
  41#define HCL_DEBUG_ALL  0x0ffff
  42#if defined(CONFIG_HCL_DEBUG)
  43static unsigned int hcl_debug_init __initdata = HCL_DEBUG_NONE;
  44#endif
  45static unsigned int hcl_debug = HCL_DEBUG_NONE;
  46#if defined(CONFIG_HCL_DEBUG) && !defined(MODULE)
  47static unsigned int boot_options = OPTION_NONE;
  48#endif
  49
  50/*
  51 * Some Global definitions.
  52 */
  53static vertex_hdl_t hcl_handle;
  54
  55invplace_t invplace_none = {
  56        GRAPH_VERTEX_NONE,
  57        GRAPH_VERTEX_PLACE_NONE,
  58        NULL
  59};
  60
  61/*
  62 * HCL device driver.
  63 * The purpose of this device driver is to provide a facility 
  64 * for User Level Apps e.g. hinv, ioconfig etc. an ioctl path 
  65 * to manipulate label entries without having to implement
  66 * system call interfaces.  This methodology will enable us to 
  67 * make this feature module loadable.
  68 */
  69static int hcl_open(struct inode * inode, struct file * filp)
  70{
  71        if (hcl_debug) {
  72                printk("HCL: hcl_open called.\n");
  73        }
  74
  75        return(0);
  76
  77}
  78
  79static int hcl_close(struct inode * inode, struct file * filp)
  80{
  81
  82        if (hcl_debug) {
  83                printk("HCL: hcl_close called.\n");
  84        }
  85
  86        return(0);
  87
  88}
  89
  90static int hcl_ioctl(struct inode * inode, struct file * file,
  91        unsigned int cmd, unsigned long arg)
  92{
  93
  94        if (hcl_debug) {
  95                printk("HCL: hcl_ioctl called.\n");
  96        }
  97
  98        switch (cmd) {
  99                default:
 100                        if (hcl_debug) {
 101                                printk("HCL: hcl_ioctl cmd = 0x%x\n", cmd);
 102                        }
 103        }
 104
 105        return(0);
 106
 107}
 108
 109struct file_operations hcl_fops = {
 110        (struct module *)0,
 111        NULL,           /* lseek - default */
 112        NULL,           /* read - general block-dev read */
 113        NULL,           /* write - general block-dev write */
 114        NULL,           /* readdir - bad */
 115        NULL,           /* poll */
 116        hcl_ioctl,      /* ioctl */
 117        NULL,           /* mmap */
 118        hcl_open,       /* open */
 119        NULL,           /* flush */
 120        hcl_close,      /* release */
 121        NULL,           /* fsync */
 122        NULL,           /* fasync */
 123        NULL,           /* lock */
 124        NULL,           /* readv */
 125        NULL,           /* writev */
 126};
 127
 128
 129/*
 130 * init_hcl() - Boot time initialization.  Ensure that it is called 
 131 *      after devfs has been initialized.
 132 *
 133 * For now this routine is being called out of devfs/base.c.  Actually 
 134 * Not a bad place to be ..
 135 *
 136 */
 137int __init init_hcl(void)
 138{
 139        extern void string_table_init(struct string_table *);
 140        extern struct string_table label_string_table;
 141        extern int init_ifconfig_net(void);
 142        extern int init_ioconfig_bus(void);
 143        int status = 0;
 144        int rv = 0;
 145
 146        if (IS_RUNNING_ON_SIMULATOR()) {
 147                extern u64 klgraph_addr[];
 148                klgraph_addr[0] = 0xe000003000030000;
 149        }
 150
 151        /*
 152         * Create the hwgraph_root on devfs.
 153         */
 154        rv = hwgraph_path_add(NULL, EDGE_LBL_HW, &hwgraph_root);
 155        if (rv)
 156                printk ("WARNING: init_hcl: Failed to create hwgraph_root. Error = %d.\n", rv);
 157
 158        status = devfs_set_flags (hwgraph_root, DEVFS_FL_HIDE);
 159
 160        /*
 161         * Create the hcl driver to support inventory entry manipulations.
 162         * By default, it is expected that devfs is mounted on /dev.
 163         *
 164         */
 165        hcl_handle = hwgraph_register(hwgraph_root, ".hcl",
 166                        0, DEVFS_FL_AUTO_DEVNUM,
 167                        0, 0,
 168                        S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
 169                        &hcl_fops, NULL);
 170
 171        if (hcl_handle == NULL) {
 172                panic("HCL: Unable to create HCL Driver in init_hcl().\n");
 173                return(0);
 174        }
 175
 176        /*
 177         * Initialize the HCL string table.
 178         */
 179        string_table_init(&label_string_table);
 180
 181        /*
 182         * Create the directory that links Linux bus numbers to our Xwidget.
 183         */
 184        rv = hwgraph_path_add(hwgraph_root, EDGE_LBL_LINUX_BUS, &linux_busnum);
 185        if (linux_busnum == NULL) {
 186                panic("HCL: Unable to create %s\n", EDGE_LBL_LINUX_BUS);
 187                return(0);
 188        }
 189
 190        pci_bus_cvlink_init();
 191
 192        /*
 193         * Initialize the ifconfgi_net driver that does network devices 
 194         * Persistent Naming.
 195         */
 196        init_ifconfig_net();
 197        init_ioconfig_bus();
 198
 199        return(0);
 200
 201}
 202
 203
 204/*
 205 * hcl_setup() - Process boot time parameters if given.
 206 *      "hcl="
 207 *      This routine gets called only if "hcl=" is given in the 
 208 *      boot line and before init_hcl().
 209 *
 210 *      We currently do not have any boot options .. when we do, 
 211 *      functionalities can be added here.
 212 *
 213 */
 214static int __init hcl_setup(char *str)
 215{
 216    while ( (*str != '\0') && !isspace (*str) )
 217    {
 218#ifdef CONFIG_HCL_DEBUG
 219        if (strncmp (str, "all", 3) == 0) {
 220            hcl_debug_init |= HCL_DEBUG_ALL;
 221            str += 3;
 222        } else 
 223                return 0;
 224#endif
 225        if (*str != ',') return 0;
 226        ++str;
 227    }
 228
 229    return 1;
 230
 231}
 232
 233__setup("hcl=", hcl_setup);
 234
 235
 236int
 237hwgraph_generate_path(
 238        vertex_hdl_t            de,
 239        char                    *path,
 240        int                     buflen)
 241{
 242        return (devfs_generate_path(de, path, buflen));
 243}
 244
 245/*
 246 * Set device specific "fast information".
 247 *
 248 */
 249void
 250hwgraph_fastinfo_set(vertex_hdl_t de, arbitrary_info_t fastinfo)
 251{
 252        labelcl_info_replace_IDX(de, HWGRAPH_FASTINFO, fastinfo, NULL);
 253}
 254
 255
 256/*
 257 * Get device specific "fast information".
 258 *
 259 */
 260arbitrary_info_t
 261hwgraph_fastinfo_get(vertex_hdl_t de)
 262{
 263        arbitrary_info_t fastinfo;
 264        int rv;
 265
 266        if (!de) {
 267                printk(KERN_WARNING "HCL: hwgraph_fastinfo_get handle given is NULL.\n");
 268                return(-1);
 269        }
 270
 271        rv = labelcl_info_get_IDX(de, HWGRAPH_FASTINFO, &fastinfo);
 272        if (rv == 0)
 273                return(fastinfo);
 274
 275        return(0);
 276}
 277
 278
 279/*
 280 * hwgraph_connectpt_set - Sets the connect point handle in de to the 
 281 *      given connect_de handle.  By default, the connect point of the 
 282 *      devfs node is the parent.  This effectively changes this assumption.
 283 */
 284int
 285hwgraph_connectpt_set(vertex_hdl_t de, vertex_hdl_t connect_de)
 286{
 287        int rv;
 288
 289        if (!de)
 290                return(-1);
 291
 292        rv = labelcl_info_connectpt_set(de, connect_de);
 293
 294        return(rv);
 295}
 296
 297
 298/*
 299 * hwgraph_connectpt_get: Returns the entry's connect point  in the devfs 
 300 *      tree.
 301 */
 302vertex_hdl_t
 303hwgraph_connectpt_get(vertex_hdl_t de)
 304{
 305        int rv;
 306        arbitrary_info_t info;
 307        vertex_hdl_t connect;
 308
 309        rv = labelcl_info_get_IDX(de, HWGRAPH_CONNECTPT, &info);
 310        if (rv != 0) {
 311                return(NULL);
 312        }
 313
 314        connect = (vertex_hdl_t)info;
 315        return(connect);
 316
 317}
 318
 319
 320/*
 321 * hwgraph_mk_dir - Creates a directory entry with devfs.
 322 *      Note that a directory entry in devfs can have children 
 323 *      but it cannot be a char|block special file.
 324 */
 325vertex_hdl_t
 326hwgraph_mk_dir(vertex_hdl_t de, const char *name,
 327                unsigned int namelen, void *info)
 328{
 329
 330        int rv;
 331        labelcl_info_t *labelcl_info = NULL;
 332        vertex_hdl_t new_devfs_handle = NULL;
 333        vertex_hdl_t parent = NULL;
 334
 335        /*
 336         * Create the device info structure for hwgraph compatiblity support.
 337         */
 338        labelcl_info = labelcl_info_create();
 339        if (!labelcl_info)
 340                return(NULL);
 341
 342        /*
 343         * Create a devfs entry.
 344         */
 345        new_devfs_handle = devfs_mk_dir(de, name, (void *)labelcl_info);
 346        if (!new_devfs_handle) {
 347                labelcl_info_destroy(labelcl_info);
 348                return(NULL);
 349        }
 350
 351        /*
 352         * Get the parent handle.
 353         */
 354        parent = devfs_get_parent (new_devfs_handle);
 355
 356        /*
 357         * To provide the same semantics as the hwgraph, set the connect point.
 358         */
 359        rv = hwgraph_connectpt_set(new_devfs_handle, parent);
 360        if (!rv) {
 361                /*
 362                 * We need to clean up!
 363                 */
 364        }
 365
 366        /*
 367         * If the caller provides a private data pointer, save it in the 
 368         * labelcl info structure(fastinfo).  This can be retrieved via
 369         * hwgraph_fastinfo_get()
 370         */
 371        if (info)
 372                hwgraph_fastinfo_set(new_devfs_handle, (arbitrary_info_t)info);
 373                
 374        return(new_devfs_handle);
 375
 376}
 377
 378/*
 379 * hwgraph_path_add - Create a directory node with the given path starting 
 380 * from the given vertex_hdl_t.
 381 */
 382int
 383hwgraph_path_add(vertex_hdl_t  fromv,
 384                 char *path,
 385                 vertex_hdl_t *new_de)
 386{
 387
 388        unsigned int    namelen = strlen(path);
 389        int             rv;
 390
 391        /*
 392         * We need to handle the case when fromv is NULL ..
 393         * in this case we need to create the path from the 
 394         * hwgraph root!
 395         */
 396        if (fromv == NULL)
 397                fromv = hwgraph_root;
 398
 399        /*
 400         * check the entry doesn't already exist, if it does
 401         * then we simply want new_de to point to it (otherwise
 402         * we'll overwrite the existing labelcl_info struct)
 403         */
 404        rv = hwgraph_edge_get(fromv, path, new_de);
 405        if (rv) {       /* couldn't find entry so we create it */
 406                *new_de = hwgraph_mk_dir(fromv, path, namelen, NULL);
 407                if (new_de == NULL)
 408                        return(-1);
 409                else
 410                        return(0);
 411        }
 412        else 
 413                return(0);
 414
 415}
 416
 417/*
 418 * hwgraph_register  - Creates a file entry with devfs.
 419 *      Note that a file entry cannot have children .. it is like a 
 420 *      char|block special vertex in hwgraph.
 421 */
 422vertex_hdl_t
 423hwgraph_register(vertex_hdl_t de, const char *name,
 424                unsigned int namelen, unsigned int flags, 
 425                unsigned int major, unsigned int minor,
 426                umode_t mode, uid_t uid, gid_t gid, 
 427                struct file_operations *fops,
 428                void *info)
 429{
 430
 431        vertex_hdl_t new_devfs_handle = NULL;
 432
 433        /*
 434         * Create a devfs entry.
 435         */
 436        new_devfs_handle = devfs_register(de, name, flags, major,
 437                                minor, mode, fops, info);
 438        if (!new_devfs_handle) {
 439                return(NULL);
 440        }
 441
 442        return(new_devfs_handle);
 443
 444}
 445
 446
 447/*
 448 * hwgraph_mk_symlink - Create a symbolic link.
 449 */
 450int
 451hwgraph_mk_symlink(vertex_hdl_t de, const char *name, unsigned int namelen,
 452                unsigned int flags, const char *link, unsigned int linklen, 
 453                vertex_hdl_t *handle, void *info)
 454{
 455
 456        void *labelcl_info = NULL;
 457        int status = 0;
 458        vertex_hdl_t new_devfs_handle = NULL;
 459
 460        /*
 461         * Create the labelcl info structure for hwgraph compatiblity support.
 462         */
 463        labelcl_info = labelcl_info_create();
 464        if (!labelcl_info)
 465                return(-1);
 466
 467        /*
 468         * Create a symbolic link devfs entry.
 469         */
 470        status = devfs_mk_symlink(de, name, flags, link,
 471                                &new_devfs_handle, labelcl_info);
 472        if ( (!new_devfs_handle) || (!status) ){
 473                labelcl_info_destroy((labelcl_info_t *)labelcl_info);
 474                return(-1);
 475        }
 476
 477        /*
 478         * If the caller provides a private data pointer, save it in the 
 479         * labelcl info structure(fastinfo).  This can be retrieved via
 480         * hwgraph_fastinfo_get()
 481         */
 482        if (info)
 483                hwgraph_fastinfo_set(new_devfs_handle, (arbitrary_info_t)info);
 484
 485        *handle = new_devfs_handle;
 486        return(0);
 487
 488}
 489
 490/*
 491 * hwgraph_vertex_destroy - Destroy the devfs entry
 492 */
 493int
 494hwgraph_vertex_destroy(vertex_hdl_t de)
 495{
 496
 497        void *labelcl_info = NULL;
 498
 499        labelcl_info = devfs_get_info(de);
 500        devfs_unregister(de);
 501
 502        if (labelcl_info)
 503                labelcl_info_destroy((labelcl_info_t *)labelcl_info);
 504
 505        return(0);
 506}
 507
 508/*
 509 * hwgraph_edge_add - This routines has changed from the original conext.
 510 * All it does now is to create a symbolic link from "from" to "to".
 511 */
 512/* ARGSUSED */
 513int
 514hwgraph_edge_add(vertex_hdl_t from, vertex_hdl_t to, char *name)
 515{
 516
 517        char *path;
 518        char *s1;
 519        char *index;
 520        int name_start;
 521        vertex_hdl_t handle = NULL;
 522        int rv;
 523        int i, count;
 524
 525        path = kmalloc(1024, GFP_KERNEL);
 526        memset(path, 0x0, 1024);
 527        name_start = devfs_generate_path (from, path, 1024);
 528        s1 = &path[name_start];
 529        count = 0;
 530        while (1) {
 531                index = strstr (s1, "/");
 532                if (index) {
 533                        count++;
 534                        s1 = ++index;
 535                } else {
 536                        count++;
 537                        break;
 538                }
 539        }
 540
 541        memset(path, 0x0, 1024);
 542        name_start = devfs_generate_path (to, path, 1024);
 543
 544        for (i = 0; i < count; i++) {
 545                strcat(path,"../");
 546        }
 547
 548        strcat(path, &path[name_start]);
 549
 550        /*
 551         * Otherwise, just create a symlink to the vertex.
 552         * In this case the vertex was previous created with a REAL pathname.
 553         */
 554        rv = devfs_mk_symlink (from, (const char *)name, 
 555                               DEVFS_FL_DEFAULT, path,
 556                               &handle, NULL);
 557
 558        name_start = devfs_generate_path (handle, path, 1024);
 559        return(rv);
 560
 561        
 562}
 563/* ARGSUSED */
 564int
 565hwgraph_edge_get(vertex_hdl_t from, char *name, vertex_hdl_t *toptr)
 566{
 567
 568        int namelen = 0;
 569        vertex_hdl_t target_handle = NULL;
 570
 571        if (name == NULL)
 572                return(-1);
 573
 574        if (toptr == NULL)
 575                return(-1);
 576
 577        /*
 578         * If the name is "." just return the current devfs entry handle.
 579         */
 580        if (!strcmp(name, HWGRAPH_EDGELBL_DOT)) {
 581                if (toptr) {
 582                        *toptr = from;
 583                }
 584        } else if (!strcmp(name, HWGRAPH_EDGELBL_DOTDOT)) {
 585                /*
 586                 * Hmmm .. should we return the connect point or parent ..
 587                 * see in hwgraph, the concept of parent is the connectpt!
 588                 *
 589                 * Maybe we should see whether the connectpt is set .. if 
 590                 * not just return the parent!
 591                 */
 592                target_handle = hwgraph_connectpt_get(from);
 593                if (target_handle) {
 594                        /*
 595                         * Just return the connect point.
 596                         */
 597                        *toptr = target_handle;
 598                        return(0);
 599                }
 600                target_handle = devfs_get_parent(from);
 601                *toptr = target_handle;
 602
 603        } else {
 604                /*
 605                 * Call devfs to get the devfs entry.
 606                 */
 607                namelen = (int) strlen(name);
 608                target_handle = devfs_find_handle (from, name, 0, 0,
 609                                        0, 1); /* Yes traverse symbolic links */
 610                if (target_handle == NULL)
 611                        return(-1);
 612                else
 613                *toptr = target_handle;
 614        }
 615
 616        return(0);
 617}
 618
 619/*
 620 * hwgraph_info_add_LBL - Adds a new label for the device.  Mark the info_desc
 621 *      of the label as INFO_DESC_PRIVATE and store the info in the label.
 622 */
 623/* ARGSUSED */
 624int
 625hwgraph_info_add_LBL(   vertex_hdl_t de,
 626                        char *name,
 627                        arbitrary_info_t info)
 628{
 629        return(labelcl_info_add_LBL(de, name, INFO_DESC_PRIVATE, info));
 630}
 631
 632/*
 633 * hwgraph_info_remove_LBL - Remove the label entry for the device.
 634 */
 635/* ARGSUSED */
 636int
 637hwgraph_info_remove_LBL(        vertex_hdl_t de,
 638                                char *name,
 639                                arbitrary_info_t *old_info)
 640{
 641        return(labelcl_info_remove_LBL(de, name, NULL, old_info));
 642}
 643
 644/*
 645 * hwgraph_info_replace_LBL - replaces an existing label with 
 646 *      a new label info value.
 647 */
 648/* ARGSUSED */
 649int
 650hwgraph_info_replace_LBL(       vertex_hdl_t de,
 651                                char *name,
 652                                arbitrary_info_t info,
 653                                arbitrary_info_t *old_info)
 654{
 655        return(labelcl_info_replace_LBL(de, name,
 656                        INFO_DESC_PRIVATE, info,
 657                        NULL, old_info));
 658}
 659/*
 660 * hwgraph_info_get_LBL - Get and return the info value in the label of the 
 661 *      device.
 662 */
 663/* ARGSUSED */
 664int
 665hwgraph_info_get_LBL(   vertex_hdl_t de,
 666                        char *name,
 667                        arbitrary_info_t *infop)
 668{
 669        return(labelcl_info_get_LBL(de, name, NULL, infop));
 670}
 671
 672/*
 673 * hwgraph_info_get_exported_LBL - Retrieve the info_desc and info pointer 
 674 *      of the given label for the device.  The weird thing is that the label 
 675 *      that matches the name is return irrespective of the info_desc value!
 676 *      Do not understand why the word "exported" is used!
 677 */
 678/* ARGSUSED */
 679int
 680hwgraph_info_get_exported_LBL(  vertex_hdl_t de,
 681                                char *name,
 682                                int *export_info,
 683                                arbitrary_info_t *infop)
 684{
 685        int rc;
 686        arb_info_desc_t info_desc;
 687
 688        rc = labelcl_info_get_LBL(de, name, &info_desc, infop);
 689        if (rc == 0)
 690                *export_info = (int)info_desc;
 691
 692        return(rc);
 693}
 694
 695/*
 696 * hwgraph_info_get_next_LBL - Returns the next label info given the 
 697 *      current label entry in place.
 698 *
 699 *      Once again this has no locking or reference count for protection.
 700 *
 701 */
 702/* ARGSUSED */
 703int
 704hwgraph_info_get_next_LBL(      vertex_hdl_t de,
 705                                char *buf,
 706                                arbitrary_info_t *infop,
 707                                labelcl_info_place_t *place)
 708{
 709        return(labelcl_info_get_next_LBL(de, buf, NULL, infop, place));
 710}
 711
 712/*
 713 * hwgraph_info_export_LBL - Retrieve the specified label entry and modify 
 714 *      the info_desc field with the given value in nbytes.
 715 */
 716/* ARGSUSED */
 717int
 718hwgraph_info_export_LBL(vertex_hdl_t de, char *name, int nbytes)
 719{
 720        arbitrary_info_t info;
 721        int rc;
 722
 723        if (nbytes == 0)
 724                nbytes = INFO_DESC_EXPORT;
 725
 726        if (nbytes < 0)
 727                return(-1);
 728
 729        rc = labelcl_info_get_LBL(de, name, NULL, &info);
 730        if (rc != 0)
 731                return(rc);
 732
 733        rc = labelcl_info_replace_LBL(de, name,
 734                                nbytes, info, NULL, NULL);
 735
 736        return(rc);
 737}
 738
 739/*
 740 * hwgraph_info_unexport_LBL - Retrieve the given label entry and change the 
 741 * label info_descr filed to INFO_DESC_PRIVATE.
 742 */
 743/* ARGSUSED */
 744int
 745hwgraph_info_unexport_LBL(vertex_hdl_t de, char *name)
 746{
 747        arbitrary_info_t info;
 748        int rc;
 749
 750        rc = labelcl_info_get_LBL(de, name, NULL, &info);
 751        if (rc != 0)
 752                return(rc);
 753
 754        rc = labelcl_info_replace_LBL(de, name,
 755                                INFO_DESC_PRIVATE, info, NULL, NULL);
 756
 757        return(rc);
 758}
 759
 760/*
 761 * hwgraph_path_lookup - return the handle for the given path.
 762 *
 763 */
 764int
 765hwgraph_path_lookup(    vertex_hdl_t start_vertex_handle,
 766                        char *lookup_path,
 767                        vertex_hdl_t *vertex_handle_ptr,
 768                        char **remainder)
 769{
 770        *vertex_handle_ptr = devfs_find_handle(start_vertex_handle,     /* start dir */
 771                                        lookup_path,            /* path */
 772                                        0,                      /* major */
 773                                        0,                      /* minor */
 774                                        0,                      /* char | block */
 775                                        1);                     /* traverse symlinks */
 776        if (*vertex_handle_ptr == NULL)
 777                return(-1);
 778        else
 779                return(0);
 780}
 781
 782/*
 783 * hwgraph_traverse - Find and return the devfs handle starting from de.
 784 *
 785 */
 786graph_error_t
 787hwgraph_traverse(vertex_hdl_t de, char *path, vertex_hdl_t *found)
 788{
 789        /* 
 790         * get the directory entry (path should end in a directory)
 791         */
 792
 793        *found = devfs_find_handle(de,  /* start dir */
 794                            path,       /* path */
 795                            0,          /* major */
 796                            0,          /* minor */
 797                            0,          /* char | block */
 798                            1);         /* traverse symlinks */
 799        if (*found == NULL)
 800                return(GRAPH_NOT_FOUND);
 801        else
 802                return(GRAPH_SUCCESS);
 803}
 804
 805/*
 806 * hwgraph_path_to_vertex - Return the devfs entry handle for the given 
 807 *      pathname .. assume traverse symlinks too!.
 808 */
 809vertex_hdl_t
 810hwgraph_path_to_vertex(char *path)
 811{
 812        return(devfs_find_handle(NULL,  /* start dir */
 813                        path,           /* path */
 814                        0,              /* major */
 815                        0,              /* minor */
 816                        0,              /* char | block */
 817                        1));            /* traverse symlinks */
 818}
 819
 820/*
 821 * hwgraph_inventory_remove - Removes an inventory entry.
 822 *
 823 *      Remove an inventory item associated with a vertex.   It is the caller's
 824 *      responsibility to make sure that there are no races between removing
 825 *      inventory from a vertex and simultaneously removing that vertex.
 826*/
 827int
 828hwgraph_inventory_remove(       vertex_hdl_t de,
 829                                int class,
 830                                int type,
 831                                major_t controller,
 832                                minor_t unit,
 833                                int state)
 834{
 835        return(0); /* Just a Stub for IRIX code. */
 836}
 837
 838/*
 839 * Find the canonical name for a given vertex by walking back through
 840 * connectpt's until we hit the hwgraph root vertex (or until we run
 841 * out of buffer space or until something goes wrong).
 842 *
 843 *      COMPATIBILITY FUNCTIONALITY
 844 * Walks back through 'parents', not necessarily the same as connectpts.
 845 *
 846 * Need to resolve the fact that devfs does not return the path from 
 847 * "/" but rather it just stops right before /dev ..
 848 */
 849int
 850hwgraph_vertex_name_get(vertex_hdl_t vhdl, char *buf, uint buflen)
 851{
 852        char *locbuf;
 853        int   pos;
 854
 855        if (buflen < 1)
 856                return(-1);     /* XXX should be GRAPH_BAD_PARAM ? */
 857
 858        locbuf = kmalloc(buflen, GFP_KERNEL);
 859
 860        pos = devfs_generate_path(vhdl, locbuf, buflen);
 861        if (pos < 0) {
 862                kfree(locbuf);
 863                return pos;
 864        }
 865
 866        strcpy(buf, &locbuf[pos]);
 867        kfree(locbuf);
 868        return 0;
 869}
 870
 871/*
 872** vertex_to_name converts a vertex into a canonical name by walking
 873** back through connect points until we hit the hwgraph root (or until
 874** we run out of buffer space).
 875**
 876** Usually returns a pointer to the original buffer, filled in as
 877** appropriate.  If the buffer is too small to hold the entire name,
 878** or if anything goes wrong while determining the name, vertex_to_name
 879** returns "UnknownDevice".
 880*/
 881
 882#define DEVNAME_UNKNOWN "UnknownDevice"
 883
 884char *
 885vertex_to_name(vertex_hdl_t vhdl, char *buf, uint buflen)
 886{
 887        if (hwgraph_vertex_name_get(vhdl, buf, buflen) == GRAPH_SUCCESS)
 888                return(buf);
 889        else
 890                return(DEVNAME_UNKNOWN);
 891}
 892
 893graph_error_t
 894hwgraph_edge_remove(vertex_hdl_t from, char *name, vertex_hdl_t *toptr)
 895{
 896        printk("WARNING: hwgraph_edge_remove NOT supported.\n");
 897        return(GRAPH_ILLEGAL_REQUEST);
 898}
 899
 900graph_error_t
 901hwgraph_vertex_unref(vertex_hdl_t vhdl)
 902{
 903        return(GRAPH_ILLEGAL_REQUEST);
 904}
 905
 906
 907EXPORT_SYMBOL(hwgraph_mk_dir);
 908EXPORT_SYMBOL(hwgraph_path_add);
 909EXPORT_SYMBOL(hwgraph_register);
 910EXPORT_SYMBOL(hwgraph_vertex_destroy);
 911EXPORT_SYMBOL(hwgraph_fastinfo_get);
 912EXPORT_SYMBOL(hwgraph_fastinfo_set);
 913EXPORT_SYMBOL(hwgraph_connectpt_set);
 914EXPORT_SYMBOL(hwgraph_connectpt_get);
 915EXPORT_SYMBOL(hwgraph_info_add_LBL);
 916EXPORT_SYMBOL(hwgraph_info_remove_LBL);
 917EXPORT_SYMBOL(hwgraph_info_replace_LBL);
 918EXPORT_SYMBOL(hwgraph_info_get_LBL);
 919EXPORT_SYMBOL(hwgraph_info_get_exported_LBL);
 920EXPORT_SYMBOL(hwgraph_info_get_next_LBL);
 921EXPORT_SYMBOL(hwgraph_info_export_LBL);
 922EXPORT_SYMBOL(hwgraph_info_unexport_LBL);
 923EXPORT_SYMBOL(hwgraph_path_lookup);
 924EXPORT_SYMBOL(hwgraph_traverse);
 925EXPORT_SYMBOL(hwgraph_vertex_name_get);
 926
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.