asmlinkage int solaris_sysinfo(int cmd, u32 buf, s32 count) { char *p, *q, *r; char buffer[256]; int len; /* Again, we cheat :)) */ switch (cmd) { case SI_SYSNAME: r = "SunOS"; break; case SI_HOSTNAME: r = buffer + 256; for (p = system_utsname.nodename, q = buffer; q < r && *p && *p != '.'; *q++ = *p++); *q = 0; r = buffer; break; case SI_RELEASE: r = "5.6"; break; case SI_MACHINE: r = machine(); break; case SI_ARCHITECTURE: r = "sparc"; break; case SI_HW_PROVIDER: r = "Sun_Microsystems"; break; case SI_HW_SERIAL: r = serial(buffer); break; case SI_PLATFORM: r = platform(buffer); break; case SI_SRPC_DOMAIN: r = ""; break; case SI_VERSION: r = "Generic"; break; default: return -EINVAL; } len = strlen(r) + 1; if (count < len) { copy_to_user_ret((char *)A(buf), r, count - 1, -EFAULT); __put_user_ret(0, (char *)A(buf) + count - 1, -EFAULT); } else copy_to_user_ret((char *)A(buf), r, len, -EFAULT); return len; }
static ssize_t kbd_read (struct file *f, char *buffer, size_t count, loff_t *ppos) { struct wait_queue wait = { current, NULL }; char *end, *p; /* Return EWOULDBLOCK, because this is what the X server expects */ if (kbd_head == kbd_tail){ if (f->f_flags & O_NONBLOCK) return -EWOULDBLOCK; add_wait_queue (&kbd_wait, &wait); while (kbd_head == kbd_tail && !signal_pending(current)) { current->state = TASK_INTERRUPTIBLE; schedule (); } current->state = TASK_RUNNING; remove_wait_queue (&kbd_wait, &wait); } /* There is data in the keyboard, fill the user buffer */ end = buffer+count; p = buffer; for (; p < end && kbd_head != kbd_tail;){ #ifdef CONFIG_SPARC32_COMPAT if (current->tss.flags & SPARC_FLAG_32BIT) { copy_to_user_ret((Firm_event *)p, &kbd_queue [kbd_tail], sizeof(Firm_event)-sizeof(struct timeval), -EFAULT); p += sizeof(Firm_event)-sizeof(struct timeval); __put_user_ret(kbd_queue[kbd_tail].time.tv_sec, (u32 *)p, -EFAULT); p += sizeof(u32); __put_user_ret(kbd_queue[kbd_tail].time.tv_usec, (u32 *)p, -EFAULT); p += sizeof(u32); } else #endif { copy_to_user_ret((Firm_event *)p, &kbd_queue [kbd_tail], sizeof(Firm_event), -EFAULT); p += sizeof (Firm_event); } #ifdef KBD_DEBUG printk ("[%s]", kbd_queue [kbd_tail].value == VKEY_UP ? "UP" : "DOWN"); #endif kbd_tail++; kbd_tail %= KBD_QSIZE; } return p-buffer; }
static ssize_t sun_mouse_read(struct file *file, char *buffer, size_t count, loff_t *ppos) { struct wait_queue wait = { current, NULL }; if (queue_empty ()){ if (file->f_flags & O_NONBLOCK) return -EWOULDBLOCK; add_wait_queue (&sunmouse.proc_list, &wait); while (queue_empty () && !signal_pending(current)) { current->state = TASK_INTERRUPTIBLE; schedule (); } current->state = TASK_RUNNING; remove_wait_queue (&sunmouse.proc_list, &wait); } if (gen_events){ char *p = buffer, *end = buffer+count; while (p < end && !queue_empty ()){ #ifdef CONFIG_SPARC32_COMPAT if (current->tss.flags & SPARC_FLAG_32BIT) { Firm_event *q = get_from_queue(); if ((end - p) < ((sizeof(Firm_event) - sizeof(struct timeval) + (sizeof(u32) * 2)))) break; copy_to_user_ret((Firm_event *)p, q, sizeof(Firm_event)-sizeof(struct timeval), -EFAULT); p += sizeof(Firm_event)-sizeof(struct timeval); __put_user_ret(q->time.tv_sec, (u32 *)p, -EFAULT); p += sizeof(u32); __put_user_ret(q->time.tv_usec, (u32 *)p, -EFAULT); p += sizeof(u32); } else #endif { if ((end - p) < sizeof(Firm_event)) break; copy_to_user_ret((Firm_event *)p, get_from_queue(), sizeof(Firm_event), -EFAULT); p += sizeof (Firm_event); } } sunmouse.ready = !queue_empty (); file->f_dentry->d_inode->i_atime = CURRENT_TIME; return p-buffer; } else { int c, limit = 3; if (count < limit) limit = count; for (c = 0; c < limit; c++) { put_user(sunmouse.queue.stream[sunmouse.tail], buffer); buffer++; sunmouse.tail = (sunmouse.tail + 1) % STREAM_SIZE; } while (c < count) { if (c >= 5) break; put_user(0, buffer); buffer++; c++; } sunmouse.ready = !queue_empty(); file->f_dentry->d_inode->i_atime = CURRENT_TIME; return c; } /* Only called if nothing was sent */ if (signal_pending(current)) return -ERESTARTSYS; return 0; }