// File: /workspace/github_c_makefile_star2_O1/lb3361[P]dosfs/ff.c
// Function: remove_chain
static FRESULT remove_chain (	/* FR_OK(0):succeeded, !=0:error */
	FFOBJID* obj,		/* Corresponding object */
	DWORD clst,			/* Cluster to remove a chain from */
	DWORD pclst			/* Previous cluster of clst (0 if entire chain) */
)
{
	FRESULT res = FR_OK;
	DWORD nxt;
	FATFS *fs = obj->fs;
#if FF_FS_EXFAT || FF_USE_TRIM
	DWORD scl = clst, ecl = clst;
#endif
#if FF_USE_TRIM
	LBA_t rt[2];
#endif

	if (clst < 2 || clst >= fs->n_fatent) return FR_INT_ERR;	/* Check if in valid range */

	/* Mark the previous cluster 'EOC' on the FAT if it exists */
	if (pclst != 0 && (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT || obj->stat != 2)) {
		res = put_fat(fs, pclst, 0xFFFFFFFF);
		if (res != FR_OK) return res;
	}

	/* Remove the chain */
	do {
		nxt = get_fat(obj, clst);			/* Get cluster status */
		if (nxt == 0) break;				/* Empty cluster? */
		if (nxt == 1) return FR_INT_ERR;	/* Internal error? */
		if (nxt == 0xFFFFFFFF) return FR_DISK_ERR;	/* Disk error? */
		if (!FF_FS_EXFAT || fs->fs_type != FS_EXFAT) {
			res = put_fat(fs, clst, 0);		/* Mark the cluster 'free' on the FAT */
			if (res != FR_OK) return res;
		}
		if (fs->free_clst < fs->n_fatent - 2) {	/* Update FSINFO */
			fs->free_clst++;
			fs->fsi_flag |= 1;
		}
#if FF_FS_EXFAT || FF_USE_TRIM
		if (ecl + 1 == nxt) {	/* Is next cluster contiguous? */
			ecl = nxt;
		} else {				/* End of contiguous cluster block */
#if FF_FS_EXFAT
			if (fs->fs_type == FS_EXFAT) {
				res = change_bitmap(fs, scl, ecl - scl + 1, 0);	/* Mark the cluster block 'free' on the bitmap */
				if (res != FR_OK) return res;
			}
#endif
#if FF_USE_TRIM
			rt[0] = clst2sect(fs, scl);					/* Start of data area to be freed */
			rt[1] = clst2sect(fs, ecl) + fs->csize - 1;	/* End of data area to be freed */
			disk_ioctl(fs->pdrv, CTRL_TRIM, rt);		/* Inform storage device that the data in the block may be erased */
#endif
			scl = ecl = nxt;
		}
#endif
		clst = nxt;					/* Next cluster */
	} while (clst < fs->n_fatent);	/* Repeat while not the last link */

#if FF_FS_EXFAT
	/* Some post processes for chain status */
	if (fs->fs_type == FS_EXFAT) {
		if (pclst == 0) {	/* Has the entire chain been removed? */
			obj->stat = 0;		/* Change the chain status 'initial' */
		} else {
			if (obj->stat == 0) {	/* Is it a fragmented chain from the beginning of this session? */
				clst = obj->sclust;		/* Follow the chain to check if it gets contiguous */
				while (clst != pclst) {
					nxt = get_fat(obj, clst);
					if (nxt < 2) return FR_INT_ERR;
					if (nxt == 0xFFFFFFFF) return FR_DISK_ERR;
					if (nxt != clst + 1) break;	/* Not contiguous? */
					clst++;
				}
				if (clst == pclst) {	/* Has the chain got contiguous again? */
					obj->stat = 2;		/* Change the chain status 'contiguous' */
				}
			} else {
				if (obj->stat == 3 && pclst >= obj->sclust && pclst <= obj->sclust + obj->n_cont) {	/* Was the chain fragmented in this session and got contiguous again? */
					obj->stat = 2;	/* Change the chain status 'contiguous' */
				}
			}
		}
	}
#endif
	return FR_OK;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
cmpl $0x2, %esi
jb 0x62da
movl %esi, %r12d
movq %rdi, %rbx
movq (%rdi), %r15
cmpl %esi, 0x28(%r15)
jbe 0x62da
movl %edx, %ebp
testl %edx, %edx
je 0x61ee
cmpb $0x4, (%r15)
jne 0x61d3
cmpb $0x2, 0xb(%rbx)
je 0x61ee
movq %r15, %rdi
movl %ebp, %esi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0xb9ca
testl %eax, %eax
je 0x61ee
movl %eax, %r14d
jmp 0x62e0
movl %ebp, 0x4(%rsp)
movl %r12d, %r13d
movl %r13d, %ebp
movq %rbx, %rdi
movl %r13d, %esi
callq 0x6363
cmpl $-0x1, %eax
je 0x62f2
movl %eax, %r13d
testl %eax, %eax
je 0x628f
cmpl $0x1, %r13d
je 0x62da
cmpb $0x4, (%r15)
je 0x6233
movq %r15, %rdi
movl %ebp, %esi
xorl %edx, %edx
callq 0xb9ca
testl %eax, %eax
jne 0x61e6
movl 0x24(%r15), %eax
movl 0x28(%r15), %ecx
addl $-0x2, %ecx
cmpl %ecx, %eax
jae 0x624d
incl %eax
movl %eax, 0x24(%r15)
orb $0x1, 0x4(%r15)
leal 0x1(%rbp), %eax
cmpl %r13d, %eax
jne 0x625a
movl %r12d, %eax
jmp 0x6282
cmpb $0x4, (%r15)
movl %r13d, %eax
jne 0x6282
subl %r12d, %ebp
incl %ebp
movq %r15, %rdi
movl %r12d, %esi
movl %ebp, %edx
xorl %ecx, %ecx
callq 0xbb18
movl %eax, %r14d
movl %r13d, %eax
testl %r14d, %r14d
jne 0x62e0
movl %eax, %r12d
cmpl 0x28(%r15), %r13d
jb 0x61f5
xorl %r14d, %r14d
cmpb $0x4, (%r15)
jne 0x62e0
movl 0x4(%rsp), %ebp
testl %ebp, %ebp
je 0x62fa
movzbl 0xb(%rbx), %eax
cmpl $0x3, %eax
je 0x6300
testl %eax, %eax
jne 0x62e0
movl 0xc(%rbx), %ecx
cmpl %ecx, %ebp
je 0x630e
movl %ecx, %r15d
movq %rbx, %rdi
movl %ecx, %esi
callq 0x6363
cmpl $0x2, %eax
jb 0x62da
cmpl $-0x1, %eax
je 0x62f2
leal 0x1(%r15), %ecx
cmpl %eax, %ecx
je 0x62b0
cmpl %r15d, %ebp
jne 0x62e0
jmp 0x630e
movl $0x2, %r14d
movl %r14d, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl $0x1, %r14d
jmp 0x62e0
movb $0x0, 0xb(%rbx)
jmp 0x62e0
movl 0xc(%rbx), %eax
cmpl %ebp, %eax
ja 0x62e0
addl 0x18(%rbx), %eax
cmpl %ebp, %eax
jb 0x62e0
movb $0x2, 0xb(%rbx)
jmp 0x62e0