static int blockdev_pager_rw_page(struct vm_pager *pager, void *buf, u32_t page_num, blockdev_rw_op *rw_func) { int rc; struct blockdev_pager *blkdev_pager; lba_t io_start_lba; /* io start LBA, inclusive */ lba_t io_end_lba; /* io end LBA, exclusive */ lba_t range_end_lba; /* last LBA in range covered by this blockdev_pager, exclusive */ blkdev_pager = pager->p; io_start_lba = lba_add_offset(blkdev_pager->start, page_num * blkdev_pager->num_blocks_per_page); io_end_lba = lba_add_offset(io_start_lba, blkdev_pager->num_blocks_per_page); /* * Special case: see if we're accessing * an incomplete page of data at the end of the range * of blocks covered by this pager. * If so, set io_end_lba such that * we avoid reading/writing past end of range. */ range_end_lba = lba_add_offset(blkdev_pager->start, blkdev_pager->num_blocks); if (lba_compare(range_end_lba, io_end_lba) < 0) { io_end_lba = range_end_lba; } /* Do the IO! */ rc = rw_func(blkdev_pager->dev, io_start_lba, lba_num_blocks_in_range(io_start_lba, io_end_lba), buf); return rc; }
_mqx_int _io_usb_mfs_read_write_sectors_internal ( /* [IN] the file handle for the device */ MQX_FILE_PTR fd_ptr, /* [IN] USB MFS state structure */ IO_USB_MFS_STRUCT_PTR info_ptr, /* [IN] where the newly-read bytes are to be stored */ char_ptr data_ptr, /* [IN] the number of sectors to read */ uint_32 num, /* [IN] Read/write mode */ boolean write ) { /* Body */ _mqx_int (_CODE_PTR_ rw_func_long)(IO_USB_MFS_STRUCT_PTR, uint_32, uint_32, uchar_ptr); _mqx_int (_CODE_PTR_ rw_func)(IO_USB_MFS_STRUCT_PTR, uint_32, uint_16, uchar_ptr); _mqx_int io_result = IO_ERROR; _mqx_uint io_error; if (write) { io_error = IO_ERROR_WRITE_ACCESS; rw_func = _io_usb_mfs_write_sector_internal; rw_func_long = _io_usb_mfs_write_sector_long_internal; } else { io_error = IO_ERROR_READ_ACCESS; rw_func = _io_usb_mfs_read_sector_internal; rw_func_long = _io_usb_mfs_read_sector_long_internal; } /* Endif */ if (fd_ptr->LOCATION >= info_ptr->BCOUNT) { fd_ptr->ERROR = io_error; } else { if ((num + fd_ptr->LOCATION) >= info_ptr->BCOUNT) { fd_ptr->ERROR = (_mqx_uint)io_error; num = (uint_32)(info_ptr->BCOUNT - fd_ptr->LOCATION + 1); } /* Endif */ /* Read all the sectors, one at a time */ if (num > 0xFFFE) { /* Read all the sectors at once */ io_result = rw_func_long(info_ptr, fd_ptr->LOCATION, num, (uchar_ptr)data_ptr); } else { io_result = rw_func(info_ptr, fd_ptr->LOCATION, (uint_16)num, (uchar_ptr)data_ptr); } /* Endif */ if (io_result == IO_ERROR ) { fd_ptr->ERROR = io_error; } else { fd_ptr->LOCATION += num; } /* Endif */ } /* Endif */ return io_result; } /* Endbody */
int do_ds4510(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { static uint8_t chip = CONFIG_SYS_I2C_DS4510_ADDR; cmd_tbl_t *c; ulong ul_arg2 = 0; ulong ul_arg3 = 0; int tmp; #ifdef CONFIG_CMD_DS4510_MEM ulong addr; ulong off; ulong cnt; int end; int (*rw_func)(uint8_t, int, uint8_t *, int); #endif c = find_cmd_tbl(argv[1], cmd_ds4510, ARRAY_SIZE(cmd_ds4510)); /* All commands but "device" require 'maxargs' arguments */ if (!c || !((argc == (c->maxargs)) || (((int)c->cmd == DS4510_CMD_DEVICE) && (argc == (c->maxargs - 1))))) { return cmd_usage(cmdtp); } /* arg2 used as chip addr and pin number */ if (argc > 2) ul_arg2 = simple_strtoul(argv[2], NULL, 16); /* arg3 used as output/pullup value */ if (argc > 3) ul_arg3 = simple_strtoul(argv[3], NULL, 16); switch ((int)c->cmd) { case DS4510_CMD_DEVICE: if (argc == 3) chip = ul_arg2; printf("Current device address: 0x%x\n", chip); return 0; case DS4510_CMD_NV: return ds4510_see_write(chip, ul_arg2); case DS4510_CMD_OUTPUT: tmp = ds4510_gpio_read(chip); if (tmp == -1) return -1; if (ul_arg3) tmp |= (1 << ul_arg2); else tmp &= ~(1 << ul_arg2); return ds4510_gpio_write(chip, tmp); case DS4510_CMD_INPUT: tmp = ds4510_gpio_read_val(chip); if (tmp == -1) return -1; return (tmp & (1 << ul_arg2)) != 0; case DS4510_CMD_PULLUP: tmp = ds4510_pullup_read(chip); if (tmp == -1) return -1; if (ul_arg3) tmp |= (1 << ul_arg2); else tmp &= ~(1 << ul_arg2); return ds4510_pullup_write(chip, tmp); #ifdef CONFIG_CMD_DS4510_INFO case DS4510_CMD_INFO: return ds4510_info(chip); #endif #ifdef CONFIG_CMD_DS4510_RST case DS4510_CMD_RSTDELAY: return ds4510_rstdelay_write(chip, ul_arg2); #endif #ifdef CONFIG_CMD_DS4510_MEM case DS4510_CMD_EEPROM: end = DS4510_EEPROM + DS4510_EEPROM_SIZE; off = DS4510_EEPROM; break; case DS4510_CMD_SEEPROM: end = DS4510_SEEPROM + DS4510_SEEPROM_SIZE; off = DS4510_SEEPROM; break; case DS4510_CMD_SRAM: end = DS4510_SRAM + DS4510_SRAM_SIZE; off = DS4510_SRAM; break; #endif default: /* We should never get here... */ return 1; } #ifdef CONFIG_CMD_DS4510_MEM /* Only eeprom, seeprom, and sram commands should make it here */ if (strcmp(argv[2], "read") == 0) rw_func = ds4510_mem_read; else if (strcmp(argv[2], "write") == 0) rw_func = ds4510_mem_write; else return cmd_usage(cmdtp); addr = simple_strtoul(argv[3], NULL, 16); off += simple_strtoul(argv[4], NULL, 16); cnt = simple_strtoul(argv[5], NULL, 16); if ((off + cnt) > end) { printf("ERROR: invalid len\n"); return -1; } return rw_func(chip, off, (uint8_t *)addr, cnt); #endif }