// File: /workspace/github_c_makefile_star2_O3/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 0x60d8
movl %esi, %r12d
movq %rdi, %rbx
movq (%rdi), %r14
cmpl %esi, 0x28(%r14)
jbe 0x60d8
movl %edx, %ebp
testl %edx, %edx
je 0x5fee
cmpb $0x4, (%r14)
jne 0x5fd3
cmpb $0x2, 0xb(%rbx)
je 0x5fee
movq %r14, %rdi
movl %ebp, %esi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
callq 0xb61f
testl %eax, %eax
je 0x5fee
movl %eax, %r15d
jmp 0x60de
movl %ebp, 0x4(%rsp)
movl %r12d, %r13d
movl %r13d, %ebp
movq %rbx, %rdi
movl %r13d, %esi
callq 0x616a
cmpl $-0x1, %eax
je 0x60f0
movl %eax, %r13d
testl %eax, %eax
je 0x6092
cmpl $0x1, %r13d
je 0x60d8
cmpb $0x4, (%r14)
je 0x6033
movq %r14, %rdi
movl %ebp, %esi
xorl %edx, %edx
callq 0xb61f
testl %eax, %eax
jne 0x5fe6
movl 0x24(%r14), %ecx
movl 0x28(%r14), %eax
leal -0x2(%rax), %edx
cmpl %edx, %ecx
jae 0x604d
incl %ecx
movl %ecx, 0x24(%r14)
orb $0x1, 0x4(%r14)
leal 0x1(%rbp), %ecx
cmpl %r13d, %ecx
jne 0x605a
movl %r12d, %ecx
jmp 0x6086
cmpb $0x4, (%r14)
movl %r13d, %ecx
jne 0x6086
subl %r12d, %ebp
incl %ebp
movq %r14, %rdi
movl %r12d, %esi
movl %ebp, %edx
xorl %ecx, %ecx
callq 0xb77c
testl %eax, %eax
jne 0x5fe6
movl 0x28(%r14), %eax
movl %r13d, %ecx
movl %ecx, %r12d
cmpl %eax, %r13d
jb 0x5ff5
xorl %r15d, %r15d
cmpb $0x4, (%r14)
jne 0x60de
movl 0x4(%rsp), %r14d
testl %r14d, %r14d
je 0x60f8
movzbl 0xb(%rbx), %eax
cmpl $0x3, %eax
je 0x60fe
testl %eax, %eax
jne 0x60de
movl 0xc(%rbx), %ebp
cmpl %r14d, %ebp
je 0x610e
movq %rbx, %rdi
movl %ebp, %esi
callq 0x616a
cmpl $0x2, %eax
jb 0x60d8
cmpl $-0x1, %eax
je 0x60f0
incl %ebp
cmpl %ebp, %eax
movl %eax, %ebp
je 0x60b5
jmp 0x60de
movl $0x2, %r15d
movl %r15d, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movl $0x1, %r15d
jmp 0x60de
movb $0x0, 0xb(%rbx)
jmp 0x60de
movl 0xc(%rbx), %eax
cmpl %r14d, %eax
ja 0x60de
addl 0x18(%rbx), %eax
cmpl %r14d, %eax
jb 0x60de
movb $0x2, 0xb(%rbx)
jmp 0x60de