Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.21-rc5 1642 lines 48 kB view raw
1/* 2 * IBM eServer Hypervisor Virtual Console Server Device Driver 3 * Copyright (C) 2003, 2004 IBM Corp. 4 * Ryan S. Arnold (rsa@us.ibm.com) 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 * 20 * Author(s) : Ryan S. Arnold <rsa@us.ibm.com> 21 * 22 * This is the device driver for the IBM Hypervisor Virtual Console Server, 23 * "hvcs". The IBM hvcs provides a tty driver interface to allow Linux 24 * user space applications access to the system consoles of logically 25 * partitioned operating systems, e.g. Linux, running on the same partitioned 26 * Power5 ppc64 system. Physical hardware consoles per partition are not 27 * practical on this hardware so system consoles are accessed by this driver 28 * using inter-partition firmware interfaces to virtual terminal devices. 29 * 30 * A vty is known to the HMC as a "virtual serial server adapter". It is a 31 * virtual terminal device that is created by firmware upon partition creation 32 * to act as a partitioned OS's console device. 33 * 34 * Firmware dynamically (via hotplug) exposes vty-servers to a running ppc64 35 * Linux system upon their creation by the HMC or their exposure during boot. 36 * The non-user interactive backend of this driver is implemented as a vio 37 * device driver so that it can receive notification of vty-server lifetimes 38 * after it registers with the vio bus to handle vty-server probe and remove 39 * callbacks. 40 * 41 * Many vty-servers can be configured to connect to one vty, but a vty can 42 * only be actively connected to by a single vty-server, in any manner, at one 43 * time. If the HMC is currently hosting the console for a target Linux 44 * partition; attempts to open the tty device to the partition's console using 45 * the hvcs on any partition will return -EBUSY with every open attempt until 46 * the HMC frees the connection between its vty-server and the desired 47 * partition's vty device. Conversely, a vty-server may only be connected to 48 * a single vty at one time even though it may have several configured vty 49 * partner possibilities. 50 * 51 * Firmware does not provide notification of vty partner changes to this 52 * driver. This means that an HMC Super Admin may add or remove partner vtys 53 * from a vty-server's partner list but the changes will not be signaled to 54 * the vty-server. Firmware only notifies the driver when a vty-server is 55 * added or removed from the system. To compensate for this deficiency, this 56 * driver implements a sysfs update attribute which provides a method for 57 * rescanning partner information upon a user's request. 58 * 59 * Each vty-server, prior to being exposed to this driver is reference counted 60 * using the 2.6 Linux kernel kobject construct. This kobject is also used by 61 * the vio bus to provide a vio device sysfs entry that this driver attaches 62 * device specific attributes to, including partner information. The vio bus 63 * framework also provides a sysfs entry for each vio driver. The hvcs driver 64 * provides driver attributes in this entry. 65 * 66 * For direction on installation and usage of this driver please reference 67 * Documentation/powerpc/hvcs.txt. 68 */ 69 70#include <linux/device.h> 71#include <linux/init.h> 72#include <linux/interrupt.h> 73#include <linux/kernel.h> 74#include <linux/kobject.h> 75#include <linux/kthread.h> 76#include <linux/list.h> 77#include <linux/major.h> 78#include <linux/module.h> 79#include <linux/moduleparam.h> 80#include <linux/sched.h> 81#include <linux/spinlock.h> 82#include <linux/stat.h> 83#include <linux/tty.h> 84#include <linux/tty_flip.h> 85#include <asm/hvconsole.h> 86#include <asm/hvcserver.h> 87#include <asm/uaccess.h> 88#include <asm/vio.h> 89 90/* 91 * 1.3.0 -> 1.3.1 In hvcs_open memset(..,0x00,..) instead of memset(..,0x3F,00). 92 * Removed braces around single statements following conditionals. Removed '= 93 * 0' after static int declarations since these default to zero. Removed 94 * list_for_each_safe() and replaced with list_for_each_entry() in 95 * hvcs_get_by_index(). The 'safe' version is un-needed now that the driver is 96 * using spinlocks. Changed spin_lock_irqsave() to spin_lock() when locking 97 * hvcs_structs_lock and hvcs_pi_lock since these are not touched in an int 98 * handler. Initialized hvcs_structs_lock and hvcs_pi_lock to 99 * SPIN_LOCK_UNLOCKED at declaration time rather than in hvcs_module_init(). 100 * Added spin_lock around list_del() in destroy_hvcs_struct() to protect the 101 * list traversals from a deletion. Removed '= NULL' from pointer declaration 102 * statements since they are initialized NULL by default. Removed wmb() 103 * instances from hvcs_try_write(). They probably aren't needed with locking in 104 * place. Added check and cleanup for hvcs_pi_buff = kmalloc() in 105 * hvcs_module_init(). Exposed hvcs_struct.index via a sysfs attribute so that 106 * the coupling between /dev/hvcs* and a vty-server can be automatically 107 * determined. Moved kobject_put() in hvcs_open outside of the 108 * spin_unlock_irqrestore(). 109 * 110 * 1.3.1 -> 1.3.2 Changed method for determining hvcs_struct->index and had it 111 * align with how the tty layer always assigns the lowest index available. This 112 * change resulted in a list of ints that denotes which indexes are available. 113 * Device additions and removals use the new hvcs_get_index() and 114 * hvcs_return_index() helper functions. The list is created with 115 * hvsc_alloc_index_list() and it is destroyed with hvcs_free_index_list(). 116 * Without these fixes hotplug vty-server adapter support goes crazy with this 117 * driver if the user removes a vty-server adapter. Moved free_irq() outside of 118 * the hvcs_final_close() function in order to get it out of the spinlock. 119 * Rearranged hvcs_close(). Cleaned up some printks and did some housekeeping 120 * on the changelog. Removed local CLC_LENGTH and used HVCS_CLC_LENGTH from 121 * include/asm-powerpc/hvcserver.h 122 * 123 * 1.3.2 -> 1.3.3 Replaced yield() in hvcs_close() with tty_wait_until_sent() to 124 * prevent possible lockup with realtime scheduling as similarily pointed out by 125 * akpm in hvc_console. Changed resulted in the removal of hvcs_final_close() 126 * to reorder cleanup operations and prevent discarding of pending data during 127 * an hvcs_close(). Removed spinlock protection of hvcs_struct data members in 128 * hvcs_write_room() and hvcs_chars_in_buffer() because they aren't needed. 129 */ 130 131#define HVCS_DRIVER_VERSION "1.3.3" 132 133MODULE_AUTHOR("Ryan S. Arnold <rsa@us.ibm.com>"); 134MODULE_DESCRIPTION("IBM hvcs (Hypervisor Virtual Console Server) Driver"); 135MODULE_LICENSE("GPL"); 136MODULE_VERSION(HVCS_DRIVER_VERSION); 137 138/* 139 * Wait this long per iteration while trying to push buffered data to the 140 * hypervisor before allowing the tty to complete a close operation. 141 */ 142#define HVCS_CLOSE_WAIT (HZ/100) /* 1/10 of a second */ 143 144/* 145 * Since the Linux TTY code does not currently (2-04-2004) support dynamic 146 * addition of tty derived devices and we shouldn't allocate thousands of 147 * tty_device pointers when the number of vty-server & vty partner connections 148 * will most often be much lower than this, we'll arbitrarily allocate 149 * HVCS_DEFAULT_SERVER_ADAPTERS tty_structs and cdev's by default when we 150 * register the tty_driver. This can be overridden using an insmod parameter. 151 */ 152#define HVCS_DEFAULT_SERVER_ADAPTERS 64 153 154/* 155 * The user can't insmod with more than HVCS_MAX_SERVER_ADAPTERS hvcs device 156 * nodes as a sanity check. Theoretically there can be over 1 Billion 157 * vty-server & vty partner connections. 158 */ 159#define HVCS_MAX_SERVER_ADAPTERS 1024 160 161/* 162 * We let Linux assign us a major number and we start the minors at zero. There 163 * is no intuitive mapping between minor number and the target vty-server 164 * adapter except that each new vty-server adapter is always assigned to the 165 * smallest minor number available. 166 */ 167#define HVCS_MINOR_START 0 168 169/* 170 * The hcall interface involves putting 8 chars into each of two registers. 171 * We load up those 2 registers (in arch/powerpc/platforms/pseries/hvconsole.c) 172 * by casting char[16] to long[2]. It would work without __ALIGNED__, but a 173 * little (tiny) bit slower because an unaligned load is slower than aligned 174 * load. 175 */ 176#define __ALIGNED__ __attribute__((__aligned__(8))) 177 178/* 179 * How much data can firmware send with each hvc_put_chars()? Maybe this 180 * should be moved into an architecture specific area. 181 */ 182#define HVCS_BUFF_LEN 16 183 184/* 185 * This is the maximum amount of data we'll let the user send us (hvcs_write) at 186 * once in a chunk as a sanity check. 187 */ 188#define HVCS_MAX_FROM_USER 4096 189 190/* 191 * Be careful when adding flags to this line discipline. Don't add anything 192 * that will cause echoing or we'll go into recursive loop echoing chars back 193 * and forth with the console drivers. 194 */ 195static struct ktermios hvcs_tty_termios = { 196 .c_iflag = IGNBRK | IGNPAR, 197 .c_oflag = OPOST, 198 .c_cflag = B38400 | CS8 | CREAD | HUPCL, 199 .c_cc = INIT_C_CC, 200 .c_ispeed = 38400, 201 .c_ospeed = 38400 202}; 203 204/* 205 * This value is used to take the place of a command line parameter when the 206 * module is inserted. It starts as -1 and stays as such if the user doesn't 207 * specify a module insmod parameter. If they DO specify one then it is set to 208 * the value of the integer passed in. 209 */ 210static int hvcs_parm_num_devs = -1; 211module_param(hvcs_parm_num_devs, int, 0); 212 213char hvcs_driver_name[] = "hvcs"; 214char hvcs_device_node[] = "hvcs"; 215char hvcs_driver_string[] 216 = "IBM hvcs (Hypervisor Virtual Console Server) Driver"; 217 218/* Status of partner info rescan triggered via sysfs. */ 219static int hvcs_rescan_status; 220 221static struct tty_driver *hvcs_tty_driver; 222 223/* 224 * In order to be somewhat sane this driver always associates the hvcs_struct 225 * index element with the numerically equal tty->index. This means that a 226 * hotplugged vty-server adapter will always map to the lowest index valued 227 * device node. If vty-servers were hotplug removed from the system and then 228 * new ones added the new vty-server may have the largest slot number of all 229 * the vty-server adapters in the partition but it may have the lowest dev node 230 * index of all the adapters due to the hole left by the hotplug removed 231 * adapter. There are a set of functions provided to get the lowest index for 232 * a new device as well as return the index to the list. This list is allocated 233 * with a number of elements equal to the number of device nodes requested when 234 * the module was inserted. 235 */ 236static int *hvcs_index_list; 237 238/* 239 * How large is the list? This is kept for traversal since the list is 240 * dynamically created. 241 */ 242static int hvcs_index_count; 243 244/* 245 * Used by the khvcsd to pick up I/O operations when the kernel_thread is 246 * already awake but potentially shifted to TASK_INTERRUPTIBLE state. 247 */ 248static int hvcs_kicked; 249 250/* 251 * Use by the kthread construct for task operations like waking the sleeping 252 * thread and stopping the kthread. 253 */ 254static struct task_struct *hvcs_task; 255 256/* 257 * We allocate this for the use of all of the hvcs_structs when they fetch 258 * partner info. 259 */ 260static unsigned long *hvcs_pi_buff; 261 262/* Only allow one hvcs_struct to use the hvcs_pi_buff at a time. */ 263static DEFINE_SPINLOCK(hvcs_pi_lock); 264 265/* One vty-server per hvcs_struct */ 266struct hvcs_struct { 267 spinlock_t lock; 268 269 /* 270 * This index identifies this hvcs device as the complement to a 271 * specific tty index. 272 */ 273 unsigned int index; 274 275 struct tty_struct *tty; 276 unsigned int open_count; 277 278 /* 279 * Used to tell the driver kernel_thread what operations need to take 280 * place upon this hvcs_struct instance. 281 */ 282 int todo_mask; 283 284 /* 285 * This buffer is required so that when hvcs_write_room() reports that 286 * it can send HVCS_BUFF_LEN characters that it will buffer the full 287 * HVCS_BUFF_LEN characters if need be. This is essential for opost 288 * writes since they do not do high level buffering and expect to be 289 * able to send what the driver commits to sending buffering 290 * [e.g. tab to space conversions in n_tty.c opost()]. 291 */ 292 char buffer[HVCS_BUFF_LEN]; 293 int chars_in_buffer; 294 295 /* 296 * Any variable below the kobject is valid before a tty is connected and 297 * stays valid after the tty is disconnected. These shouldn't be 298 * whacked until the koject refcount reaches zero though some entries 299 * may be changed via sysfs initiatives. 300 */ 301 struct kobject kobj; /* ref count & hvcs_struct lifetime */ 302 int connected; /* is the vty-server currently connected to a vty? */ 303 uint32_t p_unit_address; /* partner unit address */ 304 uint32_t p_partition_ID; /* partner partition ID */ 305 char p_location_code[HVCS_CLC_LENGTH + 1]; /* CLC + Null Term */ 306 struct list_head next; /* list management */ 307 struct vio_dev *vdev; 308}; 309 310/* Required to back map a kobject to its containing object */ 311#define from_kobj(kobj) container_of(kobj, struct hvcs_struct, kobj) 312 313static struct list_head hvcs_structs = LIST_HEAD_INIT(hvcs_structs); 314static DEFINE_SPINLOCK(hvcs_structs_lock); 315 316static void hvcs_unthrottle(struct tty_struct *tty); 317static void hvcs_throttle(struct tty_struct *tty); 318static irqreturn_t hvcs_handle_interrupt(int irq, void *dev_instance); 319 320static int hvcs_write(struct tty_struct *tty, 321 const unsigned char *buf, int count); 322static int hvcs_write_room(struct tty_struct *tty); 323static int hvcs_chars_in_buffer(struct tty_struct *tty); 324 325static int hvcs_has_pi(struct hvcs_struct *hvcsd); 326static void hvcs_set_pi(struct hvcs_partner_info *pi, 327 struct hvcs_struct *hvcsd); 328static int hvcs_get_pi(struct hvcs_struct *hvcsd); 329static int hvcs_rescan_devices_list(void); 330 331static int hvcs_partner_connect(struct hvcs_struct *hvcsd); 332static void hvcs_partner_free(struct hvcs_struct *hvcsd); 333 334static int hvcs_enable_device(struct hvcs_struct *hvcsd, 335 uint32_t unit_address, unsigned int irq, struct vio_dev *dev); 336 337static void destroy_hvcs_struct(struct kobject *kobj); 338static int hvcs_open(struct tty_struct *tty, struct file *filp); 339static void hvcs_close(struct tty_struct *tty, struct file *filp); 340static void hvcs_hangup(struct tty_struct * tty); 341 342static int __devinit hvcs_probe(struct vio_dev *dev, 343 const struct vio_device_id *id); 344static int __devexit hvcs_remove(struct vio_dev *dev); 345static int __init hvcs_module_init(void); 346static void __exit hvcs_module_exit(void); 347 348#define HVCS_SCHED_READ 0x00000001 349#define HVCS_QUICK_READ 0x00000002 350#define HVCS_TRY_WRITE 0x00000004 351#define HVCS_READ_MASK (HVCS_SCHED_READ | HVCS_QUICK_READ) 352 353static inline struct hvcs_struct *from_vio_dev(struct vio_dev *viod) 354{ 355 return viod->dev.driver_data; 356} 357/* The sysfs interface for the driver and devices */ 358 359static ssize_t hvcs_partner_vtys_show(struct device *dev, struct device_attribute *attr, char *buf) 360{ 361 struct vio_dev *viod = to_vio_dev(dev); 362 struct hvcs_struct *hvcsd = from_vio_dev(viod); 363 unsigned long flags; 364 int retval; 365 366 spin_lock_irqsave(&hvcsd->lock, flags); 367 retval = sprintf(buf, "%X\n", hvcsd->p_unit_address); 368 spin_unlock_irqrestore(&hvcsd->lock, flags); 369 return retval; 370} 371static DEVICE_ATTR(partner_vtys, S_IRUGO, hvcs_partner_vtys_show, NULL); 372 373static ssize_t hvcs_partner_clcs_show(struct device *dev, struct device_attribute *attr, char *buf) 374{ 375 struct vio_dev *viod = to_vio_dev(dev); 376 struct hvcs_struct *hvcsd = from_vio_dev(viod); 377 unsigned long flags; 378 int retval; 379 380 spin_lock_irqsave(&hvcsd->lock, flags); 381 retval = sprintf(buf, "%s\n", &hvcsd->p_location_code[0]); 382 spin_unlock_irqrestore(&hvcsd->lock, flags); 383 return retval; 384} 385static DEVICE_ATTR(partner_clcs, S_IRUGO, hvcs_partner_clcs_show, NULL); 386 387static ssize_t hvcs_current_vty_store(struct device *dev, struct device_attribute *attr, const char * buf, 388 size_t count) 389{ 390 /* 391 * Don't need this feature at the present time because firmware doesn't 392 * yet support multiple partners. 393 */ 394 printk(KERN_INFO "HVCS: Denied current_vty change: -EPERM.\n"); 395 return -EPERM; 396} 397 398static ssize_t hvcs_current_vty_show(struct device *dev, struct device_attribute *attr, char *buf) 399{ 400 struct vio_dev *viod = to_vio_dev(dev); 401 struct hvcs_struct *hvcsd = from_vio_dev(viod); 402 unsigned long flags; 403 int retval; 404 405 spin_lock_irqsave(&hvcsd->lock, flags); 406 retval = sprintf(buf, "%s\n", &hvcsd->p_location_code[0]); 407 spin_unlock_irqrestore(&hvcsd->lock, flags); 408 return retval; 409} 410 411static DEVICE_ATTR(current_vty, 412 S_IRUGO | S_IWUSR, hvcs_current_vty_show, hvcs_current_vty_store); 413 414static ssize_t hvcs_vterm_state_store(struct device *dev, struct device_attribute *attr, const char *buf, 415 size_t count) 416{ 417 struct vio_dev *viod = to_vio_dev(dev); 418 struct hvcs_struct *hvcsd = from_vio_dev(viod); 419 unsigned long flags; 420 421 /* writing a '0' to this sysfs entry will result in the disconnect. */ 422 if (simple_strtol(buf, NULL, 0) != 0) 423 return -EINVAL; 424 425 spin_lock_irqsave(&hvcsd->lock, flags); 426 427 if (hvcsd->open_count > 0) { 428 spin_unlock_irqrestore(&hvcsd->lock, flags); 429 printk(KERN_INFO "HVCS: vterm state unchanged. " 430 "The hvcs device node is still in use.\n"); 431 return -EPERM; 432 } 433 434 if (hvcsd->connected == 0) { 435 spin_unlock_irqrestore(&hvcsd->lock, flags); 436 printk(KERN_INFO "HVCS: vterm state unchanged. The" 437 " vty-server is not connected to a vty.\n"); 438 return -EPERM; 439 } 440 441 hvcs_partner_free(hvcsd); 442 printk(KERN_INFO "HVCS: Closed vty-server@%X and" 443 " partner vty@%X:%d connection.\n", 444 hvcsd->vdev->unit_address, 445 hvcsd->p_unit_address, 446 (uint32_t)hvcsd->p_partition_ID); 447 448 spin_unlock_irqrestore(&hvcsd->lock, flags); 449 return count; 450} 451 452static ssize_t hvcs_vterm_state_show(struct device *dev, struct device_attribute *attr, char *buf) 453{ 454 struct vio_dev *viod = to_vio_dev(dev); 455 struct hvcs_struct *hvcsd = from_vio_dev(viod); 456 unsigned long flags; 457 int retval; 458 459 spin_lock_irqsave(&hvcsd->lock, flags); 460 retval = sprintf(buf, "%d\n", hvcsd->connected); 461 spin_unlock_irqrestore(&hvcsd->lock, flags); 462 return retval; 463} 464static DEVICE_ATTR(vterm_state, S_IRUGO | S_IWUSR, 465 hvcs_vterm_state_show, hvcs_vterm_state_store); 466 467static ssize_t hvcs_index_show(struct device *dev, struct device_attribute *attr, char *buf) 468{ 469 struct vio_dev *viod = to_vio_dev(dev); 470 struct hvcs_struct *hvcsd = from_vio_dev(viod); 471 unsigned long flags; 472 int retval; 473 474 spin_lock_irqsave(&hvcsd->lock, flags); 475 retval = sprintf(buf, "%d\n", hvcsd->index); 476 spin_unlock_irqrestore(&hvcsd->lock, flags); 477 return retval; 478} 479 480static DEVICE_ATTR(index, S_IRUGO, hvcs_index_show, NULL); 481 482static struct attribute *hvcs_attrs[] = { 483 &dev_attr_partner_vtys.attr, 484 &dev_attr_partner_clcs.attr, 485 &dev_attr_current_vty.attr, 486 &dev_attr_vterm_state.attr, 487 &dev_attr_index.attr, 488 NULL, 489}; 490 491static struct attribute_group hvcs_attr_group = { 492 .attrs = hvcs_attrs, 493}; 494 495static ssize_t hvcs_rescan_show(struct device_driver *ddp, char *buf) 496{ 497 /* A 1 means it is updating, a 0 means it is done updating */ 498 return snprintf(buf, PAGE_SIZE, "%d\n", hvcs_rescan_status); 499} 500 501static ssize_t hvcs_rescan_store(struct device_driver *ddp, const char * buf, 502 size_t count) 503{ 504 if ((simple_strtol(buf, NULL, 0) != 1) 505 && (hvcs_rescan_status != 0)) 506 return -EINVAL; 507 508 hvcs_rescan_status = 1; 509 printk(KERN_INFO "HVCS: rescanning partner info for all" 510 " vty-servers.\n"); 511 hvcs_rescan_devices_list(); 512 hvcs_rescan_status = 0; 513 return count; 514} 515 516static DRIVER_ATTR(rescan, 517 S_IRUGO | S_IWUSR, hvcs_rescan_show, hvcs_rescan_store); 518 519static void hvcs_kick(void) 520{ 521 hvcs_kicked = 1; 522 wmb(); 523 wake_up_process(hvcs_task); 524} 525 526static void hvcs_unthrottle(struct tty_struct *tty) 527{ 528 struct hvcs_struct *hvcsd = tty->driver_data; 529 unsigned long flags; 530 531 spin_lock_irqsave(&hvcsd->lock, flags); 532 hvcsd->todo_mask |= HVCS_SCHED_READ; 533 spin_unlock_irqrestore(&hvcsd->lock, flags); 534 hvcs_kick(); 535} 536 537static void hvcs_throttle(struct tty_struct *tty) 538{ 539 struct hvcs_struct *hvcsd = tty->driver_data; 540 unsigned long flags; 541 542 spin_lock_irqsave(&hvcsd->lock, flags); 543 vio_disable_interrupts(hvcsd->vdev); 544 spin_unlock_irqrestore(&hvcsd->lock, flags); 545} 546 547/* 548 * If the device is being removed we don't have to worry about this interrupt 549 * handler taking any further interrupts because they are disabled which means 550 * the hvcs_struct will always be valid in this handler. 551 */ 552static irqreturn_t hvcs_handle_interrupt(int irq, void *dev_instance) 553{ 554 struct hvcs_struct *hvcsd = dev_instance; 555 556 spin_lock(&hvcsd->lock); 557 vio_disable_interrupts(hvcsd->vdev); 558 hvcsd->todo_mask |= HVCS_SCHED_READ; 559 spin_unlock(&hvcsd->lock); 560 hvcs_kick(); 561 562 return IRQ_HANDLED; 563} 564 565/* This function must be called with the hvcsd->lock held */ 566static void hvcs_try_write(struct hvcs_struct *hvcsd) 567{ 568 uint32_t unit_address = hvcsd->vdev->unit_address; 569 struct tty_struct *tty = hvcsd->tty; 570 int sent; 571 572 if (hvcsd->todo_mask & HVCS_TRY_WRITE) { 573 /* won't send partial writes */ 574 sent = hvc_put_chars(unit_address, 575 &hvcsd->buffer[0], 576 hvcsd->chars_in_buffer ); 577 if (sent > 0) { 578 hvcsd->chars_in_buffer = 0; 579 /* wmb(); */ 580 hvcsd->todo_mask &= ~(HVCS_TRY_WRITE); 581 /* wmb(); */ 582 583 /* 584 * We are still obligated to deliver the data to the 585 * hypervisor even if the tty has been closed because 586 * we commited to delivering it. But don't try to wake 587 * a non-existent tty. 588 */ 589 if (tty) { 590 tty_wakeup(tty); 591 } 592 } 593 } 594} 595 596static int hvcs_io(struct hvcs_struct *hvcsd) 597{ 598 uint32_t unit_address; 599 struct tty_struct *tty; 600 char buf[HVCS_BUFF_LEN] __ALIGNED__; 601 unsigned long flags; 602 int got = 0; 603 604 spin_lock_irqsave(&hvcsd->lock, flags); 605 606 unit_address = hvcsd->vdev->unit_address; 607 tty = hvcsd->tty; 608 609 hvcs_try_write(hvcsd); 610 611 if (!tty || test_bit(TTY_THROTTLED, &tty->flags)) { 612 hvcsd->todo_mask &= ~(HVCS_READ_MASK); 613 goto bail; 614 } else if (!(hvcsd->todo_mask & (HVCS_READ_MASK))) 615 goto bail; 616 617 /* remove the read masks */ 618 hvcsd->todo_mask &= ~(HVCS_READ_MASK); 619 620 if (tty_buffer_request_room(tty, HVCS_BUFF_LEN) >= HVCS_BUFF_LEN) { 621 got = hvc_get_chars(unit_address, 622 &buf[0], 623 HVCS_BUFF_LEN); 624 tty_insert_flip_string(tty, buf, got); 625 } 626 627 /* Give the TTY time to process the data we just sent. */ 628 if (got) 629 hvcsd->todo_mask |= HVCS_QUICK_READ; 630 631 spin_unlock_irqrestore(&hvcsd->lock, flags); 632 /* This is synch because tty->low_latency == 1 */ 633 if(got) 634 tty_flip_buffer_push(tty); 635 636 if (!got) { 637 /* Do this _after_ the flip_buffer_push */ 638 spin_lock_irqsave(&hvcsd->lock, flags); 639 vio_enable_interrupts(hvcsd->vdev); 640 spin_unlock_irqrestore(&hvcsd->lock, flags); 641 } 642 643 return hvcsd->todo_mask; 644 645 bail: 646 spin_unlock_irqrestore(&hvcsd->lock, flags); 647 return hvcsd->todo_mask; 648} 649 650static int khvcsd(void *unused) 651{ 652 struct hvcs_struct *hvcsd; 653 int hvcs_todo_mask; 654 655 __set_current_state(TASK_RUNNING); 656 657 do { 658 hvcs_todo_mask = 0; 659 hvcs_kicked = 0; 660 wmb(); 661 662 spin_lock(&hvcs_structs_lock); 663 list_for_each_entry(hvcsd, &hvcs_structs, next) { 664 hvcs_todo_mask |= hvcs_io(hvcsd); 665 } 666 spin_unlock(&hvcs_structs_lock); 667 668 /* 669 * If any of the hvcs adapters want to try a write or quick read 670 * don't schedule(), yield a smidgen then execute the hvcs_io 671 * thread again for those that want the write. 672 */ 673 if (hvcs_todo_mask & (HVCS_TRY_WRITE | HVCS_QUICK_READ)) { 674 yield(); 675 continue; 676 } 677 678 set_current_state(TASK_INTERRUPTIBLE); 679 if (!hvcs_kicked) 680 schedule(); 681 __set_current_state(TASK_RUNNING); 682 } while (!kthread_should_stop()); 683 684 return 0; 685} 686 687static struct vio_device_id hvcs_driver_table[] __devinitdata= { 688 {"serial-server", "hvterm2"}, 689 { "", "" } 690}; 691MODULE_DEVICE_TABLE(vio, hvcs_driver_table); 692 693static void hvcs_return_index(int index) 694{ 695 /* Paranoia check */ 696 if (!hvcs_index_list) 697 return; 698 if (index < 0 || index >= hvcs_index_count) 699 return; 700 if (hvcs_index_list[index] == -1) 701 return; 702 else 703 hvcs_index_list[index] = -1; 704} 705 706/* callback when the kboject ref count reaches zero */ 707static void destroy_hvcs_struct(struct kobject *kobj) 708{ 709 struct hvcs_struct *hvcsd = from_kobj(kobj); 710 struct vio_dev *vdev; 711 unsigned long flags; 712 713 spin_lock(&hvcs_structs_lock); 714 spin_lock_irqsave(&hvcsd->lock, flags); 715 716 /* the list_del poisons the pointers */ 717 list_del(&(hvcsd->next)); 718 719 if (hvcsd->connected == 1) { 720 hvcs_partner_free(hvcsd); 721 printk(KERN_INFO "HVCS: Closed vty-server@%X and" 722 " partner vty@%X:%d connection.\n", 723 hvcsd->vdev->unit_address, 724 hvcsd->p_unit_address, 725 (uint32_t)hvcsd->p_partition_ID); 726 } 727 printk(KERN_INFO "HVCS: Destroyed hvcs_struct for vty-server@%X.\n", 728 hvcsd->vdev->unit_address); 729 730 vdev = hvcsd->vdev; 731 hvcsd->vdev = NULL; 732 733 hvcsd->p_unit_address = 0; 734 hvcsd->p_partition_ID = 0; 735 hvcs_return_index(hvcsd->index); 736 memset(&hvcsd->p_location_code[0], 0x00, HVCS_CLC_LENGTH + 1); 737 738 spin_unlock_irqrestore(&hvcsd->lock, flags); 739 spin_unlock(&hvcs_structs_lock); 740 741 sysfs_remove_group(&vdev->dev.kobj, &hvcs_attr_group); 742 743 kfree(hvcsd); 744} 745 746static struct kobj_type hvcs_kobj_type = { 747 .release = destroy_hvcs_struct, 748}; 749 750static int hvcs_get_index(void) 751{ 752 int i; 753 /* Paranoia check */ 754 if (!hvcs_index_list) { 755 printk(KERN_ERR "HVCS: hvcs_index_list NOT valid!.\n"); 756 return -EFAULT; 757 } 758 /* Find the numerically lowest first free index. */ 759 for(i = 0; i < hvcs_index_count; i++) { 760 if (hvcs_index_list[i] == -1) { 761 hvcs_index_list[i] = 0; 762 return i; 763 } 764 } 765 return -1; 766} 767 768static int __devinit hvcs_probe( 769 struct vio_dev *dev, 770 const struct vio_device_id *id) 771{ 772 struct hvcs_struct *hvcsd; 773 int index; 774 int retval; 775 776 if (!dev || !id) { 777 printk(KERN_ERR "HVCS: probed with invalid parameter.\n"); 778 return -EPERM; 779 } 780 781 /* early to avoid cleanup on failure */ 782 index = hvcs_get_index(); 783 if (index < 0) { 784 return -EFAULT; 785 } 786 787 hvcsd = kmalloc(sizeof(*hvcsd), GFP_KERNEL); 788 if (!hvcsd) 789 return -ENODEV; 790 791 /* hvcsd->tty is zeroed out with the memset */ 792 memset(hvcsd, 0x00, sizeof(*hvcsd)); 793 794 spin_lock_init(&hvcsd->lock); 795 /* Automatically incs the refcount the first time */ 796 kobject_init(&hvcsd->kobj); 797 /* Set up the callback for terminating the hvcs_struct's life */ 798 hvcsd->kobj.ktype = &hvcs_kobj_type; 799 800 hvcsd->vdev = dev; 801 dev->dev.driver_data = hvcsd; 802 803 hvcsd->index = index; 804 805 /* hvcsd->index = ++hvcs_struct_count; */ 806 hvcsd->chars_in_buffer = 0; 807 hvcsd->todo_mask = 0; 808 hvcsd->connected = 0; 809 810 /* 811 * This will populate the hvcs_struct's partner info fields for the 812 * first time. 813 */ 814 if (hvcs_get_pi(hvcsd)) { 815 printk(KERN_ERR "HVCS: Failed to fetch partner" 816 " info for vty-server@%X on device probe.\n", 817 hvcsd->vdev->unit_address); 818 } 819 820 /* 821 * If a user app opens a tty that corresponds to this vty-server before 822 * the hvcs_struct has been added to the devices list then the user app 823 * will get -ENODEV. 824 */ 825 spin_lock(&hvcs_structs_lock); 826 list_add_tail(&(hvcsd->next), &hvcs_structs); 827 spin_unlock(&hvcs_structs_lock); 828 829 retval = sysfs_create_group(&dev->dev.kobj, &hvcs_attr_group); 830 if (retval) { 831 printk(KERN_ERR "HVCS: Can't create sysfs attrs for vty-server@%X\n", 832 hvcsd->vdev->unit_address); 833 return retval; 834 } 835 836 printk(KERN_INFO "HVCS: vty-server@%X added to the vio bus.\n", dev->unit_address); 837 838 /* 839 * DON'T enable interrupts here because there is no user to receive the 840 * data. 841 */ 842 return 0; 843} 844 845static int __devexit hvcs_remove(struct vio_dev *dev) 846{ 847 struct hvcs_struct *hvcsd = dev->dev.driver_data; 848 unsigned long flags; 849 struct kobject *kobjp; 850 struct tty_struct *tty; 851 852 if (!hvcsd) 853 return -ENODEV; 854 855 /* By this time the vty-server won't be getting any more interrups */ 856 857 spin_lock_irqsave(&hvcsd->lock, flags); 858 859 tty = hvcsd->tty; 860 861 kobjp = &hvcsd->kobj; 862 863 spin_unlock_irqrestore(&hvcsd->lock, flags); 864 865 /* 866 * Let the last holder of this object cause it to be removed, which 867 * would probably be tty_hangup below. 868 */ 869 kobject_put (kobjp); 870 871 /* 872 * The hangup is a scheduled function which will auto chain call 873 * hvcs_hangup. The tty should always be valid at this time unless a 874 * simultaneous tty close already cleaned up the hvcs_struct. 875 */ 876 if (tty) 877 tty_hangup(tty); 878 879 printk(KERN_INFO "HVCS: vty-server@%X removed from the" 880 " vio bus.\n", dev->unit_address); 881 return 0; 882}; 883 884static struct vio_driver hvcs_vio_driver = { 885 .id_table = hvcs_driver_table, 886 .probe = hvcs_probe, 887 .remove = hvcs_remove, 888 .driver = { 889 .name = hvcs_driver_name, 890 .owner = THIS_MODULE, 891 } 892}; 893 894/* Only called from hvcs_get_pi please */ 895static void hvcs_set_pi(struct hvcs_partner_info *pi, struct hvcs_struct *hvcsd) 896{ 897 int clclength; 898 899 hvcsd->p_unit_address = pi->unit_address; 900 hvcsd->p_partition_ID = pi->partition_ID; 901 clclength = strlen(&pi->location_code[0]); 902 if (clclength > HVCS_CLC_LENGTH) 903 clclength = HVCS_CLC_LENGTH; 904 905 /* copy the null-term char too */ 906 strncpy(&hvcsd->p_location_code[0], 907 &pi->location_code[0], clclength + 1); 908} 909 910/* 911 * Traverse the list and add the partner info that is found to the hvcs_struct 912 * struct entry. NOTE: At this time I know that partner info will return a 913 * single entry but in the future there may be multiple partner info entries per 914 * vty-server and you'll want to zero out that list and reset it. If for some 915 * reason you have an old version of this driver but there IS more than one 916 * partner info then hvcsd->p_* will hold the last partner info data from the 917 * firmware query. A good way to update this code would be to replace the three 918 * partner info fields in hvcs_struct with a list of hvcs_partner_info 919 * instances. 920 * 921 * This function must be called with the hvcsd->lock held. 922 */ 923static int hvcs_get_pi(struct hvcs_struct *hvcsd) 924{ 925 struct hvcs_partner_info *pi; 926 uint32_t unit_address = hvcsd->vdev->unit_address; 927 struct list_head head; 928 int retval; 929 930 spin_lock(&hvcs_pi_lock); 931 if (!hvcs_pi_buff) { 932 spin_unlock(&hvcs_pi_lock); 933 return -EFAULT; 934 } 935 retval = hvcs_get_partner_info(unit_address, &head, hvcs_pi_buff); 936 spin_unlock(&hvcs_pi_lock); 937 if (retval) { 938 printk(KERN_ERR "HVCS: Failed to fetch partner" 939 " info for vty-server@%x.\n", unit_address); 940 return retval; 941 } 942 943 /* nixes the values if the partner vty went away */ 944 hvcsd->p_unit_address = 0; 945 hvcsd->p_partition_ID = 0; 946 947 list_for_each_entry(pi, &head, node) 948 hvcs_set_pi(pi, hvcsd); 949 950 hvcs_free_partner_info(&head); 951 return 0; 952} 953 954/* 955 * This function is executed by the driver "rescan" sysfs entry. It shouldn't 956 * be executed elsewhere, in order to prevent deadlock issues. 957 */ 958static int hvcs_rescan_devices_list(void) 959{ 960 struct hvcs_struct *hvcsd; 961 unsigned long flags; 962 963 spin_lock(&hvcs_structs_lock); 964 965 list_for_each_entry(hvcsd, &hvcs_structs, next) { 966 spin_lock_irqsave(&hvcsd->lock, flags); 967 hvcs_get_pi(hvcsd); 968 spin_unlock_irqrestore(&hvcsd->lock, flags); 969 } 970 971 spin_unlock(&hvcs_structs_lock); 972 973 return 0; 974} 975 976/* 977 * Farm this off into its own function because it could be more complex once 978 * multiple partners support is added. This function should be called with 979 * the hvcsd->lock held. 980 */ 981static int hvcs_has_pi(struct hvcs_struct *hvcsd) 982{ 983 if ((!hvcsd->p_unit_address) || (!hvcsd->p_partition_ID)) 984 return 0; 985 return 1; 986} 987 988/* 989 * NOTE: It is possible that the super admin removed a partner vty and then 990 * added a different vty as the new partner. 991 * 992 * This function must be called with the hvcsd->lock held. 993 */ 994static int hvcs_partner_connect(struct hvcs_struct *hvcsd) 995{ 996 int retval; 997 unsigned int unit_address = hvcsd->vdev->unit_address; 998 999 /* 1000 * If there wasn't any pi when the device was added it doesn't meant 1001 * there isn't any now. This driver isn't notified when a new partner 1002 * vty is added to a vty-server so we discover changes on our own. 1003 * Please see comments in hvcs_register_connection() for justification 1004 * of this bizarre code. 1005 */ 1006 retval = hvcs_register_connection(unit_address, 1007 hvcsd->p_partition_ID, 1008 hvcsd->p_unit_address); 1009 if (!retval) { 1010 hvcsd->connected = 1; 1011 return 0; 1012 } else if (retval != -EINVAL) 1013 return retval; 1014 1015 /* 1016 * As per the spec re-get the pi and try again if -EINVAL after the 1017 * first connection attempt. 1018 */ 1019 if (hvcs_get_pi(hvcsd)) 1020 return -ENOMEM; 1021 1022 if (!hvcs_has_pi(hvcsd)) 1023 return -ENODEV; 1024 1025 retval = hvcs_register_connection(unit_address, 1026 hvcsd->p_partition_ID, 1027 hvcsd->p_unit_address); 1028 if (retval != -EINVAL) { 1029 hvcsd->connected = 1; 1030 return retval; 1031 } 1032 1033 /* 1034 * EBUSY is the most likely scenario though the vty could have been 1035 * removed or there really could be an hcall error due to the parameter 1036 * data but thanks to ambiguous firmware return codes we can't really 1037 * tell. 1038 */ 1039 printk(KERN_INFO "HVCS: vty-server or partner" 1040 " vty is busy. Try again later.\n"); 1041 return -EBUSY; 1042} 1043 1044/* This function must be called with the hvcsd->lock held */ 1045static void hvcs_partner_free(struct hvcs_struct *hvcsd) 1046{ 1047 int retval; 1048 do { 1049 retval = hvcs_free_connection(hvcsd->vdev->unit_address); 1050 } while (retval == -EBUSY); 1051 hvcsd->connected = 0; 1052} 1053 1054/* This helper function must be called WITHOUT the hvcsd->lock held */ 1055static int hvcs_enable_device(struct hvcs_struct *hvcsd, uint32_t unit_address, 1056 unsigned int irq, struct vio_dev *vdev) 1057{ 1058 unsigned long flags; 1059 int rc; 1060 1061 /* 1062 * It is possible that the vty-server was removed between the time that 1063 * the conn was registered and now. 1064 */ 1065 if (!(rc = request_irq(irq, &hvcs_handle_interrupt, 1066 IRQF_DISABLED, "ibmhvcs", hvcsd))) { 1067 /* 1068 * It is possible the vty-server was removed after the irq was 1069 * requested but before we have time to enable interrupts. 1070 */ 1071 if (vio_enable_interrupts(vdev) == H_SUCCESS) 1072 return 0; 1073 else { 1074 printk(KERN_ERR "HVCS: int enable failed for" 1075 " vty-server@%X.\n", unit_address); 1076 free_irq(irq, hvcsd); 1077 } 1078 } else 1079 printk(KERN_ERR "HVCS: irq req failed for" 1080 " vty-server@%X.\n", unit_address); 1081 1082 spin_lock_irqsave(&hvcsd->lock, flags); 1083 hvcs_partner_free(hvcsd); 1084 spin_unlock_irqrestore(&hvcsd->lock, flags); 1085 1086 return rc; 1087 1088} 1089 1090/* 1091 * This always increments the kobject ref count if the call is successful. 1092 * Please remember to dec when you are done with the instance. 1093 * 1094 * NOTICE: Do NOT hold either the hvcs_struct.lock or hvcs_structs_lock when 1095 * calling this function or you will get deadlock. 1096 */ 1097struct hvcs_struct *hvcs_get_by_index(int index) 1098{ 1099 struct hvcs_struct *hvcsd = NULL; 1100 unsigned long flags; 1101 1102 spin_lock(&hvcs_structs_lock); 1103 /* We can immediately discard OOB requests */ 1104 if (index >= 0 && index < HVCS_MAX_SERVER_ADAPTERS) { 1105 list_for_each_entry(hvcsd, &hvcs_structs, next) { 1106 spin_lock_irqsave(&hvcsd->lock, flags); 1107 if (hvcsd->index == index) { 1108 kobject_get(&hvcsd->kobj); 1109 spin_unlock_irqrestore(&hvcsd->lock, flags); 1110 spin_unlock(&hvcs_structs_lock); 1111 return hvcsd; 1112 } 1113 spin_unlock_irqrestore(&hvcsd->lock, flags); 1114 } 1115 hvcsd = NULL; 1116 } 1117 1118 spin_unlock(&hvcs_structs_lock); 1119 return hvcsd; 1120} 1121 1122/* 1123 * This is invoked via the tty_open interface when a user app connects to the 1124 * /dev node. 1125 */ 1126static int hvcs_open(struct tty_struct *tty, struct file *filp) 1127{ 1128 struct hvcs_struct *hvcsd; 1129 int rc, retval = 0; 1130 unsigned long flags; 1131 unsigned int irq; 1132 struct vio_dev *vdev; 1133 unsigned long unit_address; 1134 struct kobject *kobjp; 1135 1136 if (tty->driver_data) 1137 goto fast_open; 1138 1139 /* 1140 * Is there a vty-server that shares the same index? 1141 * This function increments the kobject index. 1142 */ 1143 if (!(hvcsd = hvcs_get_by_index(tty->index))) { 1144 printk(KERN_WARNING "HVCS: open failed, no device associated" 1145 " with tty->index %d.\n", tty->index); 1146 return -ENODEV; 1147 } 1148 1149 spin_lock_irqsave(&hvcsd->lock, flags); 1150 1151 if (hvcsd->connected == 0) 1152 if ((retval = hvcs_partner_connect(hvcsd))) 1153 goto error_release; 1154 1155 hvcsd->open_count = 1; 1156 hvcsd->tty = tty; 1157 tty->driver_data = hvcsd; 1158 1159 /* 1160 * Set this driver to low latency so that we actually have a chance at 1161 * catching a throttled TTY after we flip_buffer_push. Otherwise the 1162 * flush_to_async may not execute until after the kernel_thread has 1163 * yielded and resumed the next flip_buffer_push resulting in data 1164 * loss. 1165 */ 1166 tty->low_latency = 1; 1167 1168 memset(&hvcsd->buffer[0], 0x00, HVCS_BUFF_LEN); 1169 1170 /* 1171 * Save these in the spinlock for the enable operations that need them 1172 * outside of the spinlock. 1173 */ 1174 irq = hvcsd->vdev->irq; 1175 vdev = hvcsd->vdev; 1176 unit_address = hvcsd->vdev->unit_address; 1177 1178 hvcsd->todo_mask |= HVCS_SCHED_READ; 1179 spin_unlock_irqrestore(&hvcsd->lock, flags); 1180 1181 /* 1182 * This must be done outside of the spinlock because it requests irqs 1183 * and will grab the spinlock and free the connection if it fails. 1184 */ 1185 if (((rc = hvcs_enable_device(hvcsd, unit_address, irq, vdev)))) { 1186 kobject_put(&hvcsd->kobj); 1187 printk(KERN_WARNING "HVCS: enable device failed.\n"); 1188 return rc; 1189 } 1190 1191 goto open_success; 1192 1193fast_open: 1194 hvcsd = tty->driver_data; 1195 1196 spin_lock_irqsave(&hvcsd->lock, flags); 1197 if (!kobject_get(&hvcsd->kobj)) { 1198 spin_unlock_irqrestore(&hvcsd->lock, flags); 1199 printk(KERN_ERR "HVCS: Kobject of open" 1200 " hvcs doesn't exist.\n"); 1201 return -EFAULT; /* Is this the right return value? */ 1202 } 1203 1204 hvcsd->open_count++; 1205 1206 hvcsd->todo_mask |= HVCS_SCHED_READ; 1207 spin_unlock_irqrestore(&hvcsd->lock, flags); 1208open_success: 1209 hvcs_kick(); 1210 1211 printk(KERN_INFO "HVCS: vty-server@%X connection opened.\n", 1212 hvcsd->vdev->unit_address ); 1213 1214 return 0; 1215 1216error_release: 1217 kobjp = &hvcsd->kobj; 1218 spin_unlock_irqrestore(&hvcsd->lock, flags); 1219 kobject_put(&hvcsd->kobj); 1220 1221 printk(KERN_WARNING "HVCS: partner connect failed.\n"); 1222 return retval; 1223} 1224 1225static void hvcs_close(struct tty_struct *tty, struct file *filp) 1226{ 1227 struct hvcs_struct *hvcsd; 1228 unsigned long flags; 1229 struct kobject *kobjp; 1230 int irq = NO_IRQ; 1231 1232 /* 1233 * Is someone trying to close the file associated with this device after 1234 * we have hung up? If so tty->driver_data wouldn't be valid. 1235 */ 1236 if (tty_hung_up_p(filp)) 1237 return; 1238 1239 /* 1240 * No driver_data means that this close was probably issued after a 1241 * failed hvcs_open by the tty layer's release_dev() api and we can just 1242 * exit cleanly. 1243 */ 1244 if (!tty->driver_data) 1245 return; 1246 1247 hvcsd = tty->driver_data; 1248 1249 spin_lock_irqsave(&hvcsd->lock, flags); 1250 kobjp = &hvcsd->kobj; 1251 if (--hvcsd->open_count == 0) { 1252 1253 vio_disable_interrupts(hvcsd->vdev); 1254 1255 /* 1256 * NULL this early so that the kernel_thread doesn't try to 1257 * execute any operations on the TTY even though it is obligated 1258 * to deliver any pending I/O to the hypervisor. 1259 */ 1260 hvcsd->tty = NULL; 1261 1262 irq = hvcsd->vdev->irq; 1263 spin_unlock_irqrestore(&hvcsd->lock, flags); 1264 1265 tty_wait_until_sent(tty, HVCS_CLOSE_WAIT); 1266 1267 /* 1268 * This line is important because it tells hvcs_open that this 1269 * device needs to be re-configured the next time hvcs_open is 1270 * called. 1271 */ 1272 tty->driver_data = NULL; 1273 1274 free_irq(irq, hvcsd); 1275 kobject_put(kobjp); 1276 return; 1277 } else if (hvcsd->open_count < 0) { 1278 printk(KERN_ERR "HVCS: vty-server@%X open_count: %d" 1279 " is missmanaged.\n", 1280 hvcsd->vdev->unit_address, hvcsd->open_count); 1281 } 1282 1283 spin_unlock_irqrestore(&hvcsd->lock, flags); 1284 kobject_put(kobjp); 1285} 1286 1287static void hvcs_hangup(struct tty_struct * tty) 1288{ 1289 struct hvcs_struct *hvcsd = tty->driver_data; 1290 unsigned long flags; 1291 int temp_open_count; 1292 struct kobject *kobjp; 1293 int irq = NO_IRQ; 1294 1295 spin_lock_irqsave(&hvcsd->lock, flags); 1296 /* Preserve this so that we know how many kobject refs to put */ 1297 temp_open_count = hvcsd->open_count; 1298 1299 /* 1300 * Don't kobject put inside the spinlock because the destruction 1301 * callback may use the spinlock and it may get called before the 1302 * spinlock has been released. Get a pointer to the kobject and 1303 * kobject_put on that after releasing the spinlock. 1304 */ 1305 kobjp = &hvcsd->kobj; 1306 1307 vio_disable_interrupts(hvcsd->vdev); 1308 1309 hvcsd->todo_mask = 0; 1310 1311 /* I don't think the tty needs the hvcs_struct pointer after a hangup */ 1312 hvcsd->tty->driver_data = NULL; 1313 hvcsd->tty = NULL; 1314 1315 hvcsd->open_count = 0; 1316 1317 /* This will drop any buffered data on the floor which is OK in a hangup 1318 * scenario. */ 1319 memset(&hvcsd->buffer[0], 0x00, HVCS_BUFF_LEN); 1320 hvcsd->chars_in_buffer = 0; 1321 1322 irq = hvcsd->vdev->irq; 1323 1324 spin_unlock_irqrestore(&hvcsd->lock, flags); 1325 1326 free_irq(irq, hvcsd); 1327 1328 /* 1329 * We need to kobject_put() for every open_count we have since the 1330 * tty_hangup() function doesn't invoke a close per open connection on a 1331 * non-console device. 1332 */ 1333 while(temp_open_count) { 1334 --temp_open_count; 1335 /* 1336 * The final put will trigger destruction of the hvcs_struct. 1337 * NOTE: If this hangup was signaled from user space then the 1338 * final put will never happen. 1339 */ 1340 kobject_put(kobjp); 1341 } 1342} 1343 1344/* 1345 * NOTE: This is almost always from_user since user level apps interact with the 1346 * /dev nodes. I'm trusting that if hvcs_write gets called and interrupted by 1347 * hvcs_remove (which removes the target device and executes tty_hangup()) that 1348 * tty_hangup will allow hvcs_write time to complete execution before it 1349 * terminates our device. 1350 */ 1351static int hvcs_write(struct tty_struct *tty, 1352 const unsigned char *buf, int count) 1353{ 1354 struct hvcs_struct *hvcsd = tty->driver_data; 1355 unsigned int unit_address; 1356 const unsigned char *charbuf; 1357 unsigned long flags; 1358 int total_sent = 0; 1359 int tosend = 0; 1360 int result = 0; 1361 1362 /* 1363 * If they don't check the return code off of their open they may 1364 * attempt this even if there is no connected device. 1365 */ 1366 if (!hvcsd) 1367 return -ENODEV; 1368 1369 /* Reasonable size to prevent user level flooding */ 1370 if (count > HVCS_MAX_FROM_USER) { 1371 printk(KERN_WARNING "HVCS write: count being truncated to" 1372 " HVCS_MAX_FROM_USER.\n"); 1373 count = HVCS_MAX_FROM_USER; 1374 } 1375 1376 charbuf = buf; 1377 1378 spin_lock_irqsave(&hvcsd->lock, flags); 1379 1380 /* 1381 * Somehow an open succedded but the device was removed or the 1382 * connection terminated between the vty-server and partner vty during 1383 * the middle of a write operation? This is a crummy place to do this 1384 * but we want to keep it all in the spinlock. 1385 */ 1386 if (hvcsd->open_count <= 0) { 1387 spin_unlock_irqrestore(&hvcsd->lock, flags); 1388 return -ENODEV; 1389 } 1390 1391 unit_address = hvcsd->vdev->unit_address; 1392 1393 while (count > 0) { 1394 tosend = min(count, (HVCS_BUFF_LEN - hvcsd->chars_in_buffer)); 1395 /* 1396 * No more space, this probably means that the last call to 1397 * hvcs_write() didn't succeed and the buffer was filled up. 1398 */ 1399 if (!tosend) 1400 break; 1401 1402 memcpy(&hvcsd->buffer[hvcsd->chars_in_buffer], 1403 &charbuf[total_sent], 1404 tosend); 1405 1406 hvcsd->chars_in_buffer += tosend; 1407 1408 result = 0; 1409 1410 /* 1411 * If this is true then we don't want to try writing to the 1412 * hypervisor because that is the kernel_threads job now. We'll 1413 * just add to the buffer. 1414 */ 1415 if (!(hvcsd->todo_mask & HVCS_TRY_WRITE)) 1416 /* won't send partial writes */ 1417 result = hvc_put_chars(unit_address, 1418 &hvcsd->buffer[0], 1419 hvcsd->chars_in_buffer); 1420 1421 /* 1422 * Since we know we have enough room in hvcsd->buffer for 1423 * tosend we record that it was sent regardless of whether the 1424 * hypervisor actually took it because we have it buffered. 1425 */ 1426 total_sent+=tosend; 1427 count-=tosend; 1428 if (result == 0) { 1429 hvcsd->todo_mask |= HVCS_TRY_WRITE; 1430 hvcs_kick(); 1431 break; 1432 } 1433 1434 hvcsd->chars_in_buffer = 0; 1435 /* 1436 * Test after the chars_in_buffer reset otherwise this could 1437 * deadlock our writes if hvc_put_chars fails. 1438 */ 1439 if (result < 0) 1440 break; 1441 } 1442 1443 spin_unlock_irqrestore(&hvcsd->lock, flags); 1444 1445 if (result == -1) 1446 return -EIO; 1447 else 1448 return total_sent; 1449} 1450 1451/* 1452 * This is really asking how much can we guarentee that we can send or that we 1453 * absolutely WILL BUFFER if we can't send it. This driver MUST honor the 1454 * return value, hence the reason for hvcs_struct buffering. 1455 */ 1456static int hvcs_write_room(struct tty_struct *tty) 1457{ 1458 struct hvcs_struct *hvcsd = tty->driver_data; 1459 1460 if (!hvcsd || hvcsd->open_count <= 0) 1461 return 0; 1462 1463 return HVCS_BUFF_LEN - hvcsd->chars_in_buffer; 1464} 1465 1466static int hvcs_chars_in_buffer(struct tty_struct *tty) 1467{ 1468 struct hvcs_struct *hvcsd = tty->driver_data; 1469 1470 return hvcsd->chars_in_buffer; 1471} 1472 1473static const struct tty_operations hvcs_ops = { 1474 .open = hvcs_open, 1475 .close = hvcs_close, 1476 .hangup = hvcs_hangup, 1477 .write = hvcs_write, 1478 .write_room = hvcs_write_room, 1479 .chars_in_buffer = hvcs_chars_in_buffer, 1480 .unthrottle = hvcs_unthrottle, 1481 .throttle = hvcs_throttle, 1482}; 1483 1484static int hvcs_alloc_index_list(int n) 1485{ 1486 int i; 1487 1488 hvcs_index_list = kmalloc(n * sizeof(hvcs_index_count),GFP_KERNEL); 1489 if (!hvcs_index_list) 1490 return -ENOMEM; 1491 hvcs_index_count = n; 1492 for (i = 0; i < hvcs_index_count; i++) 1493 hvcs_index_list[i] = -1; 1494 return 0; 1495} 1496 1497static void hvcs_free_index_list(void) 1498{ 1499 /* Paranoia check to be thorough. */ 1500 kfree(hvcs_index_list); 1501 hvcs_index_list = NULL; 1502 hvcs_index_count = 0; 1503} 1504 1505static int __init hvcs_module_init(void) 1506{ 1507 int rc; 1508 int num_ttys_to_alloc; 1509 1510 printk(KERN_INFO "Initializing %s\n", hvcs_driver_string); 1511 1512 /* Has the user specified an overload with an insmod param? */ 1513 if (hvcs_parm_num_devs <= 0 || 1514 (hvcs_parm_num_devs > HVCS_MAX_SERVER_ADAPTERS)) { 1515 num_ttys_to_alloc = HVCS_DEFAULT_SERVER_ADAPTERS; 1516 } else 1517 num_ttys_to_alloc = hvcs_parm_num_devs; 1518 1519 hvcs_tty_driver = alloc_tty_driver(num_ttys_to_alloc); 1520 if (!hvcs_tty_driver) 1521 return -ENOMEM; 1522 1523 if (hvcs_alloc_index_list(num_ttys_to_alloc)) { 1524 rc = -ENOMEM; 1525 goto index_fail; 1526 } 1527 1528 hvcs_tty_driver->owner = THIS_MODULE; 1529 1530 hvcs_tty_driver->driver_name = hvcs_driver_name; 1531 hvcs_tty_driver->name = hvcs_device_node; 1532 1533 /* 1534 * We'll let the system assign us a major number, indicated by leaving 1535 * it blank. 1536 */ 1537 1538 hvcs_tty_driver->minor_start = HVCS_MINOR_START; 1539 hvcs_tty_driver->type = TTY_DRIVER_TYPE_SYSTEM; 1540 1541 /* 1542 * We role our own so that we DONT ECHO. We can't echo because the 1543 * device we are connecting to already echoes by default and this would 1544 * throw us into a horrible recursive echo-echo-echo loop. 1545 */ 1546 hvcs_tty_driver->init_termios = hvcs_tty_termios; 1547 hvcs_tty_driver->flags = TTY_DRIVER_REAL_RAW; 1548 1549 tty_set_operations(hvcs_tty_driver, &hvcs_ops); 1550 1551 /* 1552 * The following call will result in sysfs entries that denote the 1553 * dynamically assigned major and minor numbers for our devices. 1554 */ 1555 if (tty_register_driver(hvcs_tty_driver)) { 1556 printk(KERN_ERR "HVCS: registration as a tty driver failed.\n"); 1557 rc = -EIO; 1558 goto register_fail; 1559 } 1560 1561 hvcs_pi_buff = kmalloc(PAGE_SIZE, GFP_KERNEL); 1562 if (!hvcs_pi_buff) { 1563 rc = -ENOMEM; 1564 goto buff_alloc_fail; 1565 } 1566 1567 hvcs_task = kthread_run(khvcsd, NULL, "khvcsd"); 1568 if (IS_ERR(hvcs_task)) { 1569 printk(KERN_ERR "HVCS: khvcsd creation failed. Driver not loaded.\n"); 1570 rc = -EIO; 1571 goto kthread_fail; 1572 } 1573 1574 rc = vio_register_driver(&hvcs_vio_driver); 1575 if (rc) { 1576 printk(KERN_ERR "HVCS: can't register vio driver\n"); 1577 goto vio_fail; 1578 } 1579 1580 /* 1581 * This needs to be done AFTER the vio_register_driver() call or else 1582 * the kobjects won't be initialized properly. 1583 */ 1584 rc = driver_create_file(&(hvcs_vio_driver.driver), &driver_attr_rescan); 1585 if (rc) { 1586 printk(KERN_ERR "HVCS: sysfs attr create failed\n"); 1587 goto attr_fail; 1588 } 1589 1590 printk(KERN_INFO "HVCS: driver module inserted.\n"); 1591 1592 return 0; 1593 1594attr_fail: 1595 vio_unregister_driver(&hvcs_vio_driver); 1596vio_fail: 1597 kthread_stop(hvcs_task); 1598kthread_fail: 1599 kfree(hvcs_pi_buff); 1600buff_alloc_fail: 1601 tty_unregister_driver(hvcs_tty_driver); 1602register_fail: 1603 hvcs_free_index_list(); 1604index_fail: 1605 put_tty_driver(hvcs_tty_driver); 1606 hvcs_tty_driver = NULL; 1607 return rc; 1608} 1609 1610static void __exit hvcs_module_exit(void) 1611{ 1612 /* 1613 * This driver receives hvcs_remove callbacks for each device upon 1614 * module removal. 1615 */ 1616 1617 /* 1618 * This synchronous operation will wake the khvcsd kthread if it is 1619 * asleep and will return when khvcsd has terminated. 1620 */ 1621 kthread_stop(hvcs_task); 1622 1623 spin_lock(&hvcs_pi_lock); 1624 kfree(hvcs_pi_buff); 1625 hvcs_pi_buff = NULL; 1626 spin_unlock(&hvcs_pi_lock); 1627 1628 driver_remove_file(&hvcs_vio_driver.driver, &driver_attr_rescan); 1629 1630 vio_unregister_driver(&hvcs_vio_driver); 1631 1632 tty_unregister_driver(hvcs_tty_driver); 1633 1634 hvcs_free_index_list(); 1635 1636 put_tty_driver(hvcs_tty_driver); 1637 1638 printk(KERN_INFO "HVCS: driver module removed.\n"); 1639} 1640 1641module_init(hvcs_module_init); 1642module_exit(hvcs_module_exit);