File Index
Files and directories
Sign in
FILE

raw3270.c

File preview with syntax highlighting.

linux-6.19.14/drivers/s390/char/raw3270.c C
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * IBM/3270 Driver - core functions.
   4 *
   5 * Author(s):
   6 *   Original 3270 Code for 2.4 written by Richard Hitt (UTS Global)
   7 *   Rewritten for 2.5 by Martin Schwidefsky <schwidefsky@de.ibm.com>
   8 *     Copyright IBM Corp. 2003, 2009
   9 */
  10
  11#include <linux/export.h>
  12#include <linux/module.h>
  13#include <linux/err.h>
  14#include <linux/init.h>
  15#include <linux/interrupt.h>
  16#include <linux/list.h>
  17#include <linux/slab.h>
  18#include <linux/types.h>
  19#include <linux/wait.h>
  20
  21#include <asm/machine.h>
  22#include <asm/ccwdev.h>
  23#include <asm/cio.h>
  24#include <asm/ebcdic.h>
  25#include <asm/diag.h>
  26
  27#include "raw3270.h"
  28
  29#include <linux/major.h>
  30#include <linux/kdev_t.h>
  31#include <linux/device.h>
  32#include <linux/mutex.h>
  33
  34const struct class class3270 = {
  35	.name = "3270",
  36};
  37EXPORT_SYMBOL(class3270);
  38
  39/* The main 3270 data structure. */
  40struct raw3270 {
  41	struct list_head list;
  42	struct ccw_device *cdev;
  43	int minor;
  44
  45	int model, rows, cols;
  46	int old_model, old_rows, old_cols;
  47	unsigned int state;
  48	unsigned long flags;
  49
  50	struct list_head req_queue;	/* Request queue. */
  51	struct list_head view_list;	/* List of available views. */
  52	struct raw3270_view *view;	/* Active view. */
  53
  54	struct timer_list timer;	/* Device timer. */
  55
  56	unsigned char *ascebc;		/* ascii -> ebcdic table */
  57
  58	struct raw3270_view init_view;
  59	struct raw3270_request init_reset;
  60	struct raw3270_request init_readpart;
  61	struct raw3270_request init_readmod;
  62	unsigned char init_data[256];
  63	struct work_struct resize_work;
  64};
  65
  66/* raw3270->state */
  67#define RAW3270_STATE_INIT	0	/* Initial state */
  68#define RAW3270_STATE_RESET	1	/* Reset command is pending */
  69#define RAW3270_STATE_W4ATTN	2	/* Wait for attention interrupt */
  70#define RAW3270_STATE_READMOD	3	/* Read partition is pending */
  71#define RAW3270_STATE_READY	4	/* Device is usable by views */
  72
  73/* raw3270->flags */
  74#define RAW3270_FLAGS_14BITADDR	0	/* 14-bit buffer addresses */
  75#define RAW3270_FLAGS_BUSY	1	/* Device busy, leave it alone */
  76#define RAW3270_FLAGS_CONSOLE	2	/* Device is the console. */
  77
  78/* Semaphore to protect global data of raw3270 (devices, views, etc). */
  79static DEFINE_MUTEX(raw3270_mutex);
  80
  81/* List of 3270 devices. */
  82static LIST_HEAD(raw3270_devices);
  83
  84/*
  85 * Flag to indicate if the driver has been registered. Some operations
  86 * like waiting for the end of i/o need to be done differently as long
  87 * as the kernel is still starting up (console support).
  88 */
  89static int raw3270_registered;
  90
  91/* Module parameters */
  92static bool tubxcorrect;
  93module_param(tubxcorrect, bool, 0);
  94
  95/*
  96 * Wait queue for device init/delete, view delete.
  97 */
  98DECLARE_WAIT_QUEUE_HEAD(raw3270_wait_queue);
  99EXPORT_SYMBOL(raw3270_wait_queue);
 100
 101static void __raw3270_disconnect(struct raw3270 *rp);
 102
 103/*
 104 * Encode array for 12 bit 3270 addresses.
 105 */
 106static unsigned char raw3270_ebcgraf[64] =	{
 107	0x40, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
 108	0xc8, 0xc9, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
 109	0x50, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
 110	0xd8, 0xd9, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
 111	0x60, 0x61, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
 112	0xe8, 0xe9, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
 113	0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
 114	0xf8, 0xf9, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f
 115};
 116
 117static inline int raw3270_state_ready(struct raw3270 *rp)
 118{
 119	return rp->state == RAW3270_STATE_READY;
 120}
 121
 122void raw3270_buffer_address(struct raw3270 *rp, char *cp, int x, int y)
 123{
 124	int addr;
 125
 126	if (x < 0)
 127		x = max_t(int, 0, rp->view->cols + x);
 128	if (y < 0)
 129		y = max_t(int, 0, rp->view->rows + y);
 130	addr = (y * rp->view->cols) + x;
 131	if (test_bit(RAW3270_FLAGS_14BITADDR, &rp->flags)) {
 132		cp[0] = (addr >> 8) & 0x3f;
 133		cp[1] = addr & 0xff;
 134	} else {
 135		cp[0] = raw3270_ebcgraf[(addr >> 6) & 0x3f];
 136		cp[1] = raw3270_ebcgraf[addr & 0x3f];
 137	}
 138}
 139EXPORT_SYMBOL(raw3270_buffer_address);
 140
 141/*
 142 * Allocate a new 3270 ccw request
 143 */
 144struct raw3270_request *raw3270_request_alloc(size_t size)
 145{
 146	struct raw3270_request *rq;
 147
 148	/* Allocate request structure */
 149	rq = kzalloc(sizeof(*rq), GFP_KERNEL | GFP_DMA);
 150	if (!rq)
 151		return ERR_PTR(-ENOMEM);
 152
 153	/* alloc output buffer. */
 154	if (size > 0) {
 155		rq->buffer = kmalloc(size, GFP_KERNEL | GFP_DMA);
 156		if (!rq->buffer) {
 157			kfree(rq);
 158			return ERR_PTR(-ENOMEM);
 159		}
 160	}
 161	rq->size = size;
 162	INIT_LIST_HEAD(&rq->list);
 163
 164	/*
 165	 * Setup ccw.
 166	 */
 167	if (rq->buffer)
 168		rq->ccw.cda = virt_to_dma32(rq->buffer);
 169	rq->ccw.flags = CCW_FLAG_SLI;
 170
 171	return rq;
 172}
 173EXPORT_SYMBOL(raw3270_request_alloc);
 174
 175/*
 176 * Free 3270 ccw request
 177 */
 178void raw3270_request_free(struct raw3270_request *rq)
 179{
 180	kfree(rq->buffer);
 181	kfree(rq);
 182}
 183EXPORT_SYMBOL(raw3270_request_free);
 184
 185/*
 186 * Reset request to initial state.
 187 */
 188int raw3270_request_reset(struct raw3270_request *rq)
 189{
 190	if (WARN_ON_ONCE(!list_empty(&rq->list)))
 191		return -EBUSY;
 192	rq->ccw.cmd_code = 0;
 193	rq->ccw.count = 0;
 194	if (rq->buffer)
 195		rq->ccw.cda = virt_to_dma32(rq->buffer);
 196	rq->ccw.flags = CCW_FLAG_SLI;
 197	rq->rescnt = 0;
 198	rq->rc = 0;
 199	return 0;
 200}
 201EXPORT_SYMBOL(raw3270_request_reset);
 202
 203/*
 204 * Set command code to ccw of a request.
 205 */
 206void raw3270_request_set_cmd(struct raw3270_request *rq, u8 cmd)
 207{
 208	rq->ccw.cmd_code = cmd;
 209}
 210EXPORT_SYMBOL(raw3270_request_set_cmd);
 211
 212/*
 213 * Add data fragment to output buffer.
 214 */
 215int raw3270_request_add_data(struct raw3270_request *rq, void *data, size_t size)
 216{
 217	if (size + rq->ccw.count > rq->size)
 218		return -E2BIG;
 219	memcpy(rq->buffer + rq->ccw.count, data, size);
 220	rq->ccw.count += size;
 221	return 0;
 222}
 223EXPORT_SYMBOL(raw3270_request_add_data);
 224
 225/*
 226 * Set address/length pair to ccw of a request.
 227 */
 228void raw3270_request_set_data(struct raw3270_request *rq, void *data, size_t size)
 229{
 230	rq->ccw.cda = virt_to_dma32(data);
 231	rq->ccw.count = size;
 232}
 233EXPORT_SYMBOL(raw3270_request_set_data);
 234
 235/*
 236 * Set idal buffer to ccw of a request.
 237 */
 238void raw3270_request_set_idal(struct raw3270_request *rq, struct idal_buffer *ib)
 239{
 240	rq->ccw.cda = virt_to_dma32(ib->data);
 241	rq->ccw.count = ib->size;
 242	rq->ccw.flags |= CCW_FLAG_IDA;
 243}
 244EXPORT_SYMBOL(raw3270_request_set_idal);
 245
 246/*
 247 * Add the request to the request queue, try to start it if the
 248 * 3270 device is idle. Return without waiting for end of i/o.
 249 */
 250static int __raw3270_start(struct raw3270 *rp, struct raw3270_view *view,
 251			   struct raw3270_request *rq)
 252{
 253	rq->view = view;
 254	raw3270_get_view(view);
 255	if (list_empty(&rp->req_queue) &&
 256	    !test_bit(RAW3270_FLAGS_BUSY, &rp->flags)) {
 257		/* No other requests are on the queue. Start this one. */
 258		rq->rc = ccw_device_start(rp->cdev, &rq->ccw,
 259					  (unsigned long)rq, 0, 0);
 260		if (rq->rc) {
 261			raw3270_put_view(view);
 262			return rq->rc;
 263		}
 264	}
 265	list_add_tail(&rq->list, &rp->req_queue);
 266	return 0;
 267}
 268
 269int raw3270_view_active(struct raw3270_view *view)
 270{
 271	struct raw3270 *rp = view->dev;
 272
 273	return rp && rp->view == view;
 274}
 275
 276int raw3270_start(struct raw3270_view *view, struct raw3270_request *rq)
 277{
 278	unsigned long flags;
 279	struct raw3270 *rp;
 280	int rc;
 281
 282	spin_lock_irqsave(get_ccwdev_lock(view->dev->cdev), flags);
 283	rp = view->dev;
 284	if (!rp || rp->view != view)
 285		rc = -EACCES;
 286	else if (!raw3270_state_ready(rp))
 287		rc = -EBUSY;
 288	else
 289		rc =  __raw3270_start(rp, view, rq);
 290	spin_unlock_irqrestore(get_ccwdev_lock(view->dev->cdev), flags);
 291	return rc;
 292}
 293EXPORT_SYMBOL(raw3270_start);
 294
 295int raw3270_start_request(struct raw3270_view *view, struct raw3270_request *rq,
 296			  int cmd, void *data, size_t len)
 297{
 298	int rc;
 299
 300	rc = raw3270_request_reset(rq);
 301	if (rc)
 302		return rc;
 303	raw3270_request_set_cmd(rq, cmd);
 304	rc = raw3270_request_add_data(rq, data, len);
 305	if (rc)
 306		return rc;
 307	return raw3270_start(view, rq);
 308}
 309EXPORT_SYMBOL(raw3270_start_request);
 310
 311int raw3270_start_locked(struct raw3270_view *view, struct raw3270_request *rq)
 312{
 313	struct raw3270 *rp;
 314	int rc;
 315
 316	rp = view->dev;
 317	if (!rp || rp->view != view)
 318		rc = -EACCES;
 319	else if (!raw3270_state_ready(rp))
 320		rc = -EBUSY;
 321	else
 322		rc =  __raw3270_start(rp, view, rq);
 323	return rc;
 324}
 325EXPORT_SYMBOL(raw3270_start_locked);
 326
 327int raw3270_start_irq(struct raw3270_view *view, struct raw3270_request *rq)
 328{
 329	struct raw3270 *rp;
 330
 331	rp = view->dev;
 332	rq->view = view;
 333	raw3270_get_view(view);
 334	list_add_tail(&rq->list, &rp->req_queue);
 335	return 0;
 336}
 337EXPORT_SYMBOL(raw3270_start_irq);
 338
 339/*
 340 * 3270 interrupt routine, called from the ccw_device layer
 341 */
 342static void raw3270_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
 343{
 344	struct raw3270 *rp;
 345	struct raw3270_view *view;
 346	struct raw3270_request *rq;
 347
 348	rp = dev_get_drvdata(&cdev->dev);
 349	if (!rp)
 350		return;
 351	rq = (struct raw3270_request *)intparm;
 352	view = rq ? rq->view : rp->view;
 353
 354	if (!IS_ERR(irb)) {
 355		/* Handle CE-DE-UE and subsequent UDE */
 356		if (irb->scsw.cmd.dstat & DEV_STAT_DEV_END)
 357			clear_bit(RAW3270_FLAGS_BUSY, &rp->flags);
 358		if (irb->scsw.cmd.dstat == (DEV_STAT_CHN_END |
 359					    DEV_STAT_DEV_END |
 360					    DEV_STAT_UNIT_EXCEP))
 361			set_bit(RAW3270_FLAGS_BUSY, &rp->flags);
 362		/* Handle disconnected devices */
 363		if ((irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) &&
 364		    (irb->ecw[0] & SNS0_INTERVENTION_REQ)) {
 365			set_bit(RAW3270_FLAGS_BUSY, &rp->flags);
 366			if (rp->state > RAW3270_STATE_RESET)
 367				__raw3270_disconnect(rp);
 368		}
 369		/* Call interrupt handler of the view */
 370		if (view)
 371			view->fn->intv(view, rq, irb);
 372	}
 373
 374	if (test_bit(RAW3270_FLAGS_BUSY, &rp->flags))
 375		/* Device busy, do not start I/O */
 376		return;
 377
 378	if (rq && !list_empty(&rq->list)) {
 379		/* The request completed, remove from queue and do callback. */
 380		list_del_init(&rq->list);
 381		if (rq->callback)
 382			rq->callback(rq, rq->callback_data);
 383		/* Do put_device for get_device in raw3270_start. */
 384		raw3270_put_view(view);
 385	}
 386
 387	/*
 388	 * Try to start each request on request queue until one is
 389	 * started successful.
 390	 */
 391	while (!list_empty(&rp->req_queue)) {
 392		rq = list_entry(rp->req_queue.next, struct raw3270_request, list);
 393		rq->rc = ccw_device_start(rp->cdev, &rq->ccw,
 394					  (unsigned long)rq, 0, 0);
 395		if (rq->rc == 0)
 396			break;
 397		/* Start failed. Remove request and do callback. */
 398		list_del_init(&rq->list);
 399		if (rq->callback)
 400			rq->callback(rq, rq->callback_data);
 401		/* Do put_device for get_device in raw3270_start. */
 402		raw3270_put_view(view);
 403	}
 404}
 405
 406/*
 407 * To determine the size of the 3270 device we need to do:
 408 * 1) send a 'read partition' data stream to the device
 409 * 2) wait for the attn interrupt that precedes the query reply
 410 * 3) do a read modified to get the query reply
 411 * To make things worse we have to cope with intervention
 412 * required (3270 device switched to 'stand-by') and command
 413 * rejects (old devices that can't do 'read partition').
 414 */
 415struct raw3270_ua {	/* Query Reply structure for Usable Area */
 416	struct {	/* Usable Area Query Reply Base */
 417		short l;	/* Length of this structured field */
 418		char  sfid;	/* 0x81 if Query Reply */
 419		char  qcode;	/* 0x81 if Usable Area */
 420		char  flags0;
 421		char  flags1;
 422		short w;	/* Width of usable area */
 423		short h;	/* Heigth of usavle area */
 424		char  units;	/* 0x00:in; 0x01:mm */
 425		int   xr;
 426		int   yr;
 427		char  aw;
 428		char  ah;
 429		short buffsz;	/* Character buffer size, bytes */
 430		char  xmin;
 431		char  ymin;
 432		char  xmax;
 433		char  ymax;
 434	} __packed uab;
 435	struct {	/* Alternate Usable Area Self-Defining Parameter */
 436		char  l;	/* Length of this Self-Defining Parm */
 437		char  sdpid;	/* 0x02 if Alternate Usable Area */
 438		char  res;
 439		char  auaid;	/* 0x01 is Id for the A U A */
 440		short wauai;	/* Width of AUAi */
 441		short hauai;	/* Height of AUAi */
 442		char  auaunits;	/* 0x00:in, 0x01:mm */
 443		int   auaxr;
 444		int   auayr;
 445		char  awauai;
 446		char  ahauai;
 447	} __packed aua;
 448} __packed;
 449
 450static void raw3270_size_device_vm(struct raw3270 *rp)
 451{
 452	int rc, model;
 453	struct ccw_dev_id dev_id;
 454	struct diag210 diag_data;
 455	struct diag8c diag8c_data;
 456
 457	ccw_device_get_id(rp->cdev, &dev_id);
 458	rc = diag8c(&diag8c_data, &dev_id);
 459	if (!rc) {
 460		rp->model = 2;
 461		rp->rows = diag8c_data.height;
 462		rp->cols = diag8c_data.width;
 463		if (diag8c_data.flags & 1)
 464			set_bit(RAW3270_FLAGS_14BITADDR, &rp->flags);
 465		return;
 466	}
 467
 468	diag_data.vrdcdvno = dev_id.devno;
 469	diag_data.vrdclen = sizeof(struct diag210);
 470	rc = diag210(&diag_data);
 471	model = diag_data.vrdccrmd;
 472	/* Use default model 2 if the size could not be detected */
 473	if (rc || model < 2 || model > 5)
 474		model = 2;
 475	switch (model) {
 476	case 2:
 477		rp->model = model;
 478		rp->rows = 24;
 479		rp->cols = 80;
 480		break;
 481	case 3:
 482		rp->model = model;
 483		rp->rows = 32;
 484		rp->cols = 80;
 485		break;
 486	case 4:
 487		rp->model = model;
 488		rp->rows = 43;
 489		rp->cols = 80;
 490		break;
 491	case 5:
 492		rp->model = model;
 493		rp->rows = 27;
 494		rp->cols = 132;
 495		break;
 496	}
 497}
 498
 499static void raw3270_size_device(struct raw3270 *rp, char *init_data)
 500{
 501	struct raw3270_ua *uap;
 502
 503	/* Got a Query Reply */
 504	uap = (struct raw3270_ua *)(init_data + 1);
 505	/* Paranoia check. */
 506	if (init_data[0] != 0x88 || uap->uab.qcode != 0x81) {
 507		/* Couldn't detect size. Use default model 2. */
 508		rp->model = 2;
 509		rp->rows = 24;
 510		rp->cols = 80;
 511		return;
 512	}
 513	/* Copy rows/columns of default Usable Area */
 514	rp->rows = uap->uab.h;
 515	rp->cols = uap->uab.w;
 516	/* Check for 14 bit addressing */
 517	if ((uap->uab.flags0 & 0x0d) == 0x01)
 518		set_bit(RAW3270_FLAGS_14BITADDR, &rp->flags);
 519	/* Check for Alternate Usable Area */
 520	if (uap->uab.l == sizeof(struct raw3270_ua) &&
 521	    uap->aua.sdpid == 0x02) {
 522		rp->rows = uap->aua.hauai;
 523		rp->cols = uap->aua.wauai;
 524	}
 525	/* Try to find a model. */
 526	rp->model = 0;
 527	if (rp->rows == 24 && rp->cols == 80)
 528		rp->model = 2;
 529	if (rp->rows == 32 && rp->cols == 80)
 530		rp->model = 3;
 531	if (rp->rows == 43 && rp->cols == 80)
 532		rp->model = 4;
 533	if (rp->rows == 27 && rp->cols == 132)
 534		rp->model = 5;
 535}
 536
 537static void raw3270_resize_work(struct work_struct *work)
 538{
 539	struct raw3270 *rp = container_of(work, struct raw3270, resize_work);
 540	struct raw3270_view *view;
 541
 542	/* Notify views about new size */
 543	list_for_each_entry(view, &rp->view_list, list) {
 544		if (view->fn->resize)
 545			view->fn->resize(view, rp->model, rp->rows, rp->cols,
 546					 rp->old_model, rp->old_rows, rp->old_cols);
 547	}
 548	rp->old_cols = rp->cols;
 549	rp->old_rows = rp->rows;
 550	rp->old_model = rp->model;
 551	/* Setup processing done, now activate a view */
 552	list_for_each_entry(view, &rp->view_list, list) {
 553		rp->view = view;
 554		if (view->fn->activate(view) == 0)
 555			break;
 556		rp->view = NULL;
 557	}
 558}
 559
 560static void raw3270_size_device_done(struct raw3270 *rp)
 561{
 562	rp->view = NULL;
 563	rp->state = RAW3270_STATE_READY;
 564	schedule_work(&rp->resize_work);
 565}
 566
 567void raw3270_read_modified_cb(struct raw3270_request *rq, void *data)
 568{
 569	struct raw3270 *rp = rq->view->dev;
 570
 571	raw3270_size_device(rp, data);
 572	raw3270_size_device_done(rp);
 573}
 574EXPORT_SYMBOL(raw3270_read_modified_cb);
 575
 576static void raw3270_read_modified(struct raw3270 *rp)
 577{
 578	if (rp->state != RAW3270_STATE_W4ATTN)
 579		return;
 580	/* Use 'read modified' to get the result of a read partition. */
 581	memset(&rp->init_readmod, 0, sizeof(rp->init_readmod));
 582	memset(&rp->init_data, 0, sizeof(rp->init_data));
 583	rp->init_readmod.ccw.cmd_code = TC_READMOD;
 584	rp->init_readmod.ccw.flags = CCW_FLAG_SLI;
 585	rp->init_readmod.ccw.count = sizeof(rp->init_data);
 586	rp->init_readmod.ccw.cda = virt_to_dma32(rp->init_data);
 587	rp->init_readmod.callback = raw3270_read_modified_cb;
 588	rp->init_readmod.callback_data = rp->init_data;
 589	rp->state = RAW3270_STATE_READMOD;
 590	raw3270_start_irq(&rp->init_view, &rp->init_readmod);
 591}
 592
 593static void raw3270_writesf_readpart(struct raw3270 *rp)
 594{
 595	static const unsigned char wbuf[] = {
 596		0x00, 0x07, 0x01, 0xff, 0x03, 0x00, 0x81
 597	};
 598
 599	/* Store 'read partition' data stream to init_data */
 600	memset(&rp->init_readpart, 0, sizeof(rp->init_readpart));
 601	memset(&rp->init_data, 0, sizeof(rp->init_data));
 602	memcpy(&rp->init_data, wbuf, sizeof(wbuf));
 603	rp->init_readpart.ccw.cmd_code = TC_WRITESF;
 604	rp->init_readpart.ccw.flags = CCW_FLAG_SLI;
 605	rp->init_readpart.ccw.count = sizeof(wbuf);
 606	rp->init_readpart.ccw.cda = virt_to_dma32(&rp->init_data);
 607	rp->state = RAW3270_STATE_W4ATTN;
 608	raw3270_start_irq(&rp->init_view, &rp->init_readpart);
 609}
 610
 611/*
 612 * Device reset
 613 */
 614static void raw3270_reset_device_cb(struct raw3270_request *rq, void *data)
 615{
 616	struct raw3270 *rp = rq->view->dev;
 617
 618	if (rp->state != RAW3270_STATE_RESET)
 619		return;
 620	if (rq->rc) {
 621		/* Reset command failed. */
 622		rp->state = RAW3270_STATE_INIT;
 623	} else if (machine_is_vm()) {
 624		raw3270_size_device_vm(rp);
 625		raw3270_size_device_done(rp);
 626	} else {
 627		raw3270_writesf_readpart(rp);
 628	}
 629	memset(&rp->init_reset, 0, sizeof(rp->init_reset));
 630}
 631
 632static int __raw3270_reset_device(struct raw3270 *rp)
 633{
 634	int rc;
 635
 636	/* Check if reset is already pending */
 637	if (rp->init_reset.view)
 638		return -EBUSY;
 639	/* Store reset data stream to init_data/init_reset */
 640	rp->init_data[0] = TW_KR;
 641	rp->init_reset.ccw.cmd_code = TC_EWRITEA;
 642	rp->init_reset.ccw.flags = CCW_FLAG_SLI;
 643	rp->init_reset.ccw.count = 1;
 644	rp->init_reset.ccw.cda = virt_to_dma32(rp->init_data);
 645	rp->init_reset.callback = raw3270_reset_device_cb;
 646	rc = __raw3270_start(rp, &rp->init_view, &rp->init_reset);
 647	if (rc == 0 && rp->state == RAW3270_STATE_INIT)
 648		rp->state = RAW3270_STATE_RESET;
 649	return rc;
 650}
 651
 652static int raw3270_reset_device(struct raw3270 *rp)
 653{
 654	unsigned long flags;
 655	int rc;
 656
 657	spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags);
 658	rc = __raw3270_reset_device(rp);
 659	spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
 660	return rc;
 661}
 662
 663int raw3270_reset(struct raw3270_view *view)
 664{
 665	struct raw3270 *rp;
 666	int rc;
 667
 668	rp = view->dev;
 669	if (!rp || rp->view != view)
 670		rc = -EACCES;
 671	else if (!raw3270_state_ready(rp))
 672		rc = -EBUSY;
 673	else
 674		rc = raw3270_reset_device(view->dev);
 675	return rc;
 676}
 677EXPORT_SYMBOL(raw3270_reset);
 678
 679static void __raw3270_disconnect(struct raw3270 *rp)
 680{
 681	struct raw3270_request *rq;
 682	struct raw3270_view *view;
 683
 684	rp->state = RAW3270_STATE_INIT;
 685	rp->view = &rp->init_view;
 686	/* Cancel all queued requests */
 687	while (!list_empty(&rp->req_queue)) {
 688		rq = list_entry(rp->req_queue.next, struct raw3270_request, list);
 689		view = rq->view;
 690		rq->rc = -EACCES;
 691		list_del_init(&rq->list);
 692		if (rq->callback)
 693			rq->callback(rq, rq->callback_data);
 694		raw3270_put_view(view);
 695	}
 696	/* Start from scratch */
 697	__raw3270_reset_device(rp);
 698}
 699
 700static void raw3270_init_irq(struct raw3270_view *view, struct raw3270_request *rq,
 701			     struct irb *irb)
 702{
 703	struct raw3270 *rp;
 704
 705	if (rq) {
 706		if (irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK) {
 707			if (irb->ecw[0] & SNS0_CMD_REJECT)
 708				rq->rc = -EOPNOTSUPP;
 709			else
 710				rq->rc = -EIO;
 711		}
 712	}
 713	if (irb->scsw.cmd.dstat & DEV_STAT_ATTENTION) {
 714		/* Queue read modified after attention interrupt */
 715		rp = view->dev;
 716		raw3270_read_modified(rp);
 717	}
 718}
 719
 720static struct raw3270_fn raw3270_init_fn = {
 721	.intv = raw3270_init_irq
 722};
 723
 724/*
 725 * Setup new 3270 device.
 726 */
 727static int raw3270_setup_device(struct ccw_device *cdev, struct raw3270 *rp,
 728				char *ascebc)
 729{
 730	struct list_head *l;
 731	struct raw3270 *tmp;
 732	int minor;
 733
 734	memset(rp, 0, sizeof(struct raw3270));
 735	/* Copy ebcdic -> ascii translation table. */
 736	memcpy(ascebc, _ascebc, 256);
 737	if (tubxcorrect) {
 738		/* correct brackets and circumflex */
 739		ascebc['['] = 0xad;
 740		ascebc[']'] = 0xbd;
 741		ascebc['^'] = 0xb0;
 742	}
 743	rp->ascebc = ascebc;
 744
 745	/* Set defaults. */
 746	rp->rows = 24;
 747	rp->cols = 80;
 748	rp->old_rows = rp->rows;
 749	rp->old_cols = rp->cols;
 750
 751	INIT_LIST_HEAD(&rp->req_queue);
 752	INIT_LIST_HEAD(&rp->view_list);
 753
 754	rp->init_view.dev = rp;
 755	rp->init_view.fn = &raw3270_init_fn;
 756	rp->view = &rp->init_view;
 757	INIT_WORK(&rp->resize_work, raw3270_resize_work);
 758
 759	/*
 760	 * Add device to list and find the smallest unused minor
 761	 * number for it. Note: there is no device with minor 0,
 762	 * see special case for fs3270.c:fs3270_open().
 763	 */
 764	mutex_lock(&raw3270_mutex);
 765	/* Keep the list sorted. */
 766	minor = RAW3270_FIRSTMINOR;
 767	rp->minor = -1;
 768	list_for_each(l, &raw3270_devices) {
 769		tmp = list_entry(l, struct raw3270, list);
 770		if (tmp->minor > minor) {
 771			rp->minor = minor;
 772			__list_add(&rp->list, l->prev, l);
 773			break;
 774		}
 775		minor++;
 776	}
 777	if (rp->minor == -1 && minor < RAW3270_MAXDEVS + RAW3270_FIRSTMINOR) {
 778		rp->minor = minor;
 779		list_add_tail(&rp->list, &raw3270_devices);
 780	}
 781	mutex_unlock(&raw3270_mutex);
 782	/* No free minor number? Then give up. */
 783	if (rp->minor == -1)
 784		return -EUSERS;
 785	rp->cdev = cdev;
 786	dev_set_drvdata(&cdev->dev, rp);
 787	cdev->handler = raw3270_irq;
 788	return 0;
 789}
 790
 791#ifdef CONFIG_TN3270_CONSOLE
 792/* Tentative definition - see below for actual definition. */
 793static struct ccw_driver raw3270_ccw_driver;
 794
 795static inline int raw3270_state_final(struct raw3270 *rp)
 796{
 797	return rp->state == RAW3270_STATE_INIT ||
 798		rp->state == RAW3270_STATE_READY;
 799}
 800
 801/*
 802 * Setup 3270 device configured as console.
 803 */
 804struct raw3270 __init *raw3270_setup_console(void)
 805{
 806	struct ccw_device *cdev;
 807	unsigned long flags;
 808	struct raw3270 *rp;
 809	char *ascebc;
 810	int rc;
 811
 812	cdev = ccw_device_create_console(&raw3270_ccw_driver);
 813	if (IS_ERR(cdev))
 814		return ERR_CAST(cdev);
 815
 816	rp = kzalloc(sizeof(*rp), GFP_KERNEL | GFP_DMA);
 817	ascebc = kzalloc(256, GFP_KERNEL);
 818	rc = raw3270_setup_device(cdev, rp, ascebc);
 819	if (rc)
 820		return ERR_PTR(rc);
 821	set_bit(RAW3270_FLAGS_CONSOLE, &rp->flags);
 822
 823	rc = ccw_device_enable_console(cdev);
 824	if (rc) {
 825		ccw_device_destroy_console(cdev);
 826		return ERR_PTR(rc);
 827	}
 828
 829	spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags);
 830	do {
 831		__raw3270_reset_device(rp);
 832		while (!raw3270_state_final(rp)) {
 833			ccw_device_wait_idle(rp->cdev);
 834			barrier();
 835		}
 836	} while (rp->state != RAW3270_STATE_READY);
 837	spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
 838	return rp;
 839}
 840
 841void raw3270_wait_cons_dev(struct raw3270 *rp)
 842{
 843	unsigned long flags;
 844
 845	spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags);
 846	ccw_device_wait_idle(rp->cdev);
 847	spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
 848}
 849
 850#endif
 851
 852/*
 853 * Create a 3270 device structure.
 854 */
 855static struct raw3270 *raw3270_create_device(struct ccw_device *cdev)
 856{
 857	struct raw3270 *rp;
 858	char *ascebc;
 859	int rc;
 860
 861	rp = kzalloc(sizeof(*rp), GFP_KERNEL | GFP_DMA);
 862	if (!rp)
 863		return ERR_PTR(-ENOMEM);
 864	ascebc = kmalloc(256, GFP_KERNEL);
 865	if (!ascebc) {
 866		kfree(rp);
 867		return ERR_PTR(-ENOMEM);
 868	}
 869	rc = raw3270_setup_device(cdev, rp, ascebc);
 870	if (rc) {
 871		kfree(rp->ascebc);
 872		kfree(rp);
 873		rp = ERR_PTR(rc);
 874	}
 875	/* Get reference to ccw_device structure. */
 876	get_device(&cdev->dev);
 877	return rp;
 878}
 879
 880/*
 881 * This helper just validates that it is safe to activate a
 882 * view in the panic() context, due to locking restrictions.
 883 */
 884int raw3270_view_lock_unavailable(struct raw3270_view *view)
 885{
 886	struct raw3270 *rp = view->dev;
 887
 888	if (!rp)
 889		return -ENODEV;
 890	if (spin_is_locked(get_ccwdev_lock(rp->cdev)))
 891		return -EBUSY;
 892	return 0;
 893}
 894
 895static int raw3270_assign_activate_view(struct raw3270 *rp, struct raw3270_view *view)
 896{
 897	rp->view = view;
 898	return view->fn->activate(view);
 899}
 900
 901static int __raw3270_activate_view(struct raw3270 *rp, struct raw3270_view *view)
 902{
 903	struct raw3270_view *oldview = NULL, *nv;
 904	int rc;
 905
 906	if (rp->view == view)
 907		return 0;
 908
 909	if (!raw3270_state_ready(rp))
 910		return -EBUSY;
 911
 912	if (rp->view && rp->view->fn->deactivate) {
 913		oldview = rp->view;
 914		oldview->fn->deactivate(oldview);
 915	}
 916
 917	rc = raw3270_assign_activate_view(rp, view);
 918	if (!rc)
 919		return 0;
 920
 921	/* Didn't work. Try to reactivate the old view. */
 922	if (oldview) {
 923		rc = raw3270_assign_activate_view(rp, oldview);
 924		if (!rc)
 925			return 0;
 926	}
 927
 928	/* Didn't work as well. Try any other view. */
 929	list_for_each_entry(nv, &rp->view_list, list) {
 930		if (nv == view || nv == oldview)
 931			continue;
 932		rc = raw3270_assign_activate_view(rp, nv);
 933		if (!rc)
 934			break;
 935		rp->view = NULL;
 936	}
 937	return rc;
 938}
 939
 940/*
 941 * Activate a view.
 942 */
 943int raw3270_activate_view(struct raw3270_view *view)
 944{
 945	struct raw3270 *rp;
 946	unsigned long flags;
 947	int rc;
 948
 949	rp = view->dev;
 950	if (!rp)
 951		return -ENODEV;
 952	spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags);
 953	rc = __raw3270_activate_view(rp, view);
 954	spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
 955	return rc;
 956}
 957EXPORT_SYMBOL(raw3270_activate_view);
 958
 959/*
 960 * Deactivate current view.
 961 */
 962void raw3270_deactivate_view(struct raw3270_view *view)
 963{
 964	unsigned long flags;
 965	struct raw3270 *rp;
 966
 967	rp = view->dev;
 968	if (!rp)
 969		return;
 970	spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags);
 971	if (rp->view == view) {
 972		view->fn->deactivate(view);
 973		rp->view = NULL;
 974		/* Move deactivated view to end of list. */
 975		list_del_init(&view->list);
 976		list_add_tail(&view->list, &rp->view_list);
 977		/* Try to activate another view. */
 978		if (raw3270_state_ready(rp)) {
 979			list_for_each_entry(view, &rp->view_list, list) {
 980				rp->view = view;
 981				if (view->fn->activate(view) == 0)
 982					break;
 983				rp->view = NULL;
 984			}
 985		}
 986	}
 987	spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
 988}
 989EXPORT_SYMBOL(raw3270_deactivate_view);
 990
 991/*
 992 * Add view to device with minor "minor".
 993 */
 994int raw3270_add_view(struct raw3270_view *view, struct raw3270_fn *fn,
 995		     int minor, int subclass)
 996{
 997	unsigned long flags;
 998	struct raw3270 *rp;
 999	int rc;
1000
1001	if (minor <= 0)
1002		return -ENODEV;
1003	mutex_lock(&raw3270_mutex);
1004	rc = -ENODEV;
1005	list_for_each_entry(rp, &raw3270_devices, list) {
1006		if (rp->minor != minor)
1007			continue;
1008		spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags);
1009		atomic_set(&view->ref_count, 2);
1010		view->dev = rp;
1011		view->fn = fn;
1012		view->model = rp->model;
1013		view->rows = rp->rows;
1014		view->cols = rp->cols;
1015		view->ascebc = rp->ascebc;
1016		spin_lock_init(&view->lock);
1017		lockdep_set_subclass(&view->lock, subclass);
1018		list_add(&view->list, &rp->view_list);
1019		rc = 0;
1020		spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
1021		break;
1022	}
1023	mutex_unlock(&raw3270_mutex);
1024	return rc;
1025}
1026EXPORT_SYMBOL(raw3270_add_view);
1027
1028/*
1029 * Find specific view of device with minor "minor".
1030 */
1031struct raw3270_view *raw3270_find_view(struct raw3270_fn *fn, int minor)
1032{
1033	struct raw3270 *rp;
1034	struct raw3270_view *view, *tmp;
1035	unsigned long flags;
1036
1037	mutex_lock(&raw3270_mutex);
1038	view = ERR_PTR(-ENODEV);
1039	list_for_each_entry(rp, &raw3270_devices, list) {
1040		if (rp->minor != minor)
1041			continue;
1042		spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags);
1043		list_for_each_entry(tmp, &rp->view_list, list) {
1044			if (tmp->fn == fn) {
1045				raw3270_get_view(tmp);
1046				view = tmp;
1047				break;
1048			}
1049		}
1050		spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
1051		break;
1052	}
1053	mutex_unlock(&raw3270_mutex);
1054	return view;
1055}
1056EXPORT_SYMBOL(raw3270_find_view);
1057
1058/*
1059 * Remove view from device and free view structure via call to view->fn->free.
1060 */
1061void raw3270_del_view(struct raw3270_view *view)
1062{
1063	unsigned long flags;
1064	struct raw3270 *rp;
1065	struct raw3270_view *nv;
1066
1067	rp = view->dev;
1068	spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags);
1069	if (rp->view == view) {
1070		view->fn->deactivate(view);
1071		rp->view = NULL;
1072	}
1073	list_del_init(&view->list);
1074	if (!rp->view && raw3270_state_ready(rp)) {
1075		/* Try to activate another view. */
1076		list_for_each_entry(nv, &rp->view_list, list) {
1077			if (nv->fn->activate(nv) == 0) {
1078				rp->view = nv;
1079				break;
1080			}
1081		}
1082	}
1083	spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);
1084	/* Wait for reference counter to drop to zero. */
1085	atomic_dec(&view->ref_count);
1086	wait_event(raw3270_wait_queue, atomic_read(&view->ref_count) == 0);
1087	if (view->fn->free)
1088		view->fn->free(view);
1089}
1090EXPORT_SYMBOL(raw3270_del_view);
1091
1092/*
1093 * Remove a 3270 device structure.
1094 */
1095static void raw3270_delete_device(struct raw3270 *rp)
1096{
1097	struct ccw_device *cdev;
1098
1099	/* Remove from device chain. */
1100	mutex_lock(&raw3270_mutex);
1101	list_del_init(&rp->list);
1102	mutex_unlock(&raw3270_mutex);
1103
1104	/* Disconnect from ccw_device. */
1105	cdev = rp->cdev;
1106	rp->cdev = NULL;
1107	dev_set_drvdata(&cdev->dev, NULL);
1108	cdev->handler = NULL;
1109
1110	/* Put ccw_device structure. */
1111	put_device(&cdev->dev);
1112
1113	/* Now free raw3270 structure. */
1114	kfree(rp->ascebc);
1115	kfree(rp);
1116}
1117
1118static int raw3270_probe(struct ccw_device *cdev)
1119{
1120	return 0;
1121}
1122
1123/*
1124 * Additional attributes for a 3270 device
1125 */
1126static ssize_t model_show(struct device *dev, struct device_attribute *attr,
1127			  char *buf)
1128{
1129	return sysfs_emit(buf, "%i\n",
1130			  ((struct raw3270 *)dev_get_drvdata(dev))->model);
1131}
1132static DEVICE_ATTR_RO(model);
1133
1134static ssize_t rows_show(struct device *dev, struct device_attribute *attr,
1135			 char *buf)
1136{
1137	return sysfs_emit(buf, "%i\n",
1138			  ((struct raw3270 *)dev_get_drvdata(dev))->rows);
1139}
1140static DEVICE_ATTR_RO(rows);
1141
1142static ssize_t
1143columns_show(struct device *dev, struct device_attribute *attr,
1144	     char *buf)
1145{
1146	return sysfs_emit(buf, "%i\n",
1147			  ((struct raw3270 *)dev_get_drvdata(dev))->cols);
1148}
1149static DEVICE_ATTR_RO(columns);
1150
1151static struct attribute *raw3270_attrs[] = {
1152	&dev_attr_model.attr,
1153	&dev_attr_rows.attr,
1154	&dev_attr_columns.attr,
1155	NULL,
1156};
1157
1158static const struct attribute_group raw3270_attr_group = {
1159	.attrs = raw3270_attrs,
1160};
1161
1162static int raw3270_create_attributes(struct raw3270 *rp)
1163{
1164	return sysfs_create_group(&rp->cdev->dev.kobj, &raw3270_attr_group);
1165}
1166
1167/*
1168 * Notifier for device addition/removal
1169 */
1170static LIST_HEAD(raw3270_notifier);
1171
1172int raw3270_register_notifier(struct raw3270_notifier *notifier)
1173{
1174	struct raw3270 *rp;
1175
1176	mutex_lock(&raw3270_mutex);
1177	list_add_tail(&notifier->list, &raw3270_notifier);
1178	list_for_each_entry(rp, &raw3270_devices, list)
1179		notifier->create(rp->minor);
1180	mutex_unlock(&raw3270_mutex);
1181	return 0;
1182}
1183EXPORT_SYMBOL(raw3270_register_notifier);
1184
1185void raw3270_unregister_notifier(struct raw3270_notifier *notifier)
1186{
1187	struct raw3270 *rp;
1188
1189	mutex_lock(&raw3270_mutex);
1190	list_for_each_entry(rp, &raw3270_devices, list)
1191		notifier->destroy(rp->minor);
1192	list_del(&notifier->list);
1193	mutex_unlock(&raw3270_mutex);
1194}
1195EXPORT_SYMBOL(raw3270_unregister_notifier);
1196
1197/*
1198 * Set 3270 device online.
1199 */
1200static int raw3270_set_online(struct ccw_device *cdev)
1201{
1202	struct raw3270_notifier *np;
1203	struct raw3270 *rp;
1204	int rc;
1205
1206	rp = raw3270_create_device(cdev);
1207	if (IS_ERR(rp))
1208		return PTR_ERR(rp);
1209	rc = raw3270_create_attributes(rp);
1210	if (rc)
1211		goto failure;
1212	raw3270_reset_device(rp);
1213	mutex_lock(&raw3270_mutex);
1214	list_for_each_entry(np, &raw3270_notifier, list)
1215		np->create(rp->minor);
1216	mutex_unlock(&raw3270_mutex);
1217	return 0;
1218
1219failure:
1220	raw3270_delete_device(rp);
1221	return rc;
1222}
1223
1224/*
1225 * Remove 3270 device structure.
1226 */
1227static void raw3270_remove(struct ccw_device *cdev)
1228{
1229	unsigned long flags;
1230	struct raw3270 *rp;
1231	struct raw3270_view *v;
1232	struct raw3270_notifier *np;
1233
1234	rp = dev_get_drvdata(&cdev->dev);
1235	/*
1236	 * _remove is the opposite of _probe; it's probe that
1237	 * should set up rp.  raw3270_remove gets entered for
1238	 * devices even if they haven't been varied online.
1239	 * Thus, rp may validly be NULL here.
1240	 */
1241	if (!rp)
1242		return;
1243
1244	sysfs_remove_group(&cdev->dev.kobj, &raw3270_attr_group);
1245
1246	/* Deactivate current view and remove all views. */
1247	spin_lock_irqsave(get_ccwdev_lock(cdev), flags);
1248	if (rp->view) {
1249		if (rp->view->fn->deactivate)
1250			rp->view->fn->deactivate(rp->view);
1251		rp->view = NULL;
1252	}
1253	while (!list_empty(&rp->view_list)) {
1254		v = list_entry(rp->view_list.next, struct raw3270_view, list);
1255		if (v->fn->release)
1256			v->fn->release(v);
1257		spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
1258		raw3270_del_view(v);
1259		spin_lock_irqsave(get_ccwdev_lock(cdev), flags);
1260	}
1261	spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
1262
1263	mutex_lock(&raw3270_mutex);
1264	list_for_each_entry(np, &raw3270_notifier, list)
1265		np->destroy(rp->minor);
1266	mutex_unlock(&raw3270_mutex);
1267
1268	/* Reset 3270 device. */
1269	raw3270_reset_device(rp);
1270	/* And finally remove it. */
1271	raw3270_delete_device(rp);
1272}
1273
1274/*
1275 * Set 3270 device offline.
1276 */
1277static int raw3270_set_offline(struct ccw_device *cdev)
1278{
1279	struct raw3270 *rp;
1280
1281	rp = dev_get_drvdata(&cdev->dev);
1282	if (test_bit(RAW3270_FLAGS_CONSOLE, &rp->flags))
1283		return -EBUSY;
1284	raw3270_remove(cdev);
1285	return 0;
1286}
1287
1288static struct ccw_device_id raw3270_id[] = {
1289	{ CCW_DEVICE(0x3270, 0) },
1290	{ CCW_DEVICE(0x3271, 0) },
1291	{ CCW_DEVICE(0x3272, 0) },
1292	{ CCW_DEVICE(0x3273, 0) },
1293	{ CCW_DEVICE(0x3274, 0) },
1294	{ CCW_DEVICE(0x3275, 0) },
1295	{ CCW_DEVICE(0x3276, 0) },
1296	{ CCW_DEVICE(0x3277, 0) },
1297	{ CCW_DEVICE(0x3278, 0) },
1298	{ CCW_DEVICE(0x3279, 0) },
1299	{ CCW_DEVICE(0x3174, 0) },
1300	{ /* end of list */ },
1301};
1302
1303static struct ccw_driver raw3270_ccw_driver = {
1304	.driver = {
1305		.name	= "3270",
1306		.owner	= THIS_MODULE,
1307	},
1308	.ids		= raw3270_id,
1309	.probe		= &raw3270_probe,
1310	.remove		= &raw3270_remove,
1311	.set_online	= &raw3270_set_online,
1312	.set_offline	= &raw3270_set_offline,
1313	.int_class	= IRQIO_C70,
1314};
1315
1316static int raw3270_init(void)
1317{
1318	struct raw3270 *rp;
1319	int rc;
1320
1321	if (raw3270_registered)
1322		return 0;
1323	raw3270_registered = 1;
1324	rc = ccw_driver_register(&raw3270_ccw_driver);
1325	if (rc)
1326		return rc;
1327	rc = class_register(&class3270);
1328	if (rc)
1329		return rc;
1330	/* Create attributes for early (= console) device. */
1331	mutex_lock(&raw3270_mutex);
1332	list_for_each_entry(rp, &raw3270_devices, list) {
1333		get_device(&rp->cdev->dev);
1334		raw3270_create_attributes(rp);
1335	}
1336	mutex_unlock(&raw3270_mutex);
1337	return 0;
1338}
1339
1340static void raw3270_exit(void)
1341{
1342	ccw_driver_unregister(&raw3270_ccw_driver);
1343	class_unregister(&class3270);
1344}
1345
1346MODULE_DESCRIPTION("IBM/3270 Driver - core functions");
1347MODULE_LICENSE("GPL");
1348
1349module_init(raw3270_init);
1350module_exit(raw3270_exit);
~/ Read-only file preview.