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

📄 raw3270.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
			if (!oldview || oldview->fn->activate(oldview) != 0) {				/* Didn't work as well. Try any other view. */				list_for_each_entry(nv, &rp->view_list, list)					if (nv != view && nv != oldview) {						rp->view = nv;						if (nv->fn->activate(nv) == 0)							break;						rp->view = 0;					}			}		}	}	spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);	return rc;}/* * Deactivate current view. */voidraw3270_deactivate_view(struct raw3270_view *view){	unsigned long flags;	struct raw3270 *rp;	rp = view->dev;	if (!rp)		return;	spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags);	if (rp->view == view) {		view->fn->deactivate(view);		rp->view = 0;		/* Move deactivated view to end of list. */		list_del_init(&view->list);		list_add_tail(&view->list, &rp->view_list);		/* Try to activate another view. */		if (test_bit(RAW3270_FLAGS_READY, &rp->flags)) {			list_for_each_entry(view, &rp->view_list, list) {				rp->view = view;				if (view->fn->activate(view) == 0)					break;				rp->view = 0;			}		}	}	spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);}/* * Add view to device with minor "minor". */intraw3270_add_view(struct raw3270_view *view, struct raw3270_fn *fn, int minor){	unsigned long flags;	struct raw3270 *rp;	int rc;	if (minor <= 0)		return -ENODEV;	down(&raw3270_sem);	rc = -ENODEV;	list_for_each_entry(rp, &raw3270_devices, list) {		if (rp->minor != minor)			continue;		spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags);		if (test_bit(RAW3270_FLAGS_READY, &rp->flags)) {			atomic_set(&view->ref_count, 2);			view->dev = rp;			view->fn = fn;			view->model = rp->model;			view->rows = rp->rows;			view->cols = rp->cols;			view->ascebc = rp->ascebc;			spin_lock_init(&view->lock);			list_add(&view->list, &rp->view_list);			rc = 0;		}		spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);		break;	}	up(&raw3270_sem);	return rc;}/* * Find specific view of device with minor "minor". */struct raw3270_view *raw3270_find_view(struct raw3270_fn *fn, int minor){	struct raw3270 *rp;	struct raw3270_view *view, *tmp;	unsigned long flags;	down(&raw3270_sem);	view = ERR_PTR(-ENODEV);	list_for_each_entry(rp, &raw3270_devices, list) {		if (rp->minor != minor)			continue;		spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags);		if (test_bit(RAW3270_FLAGS_READY, &rp->flags)) {			view = ERR_PTR(-ENOENT);			list_for_each_entry(tmp, &rp->view_list, list) {				if (tmp->fn == fn) {					raw3270_get_view(tmp);					view = tmp;					break;				}			}		}		spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);		break;	}	up(&raw3270_sem);	return view;}/* * Remove view from device and free view structure via call to view->fn->free. */voidraw3270_del_view(struct raw3270_view *view){	unsigned long flags;	struct raw3270 *rp;	struct raw3270_view *nv;	rp = view->dev;	spin_lock_irqsave(get_ccwdev_lock(rp->cdev), flags);	if (rp->view == view) {		view->fn->deactivate(view);		rp->view = 0;	}	list_del_init(&view->list);	if (!rp->view && test_bit(RAW3270_FLAGS_READY, &rp->flags)) {		/* Try to activate another view. */		list_for_each_entry(nv, &rp->view_list, list) {			if (nv->fn->activate(nv) == 0) {				rp->view = nv;				break;			}		}	}	spin_unlock_irqrestore(get_ccwdev_lock(rp->cdev), flags);	/* Wait for reference counter to drop to zero. */	atomic_dec(&view->ref_count);	wait_event(raw3270_wait_queue, atomic_read(&view->ref_count) == 0);	if (view->fn->free)		view->fn->free(view);}/* * Remove a 3270 device structure. */static voidraw3270_delete_device(struct raw3270 *rp){	struct ccw_device *cdev;	/* Remove from device chain. */	down(&raw3270_sem);	if (rp->clttydev)		class_device_destroy(class3270,				     MKDEV(IBM_TTY3270_MAJOR, rp->minor));	if (rp->cltubdev)		class_device_destroy(class3270,				     MKDEV(IBM_FS3270_MAJOR, rp->minor));	list_del_init(&rp->list);	up(&raw3270_sem);	/* Disconnect from ccw_device. */	cdev = rp->cdev;	rp->cdev = 0;	cdev->dev.driver_data = 0;	cdev->handler = 0;	/* Put ccw_device structure. */	put_device(&cdev->dev);	/* Now free raw3270 structure. */	kfree(rp->ascebc);	kfree(rp);}static intraw3270_probe (struct ccw_device *cdev){	return 0;}/* * Additional attributes for a 3270 device */static ssize_traw3270_model_show(struct device *dev, struct device_attribute *attr, char *buf){	return snprintf(buf, PAGE_SIZE, "%i\n",			((struct raw3270 *) dev->driver_data)->model);}static DEVICE_ATTR(model, 0444, raw3270_model_show, 0);static ssize_traw3270_rows_show(struct device *dev, struct device_attribute *attr, char *buf){	return snprintf(buf, PAGE_SIZE, "%i\n",			((struct raw3270 *) dev->driver_data)->rows);}static DEVICE_ATTR(rows, 0444, raw3270_rows_show, 0);static ssize_traw3270_columns_show(struct device *dev, struct device_attribute *attr, char *buf){	return snprintf(buf, PAGE_SIZE, "%i\n",			((struct raw3270 *) dev->driver_data)->cols);}static DEVICE_ATTR(columns, 0444, raw3270_columns_show, 0);static struct attribute * raw3270_attrs[] = {	&dev_attr_model.attr,	&dev_attr_rows.attr,	&dev_attr_columns.attr,	NULL,};static struct attribute_group raw3270_attr_group = {	.attrs = raw3270_attrs,};static voidraw3270_create_attributes(struct raw3270 *rp){	//FIXME: check return code	sysfs_create_group(&rp->cdev->dev.kobj, &raw3270_attr_group);	rp->clttydev =		class_device_create(class3270, NULL,				    MKDEV(IBM_TTY3270_MAJOR, rp->minor),				    &rp->cdev->dev, "tty%s",				    rp->cdev->dev.bus_id);	rp->cltubdev =		class_device_create(class3270, NULL,				    MKDEV(IBM_FS3270_MAJOR, rp->minor),				    &rp->cdev->dev, "tub%s",				    rp->cdev->dev.bus_id);}/* * Notifier for device addition/removal */struct raw3270_notifier {	struct list_head list;	void (*notifier)(int, int);};static struct list_head raw3270_notifier = LIST_HEAD_INIT(raw3270_notifier);int raw3270_register_notifier(void (*notifier)(int, int)){	struct raw3270_notifier *np;	struct raw3270 *rp;	np = kmalloc(sizeof(struct raw3270_notifier), GFP_KERNEL);	if (!np)		return -ENOMEM;	np->notifier = notifier;	down(&raw3270_sem);	list_add_tail(&np->list, &raw3270_notifier);	list_for_each_entry(rp, &raw3270_devices, list) {		get_device(&rp->cdev->dev);		notifier(rp->minor, 1);	}	up(&raw3270_sem);	return 0;}void raw3270_unregister_notifier(void (*notifier)(int, int)){	struct raw3270_notifier *np;	down(&raw3270_sem);	list_for_each_entry(np, &raw3270_notifier, list)		if (np->notifier == notifier) {			list_del(&np->list);			kfree(np);			break;		}	up(&raw3270_sem);}/* * Set 3270 device online. */static intraw3270_set_online (struct ccw_device *cdev){	struct raw3270 *rp;	struct raw3270_notifier *np;	int rc;	rp = raw3270_create_device(cdev);	if (IS_ERR(rp))		return PTR_ERR(rp);	rc = raw3270_reset_device(rp);	if (rc)		goto failure;	rc = raw3270_size_device(rp);	if (rc)		goto failure;	rc = raw3270_reset_device(rp);	if (rc)		goto failure;	raw3270_create_attributes(rp);	set_bit(RAW3270_FLAGS_READY, &rp->flags);	down(&raw3270_sem);	list_for_each_entry(np, &raw3270_notifier, list)		np->notifier(rp->minor, 1);	up(&raw3270_sem);	return 0;failure:	raw3270_delete_device(rp);	return rc;}/* * Remove 3270 device structure. */static voidraw3270_remove (struct ccw_device *cdev){	unsigned long flags;	struct raw3270 *rp;	struct raw3270_view *v;	struct raw3270_notifier *np;	rp = cdev->dev.driver_data;	/*	 * _remove is the opposite of _probe; it's probe that	 * should set up rp.  raw3270_remove gets entered for	 * devices even if they haven't been varied online.	 * Thus, rp may validly be NULL here.	 */	if (rp == NULL)		return;	clear_bit(RAW3270_FLAGS_READY, &rp->flags);	sysfs_remove_group(&cdev->dev.kobj, &raw3270_attr_group);	/* Deactivate current view and remove all views. */	spin_lock_irqsave(get_ccwdev_lock(cdev), flags);	if (rp->view) {		rp->view->fn->deactivate(rp->view);		rp->view = 0;	}	while (!list_empty(&rp->view_list)) {		v = list_entry(rp->view_list.next, struct raw3270_view, list);		if (v->fn->release)			v->fn->release(v);		spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);		raw3270_del_view(v);		spin_lock_irqsave(get_ccwdev_lock(cdev), flags);	}	spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);	down(&raw3270_sem);	list_for_each_entry(np, &raw3270_notifier, list)		np->notifier(rp->minor, 0);	up(&raw3270_sem);	/* Reset 3270 device. */	raw3270_reset_device(rp);	/* And finally remove it. */	raw3270_delete_device(rp);}/* * Set 3270 device offline. */static intraw3270_set_offline (struct ccw_device *cdev){	struct raw3270 *rp;	rp = cdev->dev.driver_data;	if (test_bit(RAW3270_FLAGS_CONSOLE, &rp->flags))		return -EBUSY;	raw3270_remove(cdev);	return 0;}static struct ccw_device_id raw3270_id[] = {	{ CCW_DEVICE(0x3270, 0) },	{ CCW_DEVICE(0x3271, 0) },	{ CCW_DEVICE(0x3272, 0) },	{ CCW_DEVICE(0x3273, 0) },	{ CCW_DEVICE(0x3274, 0) },	{ CCW_DEVICE(0x3275, 0) },	{ CCW_DEVICE(0x3276, 0) },	{ CCW_DEVICE(0x3277, 0) },	{ CCW_DEVICE(0x3278, 0) },	{ CCW_DEVICE(0x3279, 0) },	{ CCW_DEVICE(0x3174, 0) },	{ /* end of list */ },};static struct ccw_driver raw3270_ccw_driver = {	.name		= "3270",	.owner		= THIS_MODULE,	.ids		= raw3270_id,	.probe		= &raw3270_probe,	.remove		= &raw3270_remove,	.set_online	= &raw3270_set_online,	.set_offline	= &raw3270_set_offline,};static intraw3270_init(void){	struct raw3270 *rp;	int rc;	if (raw3270_registered)		return 0;	raw3270_registered = 1;	rc = ccw_driver_register(&raw3270_ccw_driver);	if (rc == 0) {		/* Create attributes for early (= console) device. */		down(&raw3270_sem);		class3270 = class_create(THIS_MODULE, "3270");		list_for_each_entry(rp, &raw3270_devices, list) {			get_device(&rp->cdev->dev);			raw3270_create_attributes(rp);		}		up(&raw3270_sem);	}	return rc;}static voidraw3270_exit(void){	ccw_driver_unregister(&raw3270_ccw_driver);	class_destroy(class3270);}MODULE_LICENSE("GPL");module_init(raw3270_init);module_exit(raw3270_exit);EXPORT_SYMBOL(raw3270_request_alloc);EXPORT_SYMBOL(raw3270_request_free);EXPORT_SYMBOL(raw3270_request_reset);EXPORT_SYMBOL(raw3270_request_set_cmd);EXPORT_SYMBOL(raw3270_request_add_data);EXPORT_SYMBOL(raw3270_request_set_data);EXPORT_SYMBOL(raw3270_request_set_idal);EXPORT_SYMBOL(raw3270_buffer_address);EXPORT_SYMBOL(raw3270_add_view);EXPORT_SYMBOL(raw3270_del_view);EXPORT_SYMBOL(raw3270_find_view);EXPORT_SYMBOL(raw3270_activate_view);EXPORT_SYMBOL(raw3270_deactivate_view);EXPORT_SYMBOL(raw3270_start);EXPORT_SYMBOL(raw3270_start_locked);EXPORT_SYMBOL(raw3270_start_irq);EXPORT_SYMBOL(raw3270_reset);EXPORT_SYMBOL(raw3270_register_notifier);EXPORT_SYMBOL(raw3270_unregister_notifier);EXPORT_SYMBOL(raw3270_wait_queue);

⌨️ 快捷键说明

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