/*
  *
- * linux/drivers/s390/net/qeth_fs.c ($Revision: 1.13 $)
+ * linux/drivers/s390/net/qeth_fs.c ($Revision: 1.16 $)
  *
  * Linux on zSeries OSA Express and HiperSockets support
  * This file contains code related to procfs.
 #include "qeth_mpc.h"
 #include "qeth_fs.h"
 
-const char *VERSION_QETH_PROC_C = "$Revision: 1.13 $";
+const char *VERSION_QETH_PROC_C = "$Revision: 1.16 $";
 
 /***** /proc/qeth *****/
 #define QETH_PROCFILE_NAME "qeth"
 static int
 qeth_procfile_seq_match(struct device *dev, void *data)
 {
-       return 1;
+       return(dev ? 1 : 0);
 }
 
 static void *
 qeth_procfile_seq_start(struct seq_file *s, loff_t *offset)
 {
-       struct device *dev;
-       loff_t nr;
-
+       struct device *dev = NULL;
+       loff_t nr = 0;
+       
        down_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem);
-
-       nr = *offset;
-       if (nr == 0)
+       if (*offset == 0)
                return SEQ_START_TOKEN;
-
-       dev = driver_find_device(&qeth_ccwgroup_driver.driver, NULL,
-                                NULL, qeth_procfile_seq_match);
-
-       /* get card at pos *offset */
-       nr = *offset;
-       while (nr-- > 1 && dev)
+       while (1) {
                dev = driver_find_device(&qeth_ccwgroup_driver.driver, dev,
                                         NULL, qeth_procfile_seq_match);
-       return (void *) dev;
+               if (++nr == *offset)
+                       break;
+               put_device(dev);
+       }
+       return dev;
 }
 
 static void
 qeth_procfile_seq_next(struct seq_file *s, void *it, loff_t *offset)
 {
        struct device *prev, *next;
-
-       if (it == SEQ_START_TOKEN) {
-               next = driver_find_device(&qeth_ccwgroup_driver.driver,
-                                         NULL, NULL, qeth_procfile_seq_match);
-               if (next)
-                       (*offset)++;
-               return (void *) next;
-       }
-       prev = (struct device *) it;
+       
+       if (it == SEQ_START_TOKEN) 
+               prev = NULL;
+       else
+               prev = (struct device *) it;
        next = driver_find_device(&qeth_ccwgroup_driver.driver,
                                  prev, NULL, qeth_procfile_seq_match);
-       if (next)
-               (*offset)++;
+       (*offset)++;
        return (void *) next;
 }
 
 {
        int routing_type = 0;
 
-       if (ipv == 4){
+       if (ipv == 4) {
                routing_type = card->options.route4.type;
        } else {
 #ifdef CONFIG_QETH_IPV6
                                        card->qdio.in_buf_pool.buf_count);
                else
                        seq_printf(s, "  +++ LAN OFFLINE +++\n");
+               put_device(device);
        }
        return 0;
 }
 static struct proc_dir_entry *qeth_perf_procfile;
 
 #ifdef CONFIG_QETH_PERF_STATS
-
-static void *
-qeth_perf_procfile_seq_start(struct seq_file *s, loff_t *offset)
-{
-       struct device *dev = NULL;
-       int nr;
-
-       down_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem);
-       /* get card at pos *offset */
-       dev = driver_find_device(&qeth_ccwgroup_driver.driver, NULL, NULL,
-                                qeth_procfile_seq_match);
-
-       /* get card at pos *offset */
-       nr = *offset;
-       while (nr-- > 1 && dev)
-               dev = driver_find_device(&qeth_ccwgroup_driver.driver, dev,
-                                        NULL, qeth_procfile_seq_match);
-       return (void *) dev;
-}
-
-static void
-qeth_perf_procfile_seq_stop(struct seq_file *s, void* it)
-{
-       up_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem);
-}
-
-static void *
-qeth_perf_procfile_seq_next(struct seq_file *s, void *it, loff_t *offset)
-{
-       struct device *prev, *next;
-
-       prev = (struct device *) it;
-       next = driver_find_device(&qeth_ccwgroup_driver.driver, prev,
-                                 NULL, qeth_procfile_seq_match);
-       if (next)
-               (*offset)++;
-       return (void *) next;
-}
-
 static int
 qeth_perf_procfile_seq_show(struct seq_file *s, void *it)
 {
        struct device *device;
        struct qeth_card *card;
 
+       
+       if (it == SEQ_START_TOKEN)
+               return 0;
+
        device = (struct device *) it;
        card = device->driver_data;
        seq_printf(s, "For card with devnos %s/%s/%s (%s):\n",
                        card->perf_stats.outbound_do_qdio_time,
                        card->perf_stats.outbound_do_qdio_cnt
                  );
+       put_device(device);
        return 0;
 }
 
 static struct seq_operations qeth_perf_procfile_seq_ops = {
-       .start = qeth_perf_procfile_seq_start,
-       .stop  = qeth_perf_procfile_seq_stop,
-       .next  = qeth_perf_procfile_seq_next,
+       .start = qeth_procfile_seq_start,
+       .stop  = qeth_procfile_seq_stop,
+       .next  = qeth_procfile_seq_next,
        .show  = qeth_perf_procfile_seq_show,
 };
 
 #define qeth_perf_procfile_created 1
 #endif /* CONFIG_QETH_PERF_STATS */
 
