/* * Returns the index to a directory table */ static int ifs_get_directory(struct device *dev, int parent, char *dir) { if(dir[0] == 0 && parent == 0) return 0; bool has_sep = contains(dir, '/'); int32_t directory[256]; struct ifs_entry dentry; device_read(dev, &dentry, sizeof(struct ifs_entry), ifs_get_address(dev, parent)); int dtable = dentry.data_index; device_read(dev, directory, 1024, ifs_get_address(dev, dtable)); for (int i = 0; i < 256 && directory[i] != -1; i++) { int e = directory[i]; struct ifs_entry entry; device_read(dev, &entry, sizeof(struct ifs_entry), ifs_get_address(dev, e)); if (has_sep && strncmp(dir, entry.file_name, strindx(dir, '/')) == 0) { return ifs_get_directory(dev, e, strrchr(dir, '/') + 1); } else if (!has_sep) { if (strncmp(entry.file_name, dir, strlen(entry.file_name)) == 0) { return e; } } } return -1; }
/* * Reads a file, copies data into buff */ static size_t ifs_read_file(struct device *dev, ino_t ino, char *buff, off_t addr, size_t len) { struct ifs_entry entry; struct ifs_volume_hdr vol_header; size_t bytes_read = 0; device_read(dev, &vol_header, sizeof(struct ifs_volume_hdr), 0); device_read(dev, &entry, sizeof(struct ifs_entry), ifs_get_address(dev, ino)); int i = 0; int offset = addr % vol_header.file_block_size; int blk = entry.data_index; int start = addr - addr % vol_header.file_block_size; int end = addr + len > entry.file_size ? 0 : addr + len; do { struct ifs_block block; ifs_get_block(dev, blk, &block); if(i >= start && i < end) { int rlen = i + vol_header.file_block_size >= len ? len % vol_header.file_block_size : vol_header.file_block_size; bytes_read += device_read(dev, buff + bytes_read, rlen, block.data + offset); offset = 0; } i += vol_header.file_block_size; blk = block.next; } while(blk); return bytes_read; }
/* * Allocates a block in the IFS block pool with a * specified size */ static int ifs_block_alloc(struct device *dev, int size) { struct ifs_block blk; struct ifs_volume_hdr hdr; device_read(dev, &hdr, sizeof(struct ifs_volume_hdr), 0); for (int i = 0; i < hdr.block_pool_size; i += sizeof(struct ifs_block)) { device_read(dev, &blk, sizeof(struct ifs_block), sizeof(struct ifs_volume_hdr) + i); if (blk.state == IFS_BLOCK_NONEXISTENT) { blk.size = size; blk.state = IFS_BLOCK_ALLOCATED; blk.data = hdr.placement_new; hdr.placement_new += size; device_write(dev, &hdr, sizeof(struct ifs_volume_hdr), 0); device_write(dev, &blk, sizeof(struct ifs_block), sizeof(struct ifs_volume_hdr) + i); return i / sizeof(struct ifs_block); } else if (blk.state == IFS_BLOCK_FREE && blk.size == size) { blk.state = IFS_BLOCK_ALLOCATED; device_write(dev, &blk, sizeof(struct ifs_block), sizeof(struct ifs_volume_hdr) + i); return i / sizeof(struct ifs_block); } } return -1; }
/* * Reads an IFS directory entry */ static int ifs_read_dir(struct device *dev, ino_t ino, int d, struct dirent *dent) { struct ifs_entry entry; int32_t *directory = (int32_t *)kalloc(1024); device_read(dev, &entry, sizeof(struct ifs_entry), ifs_get_address(dev, ino)); device_read(dev, directory, 1024, ifs_get_address(dev, entry.data_index)); if (directory[d] == -1) return -1; device_read(dev, &entry, sizeof(struct ifs_entry), ifs_get_address(dev, directory[d])); dent->d_ino = directory[d]; switch(entry.file_type) { case IFS_DIRECTORY: dent->d_type = DT_DIR; break; case IFS_REG_FILE: dent->d_type = DT_REG; break; case IFS_LINK: dent->d_type = DT_LNK; break; default: dent->d_type = DT_UNKNOWN; break; } memcpy(dent->d_name, entry.file_name, 256); kfree(directory); return 0; }
static int ifs_readlink(struct device *dev, const char *path, char *buf, int len) { struct ifs_entry entry; if (ifs_get_directory(dev, 0, path) != -1) { ino_t ino = ifs_get_directory(dev, 0, path); device_read(dev, &entry, sizeof(struct ifs_entry), ifs_get_address(dev, ino)); if(entry.file_type == IFS_LINK) { device_read(dev, buf, len % 1024, ifs_get_address(dev, entry.data_index)); return 0; } } return ENOENT; }
void read_memory(usb_dev_handle *handle, const enum request r, enum index index, long address, long length, uint8_t *data) { const int packet = READ_PACKET_SIZE; while(length >= packet){ device_read(handle, r, index, address, packet, data); data += packet; address += packet; length -= packet; } if(length != 0){ device_read(handle, r, index, address, length, data); } }
static int device_ioctl(struct inode *inode, struct file *file, unsigned int ioctl_num, unsigned long ioctl_param) { int i; char *temp; char ch; switch (ioctl_num) { case IOCTL_SET_MSG : printk(KERN_INFO "ioctl : Setting a new msg\n"); /* Receive a pointer to a msg (in user space) */ temp = (char*)ioctl_param; get_user(ch, temp); for (i = 0; ch && i < BUF_LEN; i++, temp++) get_user(ch, temp); device_write(file, (char*)ioctl_param, i, 0); break; case IOCTL_GET_MSG : printk(KERN_INFO "ioctl : returning the information %s\n", msg); i = device_read(file, (char*) ioctl_param, 99, 0); put_user('\0', (char*) ioctl_param+i); break; case IOCTL_GET_NTH_BYTE : printk(KERN_INFO "ioctl : returning %c\n", msg[ioctl_param]); return msg[ioctl_param]; break; } return SUCCESS; }
/** Read from an ISO9660 handle. * @param _handle Handle to read from. * @param buf Buffer to read into. * @param count Number of bytes to read. * @param offset Offset to read from. * @return Status code describing the result of the operation. */ static status_t iso9660_read(fs_handle_t *_handle, void *buf, size_t count, offset_t offset) { iso9660_handle_t *handle = (iso9660_handle_t*)_handle; offset += (offset_t)handle->extent * ISO9660_BLOCK_SIZE; return device_read(handle->handle.mount->device, buf, count, offset); }
static inline int ifs_remove_entry(struct device *dev, const char *path, struct ifs_entry *entry) { int parent = ifs_get_parent(dev, path); struct ifs_entry p_ent; device_read(dev, &p_ent, sizeof(struct ifs_entry), ifs_get_address(dev, parent)); int32_t files[256]; device_read(dev, files, 1024, ifs_get_address(dev, p_ent.data_index)); int i = 0; while(files[i] != entry->block_index && files[i] != -1) i++; for(int j = i; j < 255 && files[j] != -1; j++) { files[j] = files[j + 1]; } device_write(dev, files, 1024, ifs_get_address(dev, p_ent.data_index)); return 0; }
long device_ioctl(struct file* file, unsigned int ioctl_num, unsigned long ioctl_param) { int i; char* temp; char ch; switch(ioctl_num) { case IOCTL_SET_MSG: { temp = (char*)ioctl_param; get_user(ch, temp); for(i = 0; ch && i < BUFFER_LEN; i++, temp++) { get_user(ch, temp); } device_write(file, (char*)ioctl_param, i, 0); break; } case IOCTL_GET_MSG: { i = device_read(file, (char*)ioctl_param, 99, 0); put_user('\0', (char*)ioctl_param + i); break; } case IOCTL_GET_NTH_BYTE: { if(ioctl_param && ioctl_param - 1 < BUFFER_LEN) return data[ioctl_param]; return 0; break; } default: { break; } } return 0; }
/* * Block read with cache. * @dev: device id to read from. * @blkno: block number. * @buf: buffer pointer to be returned. * * An actual read operation is done only when the cached * buffer is dirty. */ int bread(dev_t dev, int blkno, struct buf **bpp) { struct buf *bp; size_t size; int error; DPRINTF(VFSDB_BIO, ("bread: dev=%llx blkno=%d\n", (long long)dev, blkno)); bp = getblk(dev, blkno); if (!ISSET(bp->b_flags, (B_DONE | B_DELWRI))) { size = DEV_BSIZE; struct iovec iovec = { .iov_base = bp->b_data, .iov_len = size }; struct uio uio = { .iovcnt = 1, .iov = &iovec }; error = device_read((device_t)dev, &uio, &size, blkno); if (error) { DPRINTF(VFSDB_BIO, ("bread: i/o error\n")); brelse(bp); return error; } } CLR(bp->b_flags, B_INVAL); SET(bp->b_flags, (B_READ | B_DONE)); DPRINTF(VFSDB_BIO, ("bread: done bp=%p\n\n", bp)); *bpp = bp; return 0; } /* * Block write with cache. * @buf: buffer to write. * * The data is copied to the buffer. * Then release the buffer. */ int bwrite(struct buf *bp) { size_t size; int error; ASSERT(ISSET(bp->b_flags, B_BUSY)); DPRINTF(VFSDB_BIO, ("bwrite: dev=%llx blkno=%d\n", (long long)bp->b_dev, bp->b_blkno)); BIO_LOCK(); CLR(bp->b_flags, (B_READ | B_DONE | B_DELWRI)); BIO_UNLOCK(); size = DEV_BSIZE; error = device_write((device_t)bp->b_dev, bp->b_data, &size, bp->b_blkno); if (error) return error; BIO_LOCK(); SET(bp->b_flags, B_DONE); BIO_UNLOCK(); brelse(bp); return 0; }
int main(int argc, char *argv[]) { device_t tty_dev; int i, error; char buf[] = "?\n"; size_t len; sys_log("Keyboard test program\n"); error = device_open("tty", 0, &tty_dev); if (error) sys_log("device open error!\n"); sys_log("Press any key 10 times\n"); for (i = 0; i < 10; i++) { len = 1; device_read(tty_dev, buf, &len, 0); sys_log(buf); } error = device_close(tty_dev); if (error) sys_log("device close error!\n"); sys_log("Test completed.\n"); return 0; }
/* * New updated version * based on https://lwn.net/Articles/119652/ * New format: * long (*unlocked_ioctl) (struct file *filp, unsigned int cmd, unsigned long arg); * If a driver or filesystem provides an unlocked_ioctl() method, it will be * called in preference to the older ioctl(). The differences are that the * inode argument is not provided (it's available as filp->f_dentry->d_inode) * and the BKL is not taken prior to the call. All new code should be written * with its own locking, and should use unlocked_ioctl(). Old code should be * converted as time allows. For code which must run on multiple kernels, * there is a new HAVE_UNLOCKED_IOCTL macro which can be tested to see if * the newer method is available or not. * -------------------- * This function is called whenever a process tries to do an ioctl on our * device file. We get two extra parameters (additional to the inode and file * structures, which all device functions get): the number of the ioctl called * and the parameter given to the ioctl function. * * If the ioctl is write or read/write (meaning output is returned to the * calling process), the ioctl call returns the output of this function. * -------------------- * Old header * int old_device_ioctl(struct inode *inode, // see include/linux/fs.h * struct file *file, // ditto * unsigned int ioctl_num, // number and param for ioctl * unsigned long ioctl_param); * */ long device_ioctl(struct file *file, /* ditto */ unsigned int cmd, /* number and param for ioctl */ unsigned long arg) { int i; char *temp; char ch; printk(KERN_INFO "Pdevice_ioctl called\n"); /* * Switch according to the ioctl called */ switch (cmd) { case IOCTL_SET_MSG: /* * Receive a pointer to a message (in user space) and set that * to be the device's message. Get the parameter given to * ioctl by the process. */ temp = (char *) arg; /* * Find the length of the message */ get_user(ch, temp); for (i = 0; ch && i < BUF_LEN; i++, temp++) get_user(ch, temp); device_write(file, (char *) arg, i, 0); printk(KERN_INFO "cmd:IOCTL_SET_MSG\n"); break; case IOCTL_GET_MSG: /* * Give the current message to the calling process − * the parameter we got is a pointer, fill it. */ i = device_read(file, (char *) arg, 99, 0); /* * Put a zero at the end of the buffer, so it will be * properly terminated */ put_user('\0', (char *) arg + i); printk(KERN_INFO "cmd:IOCTL_GET_MSG\n"); break; case IOCTL_GET_NTH_BYTE: /* * This ioctl is both input (ioctl_param) and * output (the return value of this function) */ printk(KERN_INFO "cmd:IOCTL_GET_NTH_BYTE:\n"); return (long)Message[arg]; break; } return (long)SUCCESS; }
static inline int ifs_insert_entry(struct device *dev, const char *path, struct ifs_entry *entry) { int e_block = ifs_block_alloc(dev, 1024); entry->block_index = e_block; int parent = ifs_get_parent(dev, path); struct ifs_entry p_ent; device_read(dev, &p_ent, sizeof(struct ifs_entry), ifs_get_address(dev, parent)); int32_t *files = (int32_t *)kalloc(1024); device_read(dev, files, 1024, ifs_get_address(dev, p_ent.data_index)); int i = 0; while (files[i] != -1) i++; files[i] = e_block; device_write(dev, files, 1024, ifs_get_address(dev, p_ent.data_index)); device_write(dev, entry, sizeof(struct ifs_entry), ifs_get_address(dev, e_block)); kfree(files); return e_block; }
/* * Frees a block */ static int ifs_free_block(struct device *dev, int block) { struct ifs_volume_hdr hdr; struct ifs_block blk; ifs_get_block(dev, block, &blk); device_read(dev, &hdr, sizeof(struct ifs_volume_hdr), 0); blk.state = IFS_BLOCK_FREE; device_write(dev, &blk, sizeof(struct ifs_block), sizeof(struct ifs_volume_hdr) + (block * sizeof(struct ifs_block))); }
/* int device_ioctl(struct inode *inode, /see include/linux/fs.h struct file *file, ditto unsigned int ioctl_num, number and param for ioctl unsigned long arg) */ long device_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int i; unsigned char *temp; unsigned char ch; /* * Switch according to the ioctl called */ switch (cmd) { pr_debug("cmd %u \n", cmd); case IOCTL_SET_SCET_TIME: temp = (unsigned char *)arg; /* * Find the length of the message */ get_user(ch, temp); for (i = 0; ch && i < BUF_LEN; i++, temp++) get_user(ch, temp); device_write(file, (unsigned char *)arg, i, 0); break; case IOCTL_GET_SCET_TIME: i = device_read(file, (unsigned char *)arg, 6, 0); break; case IOCTL_SET_SCET_OPERATION: pr_debug("Set SCET timer mode to %u \n", (unsigned int)arg); if (arg == 0) stop_timer(scd); else start_timer(scd); /* * This ioctl is both input (ioctl_param) and * output (the return value of this function) */ return (scd->timer_run | (scd->timer_freeze << 1)); break; case IOCTL_GET_SCET_STATUS: put_user((scd->timer_run | (scd->timer_freeze << 1)), (int *)arg); break; } return 0; }
/* * This function is called whenever a process tries to do an ioctl on our * device file. We get two extra parameters (additional to the inode and file * structures, which all device functions get): the number of the ioctl called * and the parameter given to the ioctl function. * * If the ioctl is write or read/write (meaning output is returned to the * calling process), the ioctl call returns the output of this function. * */ int device_ioctl(struct inode *inode, /* see include/linux/fs.h */ struct file *file, /* ditto */ unsigned int ioctl_num, /* number and param for ioctl */ unsigned long ioctl_param) { int i; char *temp; char ch; /* * Switch according to the ioctl called */ switch (ioctl_num) { case IOCTL_SET_MSG: /* * Receive a pointer to a message (in user space) and set that * to be the device's message. Get the parameter given to * ioctl by the process. */ temp = (char *)ioctl_param; /* * Find the length of the message */ get_user(ch, temp); for (i = 0; ch && i < BUF_LEN; i++, temp++) get_user(ch, temp); device_write(file, (char *)ioctl_param, i, 0); break; case IOCTL_GET_MSG: /* * Give the current message to the calling process - * the parameter we got is a pointer, fill it. */ i = device_read(file, (char *)ioctl_param, 99, 0); /* * Put a zero at the end of the buffer, so it will be * properly terminated */ put_user('\0', (char *)ioctl_param + i); break; case IOCTL_GET_NTH_BYTE: /* * This ioctl is both input (ioctl_param) and * output (the return value of this function) */ return Message[ioctl_param]; break; } return SUCCESS; }
/* * Read one cluster to buffer. */ static int fat_read_cluster(struct fatfsmount *fmp, u_long cluster) { u_long sec; size_t size; sec = cl_to_sec(fmp, cluster); size = fmp->sec_per_cl * SEC_SIZE; return device_read(fmp->dev, fmp->io_buf, &size, sec); }
static any_t input_loop (any_t unused) { kd_event *ev; vm_offset_t buf; mach_msg_type_number_t buf_size; while (1) { struct mouse_event evt = { 0 }; device_read (mousedev, 0, 0, sizeof (kd_event), (char **) &buf, &buf_size); ev = (kd_event *) buf; /* The repeater is set, send the event to the repeater. */ if (mouse_repeater_opened) { repeat_event (ev); vm_deallocate (mach_task_self(), buf, buf_size); continue; } evt.mouse_movement = CONS_VCONS_MOUSE_MOVE_REL; switch (ev->type) { case MOUSE_LEFT: evt.button = CONS_MOUSE_BUTTON1; break; case MOUSE_MIDDLE: evt.button = CONS_MOUSE_BUTTON2; break; case MOUSE_RIGHT: evt.button = CONS_MOUSE_BUTTON3; break; case MOUSE_MOTION: evt.x = ev->value.mmotion.mm_deltaX * mouse_sens; evt.y = -ev->value.mmotion.mm_deltaY * mouse_sens; break; } if (ev->type > 0 && ev->type <= 3) { if (ev->value.up) evt.mouse_button = CONS_VCONS_MOUSE_BUTTON_RELEASED; else evt.mouse_button = CONS_VCONS_MOUSE_BUTTON_PRESSED; } /* Generate a mouse movement event. */ console_move_mouse (&evt); vm_deallocate (mach_task_self(), buf, buf_size); } }
/** Read in an MBR and convert endianness. * @param disk Disk to read from. * @param mbr MBR to read into. * @param lba LBA to read from. * @return Whether read successfully. */ static bool read_mbr(disk_device_t *disk, mbr_t *mbr, uint32_t lba) { if (device_read(&disk->device, mbr, sizeof(*mbr), (uint64_t)lba * disk->block_size) != STATUS_SUCCESS) return false; for (size_t i = 0; i < array_size(mbr->partitions); i++) { mbr->partitions[i].start_lba = le32_to_cpu(mbr->partitions[i].start_lba); mbr->partitions[i].num_sectors = le32_to_cpu(mbr->partitions[i].num_sectors); } return true; }
/** Get an inode from an Ext2 filesystem. * @note Node creation/lookup are protected by the mount lock, * meaning this function does not need to lock. * @param mount Mount to read from. * @param num Inode number to read. * @param inodep Where to store pointer to inode structure. * @return Status code describing result of the operation. */ status_t ext2_inode_get(ext2_mount_t *mount, uint32_t num, ext2_inode_t **inodep) { ext2_inode_t *inode = NULL; size_t group, bytes; offset_t offset; status_t ret; /* Get the group descriptor table containing the inode. */ group = (num - 1) / mount->inodes_per_group; if(group >= mount->block_groups) { dprintf("ext2: group number %zu is invalid on mount %p\n", group, mount); return STATUS_CORRUPT_FS; } /* Get the offset of the inode in the group's inode table. */ offset = ((num - 1) % mount->inodes_per_group) * mount->inode_size; /* Create a structure to store details of the inode in memory. */ inode = kmalloc(sizeof(ext2_inode_t), MM_WAIT); mutex_init(&inode->lock, "ext2_inode_lock", MUTEX_RECURSIVE); inode->mount = mount; inode->num = num; inode->disk_size = MIN(mount->inode_size, sizeof(ext2_disk_inode_t)); inode->disk_offset = ((offset_t)le32_to_cpu(mount->group_tbl[group].bg_inode_table) * mount->block_size) + offset; /* Read it in. */ ret = device_read(mount->device, &inode->disk, inode->disk_size, inode->disk_offset, &bytes); if(ret != STATUS_SUCCESS) { dprintf("ext2: error occurred while reading inode %" PRIu32 " (%d)\n", num, ret); kfree(inode); return ret; } else if(bytes != inode->disk_size) { kfree(inode); return STATUS_CORRUPT_FS; } /* Work out the size of the node data. Regular files can be larger than * 4GB - the high 32-bits of the file size are stored in i_dir_acl. */ inode->size = le32_to_cpu(inode->disk.i_size); if(le16_to_cpu(inode->disk.i_mode) & EXT2_S_IFREG) { inode->size |= ((uint64_t)le32_to_cpu(inode->disk.i_dir_acl)) << 32; } /* Create the various caches. */ inode->map = file_map_create(mount->block_size, &ext2_file_map_ops, inode); inode->cache = vm_cache_create(inode->size, &file_map_vm_cache_ops, inode->map); inode->entries = entry_cache_create(&ext2_entry_cache_ops, inode); dprintf("ext2: read inode %" PRIu32 " from %" PRIu64 " (group: %zu, block: %zu)\n", num, inode->disk_offset, group, le32_to_cpu(mount->group_tbl[group].bg_inode_table)); *inodep = inode; return STATUS_SUCCESS; }
void mouse_read_input(void) { mouse_input_t mouseInput; mouseInput.mouse_event=0; mouseInput.x=0; mouseInput.y=0; device_read(global_device_manager, mouse_input_handler, &mouseInput, sizeof(mouse_input_t)); __mouse_position_calculation(&mouseInput); }
static int ifs_mount(struct device *dev) { struct ifs_volume_hdr hdr; device_read(dev, &hdr, sizeof(struct ifs_volume_hdr), 0); if (hdr.mag0 != 0xCB || hdr.mag1 != 0x0A || hdr.mag2 != 0x0D || hdr.mag3 != 0x0D) return -1; return 0; }
static int ifs_chmod(struct device *dev, const char *path, mode_t newmode) { struct ifs_entry entry; if (ifs_get_directory(dev, 0, path) != -1) { ino_t ino = ifs_get_directory(dev, 0, path); device_read(dev, &entry, sizeof(struct ifs_entry), ifs_get_address(dev, ino)); entry.mode = newmode; device_write(dev, &entry, ifs_get_address(dev, ino), sizeof(struct ifs_entry)); return 0; } return ENOENT; }
void mouse_read_input(void) { int32_t mouseInput[3]; device_read(global_device_manager, mouse_input_handler, &mouseInput, sizeof(mouse_input_t)); mouse_input_t input; input.x = mouseInput[0]; input.y = mouseInput[1]; input.mouse_event = mouseInput[2]; __mouse_position_calculation(&input); }
static int ifs_fstat(struct device *dev, ino_t ino, struct stat *stat_struct) { struct ifs_entry entry; device_read(dev, &entry, sizeof(struct ifs_entry), ifs_get_address(dev, ino)); stat_struct->st_mode = entry.mode; stat_struct->st_ctime = entry.created_time; stat_struct->st_mtime = entry.modified_time; stat_struct->st_atime = entry.modified_time; stat_struct->st_ino = ino; stat_struct->st_size = entry.file_size; stat_struct->st_uid = 0; stat_struct->st_gid = 1; return 0; }
static int ifs_rmdir(struct device *dev, const char *path) { struct ifs_entry entry; if (ifs_get_directory(dev, 0, path) != -1) { ino_t ino = ifs_get_directory(dev, 0, path); device_read(dev, &entry, sizeof(struct ifs_entry), ifs_get_address(dev, ino)); if(entry.file_type != IFS_DIRECTORY) return ENOTDIR; ifs_remove_entry(dev, path, &entry); ifs_free_blockgroup(dev, &entry); ifs_free_block(dev, ino); return 0; } return ENOENT; }
// ioctl handler long device_ioctl(struct file *file, unsigned int ioctl_num, unsigned long ioctl_param) { int i; char *temp; char ch; switch(ioctl_num){ case IOCTL_SET_MSG: /* * Receive a pointer to a message (in user space) and set that * to be the device's message. Get the parameter given to * ioctl by the process. */ temp = (char *)ioctl_param; // find the length of the package get_user(ch, temp); for(i=0; ch && i < BUF_LEN; i++, temp++){ // WTF ??? !?? get_user(ch, temp); } device_write(file, (char *)ioctl_param, i, 0); break; case IOCTL_GET_MSG: /* * Give the current message to the calling process − * the parameter we got is a pointer, fill it. */ i = device_read(file, (char *)ioctl_param, 99, 0); // put \0 terminator put_user('\0', (char *)ioctl_param + i); break; case IOCTL_GET_NTH_BYTE: /* * This ioctl is both input (ioctl_param) and * output (the return value of this function) */ return Message[ioctl_param]; break; } return SUCCESS; }
int keusb_request(const char *command, ...) { va_list ap; int length; int tries = 3; char request[REQUEST_SIZE + 3]; va_start(ap, command); vsnprintf(request, REQUEST_SIZE, command, ap); va_end(ap); length = strlen(request); request[length] = '\r'; request[length + 1] = '\n'; request[length + 2] = '\0'; while (tries--) { int parts = 0; char *p, *q; reply_buf[0] = '\0'; device_write(request, length + 2); device_read(reply_buf, REQUEST_SIZE); if (!strncmp(reply_buf, "#ERR\r\n", 6) || reply_buf[0] != '#') continue; for (p = q = reply_buf + 1; *p != '\r'; p++) if (*p == ',') { reply_part[parts++] = q; *p = '\0'; q = p + 1; } *p = '\0'; reply_size = parts + 1; reply_part[parts] = q; break; } return tries + 1; }
static void _accel_io_read(struct lsm303c_accelerometer *accel, uint8_t address, uint8_t *data, uint16_t size) { address |= (uint8_t)(0x80); /* Set chip select Low at the start of the transmission */ gpio_clear(accel->cs); /* Send the Address of the indexed register */ device_write(accel->dev, &address, 1); /* Receive the data that will be read from the device (MSB First) */ device_read(accel->dev, data, size); /* Set chip select High at the end of the transmission */ gpio_set(accel->cs); }