66 #include <linux/device.h>
69 #include <linux/kernel.h>
72 #include <linux/list.h>
74 #include <linux/module.h>
76 #include <linux/sched.h>
77 #include <linux/slab.h>
79 #include <linux/stat.h>
80 #include <linux/tty.h>
84 #include <asm/uaccess.h>
128 #define HVCS_DRIVER_VERSION "1.3.3"
139 #define HVCS_CLOSE_WAIT (HZ/100)
149 #define HVCS_DEFAULT_SERVER_ADAPTERS 64
156 #define HVCS_MAX_SERVER_ADAPTERS 1024
164 #define HVCS_MINOR_START 0
173 #define __ALIGNED__ __attribute__((__aligned__(8)))
179 #define HVCS_BUFF_LEN 16
185 #define HVCS_MAX_FROM_USER 4096
192 static struct ktermios hvcs_tty_termios = {
207 static int hvcs_parm_num_devs = -1;
210 static const char hvcs_driver_name[] =
"hvcs";
211 static const char hvcs_device_node[] =
"hvcs";
212 static const char hvcs_driver_string[]
213 =
"IBM hvcs (Hypervisor Virtual Console Server) Driver";
216 static int hvcs_rescan_status;
233 static int *hvcs_index_list;
239 static int hvcs_index_count;
245 static int hvcs_kicked;
257 static unsigned long *hvcs_pi_buff;
308 static void hvcs_unthrottle(
struct tty_struct *tty);
309 static void hvcs_throttle(
struct tty_struct *tty);
310 static irqreturn_t hvcs_handle_interrupt(
int irq,
void *dev_instance);
313 const unsigned char *
buf,
int count);
314 static int hvcs_write_room(
struct tty_struct *tty);
315 static int hvcs_chars_in_buffer(
struct tty_struct *tty);
318 static void hvcs_set_pi(
struct hvcs_partner_info *pi,
321 static int hvcs_rescan_devices_list(
void);
323 static int hvcs_partner_connect(
struct hvcs_struct *hvcsd);
324 static void hvcs_partner_free(
struct hvcs_struct *hvcsd);
326 static int hvcs_enable_device(
struct hvcs_struct *hvcsd,
330 static void hvcs_close(
struct tty_struct *tty,
struct file *filp);
331 static void hvcs_hangup(
struct tty_struct * tty);
336 static int __init hvcs_module_init(
void);
337 static void __exit hvcs_module_exit(
void);
338 static int __devinit hvcs_initialize(
void);
340 #define HVCS_SCHED_READ 0x00000001
341 #define HVCS_QUICK_READ 0x00000002
342 #define HVCS_TRY_WRITE 0x00000004
343 #define HVCS_READ_MASK (HVCS_SCHED_READ | HVCS_QUICK_READ)
353 struct vio_dev *viod = to_vio_dev(dev);
360 spin_unlock_irqrestore(&hvcsd->
lock, flags);
367 struct vio_dev *viod = to_vio_dev(dev);
374 spin_unlock_irqrestore(&hvcsd->
lock, flags);
392 struct vio_dev *viod = to_vio_dev(dev);
399 spin_unlock_irqrestore(&hvcsd->
lock, flags);
404 S_IRUGO |
S_IWUSR, hvcs_current_vty_show, hvcs_current_vty_store);
409 struct vio_dev *viod = to_vio_dev(dev);
419 if (hvcsd->
port.count > 0) {
420 spin_unlock_irqrestore(&hvcsd->
lock, flags);
422 "The hvcs device node is still in use.\n");
427 spin_unlock_irqrestore(&hvcsd->
lock, flags);
429 " vty-server is not connected to a vty.\n");
433 hvcs_partner_free(hvcsd);
435 " partner vty@%X:%d connection.\n",
436 hvcsd->
vdev->unit_address,
440 spin_unlock_irqrestore(&hvcsd->
lock, flags);
446 struct vio_dev *viod = to_vio_dev(dev);
453 spin_unlock_irqrestore(&hvcsd->
lock, flags);
457 hvcs_vterm_state_show, hvcs_vterm_state_store);
461 struct vio_dev *viod = to_vio_dev(dev);
468 spin_unlock_irqrestore(&hvcsd->
lock, flags);
474 static struct attribute *hvcs_attrs[] = {
475 &dev_attr_partner_vtys.attr,
476 &dev_attr_partner_clcs.attr,
477 &dev_attr_current_vty.attr,
478 &dev_attr_vterm_state.attr,
479 &dev_attr_index.attr,
497 && (hvcs_rescan_status != 0))
500 hvcs_rescan_status = 1;
503 hvcs_rescan_devices_list();
504 hvcs_rescan_status = 0;
511 static void hvcs_kick(
void)
518 static void hvcs_unthrottle(
struct tty_struct *tty)
525 spin_unlock_irqrestore(&hvcsd->
lock, flags);
529 static void hvcs_throttle(
struct tty_struct *tty)
535 vio_disable_interrupts(hvcsd->
vdev);
536 spin_unlock_irqrestore(&hvcsd->
lock, flags);
544 static irqreturn_t hvcs_handle_interrupt(
int irq,
void *dev_instance)
548 spin_lock(&hvcsd->
lock);
549 vio_disable_interrupts(hvcsd->
vdev);
551 spin_unlock(&hvcsd->
lock);
558 static void hvcs_try_write(
struct hvcs_struct *hvcsd)
598 unit_address = hvcsd->
vdev->unit_address;
599 tty = hvcsd->
port.tty;
601 hvcs_try_write(hvcsd);
616 tty_insert_flip_string(tty, buf, got);
623 spin_unlock_irqrestore(&hvcsd->
lock, flags);
631 vio_enable_interrupts(hvcsd->
vdev);
632 spin_unlock_irqrestore(&hvcsd->
lock, flags);
638 spin_unlock_irqrestore(&hvcsd->
lock, flags);
642 static int khvcsd(
void *
unused)
654 spin_lock(&hvcs_structs_lock);
656 hvcs_todo_mask |= hvcs_io(hvcsd);
658 spin_unlock(&hvcs_structs_lock);
680 {
"serial-server",
"hvterm2"},
685 static void hvcs_return_index(
int index)
688 if (!hvcs_index_list)
690 if (index < 0 || index >= hvcs_index_count)
692 if (hvcs_index_list[index] == -1)
695 hvcs_index_list[
index] = -1;
698 static void hvcs_destruct_port(
struct tty_port *
p)
704 spin_lock(&hvcs_structs_lock);
711 hvcs_partner_free(hvcsd);
713 " partner vty@%X:%d connection.\n",
714 hvcsd->
vdev->unit_address,
719 hvcsd->
vdev->unit_address);
726 hvcs_return_index(hvcsd->
index);
729 spin_unlock_irqrestore(&hvcsd->
lock, flags);
730 spin_unlock(&hvcs_structs_lock);
738 .destruct = hvcs_destruct_port,
741 static int hvcs_get_index(
void)
745 if (!hvcs_index_list) {
750 for(i = 0; i < hvcs_index_count; i++) {
751 if (hvcs_index_list[i] == -1) {
752 hvcs_index_list[
i] = 0;
773 rc = hvcs_initialize();
775 pr_err(
"HVCS: Failed to initialize core driver.\n");
780 index = hvcs_get_index();
790 hvcsd->
port.ops = &hvcs_port_ops;
807 if (hvcs_get_pi(hvcsd)) {
809 " info for vty-server@%X on device probe.\n",
810 hvcsd->
vdev->unit_address);
818 spin_lock(&hvcs_structs_lock);
820 spin_unlock(&hvcs_structs_lock);
824 printk(
KERN_ERR "HVCS: Can't create sysfs attrs for vty-server@%X\n",
825 hvcsd->
vdev->unit_address);
829 printk(
KERN_INFO "HVCS: vty-server@%X added to the vio bus.\n", dev->unit_address);
851 tty = hvcsd->
port.tty;
853 spin_unlock_irqrestore(&hvcsd->
lock, flags);
870 " vio bus.\n", dev->unit_address);
875 .id_table = hvcs_driver_table,
878 .name = hvcs_driver_name,
882 static void hvcs_set_pi(
struct hvcs_partner_info *pi,
struct hvcs_struct *hvcsd)
888 clclength =
strlen(&pi->location_code[0]);
889 if (clclength > HVCS_CLC_LENGTH)
890 clclength = HVCS_CLC_LENGTH;
894 &pi->location_code[0], clclength + 1);
912 struct hvcs_partner_info *pi;
917 spin_lock(&hvcs_pi_lock);
919 spin_unlock(&hvcs_pi_lock);
923 spin_unlock(&hvcs_pi_lock);
926 " info for vty-server@%x.\n", unit_address);
935 hvcs_set_pi(pi, hvcsd);
945 static
int hvcs_rescan_devices_list(
void)
950 spin_lock(&hvcs_structs_lock);
955 spin_unlock_irqrestore(&hvcsd->
lock, flags);
958 spin_unlock(&hvcs_structs_lock);
981 static int hvcs_partner_connect(
struct hvcs_struct *hvcsd)
984 unsigned int unit_address = hvcsd->
vdev->unit_address;
999 }
else if (retval != -
EINVAL)
1006 if (hvcs_get_pi(hvcsd))
1009 if (!hvcs_has_pi(hvcsd))
1027 " vty is busy. Try again later.\n");
1032 static void hvcs_partner_free(
struct hvcs_struct *hvcsd)
1037 }
while (retval == -
EBUSY);
1043 unsigned int irq,
struct vio_dev *vdev)
1045 unsigned long flags;
1052 if (!(rc =
request_irq(irq, &hvcs_handle_interrupt,
1053 0,
"ibmhvcs", hvcsd))) {
1058 if (vio_enable_interrupts(vdev) == H_SUCCESS)
1062 " vty-server@%X.\n", unit_address);
1067 " vty-server@%X.\n", unit_address);
1070 hvcs_partner_free(hvcsd);
1071 spin_unlock_irqrestore(&hvcsd->
lock, flags);
1084 static struct hvcs_struct *hvcs_get_by_index(
int index)
1087 unsigned long flags;
1089 spin_lock(&hvcs_structs_lock);
1092 if (hvcsd->
index == index) {
1093 tty_port_get(&hvcsd->
port);
1094 spin_unlock_irqrestore(&hvcsd->
lock, flags);
1095 spin_unlock(&hvcs_structs_lock);
1098 spin_unlock_irqrestore(&hvcsd->
lock, flags);
1100 spin_unlock(&hvcs_structs_lock);
1117 hvcsd = hvcs_get_by_index(tty->
index);
1120 " with tty->index %d.\n", tty->
index);
1127 retval = hvcs_partner_connect(hvcsd);
1129 spin_unlock_irqrestore(&hvcsd->
lock, flags);
1135 hvcsd->
port.count = 0;
1136 hvcsd->
port.tty = tty;
1145 irq = hvcsd->
vdev->irq;
1147 unit_address = hvcsd->
vdev->unit_address;
1150 spin_unlock_irqrestore(&hvcsd->
lock, flags);
1156 retval = hvcs_enable_device(hvcsd, unit_address, irq, vdev);
1169 vio_disable_interrupts(hvcsd->
vdev);
1170 spin_unlock_irqrestore(&hvcsd->
lock, flags);
1185 unsigned long flags;
1188 hvcsd->
port.count++;
1190 spin_unlock_irqrestore(&hvcsd->
lock, flags);
1195 hvcsd->
vdev->unit_address );
1200 static void hvcs_close(
struct tty_struct *tty,
struct file *filp)
1203 unsigned long flags;
1224 if (--hvcsd->
port.count == 0) {
1226 vio_disable_interrupts(hvcsd->
vdev);
1235 irq = hvcsd->
vdev->irq;
1236 spin_unlock_irqrestore(&hvcsd->
lock, flags);
1249 }
else if (hvcsd->
port.count < 0) {
1251 " is missmanaged.\n",
1252 hvcsd->
vdev->unit_address, hvcsd->
port.count);
1255 spin_unlock_irqrestore(&hvcsd->
lock, flags);
1258 static void hvcs_cleanup(
struct tty_struct * tty)
1265 static void hvcs_hangup(
struct tty_struct * tty)
1268 unsigned long flags;
1269 int temp_open_count;
1274 temp_open_count = hvcsd->
port.count;
1281 vio_disable_interrupts(hvcsd->
vdev);
1289 hvcsd->
port.count = 0;
1296 irq = hvcsd->
vdev->irq;
1298 spin_unlock_irqrestore(&hvcsd->
lock, flags);
1307 while(temp_open_count) {
1325 static int hvcs_write(
struct tty_struct *tty,
1326 const unsigned char *buf,
int count)
1330 const unsigned char *charbuf;
1331 unsigned long flags;
1346 " HVCS_MAX_FROM_USER.\n");
1360 if (hvcsd->
port.count <= 0) {
1361 spin_unlock_irqrestore(&hvcsd->
lock, flags);
1365 unit_address = hvcsd->
vdev->unit_address;
1377 &charbuf[total_sent],
1417 spin_unlock_irqrestore(&hvcsd->
lock, flags);
1430 static int hvcs_write_room(
struct tty_struct *tty)
1434 if (!hvcsd || hvcsd->
port.count <= 0)
1440 static int hvcs_chars_in_buffer(
struct tty_struct *tty)
1448 .install = hvcs_install,
1450 .close = hvcs_close,
1451 .cleanup = hvcs_cleanup,
1452 .hangup = hvcs_hangup,
1453 .write = hvcs_write,
1454 .write_room = hvcs_write_room,
1455 .chars_in_buffer = hvcs_chars_in_buffer,
1456 .unthrottle = hvcs_unthrottle,
1457 .throttle = hvcs_throttle,
1460 static int hvcs_alloc_index_list(
int n)
1465 if (!hvcs_index_list)
1467 hvcs_index_count =
n;
1468 for (i = 0; i < hvcs_index_count; i++)
1469 hvcs_index_list[i] = -1;
1473 static void hvcs_free_index_list(
void)
1476 kfree(hvcs_index_list);
1477 hvcs_index_list =
NULL;
1478 hvcs_index_count = 0;
1481 static int __devinit hvcs_initialize(
void)
1483 int rc, num_ttys_to_alloc;
1492 if (hvcs_parm_num_devs <= 0 ||
1496 num_ttys_to_alloc = hvcs_parm_num_devs;
1498 hvcs_tty_driver = alloc_tty_driver(num_ttys_to_alloc);
1499 if (!hvcs_tty_driver)
1502 if (hvcs_alloc_index_list(num_ttys_to_alloc)) {
1508 hvcs_tty_driver->
name = hvcs_device_node;
1539 if (!hvcs_pi_buff) {
1541 goto buff_alloc_fail;
1545 if (IS_ERR(hvcs_task)) {
1558 hvcs_free_index_list();
1561 hvcs_tty_driver =
NULL;
1566 static int __init hvcs_module_init(
void)
1574 pr_info(
"HVCS: Driver registered.\n");
1586 static void __exit hvcs_module_exit(
void)
1602 spin_lock(&hvcs_pi_lock);
1604 hvcs_pi_buff =
NULL;
1605 spin_unlock(&hvcs_pi_lock);
1611 hvcs_free_index_list();