⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 raw3270.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
		char  sdpid;	/* 0x02 if Alternate Usable Area */		char  res;		char  auaid;	/* 0x01 is Id for the A U A */		short wauai;	/* Width of AUAi */		short hauai;	/* Height of AUAi */		char  auaunits;	/* 0x00:in, 0x01:mm */		int   auaxr;		int   auayr;		char  awauai;		char  ahauai;	} __attribute__ ((packed)) aua;} __attribute__ ((packed));static unsigned char raw3270_init_data[256];static struct raw3270_request raw3270_init_request;static struct diag210 raw3270_init_diag210;static DECLARE_MUTEX(raw3270_init_sem);static intraw3270_init_irq(struct raw3270_view *view, struct raw3270_request *rq,		 struct irb *irb){	/*	 * Unit-Check Processing:	 * Expect Command Reject or Intervention Required.	 */	if (irb->scsw.dstat & DEV_STAT_UNIT_CHECK) {		/* Request finished abnormally. */		if (irb->ecw[0] & SNS0_INTERVENTION_REQ) {			set_bit(RAW3270_FLAGS_BUSY, &view->dev->flags);			return RAW3270_IO_BUSY;		}	}	if (rq) {		if (irb->scsw.dstat & DEV_STAT_UNIT_CHECK) {			if (irb->ecw[0] & SNS0_CMD_REJECT)				rq->rc = -EOPNOTSUPP;			else				rq->rc = -EIO;		} else			/* Request finished normally. Copy residual count. */			rq->rescnt = irb->scsw.count;	}	if (irb->scsw.dstat & DEV_STAT_ATTENTION) {		set_bit(RAW3270_FLAGS_ATTN, &view->dev->flags);		wake_up(&raw3270_wait_queue);	}	return RAW3270_IO_DONE;}static struct raw3270_fn raw3270_init_fn = {	.intv = raw3270_init_irq};static struct raw3270_view raw3270_init_view = {	.fn = &raw3270_init_fn};/* * raw3270_wait/raw3270_wait_interruptible/__raw3270_wakeup * Wait for end of request. The request must have been started * with raw3270_start, rc = 0. The device lock may NOT have been * released between calling raw3270_start and raw3270_wait. */static voidraw3270_wake_init(struct raw3270_request *rq, void *data){	wake_up((wait_queue_head_t *) data);}/* * Special wait function that can cope with console initialization. */static intraw3270_start_init(struct raw3270 *rp, struct raw3270_view *view,		   struct raw3270_request *rq){	unsigned long flags;	wait_queue_head_t wq;	int rc;#ifdef CONFIG_TN3270_CONSOLE	if (raw3270_registered == 0) {		spin_lock_irqsave(get_ccwdev_lock(view->dev->cdev), flags);		rq->callback = 0;		rc = __raw3270_start(rp, view, rq);		if (rc == 0)			while (!raw3270_request_final(rq)) {				wait_cons_dev();				barrier();			}		spin_unlock_irqrestore(get_ccwdev_lock(view->dev->cdev), flags);		return rq->rc;	}#endif	init_waitqueue_head(&wq);	rq->callback = raw3270_wake_init;	rq->callback_data = &wq;	spin_lock_irqsave(get_ccwdev_lock(view->dev->cdev), flags);	rc = __raw3270_start(rp, view, rq);	spin_unlock_irqrestore(get_ccwdev_lock(view->dev->cdev), flags);	if (rc)		return rc;	/* Now wait for the completion. */	rc = wait_event_interruptible(wq, raw3270_request_final(rq));	if (rc == -ERESTARTSYS) {	/* Interrupted by a signal. */		raw3270_halt_io(view->dev, rq);		/* No wait for the halt to complete. */		wait_event(wq, raw3270_request_final(rq));		return -ERESTARTSYS;	}	return rq->rc;}static int__raw3270_size_device_vm(struct raw3270 *rp){	int rc, model;	raw3270_init_diag210.vrdcdvno = 		_ccw_device_get_device_number(rp->cdev);	raw3270_init_diag210.vrdclen = sizeof(struct diag210);	rc = diag210(&raw3270_init_diag210);	if (rc)		return rc;	model = raw3270_init_diag210.vrdccrmd;	switch (model) {	case 2:		rp->model = model;		rp->rows = 24;		rp->cols = 80;		break;	case 3:		rp->model = model;		rp->rows = 32;		rp->cols = 80;		break;	case 4:		rp->model = model;		rp->rows = 43;		rp->cols = 80;		break;	case 5:		rp->model = model;		rp->rows = 27;		rp->cols = 132;		break;	default:		printk(KERN_WARNING "vrdccrmd is 0x%.8x\n", model);		rc = -EOPNOTSUPP;		break;	}	return rc;}static int__raw3270_size_device(struct raw3270 *rp){	static const unsigned char wbuf[] =		{ 0x00, 0x07, 0x01, 0xff, 0x03, 0x00, 0x81 };	struct raw3270_ua *uap;	unsigned short count;	int rc;	/*	 * To determine the size of the 3270 device we need to do:	 * 1) send a 'read partition' data stream to the device	 * 2) wait for the attn interrupt that preceeds the query reply	 * 3) do a read modified to get the query reply	 * To make things worse we have to cope with intervention	 * required (3270 device switched to 'stand-by') and command	 * rejects (old devices that can't do 'read partition').	 */	memset(&raw3270_init_request, 0, sizeof(raw3270_init_request));	memset(raw3270_init_data, 0, sizeof(raw3270_init_data));	/* Store 'read partition' data stream to raw3270_init_data */	memcpy(raw3270_init_data, wbuf, sizeof(wbuf));	INIT_LIST_HEAD(&raw3270_init_request.list);	raw3270_init_request.ccw.cmd_code = TC_WRITESF;	raw3270_init_request.ccw.flags = CCW_FLAG_SLI;	raw3270_init_request.ccw.count = sizeof(wbuf);	raw3270_init_request.ccw.cda = (__u32) __pa(raw3270_init_data);	rc = raw3270_start_init(rp, &raw3270_init_view, &raw3270_init_request);	if (rc)		/* Check error cases: -ERESTARTSYS, -EIO and -EOPNOTSUPP */		return rc;	/* Wait for attention interrupt. */#ifdef CONFIG_TN3270_CONSOLE	if (raw3270_registered == 0) {		unsigned long flags;		spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags);		while (!test_and_clear_bit(RAW3270_FLAGS_ATTN, &rp->flags))			wait_cons_dev();		spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);	} else#endif		rc = wait_event_interruptible(raw3270_wait_queue,			test_and_clear_bit(RAW3270_FLAGS_ATTN, &rp->flags));	if (rc)		return rc;	/*	 * The device accepted the 'read partition' command. Now	 * set up a read ccw and issue it.	 */	raw3270_init_request.ccw.cmd_code = TC_READMOD;	raw3270_init_request.ccw.flags = CCW_FLAG_SLI;	raw3270_init_request.ccw.count = sizeof(raw3270_init_data);	raw3270_init_request.ccw.cda = (__u32) __pa(raw3270_init_data);	rc = raw3270_start_init(rp, &raw3270_init_view, &raw3270_init_request);	if (rc)		return rc;	/* Got a Query Reply */	count = sizeof(raw3270_init_data) - raw3270_init_request.rescnt;	uap = (struct raw3270_ua *) (raw3270_init_data + 1);	/* Paranoia check. */	if (raw3270_init_data[0] != 0x88 || uap->uab.qcode != 0x81)		return -EOPNOTSUPP;	/* Copy rows/columns of default Usable Area */	rp->rows = uap->uab.h;	rp->cols = uap->uab.w;	/* Check for 14 bit addressing */	if ((uap->uab.flags0 & 0x0d) == 0x01)		set_bit(RAW3270_FLAGS_14BITADDR, &rp->flags);	/* Check for Alternate Usable Area */	if (uap->uab.l == sizeof(struct raw3270_ua) &&	    uap->aua.sdpid == 0x02) {		rp->rows = uap->aua.hauai;		rp->cols = uap->aua.wauai;	}	return 0;}static intraw3270_size_device(struct raw3270 *rp){	int rc;	down(&raw3270_init_sem);	rp->view = &raw3270_init_view;	raw3270_init_view.dev = rp;	if (MACHINE_IS_VM)		rc = __raw3270_size_device_vm(rp);	else		rc = __raw3270_size_device(rp);	raw3270_init_view.dev = 0;	rp->view = 0;	up(&raw3270_init_sem);	if (rc == 0) {	/* Found something. */		/* Try to find a model. */		rp->model = 0;		if (rp->rows == 24 && rp->cols == 80)			rp->model = 2;		if (rp->rows == 32 && rp->cols == 80)			rp->model = 3;		if (rp->rows == 43 && rp->cols == 80)			rp->model = 4;		if (rp->rows == 27 && rp->cols == 132)			rp->model = 5;	} else {		/* Couldn't detect size. Use default model 2. */		rp->model = 2;		rp->rows = 24;		rp->cols = 80;		return 0;	}	return rc;}static intraw3270_reset_device(struct raw3270 *rp){	int rc;	down(&raw3270_init_sem);	memset(&raw3270_init_request, 0, sizeof(raw3270_init_request));	memset(raw3270_init_data, 0, sizeof(raw3270_init_data));	/* Store reset data stream to raw3270_init_data/raw3270_init_request */	raw3270_init_data[0] = TW_KR;	INIT_LIST_HEAD(&raw3270_init_request.list);	raw3270_init_request.ccw.cmd_code = TC_EWRITEA;	raw3270_init_request.ccw.flags = CCW_FLAG_SLI;	raw3270_init_request.ccw.count = 1;	raw3270_init_request.ccw.cda = (__u32) __pa(raw3270_init_data);	rp->view = &raw3270_init_view;	raw3270_init_view.dev = rp;	rc = raw3270_start_init(rp, &raw3270_init_view, &raw3270_init_request);	raw3270_init_view.dev = 0;	rp->view = 0;	up(&raw3270_init_sem);	return rc;}intraw3270_reset(struct raw3270_view *view){	struct raw3270 *rp;	int rc;	rp = view->dev;	if (!rp || rp->view != view)		rc = -EACCES;	else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags))		rc = -ENODEV;	else		rc = raw3270_reset_device(view->dev);	return rc;}/* * Setup new 3270 device. */static intraw3270_setup_device(struct ccw_device *cdev, struct raw3270 *rp, char *ascebc){	struct list_head *l;	struct raw3270 *tmp;	int minor;	memset(rp, 0, sizeof(struct raw3270));	/* Copy ebcdic -> ascii translation table. */	memcpy(ascebc, _ascebc, 256);	if (tubxcorrect) {		/* correct brackets and circumflex */		ascebc['['] = 0xad;		ascebc[']'] = 0xbd;		ascebc['^'] = 0xb0;	}	rp->ascebc = ascebc;	/* Set defaults. */	rp->rows = 24;	rp->cols = 80;	INIT_LIST_HEAD(&rp->req_queue);	INIT_LIST_HEAD(&rp->view_list);	/*	 * Add device to list and find the smallest unused minor	 * number for it. Note: there is no device with minor 0,	 * see special case for fs3270.c:fs3270_open().	 */	down(&raw3270_sem);	/* Keep the list sorted. */	minor = RAW3270_FIRSTMINOR;	rp->minor = -1;	list_for_each(l, &raw3270_devices) {		tmp = list_entry(l, struct raw3270, list);		if (tmp->minor > minor) {			rp->minor = minor;			__list_add(&rp->list, l->prev, l);			break;		}		minor++;	}	if (rp->minor == -1 && minor < RAW3270_MAXDEVS + RAW3270_FIRSTMINOR) {		rp->minor = minor;		list_add_tail(&rp->list, &raw3270_devices);	}	up(&raw3270_sem);	/* No free minor number? Then give up. */	if (rp->minor == -1)		return -EUSERS;	rp->cdev = cdev;	cdev->dev.driver_data = rp;	cdev->handler = raw3270_irq;	return 0;}#ifdef CONFIG_TN3270_CONSOLE/* * Setup 3270 device configured as console. */struct raw3270 *raw3270_setup_console(struct ccw_device *cdev){	struct raw3270 *rp;	char *ascebc;	int rc;	rp = (struct raw3270 *) alloc_bootmem(sizeof(struct raw3270));	ascebc = (char *) alloc_bootmem(256);	rc = raw3270_setup_device(cdev, rp, ascebc);	if (rc)		return ERR_PTR(rc);	set_bit(RAW3270_FLAGS_CONSOLE, &rp->flags);	rc = raw3270_reset_device(rp);	if (rc)		return ERR_PTR(rc);	rc = raw3270_size_device(rp);	if (rc)		return ERR_PTR(rc);	rc = raw3270_reset_device(rp);	if (rc)		return ERR_PTR(rc);	set_bit(RAW3270_FLAGS_READY, &rp->flags);	return rp;}voidraw3270_wait_cons_dev(struct raw3270 *rp){	unsigned long flags;	spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags);	wait_cons_dev();	spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);}#endif/* * Create a 3270 device structure. */static struct raw3270 *raw3270_create_device(struct ccw_device *cdev){	struct raw3270 *rp;	char *ascebc;	int rc;	rp = kmalloc(sizeof(struct raw3270), GFP_KERNEL);	if (!rp)		return ERR_PTR(-ENOMEM);	ascebc = kmalloc(256, GFP_KERNEL);	if (!ascebc) {		kfree(rp);		return ERR_PTR(-ENOMEM);	}	rc = raw3270_setup_device(cdev, rp, ascebc);	if (rc) {		kfree(rp->ascebc);		kfree(rp);		rp = ERR_PTR(rc);	}	/* Get reference to ccw_device structure. */	get_device(&cdev->dev);	return rp;}/* * Activate a view. */intraw3270_activate_view(struct raw3270_view *view){	struct raw3270 *rp;	struct raw3270_view *oldview, *nv;	unsigned long flags;	int rc;	rp = view->dev;	if (!rp)		return -ENODEV;	spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags);	if (rp->view == view)		rc = 0;	else if (!test_bit(RAW3270_FLAGS_READY, &rp->flags))		rc = -ENODEV;	else {		oldview = 0;		if (rp->view) {			oldview = rp->view;			oldview->fn->deactivate(oldview);		}		rp->view = view;		rc = view->fn->activate(view);		if (rc) {			/* Didn't work. Try to reactivate the old view. */			rp->view = oldview;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -