38extern const char apaMBRMagic[];
41#ifdef APA_FORMAT_MAKE_PARTITIONS
43static const char *formatPartList[] = {
44 "__net",
"__system",
"__sysconf",
"__common", NULL};
47#define APA_NUMBER_OF_SIZES 9
48static const char *sizeList[APA_NUMBER_OF_SIZES] = {
49 "128M",
"256M",
"512M",
"1G",
"2G",
"4G",
"8G",
"16G",
"32G"};
53static int fioPartitionSizeLookUp(
char *str);
54static int fioInputBreaker(
char const **arg,
char *outBuf,
int maxout);
61static int devctlSwapTemp(s32 device,
char *argp);
63static int fioPartitionSizeLookUp(
char *str)
67 for (i = 0; i < APA_NUMBER_OF_SIZES; i++) {
68 if (strcmp(str, sizeList[i]) == 0)
69 return (256 * 1024) << i;
71 APA_PRINTF(APA_DRV_NAME
": Error: Invalid partition size, %s.\n", str);
75static int fioInputBreaker(
char const **arg,
char *outBuf,
int maxout)
80 if ((p = strchr(arg[0],
','))) {
81 if (maxout < (len = p - arg[0]))
83 memcpy(outBuf, arg[0], len);
85 while (arg[0][0] ==
' ')
89 if (maxout < (len = strlen(arg[0])))
91 memcpy(outBuf, arg[0], len);
102static int fioGetInput(
const char *arg,
apa_params_t *params)
106 static const struct apaFsType fsTypes[] = {
107#ifdef APA_SUPPORT_MBR
110 {
"EXT2SWAP", APA_TYPE_EXT2SWAP},
111 {
"EXT2", APA_TYPE_EXT2},
112 {
"REISER", APA_TYPE_REISER},
113 {
"PFS", APA_TYPE_PFS},
114 {
"CFS", APA_TYPE_CFS},
115#ifdef APA_SUPPORT_HDL
116 {
"HDL", APA_TYPE_HDL},
124 while (arg[0] ==
' ')
127 if (arg[0] == 0 || arg[0] ==
',')
129 if ((rv = fioInputBreaker(&arg, params->id, APA_IDMAX)) != 0)
134 if ((rv = fioInputBreaker(&arg, params->fpwd, APA_PASSMAX)) != 0)
137 if (params->fpwd[0] !=
'\0')
138 apaEncryptPassword(params->id, params->fpwd, params->fpwd);
143 if ((rv = fioInputBreaker(&arg, params->rpwd, APA_PASSMAX)) != 0)
146 if (params->rpwd[0] !=
'\0')
147 apaEncryptPassword(params->id, params->rpwd, params->rpwd);
152 memset(argBuf, 0,
sizeof(argBuf));
153 if ((rv = fioInputBreaker(&arg, argBuf,
sizeof(argBuf))) != 0)
156 if ((rv = fioPartitionSizeLookUp(argBuf)) < 0)
160 memset(argBuf, 0,
sizeof(argBuf));
161 if ((rv = fioInputBreaker(&arg, argBuf,
sizeof(argBuf))) != 0)
168 for (i = 0; (
unsigned int)i < (
sizeof(fsTypes))/(
sizeof(fsTypes[0])); i++) {
169 if (!strcmp(argBuf, fsTypes[i].desc)) {
170 params->type = fsTypes[i].type;
175 if ((
unsigned int)i == (
sizeof(fsTypes))/(
sizeof(fsTypes[0]))) {
176 APA_PRINTF(APA_DRV_NAME
": error: Invalid fstype, %s.\n", argBuf);
188 for (i = 0; i < apaMaxOpen; i++) {
189 if (hddFileSlots[i].f)
190 if (memcmp(hddFileSlots[i].
id, ¶ms->id, APA_IDMAX) == 0)
193 for (i = 0; i < apaMaxOpen; i++) {
194 if (!hddFileSlots[i].f) {
195 *fileSlot = &hddFileSlots[i];
210 if (fileSlot->post + size >= 0x1FF9)
211 size = 0x1FF8 - fileSlot->post;
217 if (blkIoDmaTransfer(f->unit, buf, fileSlot->post + fileSlot->parts[0].start + 8, size, mode))
221 fileSlot->post += size;
232 if (fileSlot->nsub < arg->
sub)
236 if (arg->
sub == 0 && (arg->sector < 0x2000))
239 if (arg->
sub != 0 && (arg->sector < 2))
242 if (fileSlot->parts[arg->
sub].length < arg->sector + arg->
size)
245 if (blkIoDmaTransfer(device, arg->buffer,
246 fileSlot->parts[arg->
sub].start + arg->sector, arg->
size, arg->
mode))
261 fioSema = CreateSema(&sema);
274int hddFormat(
iomanX_iop_file_t *f,
const char *dev,
const char *blockdev,
void *arg,
int arglen)
279#ifdef APA_FORMAT_MAKE_PARTITIONS
289#ifdef APA_SUPPORT_BHDD
290 if (strcmp(f->
device->name,
"bhdd") == 0)
294 if (f->
unit >= BLKIO_MAX_VOLUMES)
298 clink = apaCacheAlloc();
300 if (blkIoDmaTransfer(f->
unit, clink->header, APA_SECTOR_SECTOR_ERROR, 1, BLKIO_DIR_WRITE)) {
304 if (blkIoDmaTransfer(f->
unit, clink->header, APA_SECTOR_PART_ERROR, 1, BLKIO_DIR_WRITE)) {
311 for (i = 1024 * 8; i < hddDevices[f->
unit].totalLBA; i += (1024 * 256)) {
316 if ((rv = apaJournalReset(f->
unit)) != 0)
320 if ((clink = apaCacheGetHeader(f->
unit, APA_SECTOR_MBR, APA_IO_MODE_WRITE, &rv))) {
323 header->magic = APA_MAGIC;
325 header->length = (1024 * 256);
328 strcpy(header->id,
"__mbr");
329#ifdef APA_FORMAT_LOCK_MBR
330 apaEncryptPassword(header->id, header->fpwd,
"sce_mbr");
331 apaEncryptPassword(header->id, header->rpwd,
"sce_mbr");
333 memcpy(header->mbr.magic, apaMBRMagic,
sizeof(header->mbr.magic));
335 header->mbr.version = APA_MBR_VERSION;
336 header->mbr.nsector = 0;
337 apaGetTime(&header->created);
338 apaGetTime(&header->mbr.created);
340#ifdef APA_SUPPORT_GPT
341 header->mbr.protective_mbr.UniqueMbrSignature = 0;
342 header->mbr.protective_mbr.Unknown = 0;
343 header->mbr.protective_mbr.partition_record1.BootIndicator = 0;
344 header->mbr.protective_mbr.partition_record1.StartHead = 0;
345 header->mbr.protective_mbr.partition_record1.StartSector = 2;
346 header->mbr.protective_mbr.partition_record1.StartTrack = 0;
347 header->mbr.protective_mbr.partition_record1.OSIndicator = 0xEE;
348 header->mbr.protective_mbr.partition_record1.EndHead = 0xFF;
349 header->mbr.protective_mbr.partition_record1.EndSector = 0xFF;
350 header->mbr.protective_mbr.partition_record1.EndTrack = 0xFF;
351 header->mbr.protective_mbr.partition_record1.StartingLBA = 1;
352 header->mbr.protective_mbr.partition_record1.SizeInLBA = hddDevices[f->
unit].totalLBA - header->mbr.protective_mbr.partition_record1.StartingLBA;
353 header->mbr.protective_mbr.Signature = 0xAA55;
356 header->checksum = apaCheckSum(header, 1);
357 clink->flags |= APA_CACHE_FLAG_DIRTY;
358 apaCacheFlushDirty(clink);
359 blkIoFlushCache(f->
unit);
361 hddDevices[f->
unit].status = 0;
362 hddDevices[f->
unit].format = APA_MBR_VERSION;
365#ifdef APA_FORMAT_MAKE_PARTITIONS
366 memset(&emptyBlocks, 0,
sizeof(emptyBlocks));
368 params.size = (1024 * 256);
369 params.type = APA_TYPE_PFS;
374 for (i = 0; formatPartList[i]; i++) {
375 memset(params.id, 0, APA_IDMAX);
376 strcpy(params.id, formatPartList[i]);
377 if (!(clink = hddAddPartitionHere(f->
unit, ¶ms, emptyBlocks, i ? clink->sector : 0, &rv)))
382 if (hddDevices[f->
unit].partitionMaxSize < params.size)
383 params.size = hddDevices[f->
unit].partitionMaxSize;
397#ifdef APA_SUPPORT_BHDD
399 if (strcmp(params->id,
"__xcontents") == 0 || strcmp(params->id,
"__extend") == 0 || strcmp(params->id,
"__xdata") == 0)
400 sector = hddDevices[device].totalLBA;
404 clink = apaCacheGetHeader(device, sector, APA_IO_MODE_READ, &rv);
405 memset(&emptyBlocks, 0,
sizeof(emptyBlocks));
407 sector = clink->sector;
409 if (memcmp(clink->header->id, params->id, APA_IDMAX) == 0)
412 apaAddEmptyBlock(clink->header, emptyBlocks);
413 clink = apaGetNextHeader(clink, &rv);
420 if (clink == NULL && (mode & FIO_O_CREAT)) {
421 if ((rv = hddCheckPartitionMax(device, params->size)) >= 0) {
422 if ((clink = hddAddPartitionHere(device, params, emptyBlocks, sector, &rv)) != NULL) {
423 sector = clink->header->start;
424 clink2 = apaCacheAlloc();
426 blkIoDmaTransfer(device, clink2->header, sector + 8, 2, BLKIO_DIR_WRITE);
427 blkIoDmaTransfer(device, clink2->header, sector + 0x2000, 2, BLKIO_DIR_WRITE);
428 apaCacheFree(clink2);
434 fileSlot->parts[0].start = clink->header->start;
435 fileSlot->parts[0].length = clink->header->length;
437 fileSlot->type = clink->header->type;
438 fileSlot->nsub = clink->header->nsub;
439 memcpy(&fileSlot->id, &clink->header->id, APA_IDMAX);
441 if (apaPassCmp(clink->header->fpwd, params->fpwd) != 0) {
442 rv = (!(mode & FIO_O_WRONLY)) ? apaPassCmp(clink->header->rpwd, params->rpwd) : -
EACCES;
449static int apaRemove(s32 device,
const char *
id,
const char *fpwd)
455 for (i = 0; i < apaMaxOpen; i++)
457 if (hddFileSlots[i].f != 0) {
458 if (memcmp(hddFileSlots[i].
id,
id, APA_IDMAX) == 0)
462#ifndef APA_ALLOW_REMOVE_PARTITION_WITH_LEADING_UNDERSCORE
463 if (
id[0] ==
'_' &&
id[1] ==
'_')
466 if ((clink = apaFindPartition(device,
id, &rv)) == NULL)
468 if (apaPassCmp(clink->header->fpwd, fpwd)) {
473 nsub = clink->header->nsub;
474 clink->header->nsub = 0;
475 clink->flags |= APA_CACHE_FLAG_DIRTY;
476 apaCacheFlushAllDirty(device);
477 for (i = nsub - 1; i != -1; i--) {
480 if ((clink2 = apaCacheGetHeader(device, clink->header->subs[i].start, APA_IO_MODE_READ, &rv))) {
481 if ((rv = apaDelete(clink2))) {
488 return apaDelete(clink);
501 if ((clink = apaFindPartition(device, newParams->id, &rv)) != NULL) {
508 for (i = 0; i < apaMaxOpen; i++) {
509 if (hddFileSlots[i].f != NULL) {
510 if (memcmp(hddFileSlots[i].
id, oldParams->id, APA_IDMAX) == 0) {
518 if (oldParams->id[0] ==
'_' && oldParams->id[1] ==
'_')
522 if ((clink = apaFindPartition(device, oldParams->id, &rv)) == NULL) {
528 if (apaPassCmp(clink->header->fpwd, oldParams->fpwd) != 0) {
534 memcpy(clink->header->id, newParams->id, APA_IDMAX);
537 memcpy(clink->header->rpwd, newParams->rpwd, APA_PASSMAX);
538 memcpy(clink->header->fpwd, newParams->fpwd, APA_PASSMAX);
540 clink->flags |= APA_CACHE_FLAG_DIRTY;
542 apaCacheFlushAllDirty(device);
553 if ((rv = fioGetInput(name, ¶ms)) < 0)
555#ifdef APA_SUPPORT_BHDD
556 if (strcmp(f->
device->name,
"bhdd") == 0)
560 rv = apaRemove(f->
unit, params.id, params.fpwd);
574 if (f->
unit >= BLKIO_MAX_VOLUMES || hddDevices[f->
unit].status != 0)
577#ifdef APA_SUPPORT_BHDD
578 if (strcmp(f->
device->name,
"bhdd") == 0)
579 if ((flags & FIO_O_CREAT) != 0)
583 if (!(f->
mode & FIO_O_DIROPEN))
584 if ((rv = fioGetInput(name, ¶ms)) < 0)
588 if ((rv = getFileSlot(¶ms, &fileSlot)) == 0) {
589 if (!(f->
mode & FIO_O_DIROPEN)) {
590 if ((rv = apaOpen(f->
unit, fileSlot, ¶ms, flags)) == 0) {
595#ifdef APA_SUPPORT_BHDD
596 if (strcmp(f->
device->name,
"bhdd") == 0) {
597 fileSlot->parts[0].start = hddDevices[f->
unit].totalLBA;
599 fileSlot->parts[0].start = 0;
620 return fioDataTransfer(f, buf, size, BLKIO_DIR_READ);
625 if (!(f->
mode & FIO_O_WRONLY))
627#ifdef APA_SUPPORT_BHDD
628 if (strcmp(f->
device->name,
"bhdd") == 0)
631 return fioDataTransfer(f, buf, size, BLKIO_DIR_WRITE);
640 if (whence == FIO_SEEK_END)
649 if (whence == FIO_SEEK_CUR) {
650 if (((
int)fileSlot->post + post) < 0 || (fileSlot->post + post) >= 0x1FF9)
653 fileSlot->post += post;
654 rv = fileSlot->post << 9;
656 }
else if (whence == FIO_SEEK_SET) {
657 if (post < 0 || post >= 0x1FF9)
660 fileSlot->post = post;
661 rv = fileSlot->post << 9;
670 stat->mode = clink->header->type;
671 stat->attr = clink->header->flags;
673 stat->size = clink->header->length;
674 memcpy(&stat->ctime, &clink->header->created,
sizeof(
apa_ps2time_t));
675 memcpy(&stat->atime, &clink->header->created,
sizeof(
apa_ps2time_t));
676 memcpy(&stat->mtime, &clink->header->created,
sizeof(
apa_ps2time_t));
685#ifndef APA_STAT_RETURN_PART_LBA
698 if ((rv = fioGetInput(name, ¶ms)) < 0)
702 if ((clink = apaFindPartition(f->
unit, params.id, &rv))) {
703 if ((rv = apaPassCmp(clink->header->fpwd, params.fpwd)) == 0 || (rv = apaPassCmp(clink->header->rpwd, params.rpwd)) == 0)
704 fioGetStatFiller(clink, stat);
713 return hddOpen(f, name, 0, 0);
722 if (!(f->
mode & FIO_O_DIROPEN))
725 if (fileSlot->parts[0].start == (u32)(-1))
729 if ((clink = apaCacheGetHeader(f->
unit, fileSlot->parts[0].start, APA_IO_MODE_READ, &rv)) &&
730 clink->header->length) {
733 apa_cache_t *cmain = apaCacheGetHeader(f->
unit, clink->header->main, APA_IO_MODE_READ, &rv);
738 strncpy(dirent->name, cmain->header->id, APA_IDMAX);
739 dirent->name[APA_IDMAX] =
'\0';
740 rv = strlen(dirent->name);
748 strncpy(dirent->name, clink->header->id, APA_IDMAX);
749 dirent->name[APA_IDMAX] =
'\0';
750 rv = strlen(dirent->name);
752 fioGetStatFiller(clink, &dirent->stat);
753 if (clink->header->next == 0)
754 fileSlot->parts[0].start = -1;
756 fileSlot->parts[0].start = clink->header->next;
774 if ((rv = fioGetInput(oldname, &oldParams)) < 0)
776 if ((rv = fioGetInput(newname, &newParams)) < 0)
780 rv = apaRename(f->
unit, &oldParams, &newParams);
789 u32 device = fileSlot->f->
unit;
796 if (!(fileSlot->f->
mode & FIO_O_WRONLY))
804 if ((rv = fioPartitionSizeLookUp(argp)) < 0)
809 params.type = fileSlot->type;
810 params.main = fileSlot->parts[0].start;
811 params.number = fileSlot->nsub + 1;
812 if ((rv = hddCheckPartitionMax(device, params.size)) < 0)
816 memset(&emptyBlocks, 0,
sizeof(emptyBlocks));
817 clink = apaCacheGetHeader(device, APA_SECTOR_MBR, APA_IO_MODE_READ, &rv);
819 sector = clink->sector;
820 apaAddEmptyBlock(clink->header, emptyBlocks);
821 clink = apaGetNextHeader(clink, &rv);
826 if (!(clink = hddAddPartitionHere(device, ¶ms, emptyBlocks, sector, &rv)))
829 sector = clink->header->start;
830 length = clink->header->length;
832 if (!(clink = apaCacheGetHeader(device, fileSlot->parts[0].start, APA_IO_MODE_READ, &rv)))
835 clink->header->subs[clink->header->nsub].start = sector;
836 clink->header->subs[clink->header->nsub].length = length;
837 clink->header->nsub++;
839 fileSlot->parts[fileSlot->nsub].start = sector;
840 fileSlot->parts[fileSlot->nsub].length = length;
841 clink->flags |= APA_CACHE_FLAG_DIRTY;
842 apaCacheFlushAllDirty(device);
850 u32 device = fileSlot->f->
unit;
854 if (!(fileSlot->f->
mode & FIO_O_WRONLY))
857 if (fileSlot->nsub == 0)
860 if (!(mainPart = apaCacheGetHeader(device, fileSlot->parts[0].start, APA_IO_MODE_READ, &rv)))
863 if ((subPart = apaCacheGetHeader(device,
864 mainPart->header->subs[mainPart->header->nsub - 1].start, APA_IO_MODE_READ, &rv))) {
866 mainPart->header->nsub--;
867 mainPart->flags |= APA_CACHE_FLAG_DIRTY;
868 apaCacheFlushAllDirty(device);
869 rv = apaDelete(subPart);
871 apaCacheFree(mainPart);
876 void *bufp,
unsigned int buflen)
885#ifdef APA_SUPPORT_BHDD
886 if (strcmp(f->
device->name,
"bhdd") == 0) {
903 rv = ioctl2AddSub(fileSlot, (
char *)argp);
907 rv = ioctl2DeleteLastSub(fileSlot);
915 blkIoFlushCache(f->
unit);
920 rv = ioctl2Transfer(f->
unit, fileSlot, argp);
924 rv = fileSlot->parts[*(u32 *)argp].length;
928 apaSetPartErrorSector(f->
unit, fileSlot->parts[0].start);
933 if ((rv = apaGetPartErrorSector(f->
unit, APA_SECTOR_PART_ERROR, &err_lba)) > 0) {
934 if (err_lba == fileSlot->parts[0].start) {
936 apaSetPartErrorSector(f->
unit, 0);
941#ifdef APA_SUPPORT_IOCTL_GETPARTSTART
943 case HIOCGETPARTSTART:
944 rv = fileSlot->parts[*(u32 *)argp].start;
956static int devctlSwapTemp(s32 device,
char *argp)
960 char szBuf[APA_IDMAX];
965 if ((rv = fioGetInput(argp, ¶ms)) < 0)
968 if (params.id[0] ==
'_' && params.id[1] ==
'_')
971 memset(szBuf, 0, APA_IDMAX);
972 strcpy(szBuf,
"_tmp");
973 if (!(partTemp = apaFindPartition(device, szBuf, &rv)))
976 if ((partNew = apaFindPartition(device, params.id, &rv))) {
977 if ((rv = apaPassCmp(partNew->header->fpwd, params.fpwd)) == 0) {
978 memcpy(partTemp->header->id, partNew->header->id, APA_IDMAX);
979 memcpy(partTemp->header->rpwd, partNew->header->rpwd, APA_PASSMAX);
980 memcpy(partTemp->header->fpwd, partNew->header->fpwd, APA_PASSMAX);
982 memset(partNew->header->id, 0, APA_IDMAX);
983 strcpy(partNew->header->id,
"_tmp");
984 memset(partNew->header->rpwd, 0, APA_PASSMAX);
985 memset(partNew->header->fpwd, 0, APA_PASSMAX);
986 partTemp->flags |= APA_CACHE_FLAG_DIRTY;
987 partNew->flags |= APA_CACHE_FLAG_DIRTY;
988 apaCacheFlushAllDirty(device);
990 apaCacheFree(partNew);
992 apaCacheFree(partTemp);
1001 if (!(clink = apaCacheGetHeader(device, APA_SECTOR_MBR, APA_IO_MODE_READ, &rv)))
1004 APA_PRINTF(APA_DRV_NAME
": mbr start: %ld\n" APA_DRV_NAME
": mbr size : %ld\n", mbrInfo->start, mbrInfo->size);
1005#ifdef APA_SUPPORT_GPT
1007 if (mbrInfo->start < APA_SECTOR_MIN_OSDSTART)
1010 clink->header->mbr.osdStart = mbrInfo->start;
1011 clink->header->mbr.osdSize = mbrInfo->size;
1012 clink->flags |= APA_CACHE_FLAG_DIRTY;
1013 apaCacheFlushAllDirty(device);
1014 apaCacheFree(clink);
1019 unsigned int arglen,
void *bufp,
unsigned int buflen)
1027#ifdef APA_SUPPORT_BHDD
1028 if (strcmp(f->
device->name,
"bhdd") == 0)
1040 blkIoSmartSaveAttr(f->
unit);
1045 rv = blkIoIdle(f->
unit, *(
char *)arg);
1049 rv = hddDevices[f->
unit].partitionMaxSize;
1053 rv = hddDevices[f->
unit].totalLBA;
1057 if (blkIoFlushCache(f->
unit))
1062 rv = devctlSwapTemp(f->
unit, (
char *)arg);
1065 case HDIOC_SMARTSTAT:
1066 rv = blkIoSmartReturnStatus(f->
unit);
1070 rv = hddDevices[f->
unit].status;
1073 case HDIOC_FORMATVER:
1074 rv = hddDevices[f->
unit].format;
1078 rv = apaGetFreeSectors(f->
unit, bufp, hddDevices);
1082 rv = blkIoIdleImmediate(f->
unit);
1094 case HDIOC_GETSECTORERROR:
1095 rv = apaGetPartErrorSector(f->
unit, APA_SECTOR_SECTOR_ERROR, 0);
1099 rv = apaGetPartErrorName(f->
unit, (
char *)bufp);
1114 rv = blkIoGetSceId(f->
unit, (u16 *)bufp);
1130 SignalSema(fioSema);
1135#ifdef APA_USE_IOMANX
1136int hddMount(
iomanX_iop_file_t *f,
const char *fsname,
const char *devname,
int flag,
void *arg,
int arglen)
1144#ifdef APA_SUPPORT_BHDD
1145 if (strcmp(f->
device->name,
"bhdd") == 0)
1150 rv = hdd_blkio_vhdd_mount(f->
unit, devname);
1151 SignalSema(fioSema);
1162#ifdef APA_SUPPORT_BHDD
1163 if (strcmp(f->
device->name,
"bhdd") == 0)
1168 rv = hdd_blkio_vhdd_umount(f->
unit);
1169 SignalSema(fioSema);
#define HDIOC_TOTALSECTOR
#define HDIOC_WRITESECTOR
#define HDIOC_SCEIDENTIFY
#define HDIOC_GETERRORPARTNAME
struct _iomanX_iop_device * device