Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v2.6.39-rc7 466 lines 11 kB view raw
1/* 2 * SN Platform system controller communication support 3 * 4 * This file is subject to the terms and conditions of the GNU General Public 5 * License. See the file "COPYING" in the main directory of this archive 6 * for more details. 7 * 8 * Copyright (C) 2004, 2006 Silicon Graphics, Inc. All rights reserved. 9 */ 10 11/* 12 * System controller communication driver 13 * 14 * This driver allows a user process to communicate with the system 15 * controller (a.k.a. "IRouter") network in an SGI SN system. 16 */ 17 18#include <linux/interrupt.h> 19#include <linux/sched.h> 20#include <linux/device.h> 21#include <linux/poll.h> 22#include <linux/module.h> 23#include <linux/slab.h> 24#include <linux/mutex.h> 25#include <asm/sn/io.h> 26#include <asm/sn/sn_sal.h> 27#include <asm/sn/module.h> 28#include <asm/sn/geo.h> 29#include <asm/sn/nodepda.h> 30#include "snsc.h" 31 32#define SYSCTL_BASENAME "snsc" 33 34#define SCDRV_BUFSZ 2048 35#define SCDRV_TIMEOUT 1000 36 37static DEFINE_MUTEX(scdrv_mutex); 38static irqreturn_t 39scdrv_interrupt(int irq, void *subch_data) 40{ 41 struct subch_data_s *sd = subch_data; 42 unsigned long flags; 43 int status; 44 45 spin_lock_irqsave(&sd->sd_rlock, flags); 46 spin_lock(&sd->sd_wlock); 47 status = ia64_sn_irtr_intr(sd->sd_nasid, sd->sd_subch); 48 49 if (status > 0) { 50 if (status & SAL_IROUTER_INTR_RECV) { 51 wake_up(&sd->sd_rq); 52 } 53 if (status & SAL_IROUTER_INTR_XMIT) { 54 ia64_sn_irtr_intr_disable 55 (sd->sd_nasid, sd->sd_subch, 56 SAL_IROUTER_INTR_XMIT); 57 wake_up(&sd->sd_wq); 58 } 59 } 60 spin_unlock(&sd->sd_wlock); 61 spin_unlock_irqrestore(&sd->sd_rlock, flags); 62 return IRQ_HANDLED; 63} 64 65/* 66 * scdrv_open 67 * 68 * Reserve a subchannel for system controller communication. 69 */ 70 71static int 72scdrv_open(struct inode *inode, struct file *file) 73{ 74 struct sysctl_data_s *scd; 75 struct subch_data_s *sd; 76 int rv; 77 78 /* look up device info for this device file */ 79 scd = container_of(inode->i_cdev, struct sysctl_data_s, scd_cdev); 80 81 /* allocate memory for subchannel data */ 82 sd = kzalloc(sizeof (struct subch_data_s), GFP_KERNEL); 83 if (sd == NULL) { 84 printk("%s: couldn't allocate subchannel data\n", 85 __func__); 86 return -ENOMEM; 87 } 88 89 /* initialize subch_data_s fields */ 90 sd->sd_nasid = scd->scd_nasid; 91 sd->sd_subch = ia64_sn_irtr_open(scd->scd_nasid); 92 93 if (sd->sd_subch < 0) { 94 kfree(sd); 95 printk("%s: couldn't allocate subchannel\n", __func__); 96 return -EBUSY; 97 } 98 99 spin_lock_init(&sd->sd_rlock); 100 spin_lock_init(&sd->sd_wlock); 101 init_waitqueue_head(&sd->sd_rq); 102 init_waitqueue_head(&sd->sd_wq); 103 sema_init(&sd->sd_rbs, 1); 104 sema_init(&sd->sd_wbs, 1); 105 106 file->private_data = sd; 107 108 /* hook this subchannel up to the system controller interrupt */ 109 mutex_lock(&scdrv_mutex); 110 rv = request_irq(SGI_UART_VECTOR, scdrv_interrupt, 111 IRQF_SHARED | IRQF_DISABLED, 112 SYSCTL_BASENAME, sd); 113 if (rv) { 114 ia64_sn_irtr_close(sd->sd_nasid, sd->sd_subch); 115 kfree(sd); 116 printk("%s: irq request failed (%d)\n", __func__, rv); 117 mutex_unlock(&scdrv_mutex); 118 return -EBUSY; 119 } 120 mutex_unlock(&scdrv_mutex); 121 return 0; 122} 123 124/* 125 * scdrv_release 126 * 127 * Release a previously-reserved subchannel. 128 */ 129 130static int 131scdrv_release(struct inode *inode, struct file *file) 132{ 133 struct subch_data_s *sd = (struct subch_data_s *) file->private_data; 134 int rv; 135 136 /* free the interrupt */ 137 free_irq(SGI_UART_VECTOR, sd); 138 139 /* ask SAL to close the subchannel */ 140 rv = ia64_sn_irtr_close(sd->sd_nasid, sd->sd_subch); 141 142 kfree(sd); 143 return rv; 144} 145 146/* 147 * scdrv_read 148 * 149 * Called to read bytes from the open IRouter pipe. 150 * 151 */ 152 153static inline int 154read_status_check(struct subch_data_s *sd, int *len) 155{ 156 return ia64_sn_irtr_recv(sd->sd_nasid, sd->sd_subch, sd->sd_rb, len); 157} 158 159static ssize_t 160scdrv_read(struct file *file, char __user *buf, size_t count, loff_t *f_pos) 161{ 162 int status; 163 int len; 164 unsigned long flags; 165 struct subch_data_s *sd = (struct subch_data_s *) file->private_data; 166 167 /* try to get control of the read buffer */ 168 if (down_trylock(&sd->sd_rbs)) { 169 /* somebody else has it now; 170 * if we're non-blocking, then exit... 171 */ 172 if (file->f_flags & O_NONBLOCK) { 173 return -EAGAIN; 174 } 175 /* ...or if we want to block, then do so here */ 176 if (down_interruptible(&sd->sd_rbs)) { 177 /* something went wrong with wait */ 178 return -ERESTARTSYS; 179 } 180 } 181 182 /* anything to read? */ 183 len = CHUNKSIZE; 184 spin_lock_irqsave(&sd->sd_rlock, flags); 185 status = read_status_check(sd, &len); 186 187 /* if not, and we're blocking I/O, loop */ 188 while (status < 0) { 189 DECLARE_WAITQUEUE(wait, current); 190 191 if (file->f_flags & O_NONBLOCK) { 192 spin_unlock_irqrestore(&sd->sd_rlock, flags); 193 up(&sd->sd_rbs); 194 return -EAGAIN; 195 } 196 197 len = CHUNKSIZE; 198 set_current_state(TASK_INTERRUPTIBLE); 199 add_wait_queue(&sd->sd_rq, &wait); 200 spin_unlock_irqrestore(&sd->sd_rlock, flags); 201 202 schedule_timeout(SCDRV_TIMEOUT); 203 204 remove_wait_queue(&sd->sd_rq, &wait); 205 if (signal_pending(current)) { 206 /* wait was interrupted */ 207 up(&sd->sd_rbs); 208 return -ERESTARTSYS; 209 } 210 211 spin_lock_irqsave(&sd->sd_rlock, flags); 212 status = read_status_check(sd, &len); 213 } 214 spin_unlock_irqrestore(&sd->sd_rlock, flags); 215 216 if (len > 0) { 217 /* we read something in the last read_status_check(); copy 218 * it out to user space 219 */ 220 if (count < len) { 221 pr_debug("%s: only accepting %d of %d bytes\n", 222 __func__, (int) count, len); 223 } 224 len = min((int) count, len); 225 if (copy_to_user(buf, sd->sd_rb, len)) 226 len = -EFAULT; 227 } 228 229 /* release the read buffer and wake anyone who might be 230 * waiting for it 231 */ 232 up(&sd->sd_rbs); 233 234 /* return the number of characters read in */ 235 return len; 236} 237 238/* 239 * scdrv_write 240 * 241 * Writes a chunk of an IRouter packet (or other system controller data) 242 * to the system controller. 243 * 244 */ 245static inline int 246write_status_check(struct subch_data_s *sd, int count) 247{ 248 return ia64_sn_irtr_send(sd->sd_nasid, sd->sd_subch, sd->sd_wb, count); 249} 250 251static ssize_t 252scdrv_write(struct file *file, const char __user *buf, 253 size_t count, loff_t *f_pos) 254{ 255 unsigned long flags; 256 int status; 257 struct subch_data_s *sd = (struct subch_data_s *) file->private_data; 258 259 /* try to get control of the write buffer */ 260 if (down_trylock(&sd->sd_wbs)) { 261 /* somebody else has it now; 262 * if we're non-blocking, then exit... 263 */ 264 if (file->f_flags & O_NONBLOCK) { 265 return -EAGAIN; 266 } 267 /* ...or if we want to block, then do so here */ 268 if (down_interruptible(&sd->sd_wbs)) { 269 /* something went wrong with wait */ 270 return -ERESTARTSYS; 271 } 272 } 273 274 count = min((int) count, CHUNKSIZE); 275 if (copy_from_user(sd->sd_wb, buf, count)) { 276 up(&sd->sd_wbs); 277 return -EFAULT; 278 } 279 280 /* try to send the buffer */ 281 spin_lock_irqsave(&sd->sd_wlock, flags); 282 status = write_status_check(sd, count); 283 284 /* if we failed, and we want to block, then loop */ 285 while (status <= 0) { 286 DECLARE_WAITQUEUE(wait, current); 287 288 if (file->f_flags & O_NONBLOCK) { 289 spin_unlock(&sd->sd_wlock); 290 up(&sd->sd_wbs); 291 return -EAGAIN; 292 } 293 294 set_current_state(TASK_INTERRUPTIBLE); 295 add_wait_queue(&sd->sd_wq, &wait); 296 spin_unlock_irqrestore(&sd->sd_wlock, flags); 297 298 schedule_timeout(SCDRV_TIMEOUT); 299 300 remove_wait_queue(&sd->sd_wq, &wait); 301 if (signal_pending(current)) { 302 /* wait was interrupted */ 303 up(&sd->sd_wbs); 304 return -ERESTARTSYS; 305 } 306 307 spin_lock_irqsave(&sd->sd_wlock, flags); 308 status = write_status_check(sd, count); 309 } 310 spin_unlock_irqrestore(&sd->sd_wlock, flags); 311 312 /* release the write buffer and wake anyone who's waiting for it */ 313 up(&sd->sd_wbs); 314 315 /* return the number of characters accepted (should be the complete 316 * "chunk" as requested) 317 */ 318 if ((status >= 0) && (status < count)) { 319 pr_debug("Didn't accept the full chunk; %d of %d\n", 320 status, (int) count); 321 } 322 return status; 323} 324 325static unsigned int 326scdrv_poll(struct file *file, struct poll_table_struct *wait) 327{ 328 unsigned int mask = 0; 329 int status = 0; 330 struct subch_data_s *sd = (struct subch_data_s *) file->private_data; 331 unsigned long flags; 332 333 poll_wait(file, &sd->sd_rq, wait); 334 poll_wait(file, &sd->sd_wq, wait); 335 336 spin_lock_irqsave(&sd->sd_rlock, flags); 337 spin_lock(&sd->sd_wlock); 338 status = ia64_sn_irtr_intr(sd->sd_nasid, sd->sd_subch); 339 spin_unlock(&sd->sd_wlock); 340 spin_unlock_irqrestore(&sd->sd_rlock, flags); 341 342 if (status > 0) { 343 if (status & SAL_IROUTER_INTR_RECV) { 344 mask |= POLLIN | POLLRDNORM; 345 } 346 if (status & SAL_IROUTER_INTR_XMIT) { 347 mask |= POLLOUT | POLLWRNORM; 348 } 349 } 350 351 return mask; 352} 353 354static const struct file_operations scdrv_fops = { 355 .owner = THIS_MODULE, 356 .read = scdrv_read, 357 .write = scdrv_write, 358 .poll = scdrv_poll, 359 .open = scdrv_open, 360 .release = scdrv_release, 361 .llseek = noop_llseek, 362}; 363 364static struct class *snsc_class; 365 366/* 367 * scdrv_init 368 * 369 * Called at boot time to initialize the system controller communication 370 * facility. 371 */ 372int __init 373scdrv_init(void) 374{ 375 geoid_t geoid; 376 cnodeid_t cnode; 377 char devname[32]; 378 char *devnamep; 379 struct sysctl_data_s *scd; 380 void *salbuf; 381 dev_t first_dev, dev; 382 nasid_t event_nasid; 383 384 if (!ia64_platform_is("sn2")) 385 return -ENODEV; 386 387 event_nasid = ia64_sn_get_console_nasid(); 388 389 if (alloc_chrdev_region(&first_dev, 0, num_cnodes, 390 SYSCTL_BASENAME) < 0) { 391 printk("%s: failed to register SN system controller device\n", 392 __func__); 393 return -ENODEV; 394 } 395 snsc_class = class_create(THIS_MODULE, SYSCTL_BASENAME); 396 397 for (cnode = 0; cnode < num_cnodes; cnode++) { 398 geoid = cnodeid_get_geoid(cnode); 399 devnamep = devname; 400 format_module_id(devnamep, geo_module(geoid), 401 MODULE_FORMAT_BRIEF); 402 devnamep = devname + strlen(devname); 403 sprintf(devnamep, "^%d#%d", geo_slot(geoid), 404 geo_slab(geoid)); 405 406 /* allocate sysctl device data */ 407 scd = kzalloc(sizeof (struct sysctl_data_s), 408 GFP_KERNEL); 409 if (!scd) { 410 printk("%s: failed to allocate device info" 411 "for %s/%s\n", __func__, 412 SYSCTL_BASENAME, devname); 413 continue; 414 } 415 416 /* initialize sysctl device data fields */ 417 scd->scd_nasid = cnodeid_to_nasid(cnode); 418 if (!(salbuf = kmalloc(SCDRV_BUFSZ, GFP_KERNEL))) { 419 printk("%s: failed to allocate driver buffer" 420 "(%s%s)\n", __func__, 421 SYSCTL_BASENAME, devname); 422 kfree(scd); 423 continue; 424 } 425 426 if (ia64_sn_irtr_init(scd->scd_nasid, salbuf, 427 SCDRV_BUFSZ) < 0) { 428 printk 429 ("%s: failed to initialize SAL for" 430 " system controller communication" 431 " (%s/%s): outdated PROM?\n", 432 __func__, SYSCTL_BASENAME, devname); 433 kfree(scd); 434 kfree(salbuf); 435 continue; 436 } 437 438 dev = first_dev + cnode; 439 cdev_init(&scd->scd_cdev, &scdrv_fops); 440 if (cdev_add(&scd->scd_cdev, dev, 1)) { 441 printk("%s: failed to register system" 442 " controller device (%s%s)\n", 443 __func__, SYSCTL_BASENAME, devname); 444 kfree(scd); 445 kfree(salbuf); 446 continue; 447 } 448 449 device_create(snsc_class, NULL, dev, NULL, 450 "%s", devname); 451 452 ia64_sn_irtr_intr_enable(scd->scd_nasid, 453 0 /*ignored */ , 454 SAL_IROUTER_INTR_RECV); 455 456 /* on the console nasid, prepare to receive 457 * system controller environmental events 458 */ 459 if(scd->scd_nasid == event_nasid) { 460 scdrv_event_init(scd); 461 } 462 } 463 return 0; 464} 465 466module_init(scdrv_init);