2013-06-22 05:11:53 +02:00
|
|
|
/**
|
|
|
|
* Shell commands for accessing storage
|
|
|
|
*
|
|
|
|
* Copyright (C) 2013 INRIA.
|
|
|
|
*
|
|
|
|
* This file subject to the terms and conditions of the GNU Lesser General
|
|
|
|
* Public License. See the file LICENSE in the top level directory for more
|
|
|
|
* details.
|
|
|
|
*
|
|
|
|
* @ingroup shell_commands
|
|
|
|
* @{
|
|
|
|
* @file sc_disk.c
|
|
|
|
* @brief provides shell commands to access storage (like mmc)
|
|
|
|
* @author Oliver Hahm <oliver.hahm@inria.fr>
|
|
|
|
* @}
|
|
|
|
*/
|
|
|
|
|
2011-12-12 17:50:22 +01:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
|
|
#include "shell_commands.h"
|
|
|
|
#include "diskio.h"
|
|
|
|
|
2013-06-22 05:11:53 +02:00
|
|
|
static inline uint8_t sector_read(unsigned char *read_buf, unsigned long sector, unsigned long length, unsigned long offset)
|
|
|
|
{
|
2011-12-12 17:50:22 +01:00
|
|
|
unsigned long i;
|
2013-06-22 05:11:53 +02:00
|
|
|
|
|
|
|
if(MCI_read(read_buf, sector, 1) == RES_OK) {
|
2011-12-12 17:50:22 +01:00
|
|
|
printf("[disk] Read sector %lu (%lu):\n", sector, offset);
|
2013-06-22 05:11:53 +02:00
|
|
|
|
|
|
|
for(i = offset + 1; i <= offset + length; i++) {
|
|
|
|
printf(" %u", read_buf[i - 1]);
|
|
|
|
|
|
|
|
if(!(i % 16)) {
|
2011-12-12 17:50:22 +01:00
|
|
|
puts("");
|
|
|
|
}
|
|
|
|
}
|
2013-06-22 05:11:53 +02:00
|
|
|
|
2011-12-12 17:50:22 +01:00
|
|
|
puts("");
|
|
|
|
return 1;
|
|
|
|
}
|
2013-06-22 05:11:53 +02:00
|
|
|
|
2011-12-12 17:50:22 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-06-22 05:11:53 +02:00
|
|
|
void _get_sectorsize(char *unused)
|
|
|
|
{
|
2011-12-12 17:50:22 +01:00
|
|
|
unsigned short ssize;
|
2013-06-22 05:11:53 +02:00
|
|
|
|
|
|
|
if(MCI_ioctl(GET_SECTOR_SIZE, &ssize) == RES_OK) {
|
2011-12-12 17:50:22 +01:00
|
|
|
printf("[disk] sector size is %u\n", ssize);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
puts("[disk] Failed to fetch sector size. Card inserted?");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-22 05:11:53 +02:00
|
|
|
void _get_blocksize(char *unused)
|
|
|
|
{
|
2011-12-12 17:50:22 +01:00
|
|
|
unsigned long bsize;
|
2013-06-22 05:11:53 +02:00
|
|
|
|
|
|
|
if(MCI_ioctl(GET_BLOCK_SIZE, &bsize) == RES_OK) {
|
2011-12-12 17:50:22 +01:00
|
|
|
printf("[disk] block size is %lu\n", bsize);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
puts("[disk] Failed to fetch block size. Card inserted?");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-22 05:11:53 +02:00
|
|
|
void _get_sectorcount(char *unused)
|
|
|
|
{
|
2011-12-12 17:50:22 +01:00
|
|
|
unsigned long scount;
|
2013-06-22 05:11:53 +02:00
|
|
|
|
|
|
|
if(MCI_ioctl(GET_SECTOR_COUNT, &scount) == RES_OK) {
|
2011-12-12 17:50:22 +01:00
|
|
|
printf("[disk] sector count is %lu\n", scount);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
puts("[disk] Failed to fetch sector count. Card inserted?");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-22 05:11:53 +02:00
|
|
|
void _read_sector(char *sector)
|
|
|
|
{
|
2011-12-12 17:50:22 +01:00
|
|
|
unsigned long sectornr, scount;
|
|
|
|
unsigned short ssize;
|
|
|
|
|
2013-06-22 05:11:53 +02:00
|
|
|
if(strlen(sector) > strlen(DISK_READ_SECTOR_CMD) + 1) {
|
2011-12-12 17:50:22 +01:00
|
|
|
|
2011-12-12 18:29:22 +01:00
|
|
|
sectornr = atol(sector + strlen(DISK_READ_SECTOR_CMD) + 1);
|
2013-06-22 05:11:53 +02:00
|
|
|
|
|
|
|
if((MCI_ioctl(GET_SECTOR_COUNT, &scount) == RES_OK) && (MCI_ioctl(GET_SECTOR_SIZE, &ssize) == RES_OK)) {
|
2011-12-12 17:50:22 +01:00
|
|
|
unsigned char read_buf[ssize];
|
2013-06-22 05:11:53 +02:00
|
|
|
|
|
|
|
if(sector_read(read_buf, sectornr, ssize, 0)) {
|
|
|
|
return;
|
2011-12-12 17:50:22 +01:00
|
|
|
}
|
|
|
|
}
|
2013-06-22 05:11:53 +02:00
|
|
|
|
2011-12-12 17:50:22 +01:00
|
|
|
printf("[disk] Error while reading sector %lu\n", sectornr);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
printf("[disk] Usage:\n%s <SECTOR>\n", DISK_READ_SECTOR_CMD);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-22 05:11:53 +02:00
|
|
|
void _read_bytes(char *bytes)
|
|
|
|
{
|
2011-12-12 17:50:22 +01:00
|
|
|
unsigned long sector = 1, scount, offset;
|
|
|
|
unsigned short ssize, length;
|
|
|
|
char *tok;
|
|
|
|
|
|
|
|
/* tokenize user input */
|
|
|
|
tok = strtok(bytes + strlen(DISK_READ_BYTES_CMD) + 1, " ");
|
2013-06-22 05:11:53 +02:00
|
|
|
|
|
|
|
if(tok) {
|
2011-12-12 17:50:22 +01:00
|
|
|
offset = atol(tok);
|
|
|
|
tok = strtok(NULL, " ");
|
2013-06-22 05:11:53 +02:00
|
|
|
|
|
|
|
if(tok) {
|
2011-12-12 17:50:22 +01:00
|
|
|
length = atoi(tok);
|
2013-06-22 05:11:53 +02:00
|
|
|
|
|
|
|
if(length) {
|
2011-12-12 17:50:22 +01:00
|
|
|
/* get card info */
|
2013-06-22 05:11:53 +02:00
|
|
|
if((MCI_ioctl(GET_SECTOR_COUNT, &scount) == RES_OK) && (MCI_ioctl(GET_SECTOR_SIZE, &ssize) == RES_OK)) {
|
2011-12-12 17:50:22 +01:00
|
|
|
/* calculate sector and offset position */
|
|
|
|
sector = (offset / ssize) + 1;
|
|
|
|
offset = (offset % ssize);
|
|
|
|
/* preapre buffer (size must be a multiple of sector size) */
|
|
|
|
unsigned char read_buf[((length / ssize) + 1) * 512];
|
2013-06-22 05:11:53 +02:00
|
|
|
|
2011-12-12 17:50:22 +01:00
|
|
|
/* read from several sectors */
|
2013-06-22 05:11:53 +02:00
|
|
|
if(length > (ssize - offset)) {
|
2011-12-12 17:50:22 +01:00
|
|
|
/* buffer offset */
|
|
|
|
unsigned long j = 0;
|
|
|
|
/* chunk from current sector */
|
|
|
|
unsigned short tmp = ssize - offset;
|
2013-06-22 05:11:53 +02:00
|
|
|
|
|
|
|
while(length) {
|
2011-12-12 17:50:22 +01:00
|
|
|
sector_read(read_buf + j, sector++, tmp, offset);
|
|
|
|
/* decrease length and recalculate chunk */
|
|
|
|
length -= tmp;
|
|
|
|
tmp = (length >= ssize) ? ssize : length;
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
} /* length > (ssize - offset) */
|
|
|
|
/* read only one sector */
|
|
|
|
else {
|
2013-06-22 05:11:53 +02:00
|
|
|
if(sector_read(read_buf, sector, length, offset)) {
|
2011-12-12 17:50:22 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
} /* length < (ssize - offset) */
|
|
|
|
} /* ioctl */
|
2013-06-22 05:11:53 +02:00
|
|
|
|
2011-12-12 17:50:22 +01:00
|
|
|
printf("[disk] Error while reading sector %lu\n", sector);
|
|
|
|
return;
|
|
|
|
} /* length */
|
|
|
|
} /* strtok #2 */
|
|
|
|
} /* strtok #1 */
|
2013-06-22 05:11:53 +02:00
|
|
|
|
2011-12-12 17:50:22 +01:00
|
|
|
printf("[disk] Usage:\n%s <OFFSET> <LENGTH>\n", DISK_READ_BYTES_CMD);
|
|
|
|
}
|