dfs_elm.c 15.0 KB
Newer Older
B
bernard.xiong 已提交
1
#include <rtthread.h>
B
bernard.xiong 已提交
2
#include "ffconf.h"
B
bernard.xiong 已提交
3 4
#include "ff.h"

5 6 7 8 9 10
/* ELM FatFs provide a DIR struct */
#define HAVE_DIR_STRUCTURE

#include <dfs_fs.h>
#include <dfs_def.h>

wuyangyong's avatar
wuyangyong 已提交
11
static rt_device_t disk[_VOLUMES] = {0};
B
bernard.xiong 已提交
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47

static int elm_result_to_dfs(FRESULT result)
{
	int status = DFS_STATUS_OK;

	switch (result)
	{
	case FR_OK:
		break;

	case FR_NO_FILE:
	case FR_NO_PATH:
	case FR_NO_FILESYSTEM:
		status = -DFS_STATUS_ENOENT;
		break;

	case FR_INVALID_NAME:
		status = -DFS_STATUS_EINVAL;
		break;

	case FR_EXIST:
	case FR_INVALID_OBJECT:
		status = -DFS_STATUS_EEXIST;
		break;

	case FR_DISK_ERR:
	case FR_NOT_READY:
	case FR_INT_ERR:
		status = -DFS_STATUS_EIO;
		break;

	case FR_WRITE_PROTECTED:
	case FR_DENIED:
		status = -DFS_STATUS_EROFS;
		break;

48 49 50
	case FR_MKFS_ABORTED:
		status = -DFS_STATUS_EINVAL;
		break;
wuyangyong's avatar
wuyangyong 已提交
51

B
bernard.xiong 已提交
52 53 54 55 56 57 58 59
	default:
		status = -1;
		break;
	}

	return status;
}

60
int dfs_elm_mount(struct dfs_filesystem* fs, unsigned long rwflag, const void* data)
B
bernard.xiong 已提交
61 62 63 64 65 66
{
	FATFS *fat;
	FRESULT result;
	rt_uint32_t index;

	/* handle RT-Thread device routine */
wuyangyong's avatar
wuyangyong 已提交
67
	for (index = 0; index < _VOLUMES; index ++)
B
bernard.xiong 已提交
68 69 70 71 72 73
	{
		if (disk[index] == RT_NULL)
		{
			break;
		}
	}
wuyangyong's avatar
wuyangyong 已提交
74
	if (index == _VOLUMES) return -DFS_STATUS_ENOSPC;
B
bernard.xiong 已提交
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100

	/* get device */
	disk[index] = fs->dev_id;

	fat = (FATFS *) rt_malloc(sizeof(FATFS));
	if (fat == RT_NULL)
	{
		return -1;
	}

	/* mount fatfs, always 0 logic driver */
	result = f_mount(index, fat);
	if (result == FR_OK)
		fs->data = fat;
	else
	{
		rt_free(fat);
		return elm_result_to_dfs(result);
	}

	return 0;
}

int dfs_elm_unmount(struct dfs_filesystem* fs)
{
	FATFS *fat;
101 102 103
	FRESULT result;
	rt_uint32_t index;

B
bernard.xiong 已提交
104 105 106 107
	fat = (FATFS*) fs->data;

	RT_ASSERT(fat != RT_NULL);

108
	/* find the device index and then umount it */
wuyangyong's avatar
wuyangyong 已提交
109
	for (index = 0; index < _VOLUMES; index ++)
110 111 112 113
	{
		if (disk[index] == fs->dev_id)
		{
			result = f_mount(index, RT_NULL);
B
bernard.xiong 已提交
114

115 116 117 118 119 120 121 122 123 124 125
			if (result == FR_OK)
			{
				fs->data = RT_NULL;
				disk[index] = RT_NULL;
				rt_free(fat);
				return DFS_STATUS_OK;
			}
		}
	}

	return -DFS_STATUS_ENOENT;
B
bernard.xiong 已提交
126 127
}

