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