38extern const char apaMBRMagic[];
41#ifdef APA_FORMAT_MAKE_PARTITIONS
43static const char *formatPartList[] = {
44 "__net",
"__system",
"__sysconf",
"__common", NULL};
47#ifndef APA_8MB_PARTITION_SIZE
48#define APA_NUMBER_OF_SIZES 9
49static const char *sizeList[APA_NUMBER_OF_SIZES] = {
61#define APA_NUMBER_OF_SIZES 13
62static const char *sizeList[APA_NUMBER_OF_SIZES] = {
81static int fioPartitionSizeLookUp(
char *str);
82static int fioInputBreaker(
char const **arg,
char *outBuf,
int maxout);
89static int devctlSwapTemp(s32 device,
char *argp);
91static int fioPartitionSizeLookUp(
char *str)
95 for (i = 0; i < APA_NUMBER_OF_SIZES; i++) {
96 if (strcmp(str, sizeList[i]) == 0)
97#ifndef APA_8MB_PARTITION_SIZE
98 return (2 * 128 * 1024) << i;
100 return (2 * 8 * 1024) << i;
103 APA_PRINTF(APA_DRV_NAME
": Error: Invalid partition size, %s.\n", str);
107static int fioInputBreaker(
char const **arg,
char *outBuf,
int maxout)
112 if ((p = strchr(arg[0],
','))) {
113 if (maxout < (len = p - arg[0]))
115 memcpy(outBuf, arg[0], len);
117 while (arg[0][0] ==
' ')
121 if (maxout < (len = strlen(arg[0])))
123 memcpy(outBuf, arg[0], len);
134static int fioGetInput(
const char *arg,
apa_params_t *params)
138 static const struct apaFsType fsTypes[] = {
139#ifdef APA_SUPPORT_MBR
142 {
"EXT2SWAP", APA_TYPE_EXT2SWAP},
143 {
"EXT2", APA_TYPE_EXT2},
144 {
"REISER", APA_TYPE_REISER},
145 {
"PFS", APA_TYPE_PFS},
146 {
"CFS", APA_TYPE_CFS},
147#ifdef APA_SUPPORT_HDL
148 {
"HDL", APA_TYPE_HDL},
156 while (arg[0] ==
' ')
159 if (arg[0] == 0 || arg[0] ==
',')
161 if ((rv = fioInputBreaker(&arg, params->id, APA_IDMAX)) != 0)
166 if ((rv = fioInputBreaker(&arg, params->fpwd, APA_PASSMAX)) != 0)
169 if (params->fpwd[0] !=
'\0')
170 apaEncryptPassword(params->id, params->fpwd, params->fpwd);
175 if ((rv = fioInputBreaker(&arg, params->rpwd, APA_PASSMAX)) != 0)
178 if (params->rpwd[0] !=
'\0')
179 apaEncryptPassword(params->id, params->rpwd, params->rpwd);
184 memset(argBuf, 0,
sizeof(argBuf));
185 if ((rv = fioInputBreaker(&arg, argBuf,
sizeof(argBuf))) != 0)
188 if ((rv = fioPartitionSizeLookUp(argBuf)) < 0)
192 memset(argBuf, 0,
sizeof(argBuf));
193 if ((rv = fioInputBreaker(&arg, argBuf,
sizeof(argBuf))) != 0)
200 for (i = 0; (
unsigned int)i < (
sizeof(fsTypes))/(
sizeof(fsTypes[0])); i++) {
201 if (!strcmp(argBuf, fsTypes[i].desc)) {
202 params->type = fsTypes[i].type;
207 if ((
unsigned int)i == (
sizeof(fsTypes))/(
sizeof(fsTypes[0]))) {
208 APA_PRINTF(APA_DRV_NAME
": error: Invalid fstype, %s.\n", argBuf);
220 for (i = 0; i < apaMaxOpen; i++) {
221 if (hddFileSlots[i].f)
222 if (memcmp(hddFileSlots[i].
id, ¶ms->id, APA_IDMAX) == 0)
225 for (i = 0; i < apaMaxOpen; i++) {
226 if (!hddFileSlots[i].f) {
227 *fileSlot = &hddFileSlots[i];
242 if (fileSlot->post + size >= 0x1FF9)
243 size = 0x1FF8 - fileSlot->post;
249 if (blkIoDmaTransfer(f->unit, buf, fileSlot->post + fileSlot->parts[0].start + 8, size, mode))
253 fileSlot->post += size;
264 if (fileSlot->nsub < arg->
sub)
268 if (arg->
sub == 0 && (arg->sector < 0x2000))
271 if (arg->
sub != 0 && (arg->sector < 2))
274 if (fileSlot->parts[arg->
sub].length < arg->sector + arg->
size)
277 if (blkIoDmaTransfer(device, arg->buffer,
278 fileSlot->parts[arg->
sub].start + arg->sector, arg->
size, arg->
mode))
293 fioSema = CreateSema(&sema);
306int hddFormat(
iomanX_iop_file_t *f,
const char *dev,
const char *blockdev,
void *arg,
int arglen)
311#ifdef APA_FORMAT_MAKE_PARTITIONS
321#ifdef APA_SUPPORT_BHDD
322 if (strcmp(f->
device->name,
"bhdd") == 0)
326 if (f->
unit >= BLKIO_MAX_VOLUMES)
330 clink = apaCacheAlloc();
332 if (blkIoDmaTransfer(f->
unit, clink->header, APA_SECTOR_SECTOR_ERROR, 1, BLKIO_DIR_WRITE)) {
336 if (blkIoDmaTransfer(f->
unit, clink->header, APA_SECTOR_PART_ERROR, 1, BLKIO_DIR_WRITE)) {
343 for (i = 1024 * 8; i < hddDevices[f->
unit].totalLBA; i += (1024 * 256)) {
348 if ((rv = apaJournalReset(f->
unit)) != 0)
352 if ((clink = apaCacheGetHeader(f->
unit, APA_SECTOR_MBR, APA_IO_MODE_WRITE, &rv))) {
355 header->magic = APA_MAGIC;
357 header->length = (1024 * 256);
360 strcpy(header->id,
"__mbr");
361#ifdef APA_FORMAT_LOCK_MBR
362 apaEncryptPassword(header->id, header->fpwd,
"sce_mbr");
363 apaEncryptPassword(header->id, header->rpwd,
"sce_mbr");
365 memcpy(header->mbr.magic, apaMBRMagic,
sizeof(header->mbr.magic));
367 header->mbr.version = APA_MBR_VERSION;
368 header->mbr.nsector = 0;
369 apaGetTime(&header->created);
370 apaGetTime(&header->mbr.created);
372#ifdef APA_SUPPORT_GPT
373 header->mbr.protective_mbr.UniqueMbrSignature = 0;
374 header->mbr.protective_mbr.Unknown = 0;
375 header->mbr.protective_mbr.partition_record1.BootIndicator = 0;
376 header->mbr.protective_mbr.partition_record1.StartHead = 0;
377 header->mbr.protective_mbr.partition_record1.StartSector = 2;
378 header->mbr.protective_mbr.partition_record1.StartTrack = 0;
379 header->mbr.protective_mbr.partition_record1.OSIndicator = 0xEE;
380 header->mbr.protective_mbr.partition_record1.EndHead = 0xFF;
381 header->mbr.protective_mbr.partition_record1.EndSector = 0xFF;
382 header->mbr.protective_mbr.partition_record1.EndTrack = 0xFF;
383 header->mbr.protective_mbr.partition_record1.StartingLBA = 1;
384 header->mbr.protective_mbr.partition_record1.SizeInLBA = hddDevices[f->
unit].totalLBA - header->mbr.protective_mbr.partition_record1.StartingLBA;
385 header->mbr.protective_mbr.Signature = 0xAA55;
388 header->checksum = apaCheckSum(header, 1);
389 clink->flags |= APA_CACHE_FLAG_DIRTY;
390 apaCacheFlushDirty(clink);
391 blkIoFlushCache(f->
unit);
393 hddDevices[f->
unit].status = 0;
394 hddDevices[f->
unit].format = APA_MBR_VERSION;
397#ifdef APA_FORMAT_MAKE_PARTITIONS
398 memset(&emptyBlocks, 0,
sizeof(emptyBlocks));
400 params.size = (1024 * 256);
401 params.type = APA_TYPE_PFS;
406 for (i = 0; formatPartList[i]; i++) {
407 memset(params.id, 0, APA_IDMAX);
408 strcpy(params.id, formatPartList[i]);
409 if (!(clink = hddAddPartitionHere(f->
unit, ¶ms, emptyBlocks, i ? clink->sector : 0, &rv)))
414 if (hddDevices[f->
unit].partitionMaxSize < params.size)
415 params.size = hddDevices[f->
unit].partitionMaxSize;
429#ifdef APA_SUPPORT_BHDD
431 if (strcmp(params->id,
"__xcontents") == 0 || strcmp(params->id,
"__extend") == 0 || strcmp(params->id,
"__xdata") == 0)
432 sector = hddDevices[device].totalLBA;
436 clink = apaCacheGetHeader(device, sector, APA_IO_MODE_READ, &rv);
437 memset(&emptyBlocks, 0,
sizeof(emptyBlocks));
439 sector = clink->sector;
441 if (memcmp(clink->header->id, params->id, APA_IDMAX) == 0)
444 apaAddEmptyBlock(clink->header, emptyBlocks);
445 clink = apaGetNextHeader(clink, &rv);
452 if (clink == NULL && (mode & FIO_O_CREAT)) {
453 if ((rv = hddCheckPartitionMax(device, params->size)) >= 0) {
454 if ((clink = hddAddPartitionHere(device, params, emptyBlocks, sector, &rv)) != NULL) {
455 sector = clink->header->start;
456 clink2 = apaCacheAlloc();
458 blkIoDmaTransfer(device, clink2->header, sector + 8, 2, BLKIO_DIR_WRITE);
459 blkIoDmaTransfer(device, clink2->header, sector + 0x2000, 2, BLKIO_DIR_WRITE);
460 apaCacheFree(clink2);
466 fileSlot->parts[0].start = clink->header->start;
467 fileSlot->parts[0].length = clink->header->length;
469 fileSlot->type = clink->header->type;
470 fileSlot->nsub = clink->header->nsub;
471 memcpy(&fileSlot->id, &clink->header->id, APA_IDMAX);
473 if (apaPassCmp(clink->header->fpwd, params->fpwd) != 0) {
474 rv = (!(mode & FIO_O_WRONLY)) ? apaPassCmp(clink->header->rpwd, params->rpwd) : -
EACCES;
481static int apaRemove(s32 device,
const char *
id,
const char *fpwd)
487 for (i = 0; i < apaMaxOpen; i++)
489 if (hddFileSlots[i].f != 0) {
490 if (memcmp(hddFileSlots[i].
id,
id, APA_IDMAX) == 0)
494#ifndef APA_ALLOW_REMOVE_PARTITION_WITH_LEADING_UNDERSCORE
495 if (
id[0] ==
'_' &&
id[1] ==
'_')
498 if ((clink = apaFindPartition(device,
id, &rv)) == NULL)
500 if (apaPassCmp(clink->header->fpwd, fpwd)) {
505 nsub = clink->header->nsub;
506 clink->header->nsub = 0;
507 clink->flags |= APA_CACHE_FLAG_DIRTY;
508 apaCacheFlushAllDirty(device);
509 for (i = nsub - 1; i != -1; i--) {
512 if ((clink2 = apaCacheGetHeader(device, clink->header->subs[i].start, APA_IO_MODE_READ, &rv))) {
513 if ((rv = apaDelete(clink2))) {
520 return apaDelete(clink);
527static int apaRename(s32 device,
const char *oldId,
const char *newId)
533 if ((clink = apaFindPartition(device, newId, &rv)) != NULL) {
540 for (i = 0; i < apaMaxOpen; i++) {
541 if (hddFileSlots[i].f != NULL) {
542 if (memcmp(hddFileSlots[i].
id, oldId, APA_IDMAX) == 0) {
550#ifndef APA_ALLOW_REMOVE_PARTITION_WITH_LEADING_UNDERSCORE
551 if (oldId[0] ==
'_' && oldId[1] ==
'_')
556 if ((clink = apaFindPartition(device, oldId, &rv)) == NULL) {
562 memcpy(clink->header->id, newId, APA_IDMAX);
565 apaGetTime(&clink->header->created);
566 clink->header->checksum = apaCheckSum(clink->header, 1);
568 clink->flags |= APA_CACHE_FLAG_DIRTY;
570 apaCacheFlushAllDirty(device);
581 if ((rv = fioGetInput(name, ¶ms)) < 0)
583#ifdef APA_SUPPORT_BHDD
584 if (strcmp(f->
device->name,
"bhdd") == 0)
588 rv = apaRemove(f->
unit, params.id, params.fpwd);
602 if (f->
unit >= BLKIO_MAX_VOLUMES || hddDevices[f->
unit].status != 0)
605#ifdef APA_SUPPORT_BHDD
606 if (strcmp(f->
device->name,
"bhdd") == 0)
607 if ((flags & FIO_O_CREAT) != 0)
611 if (!(f->
mode & FIO_O_DIROPEN))
612 if ((rv = fioGetInput(name, ¶ms)) < 0)
616 if ((rv = getFileSlot(¶ms, &fileSlot)) == 0) {
617 if (!(f->
mode & FIO_O_DIROPEN)) {
618 if ((rv = apaOpen(f->
unit, fileSlot, ¶ms, flags)) == 0) {
623#ifdef APA_SUPPORT_BHDD
624 if (strcmp(f->
device->name,
"bhdd") == 0) {
625 fileSlot->parts[0].start = hddDevices[f->
unit].totalLBA;
627 fileSlot->parts[0].start = 0;
648 return fioDataTransfer(f, buf, size, BLKIO_DIR_READ);
653 if (!(f->
mode & FIO_O_WRONLY))
655#ifdef APA_SUPPORT_BHDD
656 if (strcmp(f->
device->name,
"bhdd") == 0)
659 return fioDataTransfer(f, buf, size, BLKIO_DIR_WRITE);
668 if (whence == FIO_SEEK_END)
677 if (whence == FIO_SEEK_CUR) {
678 if (((
int)fileSlot->post + post) < 0 || (fileSlot->post + post) >= 0x1FF9)
681 fileSlot->post += post;
682 rv = fileSlot->post << 9;
684 }
else if (whence == FIO_SEEK_SET) {
685 if (post < 0 || post >= 0x1FF9)
688 fileSlot->post = post;
689 rv = fileSlot->post << 9;
698 stat->mode = clink->header->type;
699 stat->attr = clink->header->flags;
701 stat->size = clink->header->length;
702 memcpy(&stat->ctime, &clink->header->created,
sizeof(
apa_ps2time_t));
703 memcpy(&stat->atime, &clink->header->created,
sizeof(
apa_ps2time_t));
704 memcpy(&stat->mtime, &clink->header->created,
sizeof(
apa_ps2time_t));
712 u64 totalsize = (u64)clink->header->length;
713 for (
int i = 0; i < clink->header->nsub; i++) {
714 totalsize += (u64)clink->header->subs[i].length;
716 stat->private_1 = (u32)(totalsize & 0xFFFFFFFF);
717 stat->private_2 = (u32)(totalsize >> 32);
721#ifndef APA_STAT_RETURN_PART_LBA
734 if ((rv = fioGetInput(name, ¶ms)) < 0)
738 if ((clink = apaFindPartition(f->
unit, params.id, &rv))) {
739 if ((rv = apaPassCmp(clink->header->fpwd, params.fpwd)) == 0 || (rv = apaPassCmp(clink->header->rpwd, params.rpwd)) == 0)
740 fioGetStatFiller(clink, stat);
749 return hddOpen(f, name, 0, 0);
758 if (!(f->
mode & FIO_O_DIROPEN))
761 if (fileSlot->parts[0].start == (u32)(-1))
765 if ((clink = apaCacheGetHeader(f->
unit, fileSlot->parts[0].start, APA_IO_MODE_READ, &rv)) &&
766 clink->header->length) {
769 apa_cache_t *cmain = apaCacheGetHeader(f->
unit, clink->header->main, APA_IO_MODE_READ, &rv);
774 strncpy(dirent->name, cmain->header->id, APA_IDMAX);
775 dirent->name[APA_IDMAX] =
'\0';
776 rv = strlen(dirent->name);
784 strncpy(dirent->name, clink->header->id, APA_IDMAX);
785 dirent->name[APA_IDMAX] =
'\0';
786 rv = strlen(dirent->name);
788 fioGetStatFiller(clink, &dirent->stat);
789 if (clink->header->next == 0)
790 fileSlot->parts[0].start = -1;
792 fileSlot->parts[0].start = clink->header->next;
806 rv = apaRename(f->
unit, oldname, newname);
815 u32 device = fileSlot->f->
unit;
822 if (!(fileSlot->f->
mode & FIO_O_WRONLY))
830 if ((rv = fioPartitionSizeLookUp(argp)) < 0)
835 params.type = fileSlot->type;
836 params.main = fileSlot->parts[0].start;
837 params.number = fileSlot->nsub + 1;
838 if ((rv = hddCheckPartitionMax(device, params.size)) < 0)
842 memset(&emptyBlocks, 0,
sizeof(emptyBlocks));
843 clink = apaCacheGetHeader(device, APA_SECTOR_MBR, APA_IO_MODE_READ, &rv);
845 sector = clink->sector;
846 apaAddEmptyBlock(clink->header, emptyBlocks);
847 clink = apaGetNextHeader(clink, &rv);
852 if (!(clink = hddAddPartitionHere(device, ¶ms, emptyBlocks, sector, &rv)))
855 sector = clink->header->start;
856 length = clink->header->length;
858 if (!(clink = apaCacheGetHeader(device, fileSlot->parts[0].start, APA_IO_MODE_READ, &rv)))
861 clink->header->subs[clink->header->nsub].start = sector;
862 clink->header->subs[clink->header->nsub].length = length;
863 clink->header->nsub++;
865 fileSlot->parts[fileSlot->nsub].start = sector;
866 fileSlot->parts[fileSlot->nsub].length = length;
867 clink->flags |= APA_CACHE_FLAG_DIRTY;
868 apaCacheFlushAllDirty(device);
876 u32 device = fileSlot->f->
unit;
880 if (!(fileSlot->f->
mode & FIO_O_WRONLY))
883 if (fileSlot->nsub == 0)
886 if (!(mainPart = apaCacheGetHeader(device, fileSlot->parts[0].start, APA_IO_MODE_READ, &rv)))
889 if ((subPart = apaCacheGetHeader(device,
890 mainPart->header->subs[mainPart->header->nsub - 1].start, APA_IO_MODE_READ, &rv))) {
892 mainPart->header->nsub--;
893 mainPart->flags |= APA_CACHE_FLAG_DIRTY;
894 apaCacheFlushAllDirty(device);
895 rv = apaDelete(subPart);
897 apaCacheFree(mainPart);
902 void *bufp,
unsigned int buflen)
911#ifdef APA_SUPPORT_BHDD
912 if (strcmp(f->
device->name,
"bhdd") == 0) {
929 rv = ioctl2AddSub(fileSlot, (
char *)argp);
933 rv = ioctl2DeleteLastSub(fileSlot);
941 blkIoFlushCache(f->
unit);
946 rv = ioctl2Transfer(f->
unit, fileSlot, argp);
950 rv = fileSlot->parts[*(u32 *)argp].length;
954 apaSetPartErrorSector(f->
unit, fileSlot->parts[0].start);
959 if ((rv = apaGetPartErrorSector(f->
unit, APA_SECTOR_PART_ERROR, &err_lba)) > 0) {
960 if (err_lba == fileSlot->parts[0].start) {
962 apaSetPartErrorSector(f->
unit, 0);
967#ifdef APA_SUPPORT_IOCTL_GETPARTSTART
969 case HIOCGETPARTSTART:
970 rv = fileSlot->parts[*(u32 *)argp].start;
982static int devctlSwapTemp(s32 device,
char *argp)
986 char szBuf[APA_IDMAX];
991 if ((rv = fioGetInput(argp, ¶ms)) < 0)
994 if (params.id[0] ==
'_' && params.id[1] ==
'_')
997 memset(szBuf, 0, APA_IDMAX);
998 strcpy(szBuf,
"_tmp");
999 if (!(partTemp = apaFindPartition(device, szBuf, &rv)))
1002 if ((partNew = apaFindPartition(device, params.id, &rv))) {
1003 if ((rv = apaPassCmp(partNew->header->fpwd, params.fpwd)) == 0) {
1004 memcpy(partTemp->header->id, partNew->header->id, APA_IDMAX);
1005 memcpy(partTemp->header->rpwd, partNew->header->rpwd, APA_PASSMAX);
1006 memcpy(partTemp->header->fpwd, partNew->header->fpwd, APA_PASSMAX);
1008 memset(partNew->header->id, 0, APA_IDMAX);
1009 strcpy(partNew->header->id,
"_tmp");
1010 memset(partNew->header->rpwd, 0, APA_PASSMAX);
1011 memset(partNew->header->fpwd, 0, APA_PASSMAX);
1012 partTemp->flags |= APA_CACHE_FLAG_DIRTY;
1013 partNew->flags |= APA_CACHE_FLAG_DIRTY;
1014 apaCacheFlushAllDirty(device);
1016 apaCacheFree(partNew);
1018 apaCacheFree(partTemp);
1027 if (!(clink = apaCacheGetHeader(device, APA_SECTOR_MBR, APA_IO_MODE_READ, &rv)))
1030 APA_PRINTF(APA_DRV_NAME
": mbr start: %ld\n" APA_DRV_NAME
": mbr size : %ld\n", mbrInfo->start, mbrInfo->size);
1031#ifdef APA_SUPPORT_GPT
1033 if (mbrInfo->start < APA_SECTOR_MIN_OSDSTART)
1036 clink->header->mbr.osdStart = mbrInfo->start;
1037 clink->header->mbr.osdSize = mbrInfo->size;
1038 clink->flags |= APA_CACHE_FLAG_DIRTY;
1039 apaCacheFlushAllDirty(device);
1040 apaCacheFree(clink);
1045 unsigned int arglen,
void *bufp,
unsigned int buflen)
1053#ifdef APA_SUPPORT_BHDD
1054 if (strcmp(f->
device->name,
"bhdd") == 0)
1066 blkIoSmartSaveAttr(f->
unit);
1071 rv = blkIoIdle(f->
unit, *(
char *)arg);
1075 rv = hddDevices[f->
unit].partitionMaxSize;
1079 rv = hddDevices[f->
unit].totalLBA;
1083 if (blkIoFlushCache(f->
unit))
1088 rv = devctlSwapTemp(f->
unit, (
char *)arg);
1091 case HDIOC_SMARTSTAT:
1092 rv = blkIoSmartReturnStatus(f->
unit);
1096 rv = hddDevices[f->
unit].status;
1099 case HDIOC_FORMATVER:
1100 rv = hddDevices[f->
unit].format;
1104 rv = apaGetFreeSectors(f->
unit, bufp, hddDevices);
1108 rv = blkIoIdleImmediate(f->
unit);
1120 case HDIOC_GETSECTORERROR:
1121 rv = apaGetPartErrorSector(f->
unit, APA_SECTOR_SECTOR_ERROR, 0);
1125 rv = apaGetPartErrorName(f->
unit, (
char *)bufp);
1140 rv = blkIoGetSceId(f->
unit, (u16 *)bufp);
1156 SignalSema(fioSema);
1161#ifdef APA_USE_IOMANX
1162int hddMount(
iomanX_iop_file_t *f,
const char *fsname,
const char *devname,
int flag,
void *arg,
int arglen)
1170#ifdef APA_SUPPORT_BHDD
1171 if (strcmp(f->
device->name,
"bhdd") == 0)
1176 rv = hdd_blkio_vhdd_mount(f->
unit, devname);
1177 SignalSema(fioSema);
1188#ifdef APA_SUPPORT_BHDD
1189 if (strcmp(f->
device->name,
"bhdd") == 0)
1194 rv = hdd_blkio_vhdd_umount(f->
unit);
1195 SignalSema(fioSema);
#define HDIOC_TOTALSECTOR
#define HDIOC_WRITESECTOR
#define HDIOC_SCEIDENTIFY
#define HDIOC_GETERRORPARTNAME
struct _iomanX_iop_device * device