128 129 130 131 132 133 134
int dfs_elm_mkfs(const char* device_name)
{
	BYTE drv;
	rt_device_t dev;
	FRESULT result;

	/* find device name */
wuyangyong's avatar
wuyangyong 已提交
135
	for (drv = 0; drv < _VOLUMES; drv ++)
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
	{
		dev = disk[drv];
		if (rt_strncmp(dev->parent.name, device_name, RT_NAME_MAX) == 0)
		{
			/* 1: no partition table */
			/* 0: auto selection of cluster size */
			result = f_mkfs(drv, 1, 0);
			if ( result != FR_OK)
			{
				rt_kprintf("format error\n");
				return elm_result_to_dfs(result);
			}

			return DFS_STATUS_OK;
		}
	}

	/* can't find device driver */
	rt_kprintf("can not find device driver: %s\n", device_name);
	return -DFS_STATUS_EIO;
}

158
int dfs_elm_statfs(struct dfs_filesystem* fs, struct statfs *buf)
159 160 161 162 163 164 165 166 167 168 169
{
	FATFS *f;
	FRESULT res;
	char driver[4];
	DWORD fre_clust, fre_sect, tot_sect;

	RT_ASSERT(fs != RT_NULL);
	RT_ASSERT(buf != RT_NULL);

	f = (FATFS*) fs->data;

wuyangyong's avatar
wuyangyong 已提交
170
	rt_snprintf(driver, sizeof(driver), "%d:", f->drv);
171 172
	res = f_getfree(driver, &fre_clust, &f);
	if (res) return elm_result_to_dfs(res);
wuyangyong's avatar
wuyangyong 已提交
173

174
	/* Get total sectors and free sectors */
wuyangyong's avatar
wuyangyong 已提交
175
	tot_sect = (f->n_fatent - 2) * f->csize;
176 177 178 179 180 181 182 183 184
	fre_sect = fre_clust * f->csize;

	buf->f_bfree = fre_sect;
	buf->f_blocks = tot_sect;
	buf->f_bsize = 512;

	return 0;
}

