/* * 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); }
/* * 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); }
/* * 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); }
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; }
/* * 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); }
/* * 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); } }
/* * 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; }