// File: narges64[P]SIMBA/ftl.cpp
// Function: service_in_flash(ssd_info*, sub_request*)
void service_in_flash(ssd_info * ssd, sub_request * sub){
	if (sub->operation == READ) {
		if (ssd->channel_head[sub->location->channel]->
			lun_head[sub->location->lun]->
			rsubs_queue.find_subreq(sub)){
			// the request already exists
			sub->complete_time=ssd->current_time+1000;
			change_subrequest_state(ssd, sub,SR_MODE_ST_S,
					ssd->current_time,SR_MODE_COMPLETE,
					sub->complete_time);
			sub->state_current_time = sub->next_state_predict_time;
			ssd->stats->queue_read_count++;
		} else {
			ssd->channel_head[sub->location->channel]->
					lun_head[sub->location->lun]->
					rsubs_queue.push_tail(sub);
		}
	} else if (sub->operation == WRITE){
		if(invalid_old_page(ssd, sub) == FAIL) {
			#if DEBUG 
			cout << "error in invaliding the old page " << endl;
			#endif 
		}
		sub->ppn = get_new_ppn(ssd, sub->lpn, sub->location, true);

		if(sub->ppn == -1 || write_page(ssd, sub->lpn, sub->ppn) == FAIL) {
			cout << "there is problem "<< sub->ppn << endl;
			return;
		}
		find_location(ssd, sub->ppn, sub->location);
		ssd->channel_head[sub->location->channel]->lun_head[sub->location->lun]->
			wsubs_queue.push_tail(sub);

		Schedule_GC(ssd, sub);
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x10, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x10(%rbp), %rax
cmpl $0x1, 0x20(%rax)
jne 0x664e
movq -0x8(%rbp), %rax
movq 0x90(%rax), %rax
movq -0x10(%rbp), %rcx
movq 0x60(%rcx), %rcx
movslq (%rcx), %rcx
movq (%rax,%rcx,8), %rax
movq 0x50(%rax), %rax
movq -0x10(%rbp), %rcx
movq 0x60(%rcx), %rcx
movslq 0x4(%rcx), %rcx
movq (%rax,%rcx,8), %rdi
addq $0x60, %rdi
movq -0x10(%rbp), %rsi
callq 0x4fd0
testb $0x1, %al
jne 0x659f
jmp 0x660e
movq -0x8(%rbp), %rax
movq (%rax), %rcx
addq $0x3e8, %rcx            # imm = 0x3E8
movq -0x10(%rbp), %rax
movq %rcx, 0x58(%rax)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
movq -0x8(%rbp), %rax
movq (%rax), %rcx
movq -0x10(%rbp), %rax
movq 0x58(%rax), %r9
movl $0x1, %edx
movl $0x9, %r8d
callq 0x9dd0
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rcx
movq -0x10(%rbp), %rax
movq %rcx, 0x88(%rax)
movq -0x8(%rbp), %rax
movq 0x98(%rax), %rax
movq 0xb0(%rax), %rcx
addq $0x1, %rcx
movq %rcx, 0xb0(%rax)
jmp 0x6649
movq -0x8(%rbp), %rax
movq 0x90(%rax), %rax
movq -0x10(%rbp), %rcx
movq 0x60(%rcx), %rcx
movslq (%rcx), %rcx
movq (%rax,%rcx,8), %rax
movq 0x50(%rax), %rax
movq -0x10(%rbp), %rcx
movq 0x60(%rcx), %rcx
movslq 0x4(%rcx), %rcx
movq (%rax,%rcx,8), %rdi
addq $0x60, %rdi
movq -0x10(%rbp), %rsi
callq 0x50c0
jmp 0x6751
movq -0x10(%rbp), %rax
cmpl $0x0, 0x20(%rax)
jne 0x674f
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x6760
cmpl $0x0, %eax
jne 0x6670
jmp 0x6670
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0xc(%rax), %esi
movq -0x10(%rbp), %rax
movq 0x60(%rax), %rdx
movl $0x1, %ecx
callq 0x5960
movl %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x10(%rax)
movq -0x10(%rbp), %rax
cmpl $-0x1, 0x10(%rax)
je 0x66bc
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0xc(%rax), %esi
movq -0x10(%rbp), %rax
movl 0x10(%rax), %edx
callq 0x5ac0
cmpl $0x0, %eax
jne 0x66ef
movq 0xd90d(%rip), %rdi      # 0x13fd0
leaq 0x8f03(%rip), %rsi      # 0xf5cd
callq 0x2110
movq %rax, %rdi
movq -0x10(%rbp), %rax
movl 0x10(%rax), %esi
callq 0x2220
movq %rax, %rdi
movq 0xd8d8(%rip), %rsi      # 0x13fc0
callq 0x2150
jmp 0x6751
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x10(%rax), %esi
movq -0x10(%rbp), %rax
movq 0x60(%rax), %rdx
callq 0x5c70
movq -0x8(%rbp), %rax
movq 0x90(%rax), %rax
movq -0x10(%rbp), %rcx
movq 0x60(%rcx), %rcx
movslq (%rcx), %rcx
movq (%rax,%rcx,8), %rax
movq 0x50(%rax), %rax
movq -0x10(%rbp), %rcx
movq 0x60(%rcx), %rcx
movslq 0x4(%rcx), %rcx
movq (%rax,%rcx,8), %rdi
addq $0x78, %rdi
movq -0x10(%rbp), %rsi
callq 0x50c0
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0xb360
jmp 0x6751
addq $0x10, %rsp
popq %rbp
retq
nopw (%rax,%rax)