B
bernard.xiong 已提交
185 186 187 188 189
int dfs_elm_open(struct dfs_fd* file)
{
	FIL* fd;
	BYTE mode;
	FRESULT result;
B
bernard.xiong 已提交
190 191
	char *drivers_fn;

wuyangyong's avatar
wuyangyong 已提交
192
#if (_VOLUMES > 1)
B
bernard.xiong 已提交
193 194
	int vol;
	extern int elm_get_vol(FATFS *fat);
wuyangyong's avatar
wuyangyong 已提交
195

B
bernard.xiong 已提交
196 197 198 199 200 201 202 203 204 205
	/* add path for ELM FatFS driver support */
	vol = elm_get_vol((FATFS *)file->fs->data);
	if (vol < 0) return -DFS_STATUS_ENOENT;
	drivers_fn = rt_malloc(256);
	if (drivers_fn == RT_NULL) return -DFS_STATUS_ENOMEM;

	rt_snprintf(drivers_fn, 256, "%d:%s", vol, file->path);
#else
	drivers_fn = file->path;
#endif
B
bernard.xiong 已提交
206 207 208 209 210 211 212

	if (file->flags & DFS_O_DIRECTORY)
	{
		DIR *dir;

		if (file->flags & DFS_O_CREAT)
		{
B
bernard.xiong 已提交
213
			result = f_mkdir(drivers_fn);
B
bernard.xiong 已提交
214 215
			if (result != FR_OK)
			{
wuyangyong's avatar
wuyangyong 已提交
216
#if _VOLUMES > 1
B
bernard.xiong 已提交
217 218
				rt_free(drivers_fn);
#endif
B
bernard.xiong 已提交
219 220 221 222 223 224 225 226
				return elm_result_to_dfs(result);
			}
		}

		/* open directory */
		dir = (DIR *)rt_malloc(sizeof(DIR));
		if (dir == RT_NULL)
		{
wuyangyong's avatar
wuyangyong 已提交
227
#if _VOLUMES > 1
B
bernard.xiong 已提交
228 229
			rt_free(drivers_fn);
#endif
B
bernard.xiong 已提交
230 231 232
			return -DFS_STATUS_ENOMEM;
		}

B
bernard.xiong 已提交
233
		result = f_opendir(dir, drivers_fn);
wuyangyong's avatar
wuyangyong 已提交
234
#if _VOLUMES > 1
B
bernard.xiong 已提交
235 236
		rt_free(drivers_fn);
#endif
B
bernard.xiong 已提交
237 238 239 240 241 242 243 244 245 246 247 248 249 250
		if (result != FR_OK)
		{
			rt_free(dir);
			return elm_result_to_dfs(result);
		}

		file->data = dir;
		return DFS_STATUS_OK;
	}
	else
	{
		mode = FA_READ;

		if (file->flags & DFS_O_WRONLY) mode |= FA_WRITE;
B
bernard.xiong 已提交
251
		if ((file->flags & DFS_O_ACCMODE) & DFS_O_RDWR) mode |= FA_WRITE;
252 253 254
		/* Opens the file, if it is existing. If not, a new file is created. */
		if (file->flags & DFS_O_CREAT) mode |= FA_OPEN_ALWAYS;
		/* Creates a new file. If the file is existing, it is truncated and overwritten. */
255
		if (file->flags & DFS_O_TRUNC) mode |= FA_CREATE_ALWAYS;
256 257
		/* Creates a new file. The function fails if the file is already existing. */
		if (file->flags & DFS_O_EXCL) mode |= FA_CREATE_NEW;
B
bernard.xiong 已提交
258 259 260 261 262 263 264 265

		/* allocate a fd */
		fd = (FIL*)rt_malloc(sizeof(FIL));
		if (fd == RT_NULL)
		{
			return -DFS_STATUS_ENOMEM;
		}

B
bernard.xiong 已提交
266
		result = f_open(fd, drivers_fn, mode);
wuyangyong's avatar
wuyangyong 已提交
267
#if _VOLUMES > 1
B
bernard.xiong 已提交
268 269
		rt_free(drivers_fn);
#endif
B
bernard.xiong 已提交
270 271 272 273 274
		if (result == FR_OK)
		{
			file->pos  = fd->fptr;
			file->size = fd->fsize;
			file->data = fd;
275 276 277 278 279

			if (file->flags & DFS_O_APPEND)
			{
				file->pos = f_lseek(fd, fd->fsize);
			}
B
bernard.xiong 已提交
280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343
		}
		else
		{
			/* open failed, return */
			rt_free(fd);
			return elm_result_to_dfs(result);
		}
	}

	return DFS_STATUS_OK;
}

int dfs_elm_close(struct dfs_fd* file)
{
	FRESULT result;

	result = FR_OK;
	if (file->type == FT_DIRECTORY)
	{
		DIR* dir;

		dir = (DIR*)(file->data);
		RT_ASSERT(dir != RT_NULL);

		/* release memory */
		rt_free(dir);
	}
	else if (file->type == FT_REGULAR)
	{
		FIL* fd;
		fd = (FIL*)(file->data);
		RT_ASSERT(fd != RT_NULL);

		result = f_close(fd);
		if (result == FR_OK)
		{
			/* release memory */
			rt_free(fd);
		}
	}

	return elm_result_to_dfs(result);
}

int dfs_elm_ioctl(struct dfs_fd* file, int cmd,	void* args)
{
	return -DFS_STATUS_ENOSYS;
}

int dfs_elm_read(struct dfs_fd* file, void* buf, rt_size_t len)
{
	FIL* fd;
	FRESULT result;
	UINT byte_read;

	if (file->type == FT_DIRECTORY)
	{
		return -DFS_STATUS_EISDIR;
	}

	fd = (FIL*)(file->data);
	RT_ASSERT(fd != RT_NULL);

	result = f_read(fd, buf, len, &byte_read);
344 345
	/* update position */
	file->pos  = fd->fptr;
B
bernard.xiong 已提交
346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365
	if (result == FR_OK) return byte_read;

	return elm_result_to_dfs(result);
}

