25
#include "qemu/osdep.h"
26
#include "chardev/char.h"
27
#include "qapi/error.h"
28
#include "qemu/module.h"
29
#include "qemu/option.h"
33
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
34
#include <dev/ppbus/ppi.h>
35
#include <dev/ppbus/ppbconf.h>
36
#elif defined(__DragonFly__)
37
#include <dev/misc/ppi/ppi.h>
38
#include <bus/ppbus/ppbconf.h>
42
#include <linux/ppdev.h>
43
#include <linux/parport.h>
47
#include "chardev/char-fd.h"
48
#include "chardev/char-parallel.h"
58
#define PARALLEL_CHARDEV(obj) \
59
OBJECT_CHECK(ParallelChardev, (obj), TYPE_CHARDEV_PARALLEL)
61
static int pp_hw_mode(ParallelChardev *s, uint16_t mode)
63
if (s->mode != mode) {
65
if (ioctl(s->fd, PPSETMODE, &m) < 0) {
73
static int pp_ioctl(Chardev *chr, int cmd, void *arg)
75
ParallelChardev *drv = PARALLEL_CHARDEV(chr);
80
case CHR_IOCTL_PP_READ_DATA:
81
if (ioctl(fd, PPRDATA, &b) < 0) {
86
case CHR_IOCTL_PP_WRITE_DATA:
88
if (ioctl(fd, PPWDATA, &b) < 0) {
92
case CHR_IOCTL_PP_READ_CONTROL:
93
if (ioctl(fd, PPRCONTROL, &b) < 0) {
99
*(uint8_t *)arg = b | 0xc0;
101
case CHR_IOCTL_PP_WRITE_CONTROL:
103
if (ioctl(fd, PPWCONTROL, &b) < 0) {
107
case CHR_IOCTL_PP_READ_STATUS:
108
if (ioctl(fd, PPRSTATUS, &b) < 0) {
113
case CHR_IOCTL_PP_DATA_DIR:
114
if (ioctl(fd, PPDATADIR, (int *)arg) < 0) {
118
case CHR_IOCTL_PP_EPP_READ_ADDR:
119
if (pp_hw_mode(drv, IEEE1284_MODE_EPP | IEEE1284_ADDR)) {
120
struct ParallelIOArg *parg = arg;
121
int n = read(fd, parg->buffer, parg->count);
122
if (n != parg->count) {
127
case CHR_IOCTL_PP_EPP_READ:
128
if (pp_hw_mode(drv, IEEE1284_MODE_EPP)) {
129
struct ParallelIOArg *parg = arg;
130
int n = read(fd, parg->buffer, parg->count);
131
if (n != parg->count) {
136
case CHR_IOCTL_PP_EPP_WRITE_ADDR:
137
if (pp_hw_mode(drv, IEEE1284_MODE_EPP | IEEE1284_ADDR)) {
138
struct ParallelIOArg *parg = arg;
139
int n = write(fd, parg->buffer, parg->count);
140
if (n != parg->count) {
145
case CHR_IOCTL_PP_EPP_WRITE:
146
if (pp_hw_mode(drv, IEEE1284_MODE_EPP)) {
147
struct ParallelIOArg *parg = arg;
148
int n = write(fd, parg->buffer, parg->count);
149
if (n != parg->count) {
160
static void qemu_chr_open_pp_fd(Chardev *chr,
165
ParallelChardev *drv = PARALLEL_CHARDEV(chr);
169
if (ioctl(fd, PPCLAIM) < 0) {
170
error_setg_errno(errp, errno, "not a parallel port");
174
drv->mode = IEEE1284_MODE_COMPAT;
178
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
185
#define PARALLEL_CHARDEV(obj) \
186
OBJECT_CHECK(ParallelChardev, (obj), TYPE_CHARDEV_PARALLEL)
188
static int pp_ioctl(Chardev *chr, int cmd, void *arg)
190
ParallelChardev *drv = PARALLEL_CHARDEV(chr);
194
case CHR_IOCTL_PP_READ_DATA:
195
if (ioctl(drv->fd, PPIGDATA, &b) < 0) {
200
case CHR_IOCTL_PP_WRITE_DATA:
202
if (ioctl(drv->fd, PPISDATA, &b) < 0) {
206
case CHR_IOCTL_PP_READ_CONTROL:
207
if (ioctl(drv->fd, PPIGCTRL, &b) < 0) {
212
case CHR_IOCTL_PP_WRITE_CONTROL:
214
if (ioctl(drv->fd, PPISCTRL, &b) < 0) {
218
case CHR_IOCTL_PP_READ_STATUS:
219
if (ioctl(drv->fd, PPIGSTATUS, &b) < 0) {
230
static void qemu_chr_open_pp_fd(Chardev *chr,
235
ParallelChardev *drv = PARALLEL_CHARDEV(chr);
241
#ifdef HAVE_CHARDEV_PARALLEL
242
static void qmp_chardev_open_parallel(Chardev *chr,
243
ChardevBackend *backend,
247
ChardevHostdev *parallel = backend->u.parallel.data;
250
fd = qmp_chardev_open_file_source(parallel->device, O_RDWR, errp);
254
qemu_chr_open_pp_fd(chr, fd, be_opened, errp);
257
static void qemu_chr_parse_parallel(QemuOpts *opts, ChardevBackend *backend,
260
const char *device = qemu_opt_get(opts, "path");
261
ChardevHostdev *parallel;
263
if (device == NULL) {
264
error_setg(errp, "chardev: parallel: no device path given");
267
backend->type = CHARDEV_BACKEND_KIND_PARALLEL;
268
parallel = backend->u.parallel.data = g_new0(ChardevHostdev, 1);
269
qemu_chr_parse_common(opts, qapi_ChardevHostdev_base(parallel));
270
parallel->device = g_strdup(device);
273
static void char_parallel_class_init(ObjectClass *oc, void *data)
275
ChardevClass *cc = CHARDEV_CLASS(oc);
277
cc->parse = qemu_chr_parse_parallel;
278
cc->open = qmp_chardev_open_parallel;
279
cc->chr_ioctl = pp_ioctl;
282
static void char_parallel_finalize(Object *obj)
284
Chardev *chr = CHARDEV(obj);
285
ParallelChardev *drv = PARALLEL_CHARDEV(chr);
288
#if defined(__linux__)
289
pp_hw_mode(drv, IEEE1284_MODE_COMPAT);
290
ioctl(fd, PPRELEASE);
293
qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
296
static const TypeInfo char_parallel_type_info = {
297
.name = TYPE_CHARDEV_PARALLEL,
298
.parent = TYPE_CHARDEV,
299
.instance_size = sizeof(ParallelChardev),
300
.instance_finalize = char_parallel_finalize,
301
.class_init = char_parallel_class_init,
304
static void register_types(void)
306
type_register_static(&char_parallel_type_info);
309
type_init(register_types);