162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Procfs interface for the Zorro bus. 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 1998-2003 Geert Uytterhoeven 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Heavily based on the procfs interface for the PCI bus, which is 862306a36Sopenharmony_ci * 962306a36Sopenharmony_ci * Copyright (C) 1997, 1998 Martin Mares <mj@atrey.karlin.mff.cuni.cz> 1062306a36Sopenharmony_ci */ 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#include <linux/types.h> 1362306a36Sopenharmony_ci#include <linux/zorro.h> 1462306a36Sopenharmony_ci#include <linux/proc_fs.h> 1562306a36Sopenharmony_ci#include <linux/seq_file.h> 1662306a36Sopenharmony_ci#include <linux/init.h> 1762306a36Sopenharmony_ci#include <linux/export.h> 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci#include <asm/byteorder.h> 2062306a36Sopenharmony_ci#include <linux/uaccess.h> 2162306a36Sopenharmony_ci#include <asm/amigahw.h> 2262306a36Sopenharmony_ci#include <asm/setup.h> 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_cistatic loff_t 2562306a36Sopenharmony_ciproc_bus_zorro_lseek(struct file *file, loff_t off, int whence) 2662306a36Sopenharmony_ci{ 2762306a36Sopenharmony_ci return fixed_size_llseek(file, off, whence, sizeof(struct ConfigDev)); 2862306a36Sopenharmony_ci} 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_cistatic ssize_t 3162306a36Sopenharmony_ciproc_bus_zorro_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos) 3262306a36Sopenharmony_ci{ 3362306a36Sopenharmony_ci struct zorro_dev *z = pde_data(file_inode(file)); 3462306a36Sopenharmony_ci struct ConfigDev cd; 3562306a36Sopenharmony_ci loff_t pos = *ppos; 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci if (pos >= sizeof(struct ConfigDev)) 3862306a36Sopenharmony_ci return 0; 3962306a36Sopenharmony_ci if (nbytes >= sizeof(struct ConfigDev)) 4062306a36Sopenharmony_ci nbytes = sizeof(struct ConfigDev); 4162306a36Sopenharmony_ci if (pos + nbytes > sizeof(struct ConfigDev)) 4262306a36Sopenharmony_ci nbytes = sizeof(struct ConfigDev) - pos; 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci /* Construct a ConfigDev */ 4562306a36Sopenharmony_ci memset(&cd, 0, sizeof(cd)); 4662306a36Sopenharmony_ci cd.cd_Rom = z->rom; 4762306a36Sopenharmony_ci cd.cd_SlotAddr = cpu_to_be16(z->slotaddr); 4862306a36Sopenharmony_ci cd.cd_SlotSize = cpu_to_be16(z->slotsize); 4962306a36Sopenharmony_ci cd.cd_BoardAddr = cpu_to_be32(zorro_resource_start(z)); 5062306a36Sopenharmony_ci cd.cd_BoardSize = cpu_to_be32(zorro_resource_len(z)); 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci if (copy_to_user(buf, (void *)&cd + pos, nbytes)) 5362306a36Sopenharmony_ci return -EFAULT; 5462306a36Sopenharmony_ci *ppos += nbytes; 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci return nbytes; 5762306a36Sopenharmony_ci} 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_cistatic const struct proc_ops bus_zorro_proc_ops = { 6062306a36Sopenharmony_ci .proc_lseek = proc_bus_zorro_lseek, 6162306a36Sopenharmony_ci .proc_read = proc_bus_zorro_read, 6262306a36Sopenharmony_ci}; 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_cistatic void * zorro_seq_start(struct seq_file *m, loff_t *pos) 6562306a36Sopenharmony_ci{ 6662306a36Sopenharmony_ci return (*pos < zorro_num_autocon) ? pos : NULL; 6762306a36Sopenharmony_ci} 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_cistatic void * zorro_seq_next(struct seq_file *m, void *v, loff_t *pos) 7062306a36Sopenharmony_ci{ 7162306a36Sopenharmony_ci (*pos)++; 7262306a36Sopenharmony_ci return (*pos < zorro_num_autocon) ? pos : NULL; 7362306a36Sopenharmony_ci} 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_cistatic void zorro_seq_stop(struct seq_file *m, void *v) 7662306a36Sopenharmony_ci{ 7762306a36Sopenharmony_ci} 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_cistatic int zorro_seq_show(struct seq_file *m, void *v) 8062306a36Sopenharmony_ci{ 8162306a36Sopenharmony_ci unsigned int slot = *(loff_t *)v; 8262306a36Sopenharmony_ci struct zorro_dev *z = &zorro_autocon[slot]; 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci seq_printf(m, "%02x\t%08x\t%08lx\t%08lx\t%02x\n", slot, z->id, 8562306a36Sopenharmony_ci (unsigned long)zorro_resource_start(z), 8662306a36Sopenharmony_ci (unsigned long)zorro_resource_len(z), 8762306a36Sopenharmony_ci z->rom.er_Type); 8862306a36Sopenharmony_ci return 0; 8962306a36Sopenharmony_ci} 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_cistatic const struct seq_operations zorro_devices_seq_ops = { 9262306a36Sopenharmony_ci .start = zorro_seq_start, 9362306a36Sopenharmony_ci .next = zorro_seq_next, 9462306a36Sopenharmony_ci .stop = zorro_seq_stop, 9562306a36Sopenharmony_ci .show = zorro_seq_show, 9662306a36Sopenharmony_ci}; 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_cistatic struct proc_dir_entry *proc_bus_zorro_dir; 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_cistatic int __init zorro_proc_attach_device(unsigned int slot) 10162306a36Sopenharmony_ci{ 10262306a36Sopenharmony_ci struct proc_dir_entry *entry; 10362306a36Sopenharmony_ci char name[4]; 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci sprintf(name, "%02x", slot); 10662306a36Sopenharmony_ci entry = proc_create_data(name, 0, proc_bus_zorro_dir, 10762306a36Sopenharmony_ci &bus_zorro_proc_ops, 10862306a36Sopenharmony_ci &zorro_autocon[slot]); 10962306a36Sopenharmony_ci if (!entry) 11062306a36Sopenharmony_ci return -ENOMEM; 11162306a36Sopenharmony_ci proc_set_size(entry, sizeof(struct zorro_dev)); 11262306a36Sopenharmony_ci return 0; 11362306a36Sopenharmony_ci} 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_cistatic int __init zorro_proc_init(void) 11662306a36Sopenharmony_ci{ 11762306a36Sopenharmony_ci unsigned int slot; 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci if (MACH_IS_AMIGA && AMIGAHW_PRESENT(ZORRO)) { 12062306a36Sopenharmony_ci proc_bus_zorro_dir = proc_mkdir("bus/zorro", NULL); 12162306a36Sopenharmony_ci proc_create_seq("devices", 0, proc_bus_zorro_dir, 12262306a36Sopenharmony_ci &zorro_devices_seq_ops); 12362306a36Sopenharmony_ci for (slot = 0; slot < zorro_num_autocon; slot++) 12462306a36Sopenharmony_ci zorro_proc_attach_device(slot); 12562306a36Sopenharmony_ci } 12662306a36Sopenharmony_ci return 0; 12762306a36Sopenharmony_ci} 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_cidevice_initcall(zorro_proc_init); 130