int dfs_elm_write(struct dfs_fd* file, const void* buf, rt_size_t len)
{
	FIL* fd;
	FRESULT result;
	UINT byte_write;

	if (file->type == FT_DIRECTORY)
	{
		return -DFS_STATUS_EISDIR;
	}

	fd = (FIL*)(file->data);
	RT_ASSERT(fd != RT_NULL);

	result = f_write(fd, buf, len, &byte_write);
B
bernard.xiong 已提交
366
	/* update position and file size */
367
	file->pos  = fd->fptr;
B
bernard.xiong 已提交
368
	file->size = fd->fsize;
B
bernard.xiong 已提交
369 370 371 372 373
	if (result == FR_OK) return byte_write;

	return elm_result_to_dfs(result);
}

374 375 376 377 378 379 380 381 382 383 384 385
int dfs_elm_flush(struct dfs_fd* file)
{
	FIL* fd;
	FRESULT result;

	fd = (FIL*)(file->data);
	RT_ASSERT(fd != RT_NULL);

	result = f_sync(fd);
	return elm_result_to_dfs(result);
}

B
bernard.xiong 已提交
386 387 388
int dfs_elm_lseek(struct dfs_fd* file, rt_off_t offset)
{
	FRESULT result;
qiuyiuestc's avatar
qiuyiuestc 已提交
389
	if (file->type == FT_REGULAR)
390 391
	{
		FIL* fd;
B
bernard.xiong 已提交
392

393 394 395 396 397 398 399 400 401 402 403
		/* regular file type */
		fd = (FIL*)(file->data);
		RT_ASSERT(fd != RT_NULL);
		
		result = f_lseek(fd, offset);
		if (result == FR_OK)
		{
			/* return current position */
			return fd->fptr;
		}
	}
qiuyiuestc's avatar
qiuyiuestc 已提交
404
	else if (file->type == FT_DIRECTORY)
B
bernard.xiong 已提交
405
	{
406 407 408 409 410 411 412 413 414 415 416 417 418
		/* which is a directory */
		DIR* dir;

		dir = (DIR*)(file->data);
		RT_ASSERT(dir != RT_NULL);

		result = f_seekdir(dir, offset / sizeof(struct dirent));
		if (result == FR_OK)
		{
			/* update file position */
			file->pos = offset;
			return file->pos;
		}
B
bernard.xiong 已提交
419
	}
420

B
bernard.xiong 已提交
421 422 423
	return elm_result_to_dfs(result);
}

424
int dfs_elm_getdents(struct dfs_fd* file, struct dirent* dirp, rt_uint32_t count)
B
bernard.xiong 已提交
425 426 427 428 429
{
	DIR* dir;
	FILINFO fno;
	FRESULT result;
	rt_uint32_t index;
430
	struct dirent* d;
B
bernard.xiong 已提交
431 432 433 434 435

	dir = (DIR*)(file->data);
	RT_ASSERT(dir != RT_NULL);

	/* make integer count */
436
	count = (count / sizeof(struct dirent)) * sizeof(struct dirent);
B
bernard.xiong 已提交
437 438
	if ( count == 0 ) return -DFS_STATUS_EINVAL;

B
bernard.xiong 已提交
439 440 441 442 443 444
#if _USE_LFN
	/* allocate long file name */
	fno.lfname = rt_malloc(256);
	fno.lfsize = 256;
#endif

B
bernard.xiong 已提交
445 446 447 448 449 450 451 452
	index = 0;
	while (1)
	{
		char *fn;

		d = dirp + index;

		result = f_readdir(dir, &fno);
453
		if (result != FR_OK || fno.fname[0] == 0) break;
B
bernard.xiong 已提交
454 455 456 457 458 459 460 461

#if _USE_LFN
		fn = *fno.lfname? fno.lfname : fno.fname;
#else
		fn = fno.fname;
#endif

		d->d_type = DFS_DT_UNKNOWN;
J
jiaojinxing1987@gmail.com 已提交
462 463
		if (fno.fattrib & AM_DIR) d->d_type = DFS_DT_DIR;
		else d->d_type = DFS_DT_REG;
B
bernard.xiong 已提交
464

B
bernard.xiong 已提交
465
		d->d_namlen = rt_strlen(fn);
466
		d->d_reclen = (rt_uint16_t)sizeof(struct dirent);
B
bernard.xiong 已提交
467
		rt_strncpy(d->d_name, fn, rt_strlen(fn) + 1);
B
bernard.xiong 已提交
468 469

		index ++;
470
		if ( index * sizeof(struct dirent) >= count )
B
bernard.xiong 已提交
471 472 473
			break;
	}

B
bernard.xiong 已提交
474 475 476 477
#if _USE_LFN
	rt_free(fno.lfname);
#endif

B
bernard.xiong 已提交
478 479 480
	if (index == 0)
		return elm_result_to_dfs(result);

481 482
	file->pos += index * sizeof(struct dirent);

483
	return index * sizeof(struct dirent);
B
bernard.xiong 已提交
484 485 486 487 488 489
}

