/* * Compatibility mode handshaking is a matter of writing data, * strobing it, and waiting for the printer to stop being busy. */ static long write_compat(unsigned minor, const char *c, unsigned long cnt) { long rc; unsigned short pins = get_pins(minor); unsigned long remaining = cnt; while (remaining > 0) { unsigned char byte; get_user_ret(byte, c, -EFAULT); c += 1; rc = wait_for(BPP_GP_nAck, BPP_GP_Busy, TIME_IDLE_LIMIT, minor); if (rc == -1) return -ETIMEDOUT; bpp_outb_p(byte, base_addrs[minor]); remaining -= 1; /* snooze(1, minor); */ pins &= ~BPP_PP_nStrobe; set_pins(pins, minor); rc = wait_for(BPP_GP_Busy, 0, TIME_PResponse, minor); pins |= BPP_PP_nStrobe; set_pins(pins, minor); } return cnt - remaining; }
int sun_mouse_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { int i; switch (cmd){ /* VUIDGFORMAT - Get input device byte stream format */ case _IOR('v', 2, int): put_user_ret(sunmouse.vuid_mode, (int *) arg, -EFAULT); break; /* VUIDSFORMAT - Set input device byte stream format*/ case _IOW('v', 1, int): get_user_ret(i, (int *) arg, -EFAULT); if (i == VUID_NATIVE || i == VUID_FIRM_EVENT){ int value; get_user_ret(value, (int *)arg, -EFAULT); sunmouse.vuid_mode = value; sunmouse.head = sunmouse.tail = 0; } else return -EINVAL; break; case 0x8024540b: case 0x40245408: /* This is a buggy application doing termios on the mouse driver */ /* we ignore it. I keep this check here so that we will notice */ /* future mouse vuid ioctls */ return -ENOTTY; default: #ifdef DEBUG printk ("[MOUSE-ioctl: %8.8x]\n", cmd); #endif return -EINVAL; } return 0; }
/* * Write data using ECP mode. Watch out that the port may be set up * for reading. If so, turn the port around. */ static long write_ecp(unsigned minor, const char *c, unsigned long cnt) { unsigned short pins = get_pins(minor); unsigned long remaining = cnt; if (instances[minor].direction) { int rc; /* Event 47 Request bus be turned around */ pins |= BPP_PP_nInit; set_pins(pins, minor); /* Wait for Event 49: Peripheral relinquished bus */ rc = wait_for(BPP_GP_PError, 0, TIME_PResponse, minor); pins |= BPP_PP_nAutoFd; instances[minor].direction = 0; set_pins(pins, minor); } while (remaining > 0) { unsigned char byte; int rc; get_user_ret(byte, c, -EFAULT); rc = wait_for(0, BPP_GP_Busy, TIME_PResponse, minor); if (rc == -1) return -ETIMEDOUT; c += 1; bpp_outb_p(byte, base_addrs[minor]); pins &= ~BPP_PP_nStrobe; set_pins(pins, minor); pins |= BPP_PP_nStrobe; rc = wait_for(BPP_GP_Busy, 0, TIME_PResponse, minor); if (rc == -1) return -EIO; set_pins(pins, minor); } return cnt - remaining; }
static int kbd_ioctl (struct inode *i, struct file *f, unsigned int cmd, unsigned long arg) { unsigned char c; unsigned char leds = 0; int value; switch (cmd){ case KIOCTYPE: /* return keyboard type */ put_user_ret(sunkbd_type, (int *) arg, -EFAULT); break; case KIOCGTRANS: put_user_ret(TR_UNTRANS_EVENT, (int *) arg, -EFAULT); break; case KIOCTRANS: get_user_ret(value, (int *) arg, -EFAULT); if (value != TR_UNTRANS_EVENT) return -EINVAL; break; case KIOCLAYOUT: put_user_ret(sunkbd_layout, (int *) arg, -EFAULT); break; case KIOCSDIRECT: #ifndef CODING_NEW_DRIVER get_user_ret(value, (int *) arg, -EFAULT); if(value) kbd_redirected = fg_console + 1; else kbd_redirected = 0; kbd_table [fg_console].kbdmode = kbd_redirected ? VC_RAW : VC_XLATE; #endif break; case KIOCCMD: get_user_ret(value, (int *) arg, -EFAULT); c = (unsigned char) value; switch (c) { case SKBDCMD_CLICK: case SKBDCMD_NOCLICK: send_cmd(c); return 0; case SKBDCMD_BELLON: kd_mksound(1,0); return 0; case SKBDCMD_BELLOFF: kd_mksound(0,0); return 0; default: return -EINVAL; } case KIOCSLED: get_user_ret(c, (unsigned char *) arg, -EFAULT); if (c & LED_SCRLCK) leds |= (1 << VC_SCROLLOCK); if (c & LED_NLOCK) leds |= (1 << VC_NUMLOCK); if (c & LED_CLOCK) leds |= (1 << VC_CAPSLOCK); compose_led_on = !!(c & LED_CMPOSE); sun_setledstate(kbd_table + fg_console, leds); break; case KIOCGLED: put_user_ret(vcleds_to_sunkbd(getleds()), (unsigned char *) arg, -EFAULT); break; case KIOCGRATE: { struct kbd_rate rate; rate.delay = kbd_delay_ticks; if (kbd_rate_ticks) rate.rate = HZ / kbd_rate_ticks; else rate.rate = 0; copy_to_user_ret((struct kbd_rate *)arg, &rate, sizeof(struct kbd_rate), -EFAULT); return 0; } case KIOCSRATE: { struct kbd_rate rate; if (verify_area(VERIFY_READ, (void *)arg, sizeof(struct kbd_rate))) return -EFAULT; copy_from_user(&rate, (struct kbd_rate *)arg, sizeof(struct kbd_rate)); if (rate.rate > 50) return -EINVAL; if (rate.rate == 0) kbd_rate_ticks = 0; else kbd_rate_ticks = HZ / rate.rate; kbd_delay_ticks = rate.delay; return 0; } case FIONREAD: /* return number of bytes in kbd queue */ { int count; count = kbd_head - kbd_tail; put_user_ret((count < 0) ? KBD_QSIZE - count : count, (int *) arg, -EFAULT); return 0; } default: printk ("Unknown Keyboard ioctl: %8.8x\n", cmd); return -EINVAL; } return 0; }