/* * scdrv_init * * Called at boot time to initialize the system controller communication * facility. */ int __init scdrv_init(void) { geoid_t geoid; cnodeid_t cnode; char devname[32]; char *devnamep; struct sysctl_data_s *scd; void *salbuf; dev_t first_dev, dev; nasid_t event_nasid = ia64_sn_get_console_nasid(); if (alloc_chrdev_region(&first_dev, 0, numionodes, SYSCTL_BASENAME) < 0) { printk("%s: failed to register SN system controller device\n", __FUNCTION__); return -ENODEV; } snsc_class = class_create(THIS_MODULE, SYSCTL_BASENAME); for (cnode = 0; cnode < numionodes; cnode++) { geoid = cnodeid_get_geoid(cnode); devnamep = devname; format_module_id(devnamep, geo_module(geoid), MODULE_FORMAT_BRIEF); devnamep = devname + strlen(devname); sprintf(devnamep, "#%d", geo_slab(geoid)); /* allocate sysctl device data */ scd = kmalloc(sizeof (struct sysctl_data_s), GFP_KERNEL); if (!scd) { printk("%s: failed to allocate device info" "for %s/%s\n", __FUNCTION__, SYSCTL_BASENAME, devname); continue; } memset(scd, 0, sizeof (struct sysctl_data_s)); /* initialize sysctl device data fields */ scd->scd_nasid = cnodeid_to_nasid(cnode); if (!(salbuf = kmalloc(SCDRV_BUFSZ, GFP_KERNEL))) { printk("%s: failed to allocate driver buffer" "(%s%s)\n", __FUNCTION__, SYSCTL_BASENAME, devname); kfree(scd); continue; } if (ia64_sn_irtr_init(scd->scd_nasid, salbuf, SCDRV_BUFSZ) < 0) { printk ("%s: failed to initialize SAL for" " system controller communication" " (%s/%s): outdated PROM?\n", __FUNCTION__, SYSCTL_BASENAME, devname); kfree(scd); kfree(salbuf); continue; } dev = first_dev + cnode; cdev_init(&scd->scd_cdev, &scdrv_fops); if (cdev_add(&scd->scd_cdev, dev, 1)) { printk("%s: failed to register system" " controller device (%s%s)\n", __FUNCTION__, SYSCTL_BASENAME, devname); kfree(scd); kfree(salbuf); continue; } class_device_create(snsc_class, dev, NULL, "%s", devname); ia64_sn_irtr_intr_enable(scd->scd_nasid, 0 /*ignored */ , SAL_IROUTER_INTR_RECV); /* on the console nasid, prepare to receive * system controller environmental events */ if(scd->scd_nasid == event_nasid) { scdrv_event_init(scd); } } return 0; }
/* * scdrv_init * * Called at boot time to initialize the system controller communication * facility. */ int __init scdrv_init(void) { geoid_t geoid; cmoduleid_t cmod; int i; char devname[32]; char *devnamep; module_t *m; struct sysctl_data_s *scd; void *salbuf; struct class_simple *snsc_class; dev_t first_dev, dev; if (alloc_chrdev_region(&first_dev, 0, (MAX_SLABS*nummodules), SYSCTL_BASENAME) < 0) { printk("%s: failed to register SN system controller device\n", __FUNCTION__); return -ENODEV; } snsc_class = class_simple_create(THIS_MODULE, SYSCTL_BASENAME); for (cmod = 0; cmod < nummodules; cmod++) { m = sn_modules[cmod]; for (i = 0; i <= MAX_SLABS; i++) { if (m->nodes[i] == -1) { /* node is not alive in module */ continue; } geoid = m->geoid[i]; devnamep = devname; format_module_id(devnamep, geo_module(geoid), MODULE_FORMAT_BRIEF); devnamep = devname + strlen(devname); sprintf(devnamep, "#%d", geo_slab(geoid)); /* allocate sysctl device data */ scd = kmalloc(sizeof (struct sysctl_data_s), GFP_KERNEL); if (!scd) { printk("%s: failed to allocate device info" "for %s/%s\n", __FUNCTION__, SYSCTL_BASENAME, devname); continue; } memset(scd, 0, sizeof (struct sysctl_data_s)); /* initialize sysctl device data fields */ scd->scd_nasid = cnodeid_to_nasid(m->nodes[i]); if (!(salbuf = kmalloc(SCDRV_BUFSZ, GFP_KERNEL))) { printk("%s: failed to allocate driver buffer" "(%s%s)\n", __FUNCTION__, SYSCTL_BASENAME, devname); kfree(scd); continue; } if (ia64_sn_irtr_init(scd->scd_nasid, salbuf, SCDRV_BUFSZ) < 0) { printk ("%s: failed to initialize SAL for" " system controller communication" " (%s/%s): outdated PROM?\n", __FUNCTION__, SYSCTL_BASENAME, devname); kfree(scd); kfree(salbuf); continue; } dev = first_dev + m->nodes[i]; cdev_init(&scd->scd_cdev, &scdrv_fops); if (cdev_add(&scd->scd_cdev, dev, 1)) { printk("%s: failed to register system" " controller device (%s%s)\n", __FUNCTION__, SYSCTL_BASENAME, devname); kfree(scd); kfree(salbuf); continue; } class_simple_device_add(snsc_class, dev, NULL, "%s", devname); ia64_sn_irtr_intr_enable(scd->scd_nasid, 0 /*ignored */ , SAL_IROUTER_INTR_RECV); } } return 0; }