int dfs_elm_unlink(struct dfs_filesystem* fs, const char* path)
{
	FRESULT result;

wuyangyong's avatar
wuyangyong 已提交
490
#if _VOLUMES > 1
B
bernard.xiong 已提交
491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507
	int vol;
	char *drivers_fn;
	extern int elm_get_vol(FATFS *fat);

	/* add path for ELM FatFS driver support */
	vol = elm_get_vol((FATFS *)fs->data);
	if (vol < 0) return -DFS_STATUS_ENOENT;
	drivers_fn = rt_malloc(256);
	if (drivers_fn == RT_NULL) return -DFS_STATUS_ENOMEM;

	rt_snprintf(drivers_fn, 256, "%d:%s", vol, path);
#else
	const char *drivers_fn;
	drivers_fn = path;
#endif

	result = f_unlink(drivers_fn);
wuyangyong's avatar
wuyangyong 已提交
508
#if _VOLUMES > 1
B
bernard.xiong 已提交
509 510
	rt_free(drivers_fn);
#endif
B
bernard.xiong 已提交
511 512 513 514 515 516 517
	return elm_result_to_dfs(result);
}

int dfs_elm_rename(struct dfs_filesystem* fs, const char* oldpath, const char* newpath)
{
	FRESULT result;

wuyangyong's avatar
wuyangyong 已提交
518
#if _VOLUMES > 1
B
bernard.xiong 已提交
519 520 521 522 523 524 525 526 527 528 529
	char *drivers_oldfn, *drivers_newfn;
	int vol;
	extern int elm_get_vol(FATFS *fat);

	/* add path for ELM FatFS driver support */
	vol = elm_get_vol((FATFS *)fs->data);
	if (vol < 0) return -DFS_STATUS_ENOENT;

	drivers_oldfn = rt_malloc(256);
	if (drivers_oldfn == RT_NULL) return -DFS_STATUS_ENOMEM;
	drivers_newfn = rt_malloc(256);
wuyangyong's avatar
wuyangyong 已提交
530
	if (drivers_newfn == RT_NULL)
B
bernard.xiong 已提交
531 532 533 534 535 536 537 538 539 540 541
	{
		rt_free(drivers_oldfn);
		return -DFS_STATUS_ENOMEM;
	}

	rt_snprintf(drivers_oldfn, 256, "%d:%s", vol, oldpath);
	rt_snprintf(drivers_newfn, 256, "%d:%s", vol, newpath);
#else
	const char *drivers_oldfn, *drivers_newfn;

	drivers_oldfn = oldpath;
B
bernard.xiong 已提交
542
	drivers_newfn = newpath;
B
bernard.xiong 已提交
543 544 545
#endif

	result = f_rename(drivers_oldfn, drivers_newfn);
wuyangyong's avatar
wuyangyong 已提交
546
#if _VOLUMES > 1
B
bernard.xiong 已提交
547 548 549
	rt_free(drivers_oldfn);
	rt_free(drivers_newfn);
#endif
B
bernard.xiong 已提交
550 551 552
	return elm_result_to_dfs(result);
}

