static long read_nibble(unsigned minor, char *c, unsigned long cnt) { unsigned long remaining = cnt; long rc; while (remaining > 0) { unsigned char byte = 0; int pins; /* Event 7: request nibble */ set_pins(BPP_PP_nSelectIn|BPP_PP_nStrobe, minor); /* Wait for event 9: Peripher strobes first nibble */ pins = wait_for(0, BPP_GP_nAck, TIME_IDLE_LIMIT, minor); if (pins == -1) return -ETIMEDOUT; /* Event 10: I handshake nibble */ set_pins(BPP_PP_nSelectIn|BPP_PP_nStrobe|BPP_PP_nAutoFd, minor); if (pins & BPP_GP_nFault) byte |= 0x01; if (pins & BPP_GP_Select) byte |= 0x02; if (pins & BPP_GP_PError) byte |= 0x04; if (pins & BPP_GP_Busy) byte |= 0x08; /* Wait for event 11: Peripheral handshakes nibble */ rc = wait_for(BPP_GP_nAck, 0, TIME_PResponse, minor); /* Event 7: request nibble */ set_pins(BPP_PP_nSelectIn|BPP_PP_nStrobe, minor); /* Wait for event 9: Peripher strobes first nibble */ pins = wait_for(0, BPP_GP_nAck, TIME_PResponse, minor); if (rc == -1) return -ETIMEDOUT; /* Event 10: I handshake nibble */ set_pins(BPP_PP_nSelectIn|BPP_PP_nStrobe|BPP_PP_nAutoFd, minor); if (pins & BPP_GP_nFault) byte |= 0x10; if (pins & BPP_GP_Select) byte |= 0x20; if (pins & BPP_GP_PError) byte |= 0x40; if (pins & BPP_GP_Busy) byte |= 0x80; put_user_ret(byte, c, -EFAULT); c += 1; remaining -= 1; /* Wait for event 11: Peripheral handshakes nibble */ rc = wait_for(BPP_GP_nAck, 0, TIME_PResponse, minor); if (rc == -1) return -EIO; } 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; }
static long read_ecp(unsigned minor, char *c, unsigned long cnt) { unsigned long remaining; long rc; /* Turn ECP mode from forward to reverse if needed. */ if (! instances[minor].direction) { unsigned short pins = get_pins(minor); /* Event 38: Turn the bus around */ instances[minor].direction = 0x20; pins &= ~BPP_PP_nAutoFd; set_pins(pins, minor); /* Event 39: Set pins for reverse mode. */ snooze(TIME_PSetup, minor); set_pins(BPP_PP_nStrobe|BPP_PP_nSelectIn, minor); /* Wait for event 40: Peripheral ready to be strobed */ rc = wait_for(0, BPP_GP_PError, TIME_PResponse, minor); if (rc == -1) return -ETIMEDOUT; } remaining = cnt; while (remaining > 0) { /* If there is a run length for a repeated byte, repeat */ /* that byte a few times. */ if (instances[minor].run_length && !instances[minor].run_flag) { char buffer[128]; unsigned idx; unsigned repeat = remaining < instances[minor].run_length ? remaining : instances[minor].run_length; for (idx = 0 ; idx < repeat ; idx += 1) buffer[idx] = instances[minor].repeat_byte; copy_to_user_ret(c, buffer, repeat, -EFAULT); remaining -= repeat; c += repeat; instances[minor].run_length -= repeat; } if (remaining == 0) break; /* Wait for Event 43: Data active on the bus. */ rc = wait_for(0, BPP_GP_nAck, TIME_IDLE_LIMIT, minor); if (rc == -1) break; if (rc & BPP_GP_Busy) { /* OK, this is data. read it in. */ unsigned char byte = bpp_inb(base_addrs[minor]); put_user_ret(byte, c, -EFAULT); c += 1; remaining -= 1; if (instances[minor].run_flag) { instances[minor].repeat_byte = byte; instances[minor].run_flag = 0; } } else { unsigned char byte = bpp_inb(base_addrs[minor]); if (byte & 0x80) { printk("bpp%d: " "Ignoring ECP channel %u from device.\n", minor, byte & 0x7f); } else { instances[minor].run_length = byte; instances[minor].run_flag = 1; } } /* Event 44: I got it. */ set_pins(BPP_PP_nStrobe|BPP_PP_nAutoFd|BPP_PP_nSelectIn, minor); /* Wait for event 45: peripheral handshake */ rc = wait_for(BPP_GP_nAck, 0, TIME_PResponse, minor); if (rc == -1) return -ETIMEDOUT; /* Event 46: Finish handshake */ set_pins(BPP_PP_nStrobe|BPP_PP_nSelectIn, 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; }