diff --git a/iop/hdd/apa/src/apa-opt.h b/iop/hdd/apa/src/apa-opt.h index 38d40e5a4e0..1bd97e6a487 100644 --- a/iop/hdd/apa/src/apa-opt.h +++ b/iop/hdd/apa/src/apa-opt.h @@ -6,13 +6,14 @@ #ifdef APA_POSIX_VER #define APA_ALLOW_REMOVE_PARTITION_WITH_LEADING_UNDERSCORE 1 -#define APA_FORMAT_LOCK_MBR 1 -#define APA_FORMAT_MAKE_PARTITIONS 1 -#define APA_STAT_RETURN_PART_LBA 1 -#define APA_SUPPORT_HDL 1 -#define APA_SUPPORT_IOCTL_GETPARTSTART 1 -#define APA_SUPPORT_MBR 1 -#define APA_WORKAROUND_LESS_THAN_40GB_CAPACITY 1 +#define APA_FORMAT_LOCK_MBR 1 +#define APA_FORMAT_MAKE_PARTITIONS 1 +#define APA_STAT_RETURN_PART_LBA 1 +#define APA_SUPPORT_HDL 1 +#define APA_SUPPORT_IOCTL_GETPARTSTART 1 +#define APA_SUPPORT_MBR 1 +#define APA_WORKAROUND_LESS_THAN_40GB_CAPACITY 1 +#define APA_8MB_PARTITION_SIZE 1 #else /* Define APA_OSD_VER in your Makefile to build an OSD version, which will: 1. (currently disabled) When formatting, do not create any partitions other than __mbr. diff --git a/iop/hdd/apa/src/hdd.c b/iop/hdd/apa/src/hdd.c index cf2e6b0ef5f..536265f39eb 100644 --- a/iop/hdd/apa/src/hdd.c +++ b/iop/hdd/apa/src/hdd.c @@ -116,6 +116,10 @@ apa_cache_t *hddAddPartitionHere(s32 device, const apa_params_t *params, u32 *em u32 i; u32 tmp, some_size, part_end; u32 tempSize; + u32 minsize = 0x3FFFF; // 128MB +#ifdef APA_8MB_PARTITION_SIZE + minsize = 0x3FFF; // 8Mb +#endif // walk empty blocks in case can use one :) for(i=0;i< 32;i++) @@ -147,7 +151,7 @@ apa_cache_t *hddAddPartitionHere(s32 device, const apa_params_t *params, u32 *em while(part_end%params->size) { tempSize=params->size>>1; - while(0x3FFFFmode = clink->header->type; - stat->attr = clink->header->flags; + stat->mode = clink->header->type; + stat->attr = clink->header->flags; stat->hisize = 0; - stat->size = clink->header->length; + stat->size = clink->header->length; memcpy(&stat->ctime, &clink->header->created, sizeof(apa_ps2time_t)); memcpy(&stat->atime, &clink->header->created, sizeof(apa_ps2time_t)); memcpy(&stat->mtime, &clink->header->created, sizeof(apa_ps2time_t)); + stat->private_1 = 0; + stat->private_2 = 0; if (clink->header->flags & APA_FLAG_SUB) stat->private_0 = clink->header->number; - else + else { stat->private_0 = clink->header->nsub; - stat->private_1 = 0; - stat->private_2 = 0; + + u64 totalsize = (u64)clink->header->length; + for (int i = 0; i < clink->header->nsub; i++) { + totalsize += (u64)clink->header->subs[i].length; + } + stat->private_1 = (u32)(totalsize & 0xFFFFFFFF); // low size + stat->private_2 = (u32)(totalsize >> 32); // high size + } stat->private_3 = 0; stat->private_4 = 0; #ifndef APA_STAT_RETURN_PART_LBA diff --git a/iop/hdd/hdck/src/hdck.c b/iop/hdd/hdck/src/hdck.c index d59165759fa..b482925b54f 100644 --- a/iop/hdd/hdck/src/hdck.c +++ b/iop/hdd/hdck/src/hdck.c @@ -377,8 +377,12 @@ static void RecoverPartitionIfSub(int device, apa_cache_t *clink) static apa_cache_t *apaCreateAlignedEmptyPartition(apa_cache_t *clink, u32 lba, u32 length) { apa_cache_t *result; + u32 minsize = 0x3FFFF; // 128MB +#ifdef APA_8MB_PARTITION_SIZE + minsize = 0x3FFF; // 8MB +#endif - for (length >>= 1; 0x0003FFFF < length; length >>= 1) { + for (length >>= 1; minsize < length; length >>= 1) { if (lba % length == 0) { result = apaRemovePartition(clink->device, lba, lba + length, clink->header->start, length); clink->header->next = lba; diff --git a/iop/hdd/hdsk/src/sim.c b/iop/hdd/hdsk/src/sim.c index 9e3d56488b0..5241aa58a3a 100644 --- a/iop/hdd/hdsk/src/sim.c +++ b/iop/hdd/hdsk/src/sim.c @@ -27,20 +27,25 @@ void hdskSimGetFreeSectors(s32 device, struct hdskStat *stat, apa_device_t *devi sectors = 0; stat->free = 0; + u32 maxsize = 0x1FFFFF; // 1GB + u32 minsize = 0x3FFFF; // 128MB +#ifdef APA_8MB_PARTITION_SIZE + minsize = 0x3FFF; // 8MB +#endif for (i = 0; hdskBitmap[i].next != hdskBitmap; sectors += hdskBitmap[i].length, i++) { if (hdskBitmap[i].type == 0) { - if ((0x001FFFFF < hdskBitmap[i].length) || ((stat->free & hdskBitmap[i].length) == 0)) { + if ((maxsize < hdskBitmap[i].length) || ((stat->free & hdskBitmap[i].length) == 0)) { stat->free += hdskBitmap[i].length; } sectors += hdskBitmap[i].length; } } - for (partMax = deviceinfo[device].partitionMaxSize; 0x0003FFFF < partMax; partMax = deviceinfo[device].partitionMaxSize) { // As weird as it looks, this was how it was done in the original HDD.IRX. - for (; 0x0003FFFF < partMax; partMax /= 2) { + for (partMax = deviceinfo[device].partitionMaxSize; minsize < partMax; partMax = deviceinfo[device].partitionMaxSize) { // As weird as it looks, this was how it was done in the original HDD.IRX. + for (; minsize < partMax; partMax /= 2) { // Non-SONY: Perform 64-bit arithmetic here to avoid overflows when dealing with large disks. if ((sectors % partMax == 0) && ((u64)sectors + partMax < deviceinfo[device].totalLBA)) { - if ((0x001FFFFF < partMax) || (stat->free & partMax) == 0) { + if ((maxsize < partMax) || (stat->free & partMax) == 0) { stat->free += partMax; } sectors += partMax; @@ -48,7 +53,7 @@ void hdskSimGetFreeSectors(s32 device, struct hdskStat *stat, apa_device_t *devi } } - if (0x0003FFFF >= partMax) { + if (minsize >= partMax) { break; } } diff --git a/iop/hdd/libapa/src/apa.c b/iop/hdd/libapa/src/apa.c index dff4881c61e..bf1ad953f1b 100644 --- a/iop/hdd/libapa/src/apa.c +++ b/iop/hdd/libapa/src/apa.c @@ -257,6 +257,8 @@ apa_cache_t *apaDeleteFixPrev(apa_cache_t *clink, int *err) u32 saved_next = clink->header->next; u32 saved_length = clink->header->length; u32 tmp; + // TODO: switch to HDDDevices.partitionMaxSize + u32 maxsize = 0x1FFFFF; // 1Gb while (header->start) { if (!(clink2 = apaCacheGetHeader(device, header->prev, APA_IO_MODE_READ, err))) { @@ -265,6 +267,11 @@ apa_cache_t *apaDeleteFixPrev(apa_cache_t *clink, int *err) } header = clink2->header; tmp = header->length + length; + // Check if the new size is larger than the maximum allowed size per APA specs + if (tmp > maxsize) { + apaCacheFree(clink2); + break; + } if (header->type != 0) { apaCacheFree(clink2); break; @@ -302,6 +309,8 @@ apa_cache_t *apaDeleteFixNext(apa_cache_t *clink, int *err) u32 lnext = header->next; u32 device = clink->device; u32 tmp; + // TODO: switch to HDDDevices.partitionMaxSize + u32 maxsize = 0x1FFFFF; // 1Gb while (lnext != 0) { apa_cache_t *clink1; @@ -312,6 +321,11 @@ apa_cache_t *apaDeleteFixNext(apa_cache_t *clink, int *err) } header = clink1->header; tmp = header->length + length; + // Check if the new size is larger than the maximum allowed size per APA specs + if (tmp > maxsize) { + apaCacheFree(clink1); + break; + } if (header->type != 0) { apaCacheFree(clink1); break; diff --git a/iop/hdd/libapa/src/free.c b/iop/hdd/libapa/src/free.c index 955500e4af4..8e9ef86883b 100644 --- a/iop/hdd/libapa/src/free.c +++ b/iop/hdd/libapa/src/free.c @@ -24,20 +24,22 @@ static void apaCalculateFreeSpace(u32 *free, u32 sectors) { - if(0x1FFFFF < sectors) - { - *free += sectors; - return; - } - - if((*free & sectors) == 0) - { - *free |= sectors; - return; - } + u32 maxsize = 0x1FFFFF; // 1GB + u32 minsize = 0x3FFFF; // 128MB +#ifdef APA_8MB_PARTITION_SIZE + minsize = 0x3FFF; // 8Mb +#endif + if (maxsize < sectors) { + *free += sectors; + return; + } - for(sectors /= 2; 0x3FFFF < sectors; sectors /= 2) - *free |= sectors; + if ((*free & sectors) == 0) { + *free |= sectors; + return; + } + for (sectors /= 2; minsize < sectors; sectors /= 2) + *free |= sectors; } int apaGetFreeSectors(s32 device, u32 *free, apa_device_t *deviceinfo) @@ -45,6 +47,10 @@ int apaGetFreeSectors(s32 device, u32 *free, apa_device_t *deviceinfo) u32 sectors, partMax; int rv; apa_cache_t *clink; + u32 minsize = 0x3FFFF; // 128MB +#ifdef APA_8MB_PARTITION_SIZE + minsize = 0x3FFF; // 8Mb +#endif sectors = 0; *free = 0; @@ -59,9 +65,9 @@ int apaGetFreeSectors(s32 device, u32 *free, apa_device_t *deviceinfo) if(rv == 0) { - for(partMax = deviceinfo[device].partitionMaxSize; 0x0003FFFF < partMax; partMax = deviceinfo[device].partitionMaxSize) + for(partMax = deviceinfo[device].partitionMaxSize; minsize < partMax; partMax = deviceinfo[device].partitionMaxSize) { //As weird as it looks, this was how it was done in the original HDD.IRX. - for( ; 0x0003FFFF < partMax; partMax /= 2) + for( ; minsize < partMax; partMax /= 2) { //Non-SONY: Perform 64-bit arithmetic here to avoid overflows when dealing with large disks. if((sectors % partMax == 0) && ((u64)sectors + partMax < deviceinfo[device].totalLBA)) @@ -72,7 +78,7 @@ int apaGetFreeSectors(s32 device, u32 *free, apa_device_t *deviceinfo) } } - if(0x0003FFFF >= partMax) + if(minsize >= partMax) break; }