553
int dfs_elm_stat(struct dfs_filesystem* fs, const char *path, struct stat *st)
B
bernard.xiong 已提交
554 555 556 557
{
	FILINFO file_info;
	FRESULT result;

B
bernard.xiong 已提交
558

wuyangyong's avatar
wuyangyong 已提交
559
#if _VOLUMES > 1
B
bernard.xiong 已提交
560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575
	int vol;
	char *drivers_fn;
	extern int elm_get_vol(FATFS *fat);

	/* add path for ELM FatFS driver support */
	vol = elm_get_vol((FATFS *)fs->data);
	if (vol < 0) return -DFS_STATUS_ENOENT;
	drivers_fn = rt_malloc(256);
	if (drivers_fn == RT_NULL) return -DFS_STATUS_ENOMEM;

	rt_snprintf(drivers_fn, 256, "%d:%s", vol, path);
#else
	const char *drivers_fn;
	drivers_fn = path;
#endif

B
bernard.xiong 已提交
576 577 578 579 580 581
#if _USE_LFN
	/* allocate long file name */
	file_info.lfname = rt_malloc(256);
	file_info.lfsize = 256;
#endif

B
bernard.xiong 已提交
582
	result = f_stat(drivers_fn, &file_info);
wuyangyong's avatar
wuyangyong 已提交
583
#if _VOLUMES > 1
B
bernard.xiong 已提交
584 585
	rt_free(drivers_fn);
#endif
B
bernard.xiong 已提交
586 587 588 589
	if (result == FR_OK)
	{
		/* convert to dfs stat structure */
		st->st_dev   = 0;
590

591
		st->st_mode = DFS_S_IFREG | DFS_S_IRUSR | DFS_S_IRGRP | DFS_S_IROTH |
592
		DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH;
593
		if (file_info.fattrib & AM_DIR)
594 595 596 597 598 599 600
		{
			st->st_mode &= ~DFS_S_IFREG;
			st->st_mode |= DFS_S_IFDIR | DFS_S_IXUSR | DFS_S_IXGRP | DFS_S_IXOTH;
		}
		if (file_info.fattrib & AM_RDO)
			st->st_mode &= ~(DFS_S_IWUSR | DFS_S_IWGRP | DFS_S_IWOTH);

B
bernard.xiong 已提交
601 602 603 604 605
		st->st_size  = file_info.fsize;
		st->st_mtime = file_info.ftime;
		st->st_blksize = 512;
	}

B
bernard.xiong 已提交
606 607 608 609
#if _USE_LFN
	rt_free(file_info.lfname);
#endif

B
bernard.xiong 已提交
610 611 612
	return elm_result_to_dfs(result);
}

wuyangyong's avatar
wuyangyong 已提交
613
static const struct dfs_filesystem_operation dfs_elm =
B
bernard.xiong 已提交
614
{
615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632
	"elm",
	dfs_elm_mount,
	dfs_elm_unmount,
	dfs_elm_mkfs,
	dfs_elm_statfs,

	dfs_elm_open,
	dfs_elm_close,
	dfs_elm_ioctl,
	dfs_elm_read,
	dfs_elm_write,
	dfs_elm_flush,
	dfs_elm_lseek,
	dfs_elm_getdents,
	dfs_elm_unlink,
	dfs_elm_stat,
	dfs_elm_rename,
};
B
bernard.xiong 已提交
633

634 635
int elm_init(void)
{
B
bernard.xiong 已提交
636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664
    /* register fatfs file system */
    dfs_register(&dfs_elm);

	return 0;
}

/*
 * RT-Thread Device Interface for ELM FatFs
 */
#include "diskio.h"

/* Inidialize a Drive */
DSTATUS disk_initialize (BYTE drv)
{
	return 0;
}

/* Return Disk Status */
DSTATUS disk_status (BYTE drv)
{
	return 0;
}