-/***** /proc/qeth_ipa_takeover *****/
-#define QETH_IPATO_PROCFILE_NAME "qeth_ipa_takeover"
-static struct proc_dir_entry *qeth_ipato_procfile;
-
-static void *
-qeth_ipato_procfile_seq_start(struct seq_file *s, loff_t *offset)
-{
-       struct device *dev;
-       loff_t nr;
-
-       down_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem);
-       /* TODO: finish this */
-       /*
-        * maybe SEQ_SATRT_TOKEN can be returned for offset 0
-        * output driver settings then;
-        * else output setting for respective card
-        */
-
-       dev = driver_find_device(&qeth_ccwgroup_driver.driver, NULL, NULL,
-                                qeth_procfile_seq_match);
-
-       /* get card at pos *offset */
-       nr = *offset;
-       while (nr-- > 1 && dev)
-               dev = driver_find_device(&qeth_ccwgroup_driver.driver, dev,
-                                        NULL, qeth_procfile_seq_match);
-       return (void *) dev;
-}
-
-static void
-qeth_ipato_procfile_seq_stop(struct seq_file *s, void* it)
-{
-       up_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem);
-}
-
-static void *
-qeth_ipato_procfile_seq_next(struct seq_file *s, void *it, loff_t *offset)
-{
-       struct device *prev, *next;
-
-       prev = (struct device *) it;
-       next = driver_find_device(&qeth_ccwgroup_driver.driver, prev,
-                                 NULL, qeth_procfile_seq_match);
-       if (next)
-               (*offset)++;
-       return (void *) next;
-}
-
-static int
-qeth_ipato_procfile_seq_show(struct seq_file *s, void *it)
-{
-       struct device *device;
-       struct qeth_card *card;
-
-       /* TODO: finish this */
-       /*
-        * maybe SEQ_SATRT_TOKEN can be returned for offset 0
-        * output driver settings then;
-        * else output setting for respective card
-        */
-       device = (struct device *) it;
-       card = device->driver_data;
-
-       return 0;
-}
-
-static struct seq_operations qeth_ipato_procfile_seq_ops = {
-       .start = qeth_ipato_procfile_seq_start,
-       .stop  = qeth_ipato_procfile_seq_stop,
-       .next  = qeth_ipato_procfile_seq_next,
-       .show  = qeth_ipato_procfile_seq_show,
-};
-
-static int
-qeth_ipato_procfile_open(struct inode *inode, struct file *file)
-{
-       return seq_open(file, &qeth_ipato_procfile_seq_ops);
-}
-
-static struct file_operations qeth_ipato_procfile_fops = {
-       .owner   = THIS_MODULE,
-       .open    = qeth_ipato_procfile_open,
-       .read    = seq_read,
-       .llseek  = seq_lseek,
-       .release = seq_release,
-};
-
 int __init
 qeth_create_procfs_entries(void)
 {
                qeth_perf_procfile->proc_fops = &qeth_perf_procfile_fops;
 #endif /* CONFIG_QETH_PERF_STATS */
 
-       qeth_ipato_procfile = create_proc_entry(QETH_IPATO_PROCFILE_NAME,
-                                          S_IFREG | 0444, NULL);
-       if (qeth_ipato_procfile)
-               qeth_ipato_procfile->proc_fops = &qeth_ipato_procfile_fops;
-
        if (qeth_procfile &&
-           qeth_ipato_procfile &&
            qeth_perf_procfile_created)
                return 0;
        else
                remove_proc_entry(QETH_PROCFILE_NAME, NULL);
        if (qeth_perf_procfile)
                remove_proc_entry(QETH_PERF_PROCFILE_NAME, NULL);
-       if (qeth_ipato_procfile)
-               remove_proc_entry(QETH_IPATO_PROCFILE_NAME, NULL);
 }
 
-
-/* ONLY FOR DEVELOPMENT! -> make it as module */
-/*
-static void
-qeth_create_sysfs_entries(void)
-{
-       struct device *dev;
-
-       down_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem);
-
-       list_for_each_entry(dev, &qeth_ccwgroup_driver.driver.devices,
-                       driver_list)
-               qeth_create_device_attributes(dev);
-
-       up_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem);
-}
-
-static void
-qeth_remove_sysfs_entries(void)
-{
-       struct device *dev;
-
-       down_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem);
-
-       list_for_each_entry(dev, &qeth_ccwgroup_driver.driver.devices,
-                       driver_list)
-               qeth_remove_device_attributes(dev);
-
-       up_read(&qeth_ccwgroup_driver.driver.bus->subsys.rwsem);
-}
-
-static int __init
-qeth_fs_init(void)
-{
-       printk(KERN_INFO "qeth_fs_init\n");
-       qeth_create_procfs_entries();
-       qeth_create_sysfs_entries();
-
-       return 0;
-}
-
-static void __exit
-qeth_fs_exit(void)
-{
-       printk(KERN_INFO "qeth_fs_exit\n");
-       qeth_remove_procfs_entries();
-       qeth_remove_sysfs_entries();
-}
-
-
-module_init(qeth_fs_init);
-module_exit(qeth_fs_exit);
-
-MODULE_LICENSE("GPL");
-*/