コード例 #1
0
ファイル: con3215.c プロジェクト: spacex/kernel-centos7
/*
 * Put character routine for 3215 devices
 */
static void raw3215_putchar(struct raw3215_info *raw, unsigned char ch)
{
	unsigned long flags;
	unsigned int length, i;

	spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
	if (ch == '\t') {
		length = TAB_STOP_SIZE - (raw->line_pos%TAB_STOP_SIZE);
		raw->line_pos += length;
		ch = ' ';
	} else if (ch == '\n') {
		length = 1;
		raw->line_pos = 0;
	} else {
		length = 1;
		raw->line_pos++;
	}
	raw3215_make_room(raw, length);

	for (i = 0; i < length; i++) {
		raw->buffer[raw->head] = (char) _ascebc[(int) ch];
		raw->head = (raw->head + 1) & (RAW3215_BUFFER_SIZE - 1);
		raw->count++;
	}
	if (!(raw->flags & RAW3215_WORKING)) {
		raw3215_mk_write_req(raw);
		/* start or queue request */
		raw3215_try_io(raw);
	}
	spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
}
コード例 #2
0
/*
 * panic() calls console_unblank before the system enters a
 * disabled, endless loop.
 */
void con3215_unblank(void)
{
	raw3215_info *raw;
	unsigned long flags;

	raw = raw3215[0];  /* console 3215 is the first one */
	s390irq_spin_lock_irqsave(raw->irq, flags);
	raw3215_make_room(raw, RAW3215_BUFFER_SIZE);
	s390irq_spin_unlock_irqrestore(raw->irq, flags);
}
コード例 #3
0
/*
 * panic() calls console_unblank before the system enters a
 * disabled, endless loop.
 */
static void
con3215_unblank(void)
{
	struct raw3215_info *raw;
	unsigned long flags;

	raw = raw3215[0];  /* console 3215 is the first one */
	spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
	raw3215_make_room(raw, RAW3215_BUFFER_SIZE);
	spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
}
コード例 #4
0
ファイル: con3215.c プロジェクト: spacex/kernel-centos7
static int raw3215_pm_stop(struct ccw_device *cdev)
{
	struct raw3215_info *raw;
	unsigned long flags;

	/* Empty the output buffer, then prevent new I/O. */
	raw = dev_get_drvdata(&cdev->dev);
	spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
	raw3215_make_room(raw, RAW3215_BUFFER_SIZE);
	raw->port.flags |= ASYNC_SUSPENDED;
	spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
	return 0;
}
コード例 #5
0
ファイル: con3215.c プロジェクト: spacex/kernel-centos7
/*
 * panic() calls con3215_flush through a panic_notifier
 * before the system enters a disabled, endless loop.
 */
static void con3215_flush(void)
{
	struct raw3215_info *raw;
	unsigned long flags;

	raw = raw3215[0];  /* console 3215 is the first one */
	if (raw->port.flags & ASYNC_SUSPENDED)
		/* The console is still frozen for suspend. */
		if (ccw_device_force_console(raw->cdev))
			/* Forcing didn't work, no panic message .. */
			return;
	spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
	raw3215_make_room(raw, RAW3215_BUFFER_SIZE);
	spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
}
コード例 #6
0
ファイル: con3215.c プロジェクト: spacex/kernel-centos7
/*
 * String write routine for 3215 devices
 */
static void raw3215_write(struct raw3215_info *raw, const char *str,
			  unsigned int length)
{
	unsigned long flags;
	int c, count;

	while (length > 0) {
		spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
		count = (length > RAW3215_BUFFER_SIZE) ?
					     RAW3215_BUFFER_SIZE : length;
		length -= count;

		raw3215_make_room(raw, count);

		/* copy string to output buffer and convert it to EBCDIC */
		while (1) {
			c = min_t(int, count,
				  min(RAW3215_BUFFER_SIZE - raw->count,
				      RAW3215_BUFFER_SIZE - raw->head));
			if (c <= 0)
				break;
			memcpy(raw->buffer + raw->head, str, c);
			ASCEBC(raw->buffer + raw->head, c);
			raw->head = (raw->head + c) & (RAW3215_BUFFER_SIZE - 1);
			raw->count += c;
			raw->line_pos += c;
			str += c;
			count -= c;
		}
		if (!(raw->flags & RAW3215_WORKING)) {
			raw3215_mk_write_req(raw);
			/* start or queue request */
			raw3215_try_io(raw);
		}
		spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
	}
}
コード例 #7
0
/*
 * String write routine for 3215 devices
 */
static int
raw3215_write(raw3215_info *raw, const char *str,
	      int from_user, unsigned int length)
{
	unsigned long flags;
	int ret, c;
	int count;
	
	ret = 0;
	while (length > 0) {
		s390irq_spin_lock_irqsave(raw->irq, flags);
		count = (length > RAW3215_BUFFER_SIZE) ?
					     RAW3215_BUFFER_SIZE : length;
		length -= count;

                raw3215_make_room(raw, count);

		/* copy string to output buffer and convert it to EBCDIC */
		if (from_user) {
			while (1) {
				c = MIN(count,
					MIN(RAW3215_BUFFER_SIZE - raw->count,
					    RAW3215_BUFFER_SIZE - raw->head));
				if (c <= 0)
					break;
				c -= copy_from_user(raw->buffer + raw->head,
						    str, c);
				if (c == 0) {
					if (!ret)
						ret = -EFAULT;
					break;
				}
				ASCEBC(raw->buffer + raw->head, c);
				raw->head = (raw->head + c) &
					    (RAW3215_BUFFER_SIZE - 1);
				raw->count += c;
				raw->line_pos += c;
				str += c;
				count -= c;
				ret += c;
			}
		} else {
			while (1) {
				c = MIN(count,
					MIN(RAW3215_BUFFER_SIZE - raw->count,
					    RAW3215_BUFFER_SIZE - raw->head));
				if (c <= 0)
					break;
				memcpy(raw->buffer + raw->head, str, c);
				ASCEBC(raw->buffer + raw->head, c);
				raw->head = (raw->head + c) &
					    (RAW3215_BUFFER_SIZE - 1);
				raw->count += c;
				raw->line_pos += c;
				str += c;
				count -= c;
				ret += c;
			}
		}
                if (!(raw->flags & RAW3215_WORKING)) {
                        raw3215_mk_write_req(raw);
		        /* start or queue request */
		        raw3215_try_io(raw);
                }
		s390irq_spin_unlock_irqrestore(raw->irq, flags);
	}

	return ret;
}