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
6 * ioconfig_bus - SGI's Persistent PCI Bus Numbering.
8 * Copyright (C) 1992-1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
11 #include <linux/types.h>
12 #include <linux/slab.h>
13 #include <linux/ctype.h>
14 #include <linux/module.h>
15 #include <linux/init.h>
17 #include <linux/pci.h>
19 #include <asm/sn/sgi.h>
20 #include <asm/uaccess.h>
22 #include <linux/devfs_fs.h>
23 #include <linux/devfs_fs_kernel.h>
25 #include <asm/sn/iograph.h>
26 #include <asm/sn/invent.h>
27 #include <asm/sn/hcl.h>
28 #include <asm/sn/labelcl.h>
29 #include <asm//sn/sn_sal.h>
30 #include <asm/sn/addrs.h>
31 #include <asm/sn/ioconfig_bus.h>
33 #define SGI_IOCONFIG_BUS "SGI-PERSISTENT PCI BUS NUMBERING"
34 #define SGI_IOCONFIG_BUS_VERSION "1.0"
37 * Some Global definitions.
39 static vertex_hdl_t ioconfig_bus_handle;
40 static unsigned long ioconfig_bus_debug;
41 static struct ioconfig_parm parm;
43 #ifdef IOCONFIG_BUS_DEBUG
44 #define DBG(x...) printk(x)
49 static u64 ioconfig_file;
50 static u64 ioconfig_file_size;
51 static u64 ioconfig_activated;
52 static char ioconfig_kernopts[128];
55 * For debugging purpose .. hardcode a table ..
57 struct ascii_moduleid *ioconfig_bus_table;
58 u64 ioconfig_bus_table_size;
61 static int free_entry;
64 int next_basebus_number;
67 ioconfig_get_busnum(char *io_moduleid, int *bus_num)
69 struct ascii_moduleid *temp;
72 DBG("ioconfig_get_busnum io_moduleid %s\n", io_moduleid);
75 temp = ioconfig_bus_table;
76 for (index = 0; index < free_entry; temp++, index++) {
77 if ( (io_moduleid[0] == temp->io_moduleid[0]) &&
78 (io_moduleid[1] == temp->io_moduleid[1]) &&
79 (io_moduleid[2] == temp->io_moduleid[2]) &&
80 (io_moduleid[4] == temp->io_moduleid[4]) &&
81 (io_moduleid[5] == temp->io_moduleid[5]) ) {
82 *bus_num = index * 0x10;
88 * New IO Brick encountered.
90 if (((int)io_moduleid[0]) == 0) {
91 DBG("ioconfig_get_busnum: Invalid Module Id given %s\n", io_moduleid);
96 strcpy((char *)&(ioconfig_bus_table[free_entry].io_moduleid), io_moduleid);
97 *bus_num = free_entry * 0x10;
102 dump_ioconfig_table(void)
106 struct ascii_moduleid *temp;
108 temp = ioconfig_bus_table;
109 while (index < free_entry) {
110 DBG("ASSCI Module ID %s\n", temp->io_moduleid);
118 * This routine returns the nextline in the buffer.
120 int nextline(char *buffer, char **next, char *line)
125 if (buffer[0] == 0x0) {
149 * This routine parses the ioconfig contents read into
150 * memory by ioconfig command in EFI and builds the
151 * persistent pci bus naming table.
154 build_moduleid_table(char *file_contents, struct ascii_moduleid *table)
157 * Read the whole file into memory.
165 struct ascii_moduleid *moduleid;
167 line = kmalloc(256, GFP_KERNEL);
169 BUG(); /* Do not want to continue system boot .. */
171 name = kmalloc(125, GFP_KERNEL);
173 BUG(); /* Do not want to continue system boot .. */
175 memset(name, 0, 125);
177 current = file_contents;
178 while (nextline(current, &next, line)){
180 DBG("current 0x%lx next 0x%lx\n", current, next);
184 * Skip all leading Blank lines ..
186 while (isspace(*temp))
194 memset(line, 0, 256);
203 memset(line, 0, 256);
208 * Get the next free entry in the table.
210 rc = sscanf(temp, "%s", name);
211 strcpy(&moduleid->io_moduleid[0], name);
212 DBG("Found %s\n", name);
216 memset(line, 0, 256);
219 new_entry = free_entry;
227 ioconfig_bus_init(void)
230 struct ia64_sal_retval ret_stuff;
234 DBG("ioconfig_bus_init called.\n");
236 for (cnode = 0; cnode < numnodes; cnode++) {
239 * Make SAL call to get the address of the bus configuration table.
241 ret_stuff.status = (uint64_t)0;
242 ret_stuff.v0 = (uint64_t)0;
243 ret_stuff.v1 = (uint64_t)0;
244 ret_stuff.v2 = (uint64_t)0;
245 nasid = COMPACT_TO_NASID_NODEID(cnode);
246 SAL_CALL(ret_stuff, SN_SAL_BUS_CONFIG, 0, nasid, 0, 0, 0, 0, 0);
247 temp = (u64 *)TO_NODE_CAC(nasid, ret_stuff.v0);
248 ioconfig_file = *temp;
249 DBG("ioconfig_bus_init: Nasid %d ret_stuff.v0 0x%lx\n", nasid,
252 ioconfig_file_size = ret_stuff.v1;
253 ioconfig_file = (ioconfig_file | CACHEABLE_MEM_SPACE);
254 ioconfig_activated = 1;
259 DBG("ioconfig_bus_init: ret_stuff.v0 %p ioconfig_file %p %d\n",
260 ret_stuff.v0, (void *)ioconfig_file, (int)ioconfig_file_size);
262 ioconfig_bus_table = kmalloc( 512, GFP_KERNEL );
263 if (ioconfig_bus_table <= 0)
264 BUG(); /* Seriously, we should not be out of memory at init */
266 memset(ioconfig_bus_table, 0, 512);
269 * If ioconfig options are given on the bootline .. take it.
271 if (*ioconfig_kernopts != '\0') {
273 * ioconfig="..." kernel options given.
275 DBG("ioconfig_bus_init: Kernel Options given.\n");
276 (void) build_moduleid_table((char *)ioconfig_kernopts, ioconfig_bus_table);
277 (void) dump_ioconfig_table();
280 if (ioconfig_activated) {
281 DBG("ioconfig_bus_init: ioconfig file given.\n");
282 (void) build_moduleid_table((char *)ioconfig_file, ioconfig_bus_table);
283 (void) dump_ioconfig_table();
285 DBG("ioconfig_bus_init: ioconfig command not executed in prom\n");
291 ioconfig_bus_new_entries(void)
296 struct ascii_moduleid *temp;
298 if ((ioconfig_activated) && (free_entry > new_entry)) {
299 printk("### Please add the following new IO Bricks Module ID \n");
300 printk("### to your Persistent Bus Numbering Config File\n");
305 temp = &ioconfig_bus_table[index];
306 while (index < free_entry) {
307 printk("%s\n", (char *)temp);
314 static int ioconfig_bus_ioctl(struct inode * inode, struct file * file,
315 unsigned int cmd, unsigned long arg)
320 * Copy in the parameters.
322 length = copy_from_user(&parm, (char *)arg, sizeof(struct ioconfig_parm));
325 parm.number = free_entry - new_entry;
326 parm.ioconfig_activated = ioconfig_activated;
327 if (copy_to_user((char *)arg, &parm, sizeof(struct ioconfig_parm)))
330 if (copy_to_user((char *)parm.buffer, &ioconfig_bus_table[new_entry], sizeof(struct ascii_moduleid) * (free_entry - new_entry)))
337 * ioconfig_bus_open - Opens the special device node "/dev/hw/.ioconfig_bus".
339 static int ioconfig_bus_open(struct inode * inode, struct file * filp)
341 if (ioconfig_bus_debug) {
342 DBG("ioconfig_bus_open called.\n");
350 * ioconfig_bus_close - Closes the special device node "/dev/hw/.ioconfig_bus".
352 static int ioconfig_bus_close(struct inode * inode, struct file * filp)
355 if (ioconfig_bus_debug) {
356 DBG("ioconfig_bus_close called.\n");
362 struct file_operations ioconfig_bus_fops = {
363 ioctl:ioconfig_bus_ioctl,
364 open:ioconfig_bus_open, /* open */
365 release:ioconfig_bus_close /* release */
370 * init_ifconfig_bus() - Boot time initialization. Ensure that it is called
371 * after devfs has been initialized.
374 int init_ioconfig_bus(void)
376 ioconfig_bus_handle = NULL;
377 ioconfig_bus_handle = hwgraph_register(hwgraph_root, ".ioconfig_bus",
378 0, DEVFS_FL_AUTO_DEVNUM,
380 S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
381 &ioconfig_bus_fops, NULL);
383 if (ioconfig_bus_handle == NULL) {
384 panic("Unable to create SGI PERSISTENT BUS NUMBERING Driver.\n");
391 static int __init ioconfig_bus_setup (char *str)
396 DBG("ioconfig_bus_setup: Kernel Options %s\n", str);
398 temp = (char *)ioconfig_kernopts;
399 memset(temp, 0, 128);
400 while ( (*str != '\0') && !isspace (*str) ) {
415 __setup("ioconfig=", ioconfig_bus_setup);