/* * 3215 console initialization code called from console_init(). * NOTE: This is called before kmalloc is available. */ static int __init con3215_init(void) { struct ccw_device *cdev; struct raw3215_info *raw; struct raw3215_req *req; int i; /* Check if 3215 is to be the console */ if (!CONSOLE_IS_3215) return -ENODEV; /* Set the console mode for VM */ if (MACHINE_IS_VM) { cpcmd("TERM CONMODE 3215", NULL, 0); cpcmd("TERM AUTOCR OFF", NULL, 0); } /* allocate 3215 request structures */ raw3215_freelist = NULL; spin_lock_init(&raw3215_freelist_lock); for (i = 0; i < NR_3215_REQ; i++) { req = (struct raw3215_req *) alloc_bootmem_low(sizeof(struct raw3215_req)); req->next = raw3215_freelist; raw3215_freelist = req; } cdev = ccw_device_probe_console(); if (!cdev) return -ENODEV; raw3215[0] = raw = (struct raw3215_info *) alloc_bootmem_low(sizeof(struct raw3215_info)); memset(raw, 0, sizeof(struct raw3215_info)); raw->buffer = (char *) alloc_bootmem_low(RAW3215_BUFFER_SIZE); raw->inbuf = (char *) alloc_bootmem_low(RAW3215_INBUF_SIZE); raw->cdev = cdev; raw->lock = get_ccwdev_lock(cdev); cdev->dev.driver_data = raw; cdev->handler = raw3215_irq; raw->flags |= RAW3215_FIXED; tasklet_init(&raw->tasklet, (void (*)(unsigned long)) raw3215_tasklet, (unsigned long) raw); init_waitqueue_head(&raw->empty_wait); /* Request the console irq */ if (raw3215_startup(raw) != 0) { free_bootmem((unsigned long) raw->inbuf, RAW3215_INBUF_SIZE); free_bootmem((unsigned long) raw->buffer, RAW3215_BUFFER_SIZE); free_bootmem((unsigned long) raw, sizeof(struct raw3215_info)); raw3215[0] = NULL; printk("Couldn't find a 3215 console device\n"); return -ENODEV; } register_console(&con3215); return 0; }
/* * 3215 console initialization code called from console_init(). * NOTE: This is called before kmalloc is available. */ void __init con3215_init(void) { raw3215_info *raw; raw3215_req *req; int irq; int i; /* Check if 3215 is to be the console */ if (!CONSOLE_IS_3215) return; irq = raw3215_find_dev(0); /* Set the console mode for VM */ if (MACHINE_IS_VM) { cpcmd("TERM CONMODE 3215", NULL, 0); cpcmd("TERM AUTOCR OFF", NULL, 0); } /* allocate 3215 request structures */ raw3215_freelist = NULL; spin_lock_init(&raw3215_freelist_lock); for (i = 0; i < NR_3215_REQ; i++) { req = (raw3215_req *) alloc_bootmem_low(sizeof(raw3215_req)); req->next = raw3215_freelist; raw3215_freelist = req; } ctrlchar_init(); #ifdef CONFIG_TN3215_CONSOLE raw3215[0] = raw = (raw3215_info *) alloc_bootmem_low(sizeof(raw3215_info)); memset(raw, 0, sizeof(raw3215_info)); raw->buffer = (char *) alloc_bootmem_low(RAW3215_BUFFER_SIZE); raw->inbuf = (char *) alloc_bootmem_low(RAW3215_INBUF_SIZE); /* Find the first console */ raw->irq = raw3215_find_dev(0); raw->flags |= RAW3215_FIXED; raw->tqueue.routine = raw3215_softint; raw->tqueue.data = raw; init_waitqueue_head(&raw->empty_wait); /* Request the console irq */ if ( raw3215_startup(raw) != 0 ) raw->irq = -1; if (raw->irq != -1) { register_console(&con3215); } else { free_bootmem((unsigned long) raw->inbuf, RAW3215_INBUF_SIZE); free_bootmem((unsigned long) raw->buffer, RAW3215_BUFFER_SIZE); free_bootmem((unsigned long) raw, sizeof(raw3215_info)); raw3215[0] = NULL; printk("Couldn't find a 3215 console device\n"); } #endif }
static void __init conmode_default(void) { char query_buffer[1024]; char *ptr; if (MACHINE_IS_VM) { cpcmd("QUERY CONSOLE", query_buffer, 1024, NULL); console_devno = simple_strtoul(query_buffer + 5, NULL, 16); ptr = strstr(query_buffer, "SUBCHANNEL ="); console_irq = simple_strtoul(ptr + 13, NULL, 16); cpcmd("QUERY TERM", query_buffer, 1024, NULL); ptr = strstr(query_buffer, "CONMODE"); /* * Set the conmode to 3215 so that the device recognition * will set the cu_type of the console to 3215. If the * conmode is 3270 and we don't set it back then both * 3215 and the 3270 driver will try to access the console * device (3215 as console and 3270 as normal tty). */ cpcmd("TERM CONMODE 3215", NULL, 0, NULL); if (ptr == NULL) { #if defined(CONFIG_SCLP_CONSOLE) || defined(CONFIG_SCLP_VT220_CONSOLE) SET_CONSOLE_SCLP; #endif return; } if (strncmp(ptr + 8, "3270", 4) == 0) { #if defined(CONFIG_TN3270_CONSOLE) SET_CONSOLE_3270; #elif defined(CONFIG_TN3215_CONSOLE) SET_CONSOLE_3215; #elif defined(CONFIG_SCLP_CONSOLE) || defined(CONFIG_SCLP_VT220_CONSOLE) SET_CONSOLE_SCLP; #endif } else if (strncmp(ptr + 8, "3215", 4) == 0) { #if defined(CONFIG_TN3215_CONSOLE) SET_CONSOLE_3215; #elif defined(CONFIG_TN3270_CONSOLE) SET_CONSOLE_3270; #elif defined(CONFIG_SCLP_CONSOLE) || defined(CONFIG_SCLP_VT220_CONSOLE) SET_CONSOLE_SCLP; #endif } } else if (MACHINE_IS_KVM) { if (sclp.has_vt220 && IS_ENABLED(CONFIG_SCLP_VT220_CONSOLE)) SET_CONSOLE_VT220; else if (sclp.has_linemode && IS_ENABLED(CONFIG_SCLP_CONSOLE)) SET_CONSOLE_SCLP; else SET_CONSOLE_HVC; } else { #if defined(CONFIG_SCLP_CONSOLE) || defined(CONFIG_SCLP_VT220_CONSOLE) SET_CONSOLE_SCLP; #endif } }
/* * 3215 console initialization code called from console_init(). */ static int __init con3215_init(void) { struct ccw_device *cdev; struct raw3215_info *raw; struct raw3215_req *req; int i; /* Check if 3215 is to be the console */ if (!CONSOLE_IS_3215) return -ENODEV; /* Set the console mode for VM */ if (MACHINE_IS_VM) { cpcmd("TERM CONMODE 3215", NULL, 0, NULL); cpcmd("TERM AUTOCR OFF", NULL, 0, NULL); } /* allocate 3215 request structures */ raw3215_freelist = NULL; spin_lock_init(&raw3215_freelist_lock); for (i = 0; i < NR_3215_REQ; i++) { req = kzalloc(sizeof(struct raw3215_req), GFP_KERNEL | GFP_DMA); if (!req) return -ENOMEM; req->next = raw3215_freelist; raw3215_freelist = req; } cdev = ccw_device_create_console(&raw3215_ccw_driver); if (IS_ERR(cdev)) return -ENODEV; raw3215[0] = raw = raw3215_alloc_info(); raw->cdev = cdev; dev_set_drvdata(&cdev->dev, raw); cdev->handler = raw3215_irq; raw->flags |= RAW3215_FIXED; if (ccw_device_enable_console(cdev)) { ccw_device_destroy_console(cdev); raw3215_free_info(raw); raw3215[0] = NULL; return -ENODEV; } /* Request the console irq */ if (raw3215_startup(raw) != 0) { raw3215_free_info(raw); raw3215[0] = NULL; return -ENODEV; } atomic_notifier_chain_register(&panic_notifier_list, &on_panic_nb); register_reboot_notifier(&on_reboot_nb); register_console(&con3215); return 0; }
/* * 3215 console initialization code called from console_init(). * NOTE: This is called before kmalloc is available. */ static int __init con3215_init(void) { struct ccw_device *cdev; struct raw3215_info *raw; struct raw3215_req *req; int i; /* Check if 3215 is to be the console */ if (!CONSOLE_IS_3215) return -ENODEV; /* Set the console mode for VM */ if (MACHINE_IS_VM) { cpcmd("TERM CONMODE 3215", NULL, 0, NULL); cpcmd("TERM AUTOCR OFF", NULL, 0, NULL); } /* allocate 3215 request structures */ raw3215_freelist = NULL; spin_lock_init(&raw3215_freelist_lock); for (i = 0; i < NR_3215_REQ; i++) { req = kzalloc(sizeof(struct raw3215_req), GFP_KERNEL | GFP_DMA); req->next = raw3215_freelist; raw3215_freelist = req; } cdev = ccw_device_probe_console(); if (IS_ERR(cdev)) return -ENODEV; raw3215[0] = raw = (struct raw3215_info *) kzalloc(sizeof(struct raw3215_info), GFP_KERNEL | GFP_DMA); raw->buffer = kzalloc(RAW3215_BUFFER_SIZE, GFP_KERNEL | GFP_DMA); raw->inbuf = kzalloc(RAW3215_INBUF_SIZE, GFP_KERNEL | GFP_DMA); raw->cdev = cdev; dev_set_drvdata(&cdev->dev, raw); cdev->handler = raw3215_irq; raw->flags |= RAW3215_FIXED; init_waitqueue_head(&raw->empty_wait); tasklet_init(&raw->tlet, raw3215_wakeup, (unsigned long) raw); /* Request the console irq */ if (raw3215_startup(raw) != 0) { kfree(raw->inbuf); kfree(raw->buffer); kfree(raw); raw3215[0] = NULL; return -ENODEV; } atomic_notifier_chain_register(&panic_notifier_list, &on_panic_nb); register_reboot_notifier(&on_reboot_nb); register_console(&con3215); return 0; }
static int vmpanic_notify(struct notifier_block *self, unsigned long event, void *data) { if (MACHINE_IS_VM && strlen(vmpanic_cmd) > 0) cpcmd(vmpanic_cmd, NULL, 0, NULL); return NOTIFY_OK; }
static ssize_t vmcp_write(struct file *file, const char __user * buff, size_t count, loff_t * ppos) { char *cmd; struct vmcp_session *session; if (count > 240) return -EINVAL; cmd = kmalloc(count + 1, GFP_KERNEL); if (!cmd) return -ENOMEM; if (copy_from_user(cmd, buff, count)) { kfree(cmd); return -EFAULT; } cmd[count] = '\0'; session = (struct vmcp_session *)file->private_data; if (down_interruptible(&session->mutex)) { kfree(cmd); return -ERESTARTSYS; } if (!session->response) session->response = (char *)__get_free_pages(GFP_KERNEL | __GFP_REPEAT | GFP_DMA, get_order(session->bufsize)); if (!session->response) { up(&session->mutex); kfree(cmd); return -ENOMEM; } debug_text_event(vmcp_debug, 1, cmd); session->resp_size = cpcmd(cmd, session->response, session->bufsize, &session->resp_code); up(&session->mutex); kfree(cmd); *ppos = 0; /* reset the file pointer after a command */ return count; }