/* Read Sector(s) */
DRESULT disk_read (BYTE drv, BYTE *buff, DWORD sector, BYTE count)
{
	rt_size_t result;
	rt_device_t device = disk[drv];

665 666
	result = rt_device_read(device, sector, buff, count);
	if (result == count)
B
bernard.xiong 已提交
667 668 669 670 671 672 673 674 675 676 677 678 679
	{
		return RES_OK;
	}

	return RES_ERROR;
}

/* Write Sector(s) */
DRESULT disk_write (BYTE drv, const BYTE *buff, DWORD sector, BYTE count)
{
	rt_size_t result;
	rt_device_t device = disk[drv];

680 681
	result = rt_device_write(device, sector, buff, count);
	if (result == count)
B
bernard.xiong 已提交
682 683 684 685 686 687 688 689 690 691
	{
		return RES_OK;
	}

	return RES_ERROR;
}

/* Miscellaneous Functions */
DRESULT disk_ioctl (BYTE drv, BYTE ctrl, void *buff)
{
692 693 694
	rt_device_t device = disk[drv];

	if (device == RT_NULL) return RES_ERROR;
wuyangyong's avatar
wuyangyong 已提交
695

696 697 698 699 700 701 702 703
	if (ctrl == GET_SECTOR_COUNT)
	{
		struct rt_device_blk_geometry geometry;

		rt_memset(&geometry, 0, sizeof(geometry));
		rt_device_control(device, RT_DEVICE_CTRL_BLK_GETGEOME, &geometry);

		*(DWORD*)buff = geometry.sector_count;
704
		if (geometry.sector_count == 0) return RES_ERROR;
705 706 707 708 709 710 711 712
	}
	else if (ctrl == GET_SECTOR_SIZE)
	{
		struct rt_device_blk_geometry geometry;

		rt_memset(&geometry, 0, sizeof(geometry));
		rt_device_control(device, RT_DEVICE_CTRL_BLK_GETGEOME, &geometry);

wuyangyong's avatar
wuyangyong 已提交
713
		*(WORD*)buff = geometry.bytes_per_sector;
714 715 716 717 718 719 720 721 722 723 724
	}
	else if (ctrl == GET_BLOCK_SIZE) /* Get erase block size in unit of sectors (DWORD) */
	{
		struct rt_device_blk_geometry geometry;

		rt_memset(&geometry, 0, sizeof(geometry));
		rt_device_control(device, RT_DEVICE_CTRL_BLK_GETGEOME, &geometry);

		*(DWORD*)buff = geometry.block_size/geometry.bytes_per_sector;
	}

B
bernard.xiong 已提交
725 726 727 728 729 730 731
	return RES_OK;
}

rt_time_t get_fattime()
{
	return 0;
}
732 733

#if _FS_REENTRANT
wuyangyong's avatar
wuyangyong 已提交
734
int ff_cre_syncobj(BYTE drv, _SYNC_t* m)
735 736 737 738 739 740 741 742 743
{
    char name[8];
    rt_mutex_t mutex;

    rt_snprintf(name, sizeof(name), "fat%d", drv);
    mutex = rt_mutex_create(name, RT_IPC_FLAG_FIFO);
    if (mutex != RT_NULL)
    {
        *m = mutex;
wuyangyong's avatar
wuyangyong 已提交
744
        return RT_TRUE;
745 746
    }

wuyangyong's avatar
wuyangyong 已提交
747
    return RT_FALSE;
748 749
}

wuyangyong's avatar
wuyangyong 已提交
750
int ff_del_syncobj(_SYNC_t m)
751 752 753
{
    rt_mutex_delete(m);

wuyangyong's avatar
wuyangyong 已提交
754
    return RT_TRUE;
755 756
}

wuyangyong's avatar
wuyangyong 已提交
757
int ff_req_grant(_SYNC_t m)
758
{
wuyangyong's avatar
wuyangyong 已提交
759
    if (rt_mutex_take(m, _FS_TIMEOUT) == RT_EOK) return RT_TRUE;
760

wuyangyong's avatar
wuyangyong 已提交
761
    return RT_FALSE;
762 763 764 765 766 767 768 769
}

void ff_rel_grant(_SYNC_t m)
{
	rt_mutex_release(m);
}

#endif