[Feature][ZXW-88]merge P50 version
Only Configure: No
Affected branch: master
Affected module: unknown
Is it affected on both ZXIC and MTK: only ZXIC
Self-test: Yes
Doc Update: No
Change-Id: I34667719d9e0e7e29e8e4368848601cde0a48408
diff --git a/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/pcu.c b/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/pcu.c
index ae9db65..5124b9d 100755
--- a/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/pcu.c
+++ b/ap/os/linux/linux-3.4.x/arch/arm/mach-zx297520v3/pcu.c
@@ -21,6 +21,44 @@
#include <mach/irqs.h>
#include <mach/spinlock.h>
+typedef enum _T_Pcu_CoreId
+{
+ CPU_M0 = 0,
+ CPU_PS,
+ CPU_AP,
+ CPU_PHY,
+ MAX_CPU
+} T_Pcu_CoreId;
+
+/**
+ * pcu_CoreIsActive
+ *
+ *
+ */
+int pcu_CoreIsActive(T_Pcu_CoreId core)
+{
+ int active=0;
+
+ switch (core)
+ {
+ case CPU_AP:
+ if((zx_read_reg(DEBUG_SIGNAL_READ_REG0)&(0x1<<4))!=(0x1<<4))
+ active=1;
+ break;
+ case CPU_PS:
+ if((zx_read_reg(DEBUG_SIGNAL_READ_REG1)&(0x1<<11))!=(0x1<<11))
+ active=1;
+ break;
+ case CPU_PHY:
+ if((zx_read_reg(DEBUG_SIGNAL_READ_REG1)&(0x1<<10))!=(0x1<<10))
+ active=1;
+ break;
+ default:
+ break;
+ }
+
+ return active;
+}
/**
* helper function
diff --git a/ap/os/linux/linux-3.4.x/arch/arm/mm/fault.c b/ap/os/linux/linux-3.4.x/arch/arm/mm/fault.c
index 27e4e4d..a9dcbe2 100755
--- a/ap/os/linux/linux-3.4.x/arch/arm/mm/fault.c
+++ b/ap/os/linux/linux-3.4.x/arch/arm/mm/fault.c
@@ -21,12 +21,12 @@
#ifdef CONFIG_MMU
#ifdef CONFIG_KPROBES
static inline int notify_page_fault(struct pt_regs*regs,unsigned int fsr){int
-ret=(0x6ef+1787-0xdea);if(!user_mode(regs)){preempt_disable();if(kprobe_running(
-)&&kprobe_fault_handler(regs,fsr))ret=(0x1c3c+2058-0x2445);preempt_enable();}
+ret=(0xc92+3858-0x1ba4);if(!user_mode(regs)){preempt_disable();if(kprobe_running
+()&&kprobe_fault_handler(regs,fsr))ret=(0x11c+4383-0x123a);preempt_enable();}
return ret;}
#else
static inline int notify_page_fault(struct pt_regs*regs,unsigned int fsr){return
-(0x1f50+1157-0x23d5);}
+(0x22cc+96-0x232c);}
#endif
void show_pte(struct mm_struct*mm,unsigned long addr){pgd_t*pgd;if(!mm)mm=&
init_mm;printk(KERN_ALERT"\x70\x67\x64\x20\x3d\x20\x25\x70" "\n",mm->pgd);pgd=
@@ -34,10 +34,10 @@
"\x5b\x25\x30\x38\x6c\x78\x5d\x20\x2a\x70\x67\x64\x3d\x25\x30\x38\x6c\x6c\x78",
addr,(long long)pgd_val(*pgd));do{pud_t*pud;pmd_t*pmd;pte_t*pte;if(pgd_none(*pgd
))break;if(pgd_bad(*pgd)){printk("\x28\x62\x61\x64\x29");break;}pud=pud_offset(
-pgd,addr);if(PTRS_PER_PUD!=(0xa17+4067-0x19f9))printk(
+pgd,addr);if(PTRS_PER_PUD!=(0x1312+3764-0x21c5))printk(
"\x2c\x20\x2a\x70\x75\x64\x3d\x25\x30\x38\x6c\x6c\x78",(long long)pud_val(*pud))
;if(pud_none(*pud))break;if(pud_bad(*pud)){printk("\x28\x62\x61\x64\x29");break;
-}pmd=pmd_offset(pud,addr);if(PTRS_PER_PMD!=(0x566+5292-0x1a11))printk(
+}pmd=pmd_offset(pud,addr);if(PTRS_PER_PMD!=(0x1410+3631-0x223e))printk(
"\x2c\x20\x2a\x70\x6d\x64\x3d\x25\x30\x38\x6c\x6c\x78",(long long)pmd_val(*pmd))
;if(pmd_none(*pmd))break;if(pmd_bad(*pmd)){printk("\x28\x62\x61\x64\x29");break;
}if(PageHighMem(pfn_to_page(pmd_val(*pmd)>>PAGE_SHIFT)))break;pte=pte_offset_map
@@ -47,18 +47,18 @@
printk("\x2c\x20\x2a\x70\x70\x74\x65\x3d\x25\x30\x38\x6c\x6c\x78",(long long)
pte_val(pte[PTE_HWTABLE_PTRS]));
#endif
-pte_unmap(pte);}while((0x1090+1845-0x17c5));printk("\n");}
+pte_unmap(pte);}while((0xf8c+5561-0x2545));printk("\n");}
#else
void show_pte(struct mm_struct*mm,unsigned long addr){}
#endif
static void __do_kernel_fault(struct mm_struct*mm,unsigned long addr,unsigned
int fsr,struct pt_regs*regs){if(fixup_exception(regs))return;bust_spinlocks(
-(0x18fd+2706-0x238e));printk(KERN_ALERT
+(0x1e3a+25-0x1e52));printk(KERN_ALERT
"\x55\x6e\x61\x62\x6c\x65\x20\x74\x6f\x20\x68\x61\x6e\x64\x6c\x65\x20\x6b\x65\x72\x6e\x65\x6c\x20\x25\x73\x20\x61\x74\x20\x76\x69\x72\x74\x75\x61\x6c\x20\x61\x64\x64\x72\x65\x73\x73\x20\x25\x30\x38\x6c\x78" "\n"
,(addr<PAGE_SIZE)?
"\x4e\x55\x4c\x4c\x20\x70\x6f\x69\x6e\x74\x65\x72\x20\x64\x65\x72\x65\x66\x65\x72\x65\x6e\x63\x65"
:"\x70\x61\x67\x69\x6e\x67\x20\x72\x65\x71\x75\x65\x73\x74",addr);show_pte(mm,
-addr);die("\x4f\x6f\x70\x73",regs,fsr);bust_spinlocks((0xe81+2270-0x175f));
+addr);die("\x4f\x6f\x70\x73",regs,fsr);bust_spinlocks((0x141f+181-0x14d4));
do_exit(SIGKILL);}static void __do_user_fault(struct task_struct*tsk,unsigned
long addr,unsigned int fsr,unsigned int sig,int code,struct pt_regs*regs){struct
siginfo si;
@@ -69,7 +69,7 @@
,tsk->comm,sig,addr,fsr);show_pte(tsk->mm,addr);show_regs(regs);}
#endif
tsk->thread.address=addr;tsk->thread.error_code=fsr;tsk->thread.trap_no=
-(0xd65+5191-0x219e);si.si_signo=sig;si.si_errno=(0x184+9332-0x25f8);si.si_code=
+(0xa65+4689-0x1ca8);si.si_signo=sig;si.si_errno=(0xf55+2544-0x1945);si.si_code=
code;si.si_addr=(void __user*)addr;force_sig_info(sig,&si,tsk);}void do_bad_area
(unsigned long addr,unsigned int fsr,struct pt_regs*regs){struct task_struct*tsk
=current;struct mm_struct*mm=tsk->active_mm;if(user_mode(regs))__do_user_fault(
@@ -91,9 +91,9 @@
static int __kprobes do_page_fault(unsigned long addr,unsigned int fsr,struct
pt_regs*regs){struct task_struct*tsk;struct mm_struct*mm;int fault,sig,code;int
write=fsr&FSR_WRITE;unsigned int flags=FAULT_FLAG_ALLOW_RETRY|
-FAULT_FLAG_KILLABLE|(write?FAULT_FLAG_WRITE:(0x1838+1160-0x1cc0));if(
-notify_page_fault(regs,fsr))return(0xc4f+4994-0x1fd1);tsk=current;mm=tsk->mm;if(
-interrupts_enabled(regs))local_irq_enable();if(!mm||pagefault_disabled())goto
+FAULT_FLAG_KILLABLE|(write?FAULT_FLAG_WRITE:(0xeb4+372-0x1028));if(
+notify_page_fault(regs,fsr))return(0x1117+5217-0x2578);tsk=current;mm=tsk->mm;if
+(interrupts_enabled(regs))local_irq_enable();if(!mm||pagefault_disabled())goto
no_context;if(!down_read_trylock(&mm->mmap_sem)){if(!user_mode(regs)&&!
search_exception_tables(regs->ARM_pc))goto no_context;retry:down_read(&mm->
mmap_sem);}else{might_sleep();
@@ -101,23 +101,23 @@
if(!user_mode(regs)&&!search_exception_tables(regs->ARM_pc))goto no_context;
#endif
}fault=__do_page_fault(mm,addr,fsr,flags,tsk);if((fault&VM_FAULT_RETRY)&&
-fatal_signal_pending(current))return(0x333+8251-0x236e);perf_sw_event(
-PERF_COUNT_SW_PAGE_FAULTS,(0x1bd0+1313-0x20f0),regs,addr);if(!(fault&
+fatal_signal_pending(current))return(0x71b+6588-0x20d7);perf_sw_event(
+PERF_COUNT_SW_PAGE_FAULTS,(0x10e4+4358-0x21e9),regs,addr);if(!(fault&
VM_FAULT_ERROR)&&flags&FAULT_FLAG_ALLOW_RETRY){if(fault&VM_FAULT_MAJOR){tsk->
-maj_flt++;perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ,(0x420+2661-0xe84),regs,
+maj_flt++;perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MAJ,(0x12db+2597-0x1cff),regs,
addr);}else{tsk->min_flt++;perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS_MIN,
-(0x648+7540-0x23bb),regs,addr);}if(fault&VM_FAULT_RETRY){flags&=~
+(0x202d+467-0x21ff),regs,addr);}if(fault&VM_FAULT_RETRY){flags&=~
FAULT_FLAG_ALLOW_RETRY;goto retry;}}up_read(&mm->mmap_sem);if(likely(!(fault&(
-VM_FAULT_ERROR|VM_FAULT_BADMAP|VM_FAULT_BADACCESS))))return(0x10d9+5310-0x2597);
-if(fault&VM_FAULT_OOM){pagefault_out_of_memory();return(0x1b03+2939-0x267e);}if(
-!user_mode(regs))goto no_context;if(fault&VM_FAULT_SIGBUS){sig=SIGBUS;code=
+VM_FAULT_ERROR|VM_FAULT_BADMAP|VM_FAULT_BADACCESS))))return(0x113+2808-0xc0b);if
+(fault&VM_FAULT_OOM){pagefault_out_of_memory();return(0x941+780-0xc4d);}if(!
+user_mode(regs))goto no_context;if(fault&VM_FAULT_SIGBUS){sig=SIGBUS;code=
BUS_ADRERR;}else{sig=SIGSEGV;code=fault==VM_FAULT_BADACCESS?SEGV_ACCERR:
SEGV_MAPERR;}__do_user_fault(tsk,addr,fsr,sig,code,regs);return
-(0x2246+675-0x24e9);no_context:__do_kernel_fault(mm,addr,fsr,regs);return
-(0x120b+3454-0x1f89);}
+(0xb55+2826-0x165f);no_context:__do_kernel_fault(mm,addr,fsr,regs);return
+(0x30a+3334-0x1010);}
#else
static int do_page_fault(unsigned long addr,unsigned int fsr,struct pt_regs*regs
-){return(0x218b+1329-0x26bc);}
+){return(0x1df0+2011-0x25cb);}
#endif
#ifdef CONFIG_MMU
static int __kprobes do_translation_fault(unsigned long addr,unsigned int fsr,
@@ -130,21 +130,21 @@
bad_area;if(!pud_present(*pud))set_pud(pud,*pud_k);pmd=pmd_offset(pud,addr);
pmd_k=pmd_offset(pud_k,addr);
#ifdef CONFIG_ARM_LPAE
-index=(0x556+6466-0x1e98);
+index=(0xf8+4197-0x115d);
#else
-index=(addr>>SECTION_SHIFT)&(0x2ad+2390-0xc02);
+index=(addr>>SECTION_SHIFT)&(0x129+5633-0x1729);
#endif
if(pmd_none(pmd_k[index]))goto bad_area;copy_pmd(pmd,pmd_k);return
-(0x100b+5156-0x242f);bad_area:do_bad_area(addr,fsr,regs);return
-(0x1a61+415-0x1c00);}
+(0x615+4683-0x1860);bad_area:do_bad_area(addr,fsr,regs);return
+(0x1964+2399-0x22c3);}
#else
static int do_translation_fault(unsigned long addr,unsigned int fsr,struct
-pt_regs*regs){return(0x216f+575-0x23ae);}
+pt_regs*regs){return(0x675+6018-0x1df7);}
#endif
static int do_sect_fault(unsigned long addr,unsigned int fsr,struct pt_regs*regs
){if(interrupts_enabled(regs))local_irq_enable();do_bad_area(addr,fsr,regs);
-return(0x178a+442-0x1944);}static int do_bad(unsigned long addr,unsigned int fsr
-,struct pt_regs*regs){return(0x1986+838-0x1ccb);}struct fsr_info{int(*fn)(
+return(0xf8+1312-0x618);}static int do_bad(unsigned long addr,unsigned int fsr,
+struct pt_regs*regs){return(0x75b+3411-0x14ad);}struct fsr_info{int(*fn)(
unsigned long addr,unsigned int fsr,struct pt_regs*regs);int sig;int code;const
char*name;};
#ifdef CONFIG_ARM_LPAE
@@ -153,42 +153,42 @@
#include "fsr-2level.c"
#endif
void __init hook_fault_code(int nr,int(*fn)(unsigned long,unsigned int,struct
-pt_regs*),int sig,int code,const char*name){if(nr<(0xbf9+1207-0x10b0)||nr>=
+pt_regs*),int sig,int code,const char*name){if(nr<(0x1974+368-0x1ae4)||nr>=
ARRAY_SIZE(fsr_info))BUG();fsr_info[nr].fn=fn;fsr_info[nr].sig=sig;fsr_info[nr].
code=code;fsr_info[nr].name=name;}
#ifdef CONFIG_MODEM_CODE_IS_MAPPING
static DECLARE_RWSEM(shrinker_rwsem);atomic_t _code_page_count=ATOMIC_INIT(
-(0x3a5+1630-0xa03));struct addr_info{struct list_head node;unsigned long vaddr;
-unsigned long kaddr;unsigned long page_index;};enum modem_access_technology{GSM=
-(0x9d4+2796-0x14c0),UTRAN=(0x19b9+1702-0x205e),LTE=(0x1182+1686-0x1816),COM=
-(0x79d+190-0x858),NR_MODEM_ACCESS=(0xc18+34-0xc36)};struct list_head
+(0x169f+4028-0x265b));struct addr_info{struct list_head node;unsigned long vaddr
+;unsigned long kaddr;unsigned long page_index;};enum modem_access_technology{GSM
+=(0xf2+105-0x15b),UTRAN=(0x12aa+2629-0x1cee),LTE=(0xae8+4652-0x1d12),COM=
+(0x1c50+1062-0x2073),NR_MODEM_ACCESS=(0x46f+4843-0x1756)};struct list_head
modem_page_list[NR_MODEM_ACCESS]={LIST_HEAD_INIT(modem_page_list[
-(0x884+455-0xa4b)]),LIST_HEAD_INIT(modem_page_list[(0x13d1+1582-0x19fe)]),
-LIST_HEAD_INIT(modem_page_list[(0x1cfd+2123-0x2546)]),LIST_HEAD_INIT(
-modem_page_list[(0xbc3+3792-0x1a90)]),};unsigned int page_used[
-(0x260+6029-0x19c5)];struct completion page_completion[(0xb4d+2529-0x1506)*
-(0x7f4+37-0x7f9)];static void unmap_pte_range(pmd_t*pmd,unsigned long addr,
-unsigned long end){pte_t*pte;pte=pte_offset_kernel(pmd,addr);do{pte_t ptent=
-ptep_get_and_clear(&init_mm,addr,pte);WARN_ON(!pte_none(ptent)&&!pte_present(
-ptent));}while(pte++,addr+=PAGE_SIZE,addr!=end);}static void unmap_pmd_range(
-pud_t*pud,unsigned long addr,unsigned long end){pmd_t*pmd;unsigned long next;pmd
-=pmd_offset(pud,addr);do{next=pmd_addr_end(addr,end);if(pmd_none_or_clear_bad(
-pmd))continue;unmap_pte_range(pmd,addr,next);}while(pmd++,addr=next,addr!=end);}
-static void unmap_pud_range(pgd_t*pgd,unsigned long addr,unsigned long end){
-pud_t*pud;unsigned long next;pud=pud_offset(pgd,addr);do{next=pud_addr_end(addr,
-end);if(pud_none_or_clear_bad(pud))continue;unmap_pmd_range(pud,addr,next);}
-while(pud++,addr=next,addr!=end);}static void unmap_page_range(unsigned long
-addr,unsigned long end){pgd_t*pgd;unsigned long next;BUG_ON(addr>=end);pgd=
-pgd_offset_k(addr);do{next=pgd_addr_end(addr,end);if(pgd_none_or_clear_bad(pgd))
-continue;unmap_pud_range(pgd,addr,next);}while(pgd++,addr=next,addr!=end);}void
-shrink_modem_mem(unsigned int access_type){int i=(0x129c+1251-0x177f);unsigned
+(0xeb1+4232-0x1f39)]),LIST_HEAD_INIT(modem_page_list[(0x3a6+1703-0xa4c)]),
+LIST_HEAD_INIT(modem_page_list[(0x7bc+539-0x9d5)]),LIST_HEAD_INIT(
+modem_page_list[(0x24ac+515-0x26ac)]),};unsigned int page_used[(0x3a+15-0x21)];
+struct completion page_completion[(0x1a1+6451-0x1aac)*(0x132b+3356-0x2027)];
+static void unmap_pte_range(pmd_t*pmd,unsigned long addr,unsigned long end){
+pte_t*pte;pte=pte_offset_kernel(pmd,addr);do{pte_t ptent=ptep_get_and_clear(&
+init_mm,addr,pte);WARN_ON(!pte_none(ptent)&&!pte_present(ptent));}while(pte++,
+addr+=PAGE_SIZE,addr!=end);}static void unmap_pmd_range(pud_t*pud,unsigned long
+addr,unsigned long end){pmd_t*pmd;unsigned long next;pmd=pmd_offset(pud,addr);do
+{next=pmd_addr_end(addr,end);if(pmd_none_or_clear_bad(pmd))continue;
+unmap_pte_range(pmd,addr,next);}while(pmd++,addr=next,addr!=end);}static void
+unmap_pud_range(pgd_t*pgd,unsigned long addr,unsigned long end){pud_t*pud;
+unsigned long next;pud=pud_offset(pgd,addr);do{next=pud_addr_end(addr,end);if(
+pud_none_or_clear_bad(pud))continue;unmap_pmd_range(pud,addr,next);}while(pud++,
+addr=next,addr!=end);}static void unmap_page_range(unsigned long addr,unsigned
+long end){pgd_t*pgd;unsigned long next;BUG_ON(addr>=end);pgd=pgd_offset_k(addr);
+do{next=pgd_addr_end(addr,end);if(pgd_none_or_clear_bad(pgd))continue;
+unmap_pud_range(pgd,addr,next);}while(pgd++,addr=next,addr!=end);}void
+shrink_modem_mem(unsigned int access_type){int i=(0x196d+2610-0x239f);unsigned
long vaddr;struct addr_info*addr,*tmp_addr;struct list_head tmp_page_list;for(i=
-(0xdaf+1270-0x12a5);i<NR_MODEM_ACCESS;i++){if(i==access_type)continue;down_write
+(0x6f6+2488-0x10ae);i<NR_MODEM_ACCESS;i++){if(i==access_type)continue;down_write
(&shrinker_rwsem);list_replace_init(&modem_page_list[i],&tmp_page_list);up_write
(&shrinker_rwsem);list_for_each_entry_safe(addr,tmp_addr,&tmp_page_list,node){
list_del_init(&addr->node);page_completion[addr->page_index].done=
-(0x3a3+15-0x3b2);page_used[addr->page_index/BITS_PER_LONG]&=~(
-(0x1431+116-0x14a4)<<(addr->page_index%BITS_PER_LONG));vaddr=addr->vaddr&
+(0x1296+1173-0x172b);page_used[addr->page_index/BITS_PER_LONG]&=~(
+(0xd13+5648-0x2322)<<(addr->page_index%BITS_PER_LONG));vaddr=addr->vaddr&
PAGE_MASK;if(vaddr<cpps_global_var.cpko_text_start||vaddr>cpps_global_var.
modem_text_end){panic(
"\x61\x64\x64\x72\x5f\x69\x6e\x66\x6f\x3a\x20\x25\x30\x38\x78\x20\x69\x73\x20\x20\x64\x65\x73\x74\x72\x6f\x79"
@@ -196,28 +196,28 @@
PAGE_SIZE);flush_tlb_kernel_range(vaddr,vaddr+PAGE_SIZE);
#ifdef CONFIG_DEBUG_RODATA
unsigned int flags;local_irq_save(flags);set_memory_rw(addr->kaddr,
-(0x4b0+2552-0xea7));local_irq_restore(flags);
+(0x236+3876-0x1159));local_irq_restore(flags);
#endif
free_page(addr->kaddr);kfree(addr);atomic_dec(&_code_page_count);};}}
EXPORT_SYMBOL(shrink_modem_mem);phys_addr_t virt_is_mapping(unsigned long addr){
pgd_t*pgd;pmd_t*pmd;pte_t*ptep,pte;unsigned long pfn;pgd=pgd_offset_k(addr);if(!
pgd_none(*pgd)){pmd=pmd_offset(pgd,addr);if(!pmd_none(*pmd)){ptep=pte_offset_map
(pmd,addr);pte=*ptep;if(pte_present(pte)){pfn=pte_pfn(pte);return __pfn_to_phys(
-pfn);}}}return(0x3eb+976-0x7bb);}static int sync_pgd(unsigned long addr,unsigned
- int fsr,struct pt_regs*regs){unsigned int index;pgd_t*pgd,*pgd_k;pud_t*pud,*
-pud_k;pmd_t*pmd,*pmd_k;index=pgd_index(addr);pgd=cpu_get_pgd()+index;pgd_k=
+pfn);}}}return(0x18b4+115-0x1927);}static int sync_pgd(unsigned long addr,
+unsigned int fsr,struct pt_regs*regs){unsigned int index;pgd_t*pgd,*pgd_k;pud_t*
+pud,*pud_k;pmd_t*pmd,*pmd_k;index=pgd_index(addr);pgd=cpu_get_pgd()+index;pgd_k=
init_mm.pgd+index;if(pgd_none(*pgd_k))goto bad_area;if(!pgd_present(*pgd))
set_pgd(pgd,*pgd_k);pud=pud_offset(pgd,addr);pud_k=pud_offset(pgd_k,addr);if(
pud_none(*pud_k))goto bad_area;if(!pud_present(*pud))set_pud(pud,*pud_k);pmd=
pmd_offset(pud,addr);pmd_k=pmd_offset(pud_k,addr);
#ifdef CONFIG_ARM_LPAE
-index=(0x532+6727-0x1f79);
+index=(0x12fa+3801-0x21d3);
#else
-index=(addr>>SECTION_SHIFT)&(0xc67+4122-0x1c80);
+index=(addr>>SECTION_SHIFT)&(0x9b4+895-0xd32);
#endif
if(pmd_none(pmd_k[index]))goto bad_area;copy_pmd(pmd,pmd_k);return
-(0xebf+3585-0x1cc0);bad_area:do_bad_area(addr,fsr,regs);return
-(0x12a3+3758-0x2151);}unsigned long*read_code_file(unsigned long page_index){
+(0x16f1+2780-0x21cd);bad_area:do_bad_area(addr,fsr,regs);return
+(0xe64+6096-0x2634);}unsigned long*read_code_file(unsigned long page_index){
unsigned long*code_buf;ssize_t result;code_buf=get_zeroed_page(GFP_ATOMIC);if(!
code_buf)panic(
"\x6d\x65\x6d\x65\x6f\x72\x79\x20\x6e\x6f\x74\x20\x65\x6e\x6f\x75\x67\x68\x21\x21"
@@ -226,80 +226,80 @@
"\x6f\x70\x65\x6e\x20\x66\x69\x6c\x65\x20\x65\x72\x72\x6f\x72" "\n");}
mm_segment_t old_fs;old_fs=get_fs();set_fs(KERNEL_DS);loff_t pos;pos=page_index*
PAGE_SIZE+cpps_global_var.modem_offset;result=vfs_read(cpps_global_var.fp_code,(
-char*)code_buf,PAGE_SIZE,&pos);if(result<(0x59d+1700-0xc41)){panic(
+char*)code_buf,PAGE_SIZE,&pos);if(result<(0x620+4549-0x17e5)){panic(
"\x72\x65\x61\x64\x20\x63\x6f\x64\x65\x20\x66\x69\x6c\x65\x20\x65\x72\x72\x6f\x72" "\n"
);}
#ifdef CONFIG_DEBUG_RODATA
unsigned int flags;local_irq_save(flags);set_memory_ro((unsigned long)code_buf,
-(0x1f+9427-0x24f1));local_irq_restore(flags);
+(0x1bf+9361-0x264f));local_irq_restore(flags);
#endif
set_fs(old_fs);return code_buf;}void read_code_mapping(unsigned long addr,
unsigned int fsr,struct pt_regs*regs){unsigned long offset;unsigned long vaddr;
const struct mem_type*mtype;unsigned long*vir_codebuf;unsigned long page_index;
-unsigned long page_shift;if(virt_is_mapping(addr&PAGE_MASK)!=(0x9c2+6248-0x222a)
-){sync_pgd(addr&PAGE_MASK,fsr,regs);return;}vaddr=addr&PAGE_MASK;offset=vaddr&(~
-cpps_global_var.cpko_text_start);page_index=offset>>PAGE_SHIFT;page_shift=
-page_index%BITS_PER_LONG;if((page_used[page_index/BITS_PER_LONG]>>page_shift)&
-(0x982+4838-0x1c67)){wait_for_completion(&page_completion[page_index]);sync_pgd(
-vaddr,fsr,regs);return;}else page_used[page_index/BITS_PER_LONG]|=(
-(0x936+3686-0x179b)<<page_shift);local_irq_enable();vir_codebuf=read_code_file(
-page_index);struct addr_info*addr_info;addr_info=kzalloc(sizeof(struct addr_info
-),GFP_KERNEL);addr_info->kaddr=vir_codebuf;addr_info->vaddr=addr;addr_info->
-page_index=page_index;down_write(&shrinker_rwsem);if(vaddr<cpps_global_var.
-__utran_modem_text_start)list_add(&addr_info->node,&modem_page_list[GSM]);else
-if(vaddr<cpps_global_var.__lte_modem_text_start)list_add(&addr_info->node,&
-modem_page_list[UTRAN]);else if(vaddr<cpps_global_var.__comm_modem_text_start)
-list_add(&addr_info->node,&modem_page_list[LTE]);else list_add(&addr_info->node,
-&modem_page_list[COM]);up_write(&shrinker_rwsem);local_irq_disable();mtype=
-get_mem_type(MT_MEMORY);ioremap_page(vaddr,__pa(vir_codebuf),mtype);sync_pgd(
-vaddr,fsr,regs);flush_icache_range(vaddr,vaddr+PAGE_SIZE);if(waitqueue_active(&
-page_completion[page_index].wait))complete_all(&page_completion[page_index]);
-return;}
+unsigned long page_shift;if(virt_is_mapping(addr&PAGE_MASK)!=
+(0x1df5+1764-0x24d9)){sync_pgd(addr&PAGE_MASK,fsr,regs);return;}vaddr=addr&
+PAGE_MASK;offset=vaddr&(~cpps_global_var.cpko_text_start);page_index=offset>>
+PAGE_SHIFT;page_shift=page_index%BITS_PER_LONG;if((page_used[page_index/
+BITS_PER_LONG]>>page_shift)&(0xc6+8408-0x219d)){wait_for_completion(&
+page_completion[page_index]);sync_pgd(vaddr,fsr,regs);return;}else page_used[
+page_index/BITS_PER_LONG]|=((0x2d1+7082-0x1e7a)<<page_shift);local_irq_enable();
+vir_codebuf=read_code_file(page_index);struct addr_info*addr_info;addr_info=
+kzalloc(sizeof(struct addr_info),GFP_KERNEL);addr_info->kaddr=vir_codebuf;
+addr_info->vaddr=addr;addr_info->page_index=page_index;down_write(&
+shrinker_rwsem);if(vaddr<cpps_global_var.__utran_modem_text_start)list_add(&
+addr_info->node,&modem_page_list[GSM]);else if(vaddr<cpps_global_var.
+__lte_modem_text_start)list_add(&addr_info->node,&modem_page_list[UTRAN]);else
+if(vaddr<cpps_global_var.__comm_modem_text_start)list_add(&addr_info->node,&
+modem_page_list[LTE]);else list_add(&addr_info->node,&modem_page_list[COM]);
+up_write(&shrinker_rwsem);local_irq_disable();mtype=get_mem_type(MT_MEMORY);
+ioremap_page(vaddr,__pa(vir_codebuf),mtype);sync_pgd(vaddr,fsr,regs);
+flush_icache_range(vaddr,vaddr+PAGE_SIZE);if(waitqueue_active(&page_completion[
+page_index].wait))complete_all(&page_completion[page_index]);return;}
#endif
asmlinkage void __exception do_DataAbort(unsigned long addr,unsigned int fsr,
struct pt_regs*regs){const struct fsr_info*inf=fsr_info+fsr_fs(fsr);struct
siginfo info;
#ifdef CONFIG_MODEM_CODE_IS_MAPPING
-if(addr!=(0x1ccd+2394-0x2627)&&addr>=cpps_global_var.cpko_text_start&&addr<=
+if(addr!=(0x1d86+2141-0x25e3)&&addr>=cpps_global_var.cpko_text_start&&addr<=
cpps_global_var.modem_text_end){read_code_mapping(addr,fsr&~FSR_LNX_PF,regs);
return;}
#endif
if(!inf->fn(addr,fsr&~FSR_LNX_PF,regs))return;printk(KERN_ALERT
"\x55\x6e\x68\x61\x6e\x64\x6c\x65\x64\x20\x66\x61\x75\x6c\x74\x3a\x20\x25\x73\x20\x28\x30\x78\x25\x30\x33\x78\x29\x20\x61\x74\x20\x30\x78\x25\x30\x38\x6c\x78" "\n"
-,inf->name,fsr,addr);info.si_signo=inf->sig;info.si_errno=(0x10dd+3541-0x1eb2);
+,inf->name,fsr,addr);info.si_signo=inf->sig;info.si_errno=(0x9b9+4581-0x1b9e);
info.si_code=inf->code;info.si_addr=(void __user*)addr;arm_notify_die("",regs,&
-info,fsr,(0x390+3520-0x1150));}void __init hook_ifault_code(int nr,int(*fn)(
+info,fsr,(0x242f+486-0x2615));}void __init hook_ifault_code(int nr,int(*fn)(
unsigned long,unsigned int,struct pt_regs*),int sig,int code,const char*name){if
-(nr<(0xbb5+3866-0x1acf)||nr>=ARRAY_SIZE(ifsr_info))BUG();ifsr_info[nr].fn=fn;
+(nr<(0x795+1718-0xe4b)||nr>=ARRAY_SIZE(ifsr_info))BUG();ifsr_info[nr].fn=fn;
ifsr_info[nr].sig=sig;ifsr_info[nr].code=code;ifsr_info[nr].name=name;}
asmlinkage void __exception do_PrefetchAbort(unsigned long addr,unsigned int
ifsr,struct pt_regs*regs){const struct fsr_info*inf=ifsr_info+fsr_fs(ifsr);
struct siginfo info;
#ifdef CONFIG_MODEM_CODE_IS_MAPPING
-if(addr!=(0xdc7+6420-0x26db)&&addr>=cpps_global_var.cpko_text_start&&addr<=
+if(addr!=(0x1b73+1424-0x2103)&&addr>=cpps_global_var.cpko_text_start&&addr<=
cpps_global_var.modem_text_end){read_code_mapping(addr,ifsr|FSR_LNX_PF,regs);
return;}
#endif
if(!inf->fn(addr,ifsr|FSR_LNX_PF,regs))return;printk(KERN_ALERT
"\x55\x6e\x68\x61\x6e\x64\x6c\x65\x64\x20\x70\x72\x65\x66\x65\x74\x63\x68\x20\x61\x62\x6f\x72\x74\x3a\x20\x25\x73\x20\x28\x30\x78\x25\x30\x33\x78\x29\x20\x61\x74\x20\x30\x78\x25\x30\x38\x6c\x78" "\n"
-,inf->name,ifsr,addr);info.si_signo=inf->sig;info.si_errno=(0x8b3+2422-0x1229);
+,inf->name,ifsr,addr);info.si_signo=inf->sig;info.si_errno=(0x10b6+3532-0x1e82);
info.si_code=inf->code;info.si_addr=(void __user*)addr;arm_notify_die("",regs,&
-info,ifsr,(0x9dd+4243-0x1a70));}
+info,ifsr,(0x11+5858-0x16f3));}
#ifndef CONFIG_ARM_LPAE
static int __init exceptions_init(void){if(cpu_architecture()>=CPU_ARCH_ARMv6){
-hook_fault_code((0x6cb+7772-0x2523),do_translation_fault,SIGSEGV,SEGV_MAPERR,
+hook_fault_code((0x11+2540-0x9f9),do_translation_fault,SIGSEGV,SEGV_MAPERR,
"\x49\x2d\x63\x61\x63\x68\x65\x20\x6d\x61\x69\x6e\x74\x65\x6e\x61\x6e\x63\x65\x20\x66\x61\x75\x6c\x74"
-);}if(cpu_architecture()>=CPU_ARCH_ARMv7){hook_fault_code((0xa8+69-0xea),do_bad,
-SIGSEGV,SEGV_MAPERR,
+);}if(cpu_architecture()>=CPU_ARCH_ARMv7){hook_fault_code((0x397+544-0x5b4),
+do_bad,SIGSEGV,SEGV_MAPERR,
"\x73\x65\x63\x74\x69\x6f\x6e\x20\x61\x63\x63\x65\x73\x73\x20\x66\x6c\x61\x67\x20\x66\x61\x75\x6c\x74"
-);hook_fault_code((0x630+1162-0xab4),do_bad,SIGSEGV,SEGV_MAPERR,
+);hook_fault_code((0xb36+6682-0x254a),do_bad,SIGSEGV,SEGV_MAPERR,
"\x73\x65\x63\x74\x69\x6f\x6e\x20\x61\x63\x63\x65\x73\x73\x20\x66\x6c\x61\x67\x20\x66\x61\x75\x6c\x74"
);}
#ifdef CONFIG_MODEM_CODE_IS_MAPPING
-int index=(0x74f+298-0x879);for(index=(0x6c+5061-0x1431);index<
-(0x190+7054-0x1cf6)*(0x13cf+4383-0x24ce);index++)init_completion(&
-page_completion[index]);
+int index=(0xa5f+2859-0x158a);for(index=(0xf49+5337-0x2422);index<
+(0xd97+1707-0x141a)*(0xaa6+1773-0x1173);index++)init_completion(&page_completion
+[index]);
#endif
-return(0x16fa+3252-0x23ae);}arch_initcall(exceptions_init);
+return(0x148d+4593-0x267e);}arch_initcall(exceptions_init);
#endif
diff --git a/ap/os/linux/linux-3.4.x/drivers/cpko/cpko_main.c b/ap/os/linux/linux-3.4.x/drivers/cpko/cpko_main.c
index 9808d24..09782a0 100755
--- a/ap/os/linux/linux-3.4.x/drivers/cpko/cpko_main.c
+++ b/ap/os/linux/linux-3.4.x/drivers/cpko/cpko_main.c
@@ -82,31 +82,30 @@
__comm_modem_text_start;unsigned int modem_text_end;unsigned int cpko_data_start
;unsigned int cpko_bss_start;unsigned int cpko_text_offset;}cpko_section_layout;
cpko_section_layout cpko_ps_section;int raise(int signo){return
-(0x588+2748-0x1044);}extern unsigned int SysEntry(void);static int
+(0x1019+2285-0x1906);}extern unsigned int SysEntry(void);static int
ko_Main_Thread(void*data){struct sched_param param={.sched_priority=
-MAX_USER_RT_PRIO/(0x1aa2+478-0x1c7e)-(0xb4b+3818-0x1a32)};int ret=
-(0x985+3929-0x18de);sched_setscheduler(current,SCHED_FIFO,¶m);ret=SysEntry()
-;if(ret!=(0xacd+2158-0x133b))panic("Main_Thread\n");param.sched_priority=
-MAX_USER_RT_PRIO-(0x1194+2176-0x19e6);sched_setscheduler(kthreadd_task,
-SCHED_FIFO,¶m);return(0x1e56+83-0x1ea9);}int zte_modem_ko_start(void){
-kthread_run(ko_Main_Thread,NULL,
-"\x5a\x54\x45\x4d\x61\x69\x6e\x54\x68\x72\x65\x61\x64");return
-(0x1109+1789-0x1806);}static void cpko_sectioninfo_set(void){int ret;struct file
-*fp;mm_segment_t old_fs;loff_t cpko_pos=(0x16fb+814-0x1a29);struct
+MAX_USER_RT_PRIO/(0x1e05+849-0x2154)-(0x163f+244-0x1730)};int ret=
+(0x6a0+1651-0xd13);sched_setscheduler(current,SCHED_FIFO,¶m);ret=SysEntry();
+if(ret!=(0x1c59+477-0x1e36))panic("Main_Thread\n");param.sched_priority=
+MAX_USER_RT_PRIO-(0xa62+2452-0x13c8);sched_setscheduler(kthreadd_task,SCHED_FIFO
+,¶m);return(0x1874+837-0x1bb9);}int zte_modem_ko_start(void){kthread_run(
+ko_Main_Thread,NULL,"\x5a\x54\x45\x4d\x61\x69\x6e\x54\x68\x72\x65\x61\x64");
+return(0x16ed+2471-0x2094);}static void cpko_sectioninfo_set(void){int ret;
+struct file*fp;mm_segment_t old_fs;loff_t cpko_pos=(0x82b+1876-0xf7f);struct
cpps_globalModem globalVar;fp=filp_open(
"\x2f\x6c\x69\x62\x2f\x63\x70\x6b\x6f\x2f\x63\x70\x6b\x6f\x5f\x73\x65\x63\x69\x6e\x66\x6f\x2e\x62\x69\x6e"
-,(0x2fa+1778-0x9ec),(0x13ec+700-0x16a8));if(IS_ERR(fp)||fp==NULL)panic(
+,(0xe32+3591-0x1c39),(0xe13+5426-0x2345));if(IS_ERR(fp)||fp==NULL)panic(
"\x6f\x70\x65\x6e\x20\x66\x69\x6c\x65\x20\x65\x72\x72\x6f\x72" "\n");old_fs=
get_fs();set_fs(KERNEL_DS);ret=vfs_read(fp,(char*)&cpko_ps_section,sizeof(
-cpko_section_layout),&cpko_pos);if(ret<=(0xd62+2480-0x1712))panic(
+cpko_section_layout),&cpko_pos);if(ret<=(0x16f9+2110-0x1f37))panic(
"\x72\x65\x61\x64\x20\x66\x69\x6c\x65\x20\x65\x72\x72\x6f\x72" "\n");filp_close(
fp,NULL);
#ifdef CONFIG_MODEM_CODE_IS_MAPPING
fp=filp_open(
"\x2f\x6c\x69\x62\x2f\x63\x70\x6b\x6f\x2f\x63\x70\x6b\x6f\x2e\x6b\x6f",
-(0x172f+1154-0x1bb1),(0xc82+3654-0x1ac8));if(IS_ERR(fp)||fp==NULL)panic(
+(0xa57+3978-0x19e1),(0x1938+3499-0x26e3));if(IS_ERR(fp)||fp==NULL)panic(
"\x6f\x70\x65\x6e\x20\x66\x69\x6c\x65\x20\x65\x72\x72\x6f\x72" "\n");fp->f_ra.
-ra_pages=(0xb17+2019-0x12fa);
+ra_pages=(0x90+7657-0x1e79);
#endif
if(cpko_ps_section.cpko_text_start){globalVar.cpko_text_start=(unsigned long)
cpko_ps_section.cpko_text_start;globalVar.cpko_rodata_start=(unsigned long)
@@ -126,7 +125,7 @@
vfree_modem_section(globalVar.cpko_text_start,globalVar.modem_text_end);
#endif
}else panic("\x66\x69\x6c\x65\x20\x65\x72\x72\x6f\x72" "\n");}static int
-cpko_start(void){struct cpps_callbacks callback={(0x800+2644-0x1254)};callback.
+cpko_start(void){struct cpps_callbacks callback={(0xfcd+1554-0x15df)};callback.
zOss_ResetNVFactory=zOss_ResetNVFactory;callback.zOss_NvramFlush=zOss_NvramFlush
;callback.zOss_NvItemWrite=zOss_NvItemWrite;callback.zOss_NvItemWriteFactory=
zOss_NvItemWriteFactory;callback.zOss_NvItemRead=zOss_NvItemRead;callback.
@@ -196,5 +195,5 @@
psm_GetModemSleepFlagStatus=psm_GetModemSleepFlagStatus;
#endif
cpps_callbacks_register(&callback);cpko_sectioninfo_set();zte_modem_ko_start();
-return(0x990+7510-0x26e6);}static int cpko_stop(void){return(0xe70+451-0x1033);}
-module_init(cpko_start);module_exit(cpko_stop);
+return(0x99a+2509-0x1367);}static int cpko_stop(void){return(0xa38+1976-0x11f0);
+}module_init(cpko_start);module_exit(cpko_stop);
diff --git a/ap/os/linux/linux-3.4.x/drivers/mfd/zx234290-core.c b/ap/os/linux/linux-3.4.x/drivers/mfd/zx234290-core.c
old mode 100644
new mode 100755
index 7fc94b3..21fda0e
--- a/ap/os/linux/linux-3.4.x/drivers/mfd/zx234290-core.c
+++ b/ap/os/linux/linux-3.4.x/drivers/mfd/zx234290-core.c
@@ -576,7 +576,9 @@
}
/*************************/
-#ifndef AP_NO_NEED_PMU_INT_FOR_PHONE
+#if (defined AP_NO_NEED_PMU_INT_FOR_PHONE) || (defined _USE_VEHICLE_DC)
+
+#else
//init_data->irq = pmic_plat_data->irq;
//init_data->irq_base = pmic_plat_data->irq_base;
irq = gpio_to_irq(pmic_plat_data->irq_gpio_num);
diff --git a/ap/os/linux/linux-3.4.x/drivers/mmc/core/mmc.c b/ap/os/linux/linux-3.4.x/drivers/mmc/core/mmc.c
old mode 100644
new mode 100755
index 6d74683..d79088d
--- a/ap/os/linux/linux-3.4.x/drivers/mmc/core/mmc.c
+++ b/ap/os/linux/linux-3.4.x/drivers/mmc/core/mmc.c
@@ -22,6 +22,7 @@
#include "bus.h"
#include "mmc_ops.h"
#include "sd_ops.h"
+#include "pub_debug_info.h"
static const unsigned int tran_exp[] = {
10000, 100000, 1000000, 10000000,
@@ -1537,6 +1538,8 @@
host->card = NULL;
err:
mmc_detach_bus(host);
+ sc_debug_info_record(MODULE_ID_AP_MMC, "%s: error %d whilst initialising MMC card\n",
+ mmc_hostname(host),err);
pr_err("%s: error %d whilst initialising MMC card\n",
mmc_hostname(host), err);
diff --git a/ap/os/linux/linux-3.4.x/drivers/mmc/core/sdio.c b/ap/os/linux/linux-3.4.x/drivers/mmc/core/sdio.c
old mode 100644
new mode 100755
index 4bcac91..81a5f51
--- a/ap/os/linux/linux-3.4.x/drivers/mmc/core/sdio.c
+++ b/ap/os/linux/linux-3.4.x/drivers/mmc/core/sdio.c
@@ -30,6 +30,7 @@
#include "sd_ops.h"
#include "sdio_ops.h"
#include "sdio_cis.h"
+#include "pub_debug_info.h"
#ifdef CONFIG_MMC_EMBEDDED_SDIO
#include <linux/mmc/sdio_ids.h>
@@ -1267,6 +1268,9 @@
err:
mmc_printk("%s: Error resetting SDIO communications (%d)\n",
mmc_hostname(host), err); //xiu
+ sc_debug_info_record(MODULE_ID_AP_MMC, "%s: Error resetting SDIO communications (%d)\n",
+ mmc_hostname(host),err);
+
mmc_release_host(host);
return err;
}
diff --git a/ap/os/linux/linux-3.4.x/drivers/mmc/host/zx29_mmc.c b/ap/os/linux/linux-3.4.x/drivers/mmc/host/zx29_mmc.c
old mode 100644
new mode 100755
index b1a7a72..425d6a7
--- a/ap/os/linux/linux-3.4.x/drivers/mmc/host/zx29_mmc.c
+++ b/ap/os/linux/linux-3.4.x/drivers/mmc/host/zx29_mmc.c
@@ -50,6 +50,7 @@
#include <linux/gpio.h>
//#include "dw_mmc.h"
#include "zx29_mmc.h"
+#include "pub_debug_info.h"
#if (defined CONFIG_ARCH_ZX297520V2)||(defined CONFIG_ARCH_ZX297520V3)
#include <mach/gpio_cfg.h>
@@ -235,6 +236,9 @@
"ERROR dw_dto_timer_expired", host->dw_dto_timer_expired_cnt, host->completed_events, host->state);
xlog_mmc_log_opkey(host->host_id, opcode,
"ERROR dw_dto_timer_expired", mci_readl(host, STATUS), mci_readl(host,IDSTS), mci_readl(host, RINTSTS));
+ sc_debug_info_record(MODULE_ID_AP_MMC, "ERROR dw_dto_timer_expired cnt=%d,STATUS=0x%x\n",
+ host->dw_dto_timer_expired_cnt,mci_readl(host, STATUS));
+
/*
mmc_printk("ERROR %s,STATUS=0x%x,IDSTS=0x%x, RINTSTS=0x%x,MINTSTS=0x%x\n", __func__,
mci_readl(host, STATUS),mci_readl(host,IDSTS),mci_readl(host, RINTSTS),mci_readl(host, MINTSTS)); //xiu
@@ -1605,7 +1609,9 @@
if (!(cmd_status & SDMMC_CMD_START))
return 0;
}
- xlog_mmc_log(host->host_id, "INFO mci_send_cmd TIMEOUT", cmd, arg, cmd_status);
+ xlog_mmc_log(host->host_id, "INFO mci_send_cmd TIMEOUT", cmd, arg, cmd_status);
+ sc_debug_info_record(MODULE_ID_AP_MMC, "Timeout sending command (cmd %#x arg %#x status %#x)\n",
+ cmd, arg, cmd_status);
dev_err(&slot->mmc->class_dev,
"Timeout sending command (cmd %#x arg %#x status %#x)\n",
cmd, arg, cmd_status);
@@ -1713,6 +1719,7 @@
} while (time_before(jiffies, timeout));
dev_err(host->dev, "%s: SDIO device busy timeout,status is 0x%08x\n",__func__,status);
+ sc_debug_info_record(MODULE_ID_AP_MMC,"%s(%d): timeout,status is 0x%08x\n",__func__,host->host_id,status);
return -1;
@@ -2277,14 +2284,20 @@
}
}
- if (status & SDMMC_INT_HLE)
- cmd->error = -EIO;
+ if (status & SDMMC_INT_HLE){
+ cmd->error = -EIO;
+ sc_debug_info_record(MODULE_ID_AP_MMC,"%s(%d): cmd->error=0x%x\n",__func__,host->host_id,cmd->error);
+ }
else if (status & SDMMC_INT_RTO)
cmd->error = -ETIMEDOUT;
- else if ((cmd->flags & MMC_RSP_CRC) && (status & SDMMC_INT_RCRC))
+ else if ((cmd->flags & MMC_RSP_CRC) && (status & SDMMC_INT_RCRC)){
cmd->error = -EILSEQ;
- else if (status & SDMMC_INT_RESP_ERR)
- cmd->error = -EIO;
+ sc_debug_info_record(MODULE_ID_AP_MMC,"%s(%d): cmd->error=0x%x\n",__func__,host->host_id,cmd->error);
+ }
+ else if (status & SDMMC_INT_RESP_ERR){
+ cmd->error = -EIO;
+ sc_debug_info_record(MODULE_ID_AP_MMC,"%s(%d): cmd->error=0x%x\n",__func__,host->host_id,cmd->error);
+ }
else
cmd->error = 0;
@@ -2330,7 +2343,8 @@
}
temp = mci_readl(host, STATUS);
- dev_err(host->dev, "DATA ERROR, MINTSTS 0x%X, STATUS 0x%X\n", status, temp);
+ dev_err(host->dev, "DATA ERROR, MINTSTS 0x%X, STATUS 0x%X\n", status, temp);
+ sc_debug_info_record(MODULE_ID_AP_MMC,"DATA ERROR, MINTSTS 0x%X, STATUS 0x%X\n", status, temp);
xlog_mmc_status(host->host_id, data->mrq->cmd->opcode, XLOG_TF_STATUS_DATA_COMPLETE, data->error, status, temp);
if (status & SDMMC_INT_FRUN) {
xlog_mmc_log_opkey(host->host_id, data->mrq->cmd->opcode,
diff --git a/ap/os/linux/linux-3.4.x/drivers/net/ppp/ppp_generic.c b/ap/os/linux/linux-3.4.x/drivers/net/ppp/ppp_generic.c
old mode 100644
new mode 100755
index db2c894..7888719
--- a/ap/os/linux/linux-3.4.x/drivers/net/ppp/ppp_generic.c
+++ b/ap/os/linux/linux-3.4.x/drivers/net/ppp/ppp_generic.c
@@ -2282,8 +2282,9 @@
spin_lock_bh(&pn->all_channels_lock);
list_del(&pch->list);
spin_unlock_bh(&pn->all_channels_lock);
- put_net(pch->chan_net);
- pch->chan_net = NULL;
+ //205e1e255c479f3fd77446415706463b282f94e4
+ //put_net(pch->chan_net);
+ //pch->chan_net = NULL;
pch->file.dead = 1;
wake_up_interruptible(&pch->file.rwait);
@@ -2890,6 +2891,9 @@
*/
static void ppp_destroy_channel(struct channel *pch)
{
+ put_net(pch->chan_net);
+ pch->chan_net = NULL;
+ //205e1e255c479f3fd77446415706463b282f94e4
atomic_dec(&channel_count);
if (!pch->file.dead) {
diff --git a/ap/os/linux/linux-3.4.x/drivers/net/ppp/pppoe.c b/ap/os/linux/linux-3.4.x/drivers/net/ppp/pppoe.c
old mode 100644
new mode 100755
index 98e92cb..79090d0
--- a/ap/os/linux/linux-3.4.x/drivers/net/ppp/pppoe.c
+++ b/ap/os/linux/linux-3.4.x/drivers/net/ppp/pppoe.c
@@ -577,7 +577,9 @@
po = pppox_sk(sk);
- if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND | PPPOX_ZOMBIE)) {
+ //if (sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND | PPPOX_ZOMBIE)) {
+ //1acea4f6ce1b1c0941438aca75dd2e5c6b09db60
+ if (po->pppoe_dev) {
dev_put(po->pppoe_dev);
po->pppoe_dev = NULL;
}
diff --git a/ap/os/linux/linux-3.4.x/drivers/net/zvnet/zvnet_dev.c b/ap/os/linux/linux-3.4.x/drivers/net/zvnet/zvnet_dev.c
old mode 100644
new mode 100755
index 723810d..6e22779
--- a/ap/os/linux/linux-3.4.x/drivers/net/zvnet/zvnet_dev.c
+++ b/ap/os/linux/linux-3.4.x/drivers/net/zvnet/zvnet_dev.c
@@ -4,6 +4,10 @@
#include <linux/module.h>
#include <linux/etherdevice.h>
#include <net/sock.h>
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <net/addrconf.h>
#include "zvnet_dev.h"
/*******************************************************************************
@@ -413,6 +417,7 @@
}
}
#endif
+extern int pcu_CoreIsActive(int core);
static netdev_tx_t zvnet_xmit(struct sk_buff *skb, struct net_device *net)
{
#ifdef USE_ZVNET_PACKET
@@ -426,7 +431,43 @@
kfree_skb(skb);
return NET_XMIT_SUCCESS;
}
-
+ if(!(skb->now_location & (FASTNAT_SUCC | FASTBR_SUCC))){
+ struct iphdr *iph;
+ iph = ip_hdr(skb);
+ if (iph->version == 4){
+ if (ipv4_is_multicast(iph->daddr) || ipv4_is_lbcast(iph->daddr)){
+ if(pcu_CoreIsActive(2) == 0){
+ net->stats.tx_errors++;
+ net->stats.tx_dropped++;
+ zv_err("cap psm zvnet drop v4!");
+ kfree_skb(skb);
+ return NET_XMIT_SUCCESS;
+ }
+ }
+ }else if (iph->version == 6){
+ if(ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr)){
+ if(pcu_CoreIsActive(2) == 0){
+ net->stats.tx_errors++;
+ net->stats.tx_dropped++;
+ zv_err("cap psm zvnet drop v6!");
+ kfree_skb(skb);
+ return NET_XMIT_SUCCESS;
+ }
+ }
+ }else{
+#if 0
+ if(is_multicast_ether_addr(skb_mac_header(skb))){
+ if(pcu_CoreIsActive(2) == 0){
+ net->stats.tx_errors++;
+ net->stats.tx_dropped++;
+ zv_err("cap psm zvnet drop arp?");
+ kfree_skb(skb);
+ return NET_XMIT_SUCCESS;
+ }
+ }
+#endif
+ }
+ }
if(unlikely(skb->capHead || skb->next || skb->fclone || skb->cloned
|| (skb_shinfo(skb)->nr_frags) || (skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY)
|| (skb_has_frag_list(skb)))){
diff --git a/ap/os/linux/linux-3.4.x/drivers/rtc/zx234290-rtc.c b/ap/os/linux/linux-3.4.x/drivers/rtc/zx234290-rtc.c
old mode 100644
new mode 100755
index ddfa780..54428db
--- a/ap/os/linux/linux-3.4.x/drivers/rtc/zx234290-rtc.c
+++ b/ap/os/linux/linux-3.4.x/drivers/rtc/zx234290-rtc.c
@@ -1111,6 +1111,9 @@
rtc->max_user_freq = 64; //32768;//32k clock
zx234290_rtc_irqno = zx234290_rtc.zx234290->chip_irq;
platform_set_drvdata(pdev, rtc);
+#ifdef _USE_VEHICLE_DC
+ printk("rtc get time only probe ok!\n");
+#else
ret = zx234290_rtc_request_irq(pdev, rtc);
if (ret)
{
@@ -1120,6 +1123,8 @@
zx234290_rtc_write_register(ZX234290_REG_ADDR_RTC_CTRL1, 0, 0xff);
zx234290_rtc_setuie(&pdev->dev, 0);
zx234290_rtc_enable(&pdev->dev, 0);
+#endif
+
sema_init(&timerSemaphore,0);
//zx234290_rtc_ioctl(NULL,ZX234290_SET_TIMER,20);
return 0;
diff --git a/ap/os/linux/linux-3.4.x/drivers/rtc/zx234290-rtc.h b/ap/os/linux/linux-3.4.x/drivers/rtc/zx234290-rtc.h
old mode 100644
new mode 100755
index 4e68c8e..3233c6e
--- a/ap/os/linux/linux-3.4.x/drivers/rtc/zx234290-rtc.h
+++ b/ap/os/linux/linux-3.4.x/drivers/rtc/zx234290-rtc.h
@@ -42,7 +42,7 @@
#define ZX234290_RTC_TIME_CENTURY_WID (1)
#define ZX234290_RTC_TIME_YEAR_LSH (0)
-#define ZX234290_RTC_TIME_YEAR_WID (7)
+#define ZX234290_RTC_TIME_YEAR_WID (8)
#define ZX234290_RTC_TIME_WEEKDAY_LSH (0)
#define ZX234290_RTC_TIME_WEEKDAY_WID (3)
diff --git a/ap/os/linux/linux-3.4.x/drivers/staging/android/Kconfig b/ap/os/linux/linux-3.4.x/drivers/staging/android/Kconfig
old mode 100644
new mode 100755
index 43d17c2..e66333a
--- a/ap/os/linux/linux-3.4.x/drivers/staging/android/Kconfig
+++ b/ap/os/linux/linux-3.4.x/drivers/staging/android/Kconfig
@@ -87,6 +87,10 @@
elapsed realtime, and a non-wakeup alarm on the monotonic clock.
Also exports the alarm interface to user-space.
+config ANDROID_BINDER_RPC
+ bool "Android Binder RPC Driver"
+ default n
+
endif # if ANDROID
endmenu
diff --git a/ap/os/linux/linux-3.4.x/drivers/staging/android/Makefile b/ap/os/linux/linux-3.4.x/drivers/staging/android/Makefile
old mode 100644
new mode 100755
index 8769e32..8f9caaf
--- a/ap/os/linux/linux-3.4.x/drivers/staging/android/Makefile
+++ b/ap/os/linux/linux-3.4.x/drivers/staging/android/Makefile
@@ -11,5 +11,6 @@
obj-$(CONFIG_ANDROID_SWITCH) += switch/
obj-$(CONFIG_ANDROID_INTF_ALARM_DEV) += alarm-dev.o
obj-$(CONFIG_PERSISTENT_TRACER) += trace_persistent.o
+obj-$(CONFIG_ANDROID_BINDER_RPC) += binder_rpc.o
CFLAGS_REMOVE_trace_persistent.o = -pg
diff --git a/ap/os/linux/linux-3.4.x/drivers/staging/android/binder.c b/ap/os/linux/linux-3.4.x/drivers/staging/android/binder.c
old mode 100644
new mode 100755
index c831dcc..aab6c15
--- a/ap/os/linux/linux-3.4.x/drivers/staging/android/binder.c
+++ b/ap/os/linux/linux-3.4.x/drivers/staging/android/binder.c
@@ -36,6 +36,13 @@
#include "binder.h"
#include "binder_trace.h"
+#ifdef CONFIG_ANDROID_BINDER_RPC
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <asm-generic/mman-common.h>
+
+#include "binder_rpc.h"
+#endif
static DEFINE_MUTEX(binder_main_lock);
static DEFINE_MUTEX(binder_deferred_lock);
@@ -51,7 +58,38 @@
static uid_t binder_context_mgr_uid = -1;
static int binder_last_id;
static struct workqueue_struct *binder_deferred_workqueue;
+#ifdef CONFIG_ANDROID_BINDER_RPC
+/***********************************************************************
+ BINDER RPC DEFINE START
+***********************************************************************/
+#define BINDER_RPC_IGNORE_PRIV (0xFFFFFFFF)
+struct binder_transaction;
+struct binder_proc;
+struct binder_thread;
+struct binder_transaction_entry {
+ struct list_head list;
+ struct binder_transaction *t;
+};
+struct binder_rpc_operations_struct binder_rpc_ops;
+
+struct binder_proc *rpc_own_proc = NULL;
+struct binder_proc *rpc_proc = NULL;
+struct binder_thread *rpc_thread = NULL;
+
+static int binder_init_rpc(struct binder_proc *own_proc);
+static int binder_deinit_rpc(void);
+static struct binder_proc *binder_get_rpcproc(void);
+static struct binder_thread *binder_get_rpcthread(void);
+static void binder_rpc_dequeue_todo(struct binder_transaction *t,
+ struct binder_thread *target_thread);
+static void binder_rpc_enqueue_todo(struct binder_transaction *t,
+ struct binder_thread *target_thread);
+
+/***********************************************************************
+ BINDER RPC DEFINE END
+***********************************************************************/
+#endif
#define BINDER_DEBUG_ENTRY(name) \
static int binder_##name##_open(struct inode *inode, struct file *file) \
{ \
@@ -177,6 +215,8 @@
int to_node;
int data_size;
int offsets_size;
+ int return_error_line;
+ uint32_t return_error;
};
struct binder_transaction_log {
int next;
@@ -358,6 +398,10 @@
long priority;
long saved_priority;
uid_t sender_euid;
+#ifdef CONFIG_ANDROID_BINDER_RPC
+ /*¹ØÁªremote tr,ÓÃÓÚÏìӦʱ²éÕÒremote target*/
+ binder_uintptr_t remote_priv;
+#endif
};
static void
@@ -1022,7 +1066,10 @@
node->local_strong_refs++;
if (!node->has_strong_ref && target_list) {
list_del_init(&node->work.entry);
- list_add_tail(&node->work.entry, target_list);
+#ifdef CONFIG_ANDROID_BINDER_RPC
+ if(target_list != (&(binder_get_rpcthread()->todo)))
+#endif
+ list_add_tail(&node->work.entry, target_list);
}
} else {
if (!internal)
@@ -1033,7 +1080,10 @@
"for %d\n", node->debug_id);
return -EINVAL;
}
- list_add_tail(&node->work.entry, target_list);
+#ifdef CONFIG_ANDROID_BINDER_RPC
+ if(target_list != (&(binder_get_rpcthread()->todo)))
+#endif
+ list_add_tail(&node->work.entry, target_list);
}
}
return 0;
@@ -1253,7 +1303,11 @@
static void binder_pop_transaction(struct binder_thread *target_thread,
struct binder_transaction *t)
{
- if (target_thread) {
+ if (target_thread
+#ifdef CONFIG_ANDROID_BINDER_RPC
+ && target_thread != binder_get_rpcthread()
+#endif
+ ) {
BUG_ON(target_thread->transaction_stack != t);
BUG_ON(target_thread->transaction_stack->from != target_thread);
target_thread->transaction_stack =
@@ -1290,7 +1344,21 @@
binder_pop_transaction(target_thread, t);
target_thread->return_error = error_code;
+#ifdef CONFIG_ANDROID_BINDER_RPC
+ if(target_thread == binder_get_rpcthread()) {
+ struct binder_rpc_operations_info ops_info;
+
+ ops_info.tr = NULL;
+ ops_info.cmd = target_thread->return_error;
+ ops_info.priv = t->remote_priv;
+
+ /*send error to remote thread*/
+ binder_rpc_ops.binder_return_error(&ops_info, 1);
+ }
+#else
wake_up_interruptible(&target_thread->wait);
+#endif
+
} else {
printk(KERN_ERR "binder: reply failed, target "
"thread, %d:%d, has error code %d "
@@ -1411,7 +1479,11 @@
wait_queue_head_t *target_wait;
struct binder_transaction *in_reply_to = NULL;
struct binder_transaction_log_entry *e;
- uint32_t return_error;
+ uint32_t return_error;
+ uint32_t return_error_line;
+#ifdef CONFIG_ANDROID_BINDER_RPC
+ u32 fp_handle = 0;
+#endif
e = binder_transaction_log_add(&binder_transaction_log);
e->call_type = reply ? 2 : !!(tr->flags & TF_ONE_WAY);
@@ -1428,6 +1500,7 @@
"with no transaction stack\n",
proc->pid, thread->pid);
return_error = BR_FAILED_REPLY;
+ return_error_line = __LINE__;
goto err_empty_call_stack;
}
binder_set_nice(in_reply_to->saved_priority);
@@ -1441,6 +1514,7 @@
in_reply_to->to_thread ?
in_reply_to->to_thread->pid : 0);
return_error = BR_FAILED_REPLY;
+ return_error_line = __LINE__;
in_reply_to = NULL;
goto err_bad_call_stack;
}
@@ -1448,9 +1522,14 @@
target_thread = in_reply_to->from;
if (target_thread == NULL) {
return_error = BR_DEAD_REPLY;
+ return_error_line = __LINE__;
goto err_dead_binder;
}
- if (target_thread->transaction_stack != in_reply_to) {
+ if (target_thread->transaction_stack != in_reply_to
+#ifdef CONFIG_ANDROID_BINDER_RPC
+ && target_thread != binder_get_rpcthread()
+#endif
+ ) {
binder_user_error("binder: %d:%d got reply transaction "
"with bad target transaction stack %d, "
"expected %d\n",
@@ -1459,6 +1538,7 @@
target_thread->transaction_stack->debug_id : 0,
in_reply_to->debug_id);
return_error = BR_FAILED_REPLY;
+ return_error_line = __LINE__;
in_reply_to = NULL;
target_thread = NULL;
goto err_dead_binder;
@@ -1473,6 +1553,7 @@
"transaction to invalid handle\n",
proc->pid, thread->pid);
return_error = BR_FAILED_REPLY;
+ return_error_line = __LINE__;
goto err_invalid_target_handle;
}
target_node = ref->node;
@@ -1480,6 +1561,7 @@
target_node = binder_context_mgr_node;
if (target_node == NULL) {
return_error = BR_DEAD_REPLY;
+ return_error_line = __LINE__;
goto err_no_context_mgr_node;
}
}
@@ -1487,9 +1569,19 @@
target_proc = target_node->proc;
if (target_proc == NULL) {
return_error = BR_DEAD_REPLY;
+ return_error_line = __LINE__;
goto err_dead_binder;
}
- if (!(tr->flags & TF_ONE_WAY) && thread->transaction_stack) {
+#ifdef CONFIG_ANDROID_BINDER_RPC
+ if(target_proc == binder_get_rpcproc()) {
+ target_thread = binder_get_rpcthread();
+ }
+#endif
+ if (!(tr->flags & TF_ONE_WAY) && thread->transaction_stack
+#ifdef CONFIG_ANDROID_BINDER_RPC
+ && (thread != binder_get_rpcthread())
+#endif
+ ) {
struct binder_transaction *tmp;
tmp = thread->transaction_stack;
if (tmp->to_thread != thread) {
@@ -1501,6 +1593,7 @@
tmp->to_thread ?
tmp->to_thread->pid : 0);
return_error = BR_FAILED_REPLY;
+ return_error_line = __LINE__;
goto err_bad_call_stack;
}
while (tmp) {
@@ -1524,6 +1617,7 @@
t = kzalloc(sizeof(*t), GFP_KERNEL);
if (t == NULL) {
return_error = BR_FAILED_REPLY;
+ return_error_line = __LINE__;
goto err_alloc_t_failed;
}
binder_stats_created(BINDER_STAT_TRANSACTION);
@@ -1531,6 +1625,7 @@
tcomplete = kzalloc(sizeof(*tcomplete), GFP_KERNEL);
if (tcomplete == NULL) {
return_error = BR_FAILED_REPLY;
+ return_error_line = __LINE__;
goto err_alloc_tcomplete_failed;
}
binder_stats_created(BINDER_STAT_TRANSACTION_COMPLETE);
@@ -1572,6 +1667,7 @@
tr->offsets_size, !reply && (t->flags & TF_ONE_WAY));
if (t->buffer == NULL) {
return_error = BR_FAILED_REPLY;
+ return_error_line = __LINE__;
goto err_binder_alloc_buf_failed;
}
t->buffer->allow_user_free = 0;
@@ -1588,12 +1684,14 @@
binder_user_error("binder: %d:%d got transaction with invalid "
"data ptr\n", proc->pid, thread->pid);
return_error = BR_FAILED_REPLY;
+ return_error_line = __LINE__;
goto err_copy_data_failed;
}
if (copy_from_user(offp, tr->data.ptr.offsets, tr->offsets_size)) {
binder_user_error("binder: %d:%d got transaction with invalid "
"offsets ptr\n", proc->pid, thread->pid);
return_error = BR_FAILED_REPLY;
+ return_error_line = __LINE__;
goto err_copy_data_failed;
}
if (!IS_ALIGNED(tr->offsets_size, sizeof(size_t))) {
@@ -1601,6 +1699,7 @@
"invalid offsets size, %zd\n",
proc->pid, thread->pid, tr->offsets_size);
return_error = BR_FAILED_REPLY;
+ return_error_line = __LINE__;
goto err_bad_offset;
}
off_end = (void *)offp + tr->offsets_size;
@@ -1613,6 +1712,7 @@
"invalid offset, %zd\n",
proc->pid, thread->pid, *offp);
return_error = BR_FAILED_REPLY;
+ return_error_line = __LINE__;
goto err_bad_offset;
}
fp = (struct flat_binder_object *)(t->buffer->data + *offp);
@@ -1625,6 +1725,7 @@
node = binder_new_node(proc, fp->binder, fp->cookie);
if (node == NULL) {
return_error = BR_FAILED_REPLY;
+ return_error_line = __LINE__;
goto err_binder_new_node_failed;
}
node->min_priority = fp->flags & FLAT_BINDER_FLAG_PRIORITY_MASK;
@@ -1641,6 +1742,7 @@
ref = binder_get_ref_for_node(target_proc, node);
if (ref == NULL) {
return_error = BR_FAILED_REPLY;
+ return_error_line = __LINE__;
goto err_binder_get_ref_for_node_failed;
}
if (fp->type == BINDER_TYPE_BINDER)
@@ -1656,6 +1758,39 @@
" node %d u%p -> ref %d desc %d\n",
node->debug_id, node->ptr, ref->debug_id,
ref->desc);
+#ifdef CONFIG_ANDROID_BINDER_RPC
+ /*1.service add (tr->target.handle == 0 && tr->code == 3)
+ *2.client add listen (target_thread == rpc_thread)
+ */
+ if((proc != binder_get_rpcproc() || thread != binder_get_rpcthread()) &&
+ NULL != binder_rpc_ops.binder_broadcast) {
+ struct binder_rpc_operations_info ops_info;
+
+ fp_handle = fp->handle;
+ /*tagret isn't rpc_proc. err?*/
+ /**/
+ binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,"%s %d 0x%x debug_id:%d\n",__FUNCTION__,fp->handle, fp->type, node->debug_id);
+ if(NULL != node &&
+ ((tr->target.handle == 0 && tr->code == ADD_SERVICE_TRANSACTION))) {
+ ref = binder_get_ref_for_node(binder_get_rpcproc(), node);
+ if (NULL != ref) {
+ fp_handle = ref->desc;
+
+ ops_info.cmd = BC_TRANSACTION;
+ ops_info.tr = tr;
+ ops_info.priv = BINDER_RPC_IGNORE_PRIV;
+
+ if(0 != binder_rpc_ops.binder_broadcast(&ops_info, fp_handle)) {
+ binder_delete_ref(ref);
+ binder_user_error("%s binder_broadcast fail. \n",__FUNCTION__);
+ }
+ }
+ else {
+ binder_user_error("%s binder_get_ref_for_node fail,\n",__FUNCTION__);
+ }
+ }
+ }
+#endif
} break;
case BINDER_TYPE_HANDLE:
case BINDER_TYPE_WEAK_HANDLE: {
@@ -1666,6 +1801,7 @@
"handle, %ld\n", proc->pid,
thread->pid, fp->handle);
return_error = BR_FAILED_REPLY;
+ return_error_line = __LINE__;
goto err_binder_get_ref_failed;
}
if (ref->node->proc == target_proc) {
@@ -1686,6 +1822,7 @@
new_ref = binder_get_ref_for_node(target_proc, ref->node);
if (new_ref == NULL) {
return_error = BR_FAILED_REPLY;
+ return_error_line = __LINE__;
goto err_binder_get_ref_for_node_failed;
}
fp->handle = new_ref->desc;
@@ -1708,12 +1845,14 @@
binder_user_error("binder: %d:%d got reply with fd, %ld, but target does not allow fds\n",
proc->pid, thread->pid, fp->handle);
return_error = BR_FAILED_REPLY;
+ return_error_line = __LINE__;
goto err_fd_not_allowed;
}
} else if (!target_node->accept_fds) {
binder_user_error("binder: %d:%d got transaction with fd, %ld, but target does not allow fds\n",
proc->pid, thread->pid, fp->handle);
return_error = BR_FAILED_REPLY;
+ return_error_line = __LINE__;
goto err_fd_not_allowed;
}
@@ -1722,12 +1861,14 @@
binder_user_error("binder: %d:%d got transaction with invalid fd, %ld\n",
proc->pid, thread->pid, fp->handle);
return_error = BR_FAILED_REPLY;
+ return_error_line = __LINE__;
goto err_fget_failed;
}
target_fd = task_get_unused_fd_flags(target_proc, O_CLOEXEC);
if (target_fd < 0) {
fput(file);
return_error = BR_FAILED_REPLY;
+ return_error_line = __LINE__;
goto err_get_unused_fd_failed;
}
task_fd_install(target_proc, target_fd, file);
@@ -1743,17 +1884,79 @@
"n with invalid object type, %lx\n",
proc->pid, thread->pid, fp->type);
return_error = BR_FAILED_REPLY;
+ return_error_line = __LINE__;
goto err_bad_object_type;
}
}
if (reply) {
BUG_ON(t->buffer->async_transaction != 0);
- binder_pop_transaction(target_thread, in_reply_to);
+#ifdef CONFIG_ANDROID_BINDER_RPC
+ if(target_thread == binder_get_rpcthread() && target_proc == binder_get_rpcproc()) {
+ binder_rpc_dequeue_todo(in_reply_to, target_thread);
+ if(NULL != binder_rpc_ops.binder_reply) {
+ struct binder_rpc_operations_info ops_info;
+ struct binder_buffer *tmp_buffer = t->buffer;
+
+ ops_info.cmd = BC_REPLY;
+ ops_info.tr = tr;
+ ops_info.priv = in_reply_to->remote_priv;
+
+ /*free t*/
+ if (tmp_buffer->transaction) {
+ binder_debug(BINDER_DEBUG_TRANSACTION,"%s %d 0x%x\n",__FUNCTION__, __LINE__, tmp_buffer);
+ tmp_buffer->transaction->buffer = NULL;
+ tmp_buffer->transaction = NULL;
+ }
+ if (tmp_buffer->async_transaction && tmp_buffer->target_node) {
+ BUG_ON(!tmp_buffer->target_node->has_async_transaction);
+ if (list_empty(&tmp_buffer->target_node->async_todo))
+ tmp_buffer->target_node->has_async_transaction = 0;
+ else {
+ //list_move_tail(tmp_buffer->target_node->async_todo.next, &target_thread->todo);
+ binder_debug(BINDER_DEBUG_TRANSACTION,"%s %d\n",__FUNCTION__, __LINE__);
+ }
+ }
+ trace_binder_transaction_buffer_release(tmp_buffer);
+
+ //binder_transaction_buffer_release(target_proc, tmp_buffer, NULL);
+
+ //t->buffer->transaction = NULL;
+ binder_free_buf(target_proc, tmp_buffer);
+
+ binder_pop_transaction(NULL, t);
+
+ binder_rpc_ops.binder_reply(&ops_info, fp_handle);
+ }
+
+ binder_pop_transaction(NULL, in_reply_to);
+ }
+ else {
+#endif
+ binder_pop_transaction(target_thread, in_reply_to);
+#ifdef CONFIG_ANDROID_BINDER_RPC
+ }
+#endif
} else if (!(t->flags & TF_ONE_WAY)) {
BUG_ON(t->buffer->async_transaction != 0);
t->need_reply = 1;
t->from_parent = thread->transaction_stack;
thread->transaction_stack = t;
+#ifdef CONFIG_ANDROID_BINDER_RPC
+ if((target_proc == binder_get_rpcproc() && target_thread == binder_get_rpcthread()) &&
+ NULL != binder_rpc_ops.binder_transaction) {
+ struct binder_node *target_node = t->buffer->target_node;
+ struct binder_rpc_operations_info ops_info;
+
+ ops_info.cmd = BC_TRANSACTION;
+ ops_info.tr = tr;
+ ops_info.priv = (binder_uintptr_t)t;
+
+ binder_rpc_enqueue_todo(t, target_thread);
+ if(0 != binder_rpc_ops.binder_transaction(&ops_info,fp_handle, (void *)target_node->ptr, (void *)target_node->cookie)) {
+ binder_rpc_dequeue_todo(t, target_thread);
+ }
+ }
+#endif
} else {
BUG_ON(target_node == NULL);
BUG_ON(t->buffer->async_transaction != 1);
@@ -1762,13 +1965,76 @@
target_wait = NULL;
} else
target_node->has_async_transaction = 1;
+#ifdef CONFIG_ANDROID_BINDER_RPC
+ if((target_proc == binder_get_rpcproc() && target_thread == binder_get_rpcthread()) &&
+ NULL != binder_rpc_ops.binder_transaction) {
+ struct binder_node *target_node = t->buffer->target_node;
+ struct binder_rpc_operations_info ops_info;
+ struct binder_buffer *tmp_buffer = t->buffer;
+
+ ops_info.cmd = BC_TRANSACTION;
+ ops_info.tr = tr;
+ ops_info.priv = (binder_uintptr_t)t;
+
+ binder_rpc_enqueue_todo(t, target_thread);
+ if(0 != binder_rpc_ops.binder_transaction(&ops_info,fp_handle, (void *)target_node->ptr, (void *)target_node->cookie)) {
+ binder_rpc_dequeue_todo(t, target_thread);
+ }
+
+ /*free t*/
+ if (tmp_buffer->transaction) {
+ binder_debug(BINDER_DEBUG_TRANSACTION,"%s %d 0x%x\n",__FUNCTION__, __LINE__, tmp_buffer);
+ tmp_buffer->transaction->buffer = NULL;
+ tmp_buffer->transaction = NULL;
+ }
+ if (tmp_buffer->async_transaction && tmp_buffer->target_node) {
+ BUG_ON(!tmp_buffer->target_node->has_async_transaction);
+ if (list_empty(&tmp_buffer->target_node->async_todo))
+ tmp_buffer->target_node->has_async_transaction = 0;
+ else {
+ //list_move_tail(tmp_buffer->target_node->async_todo.next, &target_thread->todo);
+ binder_debug(BINDER_DEBUG_TRANSACTION,"%s %d\n",__FUNCTION__, __LINE__);
+ }
+ }
+ trace_binder_transaction_buffer_release(tmp_buffer);
+
+ binder_free_buf(target_proc, tmp_buffer);
+
+ binder_pop_transaction(NULL, t);
+ }
+#endif
}
- t->work.type = BINDER_WORK_TRANSACTION;
- list_add_tail(&t->work.entry, target_list);
- tcomplete->type = BINDER_WORK_TRANSACTION_COMPLETE;
- list_add_tail(&tcomplete->entry, &thread->todo);
+#ifdef CONFIG_ANDROID_BINDER_RPC
+ if(target_thread != binder_get_rpcthread()) {
+#endif
+ t->work.type = BINDER_WORK_TRANSACTION;
+ list_add_tail(&t->work.entry, target_list);
+#ifdef CONFIG_ANDROID_BINDER_RPC
+ }
+#endif
+
+#ifdef CONFIG_ANDROID_BINDER_RPC
+ if(thread != binder_get_rpcthread()) {
+#endif
+ tcomplete->type = BINDER_WORK_TRANSACTION_COMPLETE;
+ list_add_tail(&tcomplete->entry, &thread->todo);
+
+#ifdef CONFIG_ANDROID_BINDER_RPC
+ }
+ else {
+ kfree(tcomplete);
+ }
+#endif
+
+#ifdef CONFIG_ANDROID_BINDER_RPC
+ if(target_thread != binder_get_rpcthread()) {
+#endif
if (target_wait)
wake_up_interruptible(target_wait);
+
+#ifdef CONFIG_ANDROID_BINDER_RPC
+ }
+#endif
return;
err_get_unused_fd_failed:
@@ -1802,12 +2068,16 @@
tr->data_size, tr->offsets_size);
{
- struct binder_transaction_log_entry *fe;
+ struct binder_transaction_log_entry *fe;
+
+ e->return_error = return_error;
+ e->return_error_line = return_error_line;
fe = binder_transaction_log_add(&binder_transaction_log_failed);
*fe = *e;
}
BUG_ON(thread->return_error != BR_OK);
+ binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,"return_error_line %d \n",return_error_line);
if (in_reply_to) {
thread->return_error = BR_TRANSACTION_COMPLETE;
binder_send_failed_reply(in_reply_to, return_error);
@@ -2822,6 +3092,11 @@
if (thread)
thread->looper &= ~BINDER_LOOPER_STATE_NEED_RETURN;
binder_unlock(__func__);
+#ifdef CONFIG_ANDROID_BINDER_RPC
+ if(BINDER_SET_CONTEXT_MGR == cmd && NULL == binder_get_rpcproc()) {
+ binder_init_rpc(proc);
+ }
+#endif
wait_event_interruptible(binder_user_error_wait, binder_stop_on_user_error < 2);
if (ret && ret != -ERESTARTSYS)
printk(KERN_INFO "binder: %d:%d ioctl %x %lx returned %d\n", proc->pid, current->pid, cmd, arg, ret);
@@ -3023,6 +3298,11 @@
struct binder_proc *proc = filp->private_data;
debugfs_remove(proc->debugfs_entry);
binder_defer_work(proc, BINDER_DEFERRED_RELEASE);
+#ifdef CONFIG_ANDROID_BINDER_RPC
+ if(proc == rpc_own_proc) {
+ binder_deinit_rpc();
+ }
+#endif
return 0;
}
@@ -3061,6 +3341,12 @@
rb_erase(&node->rb_node, &proc->nodes);
list_del_init(&node->work.entry);
binder_release_work(&node->async_todo);
+
+#ifdef CONFIG_ANDROID_BINDER_RPC
+ if(binder_rpc_ops.binder_release) {
+ binder_rpc_ops.binder_release((void *)proc, (void *)node);
+ }
+#endif
if (hlist_empty(&node->refs)) {
kfree(node);
binder_stats_deleted(BINDER_STAT_NODE);
@@ -3206,6 +3492,854 @@
}
mutex_unlock(&binder_deferred_lock);
}
+#ifdef CONFIG_ANDROID_BINDER_RPC
+/***********************************************************************
+ BINDER RPC API START
+***********************************************************************/
+static int binder_init_rpc(struct binder_proc *own_proc)
+{
+ struct binder_proc *proc;
+ unsigned long unused;
+ unsigned long mmap_base;
+ unsigned long mmap_size;
+
+ struct file *pfile = filp_open("/dev/binder",O_RDWR,0);
+
+ if(NULL == pfile) {
+ binder_user_error("%s: filp_open fail.\n", __func__);
+ return -1;
+ }
+ proc = pfile->private_data;
+
+ mmap_size = 16*PAGE_SIZE;
+ mmap_base = do_mmap(pfile, 0, mmap_size,
+ PROT_READ,
+ MAP_PRIVATE | MAP_NORESERVE, 0);
+
+ rpc_proc = proc;
+ rpc_own_proc = own_proc;
+ return binder_rpc_init((void *)proc, pfile, &binder_rpc_ops);
+}
+
+static int binder_deinit_rpc(void)
+{
+ struct binder_proc *proc = binder_get_rpcproc();
+ struct vm_area_struct *vma = proc->vma;
+
+ binder_debug(BINDER_DEBUG_OPEN_CLOSE,"%s rpc proc %d release.\n",__FUNCTION__, proc->pid);
+ binder_rpc_deinit(vma);
+
+ rpc_proc = NULL;
+ rpc_own_proc = NULL;
+ return 0;
+}
+
+static struct binder_proc *binder_get_rpcproc(void)
+{
+ return rpc_proc;
+}
+static struct binder_thread *binder_get_rpcthread(void)
+{
+ return rpc_thread;
+}
+
+/*ÓÃÓÚÌí¼ÓÉÏÐÐbinder_transactionµ½target_thread->todoÁ´±í*/
+static void binder_rpc_enqueue_todo(struct binder_transaction *t,
+ struct binder_thread *target_thread)
+{
+ struct binder_transaction_entry *entry;
+ struct list_head *target_list = &target_thread->todo;
+
+ BUG_ON(target_list == NULL || t == NULL);
+
+ entry = kzalloc(sizeof(*entry), GFP_KERNEL);
+ if (entry == NULL) {
+ return;
+ }
+ entry->t = t;
+
+ //binder_inner_proc_lock(target_thread->proc);
+ list_add_tail(&entry->list, target_list);
+ //binder_inner_proc_unlock(target_thread->proc);
+ binder_debug(BINDER_DEBUG_TRANSACTION, "%s add %x to thread(%d) todo", __FUNCTION__, t, target_thread->pid);
+}
+/*ÓÃÓÚɾ³ýÉÏÐÐbinder_transaction½Úµã*/
+static void binder_rpc_dequeue_todo(struct binder_transaction *t,
+ struct binder_thread *target_thread)
+{
+ struct binder_transaction_entry *entry,*tmp_entry;
+ struct binder_transaction *tmp_t;
+ struct list_head *target_list = &target_thread->todo;
+
+ //binder_inner_proc_lock(target_thread->proc);
+ list_for_each_entry_safe(entry,tmp_entry,target_list,list) {
+ tmp_t = entry->t;
+ if(t == tmp_t) {
+ list_del(&entry->list);
+ kfree(entry);
+ binder_debug(BINDER_DEBUG_TRANSACTION, "%s del %x from thread(%d) todo", __FUNCTION__, t, target_thread->pid);
+ return;
+ }
+ }
+ //binder_inner_proc_unlock(target_thread->proc);
+}
+
+/*ÓÃÓÚ²éÕÒÆ¥ÅäÏÂÐÐBC_REPLYÃüÁîʱbinder_transaction*/
+static struct binder_transaction *binder_rpc_find_todo_by_priv(binder_uintptr_t priv,
+ struct binder_thread *target_thread)
+{
+ struct binder_transaction_entry *entry,*tmp_entry;
+ struct binder_transaction *tmp_t;
+ struct list_head *target_list = &target_thread->todo;
+
+ //binder_inner_proc_lock(target_thread->proc);
+ list_for_each_entry_safe(entry,tmp_entry,target_list,list) {
+ tmp_t = entry->t;
+ if(priv == (binder_uintptr_t)tmp_t) {
+ list_del(&entry->list);
+ kfree(entry);
+ //binder_inner_proc_unlock(target_thread->proc);
+ binder_debug(BINDER_DEBUG_TRANSACTION, "%s del %x from thread(%d) todo", __FUNCTION__, priv, target_thread->pid);
+ return tmp_t;
+ }
+ }
+
+ //binder_inner_proc_unlock(target_thread->proc);
+ return NULL;
+}
+
+
+void *binder_rpc_get_thread(void *brpc_proc)
+{
+ rpc_thread = binder_get_thread(brpc_proc);
+
+ return (void *)rpc_thread;
+}
+int binder_rpc_thread_write(void *brpc_proc,
+ binder_uintptr_t brpc_buffer, size_t size,
+ binder_size_t *consumed)
+{
+ struct binder_proc *proc = brpc_proc;
+ struct binder_thread *thread = binder_get_thread(proc);
+ int ret = 0;
+
+ binder_lock(__func__);
+ ret= binder_thread_write(proc, thread, brpc_buffer, size, consumed);
+ binder_unlock(__func__);
+
+ return ret;
+}
+/*ÏÂÐÐtransanction´¦Àíº¯Êý£¬ÉÏÐÐtransanction´¦ÀíÓÉrpc_transactionº¯Êý´¦Àí*/
+void binder_rpc_transaction(void *prpc_proc,
+ void *prpc_thread,
+ struct binder_transaction_data *tr, int reply,
+ binder_size_t extra_buffers_size,
+ binder_uintptr_t priv)
+{
+ struct binder_proc *proc = (struct binder_proc *)prpc_proc;
+ struct binder_thread *thread = (struct binder_thread *)prpc_thread;
+ struct binder_transaction *t;
+ struct binder_work *tcomplete;
+ size_t *offp, *off_end;
+ struct binder_proc *target_proc;
+ struct binder_thread *target_thread = NULL;
+ struct binder_node *target_node = NULL;
+ struct list_head *target_list;
+ wait_queue_head_t *target_wait;
+ struct binder_transaction *in_reply_to = NULL;
+ struct binder_transaction_log_entry *e;
+ uint32_t return_error;
+ uint32_t return_error_line;
+
+ binder_lock(__func__);
+
+ /*ignore binder_rpc_ops.binder_broadcast reply*/
+ if(reply && (priv == BINDER_RPC_IGNORE_PRIV)) {
+ binder_unlock(__func__);
+ return;
+ }
+
+ e = binder_transaction_log_add(&binder_transaction_log);
+ e->call_type = reply ? 2 : !!(tr->flags & TF_ONE_WAY);
+ e->from_proc = proc->pid;
+ e->from_thread = thread->pid;
+ e->target_handle = tr->target.handle;
+ e->data_size = tr->data_size;
+ e->offsets_size = tr->offsets_size;
+
+ if (reply) {
+ if((thread == binder_get_rpcthread() && proc == binder_get_rpcproc())) {
+ in_reply_to = binder_rpc_find_todo_by_priv(priv, thread);
+ }
+ else {
+ in_reply_to = thread->transaction_stack;
+ }
+
+ if (in_reply_to == NULL) {
+ binder_user_error("binder: %d:%d got reply transaction "
+ "with no transaction stack\n",
+ proc->pid, thread->pid);
+ return_error = BR_FAILED_REPLY;
+ return_error_line = __LINE__;
+ goto err_empty_call_stack;
+ }
+ binder_set_nice(in_reply_to->saved_priority);
+ if (in_reply_to->to_thread != thread) {
+ binder_user_error("binder: %d:%d got reply transaction "
+ "with bad transaction stack,"
+ " transaction %d has target %d:%d\n",
+ proc->pid, thread->pid, in_reply_to->debug_id,
+ in_reply_to->to_proc ?
+ in_reply_to->to_proc->pid : 0,
+ in_reply_to->to_thread ?
+ in_reply_to->to_thread->pid : 0);
+ return_error = BR_FAILED_REPLY;
+ return_error_line = __LINE__;
+ in_reply_to = NULL;
+ goto err_bad_call_stack;
+ }
+ thread->transaction_stack = in_reply_to->to_parent;
+ target_thread = in_reply_to->from;
+ if (target_thread == NULL) {
+ return_error = BR_DEAD_REPLY;
+ return_error_line = __LINE__;
+ goto err_dead_binder;
+ }
+ if (target_thread->transaction_stack != in_reply_to) {
+ binder_user_error("binder: %d:%d got reply transaction "
+ "with bad target transaction stack %d, "
+ "expected %d\n",
+ proc->pid, thread->pid,
+ target_thread->transaction_stack ?
+ target_thread->transaction_stack->debug_id : 0,
+ in_reply_to->debug_id);
+ return_error = BR_FAILED_REPLY;
+ return_error_line = __LINE__;
+ in_reply_to = NULL;
+ target_thread = NULL;
+ goto err_dead_binder;
+ }
+ target_proc = target_thread->proc;
+ } else {
+ if (tr->target.handle) {
+ struct binder_ref *ref;
+ ref = binder_get_ref(proc, tr->target.handle);
+ if (ref == NULL) {
+ binder_user_error("binder: %d:%d got "
+ "transaction to invalid handle\n",
+ proc->pid, thread->pid);
+ return_error = BR_FAILED_REPLY;
+ return_error_line = __LINE__;
+ //panic("binder_get_ref fail.\n");
+ goto err_invalid_target_handle;
+ }
+ target_node = ref->node;
+ } else {
+ target_node = binder_context_mgr_node;
+ if (target_node == NULL) {
+ return_error = BR_DEAD_REPLY;
+ return_error_line = __LINE__;
+ goto err_no_context_mgr_node;
+ }
+ }
+ e->to_node = target_node->debug_id;
+ target_proc = target_node->proc;
+ if (target_proc == NULL) {
+ return_error = BR_DEAD_REPLY;
+ return_error_line = __LINE__;
+ goto err_dead_binder;
+ }
+ if(target_proc == binder_get_rpcproc()) {
+ target_thread = binder_get_rpcthread();
+ }
+ if (!(tr->flags & TF_ONE_WAY) && thread->transaction_stack && (thread != binder_get_rpcthread())) {
+ struct binder_transaction *tmp;
+ tmp = thread->transaction_stack;
+ if (tmp->to_thread != thread) {
+ binder_user_error("binder: %d:%d got new "
+ "transaction with bad transaction stack"
+ ", transaction %d has target %d:%d\n",
+ proc->pid, thread->pid, tmp->debug_id,
+ tmp->to_proc ? tmp->to_proc->pid : 0,
+ tmp->to_thread ?
+ tmp->to_thread->pid : 0);
+ return_error = BR_FAILED_REPLY;
+ return_error_line = __LINE__;
+ goto err_bad_call_stack;
+ }
+ while (tmp) {
+ if (tmp->from && tmp->from->proc == target_proc)
+ target_thread = tmp->from;
+ tmp = tmp->from_parent;
+ }
+ }
+ }
+ if (target_thread) {
+ e->to_thread = target_thread->pid;
+ target_list = &target_thread->todo;
+ target_wait = &target_thread->wait;
+ } else {
+ target_list = &target_proc->todo;
+ target_wait = &target_proc->wait;
+ }
+ e->to_proc = target_proc->pid;
+
+ /* TODO: reuse incoming transaction for reply */
+ t = kzalloc(sizeof(*t), GFP_KERNEL);
+ if (t == NULL) {
+ return_error = BR_FAILED_REPLY;
+ return_error_line = __LINE__;
+ goto err_alloc_t_failed;
+ }
+ binder_stats_created(BINDER_STAT_TRANSACTION);
+
+ tcomplete = kzalloc(sizeof(*tcomplete), GFP_KERNEL);
+ if (tcomplete == NULL) {
+ return_error = BR_FAILED_REPLY;
+ return_error_line = __LINE__;
+ goto err_alloc_tcomplete_failed;
+ }
+ binder_stats_created(BINDER_STAT_TRANSACTION_COMPLETE);
+
+ t->debug_id = ++binder_last_id;
+ e->debug_id = t->debug_id;
+
+ if (reply)
+ binder_debug(BINDER_DEBUG_TRANSACTION,
+ "binder: %d:%d BC_REPLY %d -> %d:%d, "
+ "data %p-%p size %zd-%zd\n",
+ proc->pid, thread->pid, t->debug_id,
+ target_proc->pid, target_thread->pid,
+ tr->data.ptr.buffer, tr->data.ptr.offsets,
+ tr->data_size, tr->offsets_size);
+ else
+ binder_debug(BINDER_DEBUG_TRANSACTION,
+ "binder: %d:%d BC_TRANSACTION %d -> "
+ "%d - node %d, data %p-%p size %zd-%zd\n",
+ proc->pid, thread->pid, t->debug_id,
+ target_proc->pid, target_node->debug_id,
+ tr->data.ptr.buffer, tr->data.ptr.offsets,
+ tr->data_size, tr->offsets_size);
+
+ if (!reply && !(tr->flags & TF_ONE_WAY))
+ t->from = thread;
+ else
+ t->from = NULL;
+ t->sender_euid = proc->tsk->cred->euid;
+ t->to_proc = target_proc;
+ t->to_thread = target_thread;
+ t->code = tr->code;
+ t->flags = tr->flags;
+ t->priority = task_nice(current);
+
+ trace_binder_transaction(reply, t, target_node);
+
+ t->buffer = binder_alloc_buf(target_proc, tr->data_size,
+ tr->offsets_size, !reply && (t->flags & TF_ONE_WAY));
+ if (t->buffer == NULL) {
+ return_error = BR_FAILED_REPLY;
+ return_error_line = __LINE__;
+ goto err_binder_alloc_buf_failed;
+ }
+ t->buffer->allow_user_free = 0;
+ t->buffer->debug_id = t->debug_id;
+ t->buffer->transaction = t;
+ t->buffer->target_node = target_node;
+ trace_binder_transaction_alloc_buf(t->buffer);
+ if (target_node)
+ binder_inc_node(target_node, 1, 0, NULL);
+
+ offp = (size_t *)(t->buffer->data + ALIGN(tr->data_size, sizeof(void *)));
+
+ if (copy_from_user(t->buffer->data, tr->data.ptr.buffer, tr->data_size)) {
+ binder_user_error("binder: %d:%d got transaction with invalid "
+ "data ptr\n", proc->pid, thread->pid);
+ return_error = BR_FAILED_REPLY;
+ return_error_line = __LINE__;
+ goto err_copy_data_failed;
+ }
+ if (copy_from_user(offp, tr->data.ptr.offsets, tr->offsets_size)) {
+ binder_user_error("binder: %d:%d got transaction with invalid "
+ "offsets ptr\n", proc->pid, thread->pid);
+ return_error = BR_FAILED_REPLY;
+ return_error_line = __LINE__;
+ goto err_copy_data_failed;
+ }
+ if (!IS_ALIGNED(tr->offsets_size, sizeof(size_t))) {
+ binder_user_error("binder: %d:%d got transaction with "
+ "invalid offsets size, %zd\n",
+ proc->pid, thread->pid, tr->offsets_size);
+ return_error = BR_FAILED_REPLY;
+ return_error_line = __LINE__;
+ goto err_bad_offset;
+ }
+ off_end = (void *)offp + tr->offsets_size;
+ for (; offp < off_end; offp++) {
+ struct flat_binder_object *fp;
+ if (*offp > t->buffer->data_size - sizeof(*fp) ||
+ t->buffer->data_size < sizeof(*fp) ||
+ !IS_ALIGNED(*offp, sizeof(void *))) {
+ binder_user_error("binder: %d:%d got transaction with "
+ "invalid offset, %zd\n",
+ proc->pid, thread->pid, *offp);
+ return_error = BR_FAILED_REPLY;
+ return_error_line = __LINE__;
+ goto err_bad_offset;
+ }
+ fp = (struct flat_binder_object *)(t->buffer->data + *offp);
+ switch (fp->type) {
+ case BINDER_TYPE_BINDER:
+ case BINDER_TYPE_WEAK_BINDER: {
+ struct binder_ref *ref;
+ struct binder_node *node = binder_get_node(proc, fp->binder);
+ if (node == NULL) {
+ node = binder_new_node(proc, fp->binder, fp->cookie);
+ if (node == NULL) {
+ return_error = BR_FAILED_REPLY;
+ return_error_line = __LINE__;
+ goto err_binder_new_node_failed;
+ }
+ node->min_priority = fp->flags & FLAT_BINDER_FLAG_PRIORITY_MASK;
+ node->accept_fds = !!(fp->flags & FLAT_BINDER_FLAG_ACCEPTS_FDS);
+ }
+ if (fp->cookie != node->cookie) {
+ binder_user_error("binder: %d:%d sending u%p "
+ "node %d, cookie mismatch %p != %p\n",
+ proc->pid, thread->pid,
+ fp->binder, node->debug_id,
+ fp->cookie, node->cookie);
+ goto err_binder_get_ref_for_node_failed;
+ }
+ ref = binder_get_ref_for_node(target_proc, node);
+ if (ref == NULL) {
+ return_error = BR_FAILED_REPLY;
+ return_error_line = __LINE__;
+ goto err_binder_get_ref_for_node_failed;
+ }
+ if (fp->type == BINDER_TYPE_BINDER)
+ fp->type = BINDER_TYPE_HANDLE;
+ else
+ fp->type = BINDER_TYPE_WEAK_HANDLE;
+ fp->handle = ref->desc;
+ binder_inc_ref(ref, fp->type == BINDER_TYPE_HANDLE,
+ &thread->todo);
+
+ trace_binder_transaction_node_to_ref(t, node, ref);
+ binder_debug(BINDER_DEBUG_TRANSACTION,
+ " node %d u%p -> ref %d desc %d\n",
+ node->debug_id, node->ptr, ref->debug_id,
+ ref->desc);
+ } break;
+ case BINDER_TYPE_HANDLE:
+ case BINDER_TYPE_WEAK_HANDLE: {
+ struct binder_ref *ref = binder_get_ref(proc, fp->handle);
+ if (ref == NULL) {
+ binder_user_error("binder: %d:%d got "
+ "transaction with invalid "
+ "handle, %ld\n", proc->pid,
+ thread->pid, fp->handle);
+ return_error = BR_FAILED_REPLY;
+ return_error_line = __LINE__;
+ goto err_binder_get_ref_failed;
+ }
+ if (ref->node->proc == target_proc) {
+ if (fp->type == BINDER_TYPE_HANDLE)
+ fp->type = BINDER_TYPE_BINDER;
+ else
+ fp->type = BINDER_TYPE_WEAK_BINDER;
+ fp->binder = ref->node->ptr;
+ fp->cookie = ref->node->cookie;
+ binder_inc_node(ref->node, fp->type == BINDER_TYPE_BINDER, 0, NULL);
+ trace_binder_transaction_ref_to_node(t, ref);
+ binder_debug(BINDER_DEBUG_TRANSACTION,
+ " ref %d desc %d -> node %d u%p\n",
+ ref->debug_id, ref->desc, ref->node->debug_id,
+ ref->node->ptr);
+ } else {
+ struct binder_ref *new_ref;
+ new_ref = binder_get_ref_for_node(target_proc, ref->node);
+ if (new_ref == NULL) {
+ return_error = BR_FAILED_REPLY;
+ return_error_line = __LINE__;
+ goto err_binder_get_ref_for_node_failed;
+ }
+ fp->handle = new_ref->desc;
+ binder_inc_ref(new_ref, fp->type == BINDER_TYPE_HANDLE, NULL);
+ trace_binder_transaction_ref_to_ref(t, ref,
+ new_ref);
+ binder_debug(BINDER_DEBUG_TRANSACTION,
+ " ref %d desc %d -> ref %d desc %d (node %d)\n",
+ ref->debug_id, ref->desc, new_ref->debug_id,
+ new_ref->desc, ref->node->debug_id);
+ }
+ } break;
+
+ case BINDER_TYPE_FD: {
+ int target_fd;
+ struct file *file;
+
+ if (reply) {
+ if (!(in_reply_to->flags & TF_ACCEPT_FDS)) {
+ binder_user_error("binder: %d:%d got reply with fd, %ld, but target does not allow fds\n",
+ proc->pid, thread->pid, fp->handle);
+ return_error = BR_FAILED_REPLY;
+ return_error_line = __LINE__;
+ goto err_fd_not_allowed;
+ }
+ } else if (!target_node->accept_fds) {
+ binder_user_error("binder: %d:%d got transaction with fd, %ld, but target does not allow fds\n",
+ proc->pid, thread->pid, fp->handle);
+ return_error = BR_FAILED_REPLY;
+ return_error_line = __LINE__;
+ goto err_fd_not_allowed;
+ }
+
+ file = fget(fp->handle);
+ if (file == NULL) {
+ binder_user_error("binder: %d:%d got transaction with invalid fd, %ld\n",
+ proc->pid, thread->pid, fp->handle);
+ return_error = BR_FAILED_REPLY;
+ return_error_line = __LINE__;
+ goto err_fget_failed;
+ }
+ target_fd = task_get_unused_fd_flags(target_proc, O_CLOEXEC);
+ if (target_fd < 0) {
+ fput(file);
+ return_error = BR_FAILED_REPLY;
+ return_error_line = __LINE__;
+ goto err_get_unused_fd_failed;
+ }
+ task_fd_install(target_proc, target_fd, file);
+ trace_binder_transaction_fd(t, fp->handle, target_fd);
+ binder_debug(BINDER_DEBUG_TRANSACTION,
+ " fd %ld -> %d\n", fp->handle, target_fd);
+ /* TODO: fput? */
+ fp->handle = target_fd;
+ } break;
+
+ default:
+ binder_user_error("binder: %d:%d got transactio"
+ "n with invalid object type, %lx\n",
+ proc->pid, thread->pid, fp->type);
+ return_error = BR_FAILED_REPLY;
+ return_error_line = __LINE__;
+ goto err_bad_object_type;
+ }
+ }
+ if (reply) {
+ BUG_ON(t->buffer->async_transaction != 0);
+
+ if(in_reply_to->to_proc == binder_get_rpcproc() && in_reply_to->to_thread == binder_get_rpcthread()) {
+ struct binder_buffer *tmp_buffer = in_reply_to->buffer;
+
+ binder_debug(BINDER_DEBUG_TRANSACTION, "%s %d \n", __FUNCTION__, __LINE__);
+
+ /*free in_reply_to*/
+ if (tmp_buffer->transaction) {
+ binder_debug(BINDER_DEBUG_TRANSACTION,"%s %d 0x%x\n",__FUNCTION__, __LINE__, tmp_buffer);
+ tmp_buffer->transaction->buffer = NULL;
+ tmp_buffer->transaction = NULL;
+ }
+ if (tmp_buffer->async_transaction && tmp_buffer->target_node) {
+ BUG_ON(!tmp_buffer->target_node->has_async_transaction);
+ if (list_empty(&tmp_buffer->target_node->async_todo))
+ tmp_buffer->target_node->has_async_transaction = 0;
+ else {
+ //list_move_tail(tmp_buffer->target_node->async_todo.next, &thread->todo);
+ binder_debug(BINDER_DEBUG_TRANSACTION,"%s %d\n",__FUNCTION__, __LINE__);
+ }
+ }
+ trace_binder_transaction_buffer_release(tmp_buffer);
+
+ //binder_transaction_buffer_release(in_reply_to->to_proc, tmp_buffer, NULL);
+
+ binder_free_buf(in_reply_to->to_proc, tmp_buffer);
+ }
+ binder_pop_transaction(target_thread, in_reply_to);
+ } else if (!(t->flags & TF_ONE_WAY)) {
+ BUG_ON(t->buffer->async_transaction != 0);
+ t->need_reply = 1;
+ t->from_parent = thread->transaction_stack;
+ thread->transaction_stack = t;
+ if(thread == binder_get_rpcthread() && proc == binder_get_rpcproc()) {
+ t->remote_priv = priv;
+ binder_rpc_enqueue_todo(t, thread);
+ }
+ } else {
+ BUG_ON(target_node == NULL);
+ BUG_ON(t->buffer->async_transaction != 1);
+ if (target_node->has_async_transaction) {
+ target_list = &target_node->async_todo;
+ target_wait = NULL;
+ } else
+ target_node->has_async_transaction = 1;
+
+ if(thread == binder_get_rpcthread() && proc == binder_get_rpcproc()) {
+ binder_debug(BINDER_DEBUG_TRANSACTION, "%s %d \n", __FUNCTION__, __LINE__);
+
+ //t->remote_priv = priv;
+ //binder_rpc_enqueue_todo(t, thread);
+ }
+ }
+ if(target_thread != binder_get_rpcthread()) {
+ t->work.type = BINDER_WORK_TRANSACTION;
+ list_add_tail(&t->work.entry, target_list);
+ }
+
+ if(thread != binder_get_rpcthread()) {
+ tcomplete->type = BINDER_WORK_TRANSACTION_COMPLETE;
+ list_add_tail(&tcomplete->entry, &thread->todo);
+ }
+ else {
+ kfree(tcomplete);
+ }
+
+ if(target_thread != binder_get_rpcthread()) {
+ if (target_wait)
+ wake_up_interruptible(target_wait);
+ }
+ binder_unlock(__func__);
+ return;
+
+err_get_unused_fd_failed:
+err_fget_failed:
+err_fd_not_allowed:
+err_binder_get_ref_for_node_failed:
+err_binder_get_ref_failed:
+err_binder_new_node_failed:
+err_bad_object_type:
+err_bad_offset:
+err_copy_data_failed:
+ trace_binder_transaction_failed_buffer_release(t->buffer);
+ binder_transaction_buffer_release(target_proc, t->buffer, offp);
+ t->buffer->transaction = NULL;
+ binder_free_buf(target_proc, t->buffer);
+err_binder_alloc_buf_failed:
+ kfree(tcomplete);
+ binder_stats_deleted(BINDER_STAT_TRANSACTION_COMPLETE);
+err_alloc_tcomplete_failed:
+ kfree(t);
+ binder_stats_deleted(BINDER_STAT_TRANSACTION);
+err_alloc_t_failed:
+err_bad_call_stack:
+err_empty_call_stack:
+err_dead_binder:
+err_invalid_target_handle:
+err_no_context_mgr_node:
+ binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,
+ "binder: %d:%d transaction failed %d, size %zd-%zd\n",
+ proc->pid, thread->pid, return_error,
+ tr->data_size, tr->offsets_size);
+
+ {
+ struct binder_transaction_log_entry *fe;
+ fe = binder_transaction_log_add(&binder_transaction_log_failed);
+ *fe = *e;
+ }
+
+ BUG_ON(thread->return_error != BR_OK);
+ binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,"return_error_line %d \n",return_error_line);
+ if(thread == binder_get_rpcthread() && proc == binder_get_rpcproc()) {
+ if(NULL != binder_rpc_ops.binder_return_error) {
+ struct binder_rpc_operations_info ops_info;
+
+ ops_info.tr = NULL;
+
+ if (in_reply_to) {
+ ops_info.cmd = BR_TRANSACTION_COMPLETE;
+ /*this cmd will be ignored on remote thread.*/
+ ops_info.priv = BINDER_RPC_IGNORE_PRIV;
+
+ /*send target_thread fail reply*/
+ binder_send_failed_reply(in_reply_to, return_error);
+ }
+ else {
+ ops_info.cmd = return_error;
+ ops_info.priv = priv;
+ }
+ /*send error to remote thread*/
+ binder_rpc_ops.binder_return_error(&ops_info, reply);
+ }
+ }
+ else {
+ if (in_reply_to) {
+ thread->return_error = BR_TRANSACTION_COMPLETE;
+ binder_send_failed_reply(in_reply_to, return_error);
+ } else
+ thread->return_error = return_error;
+ }
+
+ binder_unlock(__func__);
+}
+
+void binder_rpc_return_error(void *brpc_proc,
+ void *prpc_thread,
+ uint32_t return_error,
+ binder_uintptr_t priv,
+ int reply)
+{
+ struct binder_proc *proc = (struct binder_proc *)brpc_proc;
+ struct binder_thread *thread = (struct binder_thread *)prpc_thread;
+
+ struct binder_proc *target_proc = NULL;
+ struct binder_thread *target_thread = NULL;
+ struct binder_transaction *in_reply_to = NULL;
+
+ binder_lock(__func__);
+ /*ignore binder_rpc_ops.binder_broadcast reply*/
+ if(priv == BINDER_RPC_IGNORE_PRIV) {
+ binder_unlock(__func__);
+ return;
+ }
+ binder_debug(BINDER_DEBUG_TRANSACTION,"%s %d \n",__FUNCTION__,__LINE__);
+ if((thread == binder_get_rpcthread() && proc == binder_get_rpcproc())) {
+ in_reply_to = binder_rpc_find_todo_by_priv(priv, thread);
+ }
+
+ if (in_reply_to == NULL) {
+ binder_user_error("%s binder: %d:%d got reply transaction "
+ "with no transaction stack\n", __FUNCTION__, proc->pid, thread->pid);
+ binder_unlock(__func__);
+ return;
+ }
+ /*no reply*/
+ if(in_reply_to->flags & TF_ONE_WAY) {
+ binder_unlock(__func__);
+ return;
+ }
+
+ binder_set_nice(in_reply_to->saved_priority);
+ if (in_reply_to->to_thread != thread) {
+ binder_user_error("binder: %d:%d got reply transaction "
+ "with bad transaction stack,"
+ " transaction %d has target %d:%d\n",
+ proc->pid, thread->pid, in_reply_to->debug_id,
+ in_reply_to->to_proc ?
+ in_reply_to->to_proc->pid : 0,
+ in_reply_to->to_thread ?
+ in_reply_to->to_thread->pid : 0);
+ binder_unlock(__func__);
+ return;
+ }
+
+ target_thread = in_reply_to->from;
+ if (target_thread == NULL) {
+ binder_unlock(__func__);
+ return;
+ }
+ if (target_thread->transaction_stack != in_reply_to) {
+ binder_user_error("binder: %d:%d got reply transaction "
+ "with bad target transaction stack %d, "
+ "expected %d\n",
+ proc->pid, thread->pid,
+ target_thread->transaction_stack ?
+ target_thread->transaction_stack->debug_id : 0,
+ in_reply_to->debug_id);
+ binder_unlock(__func__);
+ return;
+ }
+
+ binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,"%s %d:%d transaction failed %d \n",
+ __FUNCTION__, target_thread->proc->pid, target_thread->pid, return_error);
+
+ if(reply) {
+ //target_thread->return_error = BR_TRANSACTION_COMPLETE;
+ binder_send_failed_reply(in_reply_to, return_error);
+ }
+ else {
+ target_thread->return_error = return_error;
+ wake_up_interruptible(&target_thread->wait);//need ?
+ }
+
+ binder_unlock(__func__);
+}
+
+void binder_rpc_node_release(void *node)
+{
+ struct binder_proc *proc = binder_get_rpcproc();
+ struct rb_node *n;
+ struct binder_node *releasing_node = (struct binder_node *)node;
+
+ binder_lock(__func__);
+ for (n = rb_first(&proc->refs_by_desc);
+ n != NULL;
+ n = rb_next(n)) {
+
+ struct binder_ref *ref;
+
+ ref = rb_entry(n, struct binder_ref, rb_node_desc);
+
+ if(ref->node == releasing_node) {
+ binder_debug(BINDER_DEBUG_OPEN_CLOSE,"%s %d debug_id:%d desc:%d strong:%d weak:%d \n",__FUNCTION__,__LINE__,
+ ref->debug_id,ref->desc,ref->strong,ref->weak);
+ if(binder_rpc_ops.binder_dead_notify) {
+ binder_rpc_ops.binder_dead_notify(ref->desc);
+ }
+
+ binder_delete_ref(ref);
+ }
+ }
+ binder_unlock(__func__);
+}
+
+void binder_rpc_dead(void *brpc_proc, uint32_t handle)
+{
+ struct binder_proc *proc = (struct binder_proc *)brpc_proc;
+ struct binder_node *node;
+
+ struct hlist_node *pos, *n;
+ struct binder_transaction *t;
+ int incoming_refs = 0;
+
+ binder_lock(__func__);
+ node = binder_get_node(proc, handle);
+ if(!node) {
+ binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,"binder_get_node(%d) fail\n",handle);
+ }
+ else {
+ binder_debug(BINDER_DEBUG_FAILED_TRANSACTION,"binder_get_node(%d) success\n",handle);
+ rb_erase(&node->rb_node, &proc->nodes);
+ list_del_init(&node->work.entry);
+ //binder_release_work(&node->async_todo);
+ if (hlist_empty(&node->refs)) {
+ kfree(node);
+ binder_stats_deleted(BINDER_STAT_NODE);
+ } else {
+ struct binder_ref *ref;
+ int death = 0;
+
+ node->proc = NULL;
+ node->local_strong_refs = 0;
+ node->local_weak_refs = 0;
+ hlist_add_head(&node->dead_node, &binder_dead_nodes);
+ hlist_for_each_entry_safe(ref, pos, n, &node->refs, node_entry) {
+ binder_debug(BINDER_DEBUG_OPEN_CLOSE,"%s %d debug_id:%d desc:%d strong:%d weak:%d \n",
+ __FUNCTION__, ref->proc->pid, ref->debug_id,ref->desc,ref->strong,ref->weak);
+ incoming_refs++;
+ if (ref->death) {
+ death++;
+ if (list_empty(&ref->death->work.entry)) {
+ ref->death->work.type = BINDER_WORK_DEAD_BINDER;
+ list_add_tail(&ref->death->work.entry, &ref->proc->todo);
+ wake_up_interruptible(&ref->proc->wait);
+ } else
+ BUG();
+ }
+ }
+ binder_debug(BINDER_DEBUG_DEAD_BINDER,
+ "binder: node %d now dead, "
+ "refs %d, death %d\n", node->debug_id,
+ incoming_refs, death);
+ }
+ }
+
+ binder_unlock(__func__);
+}
+
+/***********************************************************************
+ BINDER RPC API END
+***********************************************************************/
+#endif
static void print_binder_transaction(struct seq_file *m, const char *prefix,
struct binder_transaction *t)
@@ -3283,7 +4417,12 @@
size_t start_pos = m->count;
size_t header_pos;
- seq_printf(m, " thread %d: l %02x\n", thread->pid, thread->looper);
+ seq_printf(m, " thread %d: l %02x\n", thread->pid, thread->looper);
+#ifdef CONFIG_ANDROID_BINDER_RPC
+ if(thread == binder_get_rpcthread) {
+ return;
+ }
+#endif
header_pos = m->count;
t = thread->transaction_stack;
while (t) {
diff --git a/ap/os/linux/linux-3.4.x/drivers/staging/android/binder_rpc.c b/ap/os/linux/linux-3.4.x/drivers/staging/android/binder_rpc.c
new file mode 100755
index 0000000..1dc410e
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/staging/android/binder_rpc.c
@@ -0,0 +1,752 @@
+#include <linux/fdtable.h>
+#include <linux/file.h>
+#include <linux/freezer.h>
+#include <linux/fs.h>
+#include <linux/list.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/nsproxy.h>
+#include <linux/poll.h>
+#include <linux/debugfs.h>
+#include <linux/rbtree.h>
+//#include <linux/sched/signal.h>
+//#include <linux/sched/mm.h>
+#include <linux/seq_file.h>
+#include <linux/string.h>
+#include <linux/uaccess.h>
+#include <linux/pid_namespace.h>
+#include <linux/security.h>
+#include <linux/spinlock.h>
+#include <linux/ratelimit.h>
+#include <linux/syscalls.h>
+//#include <linux/task_work.h>
+//#include <linux/sizes.h>
+
+#include <linux/delay.h>
+//#include "binder_alloc.h"
+#include "binder_rpc.h"
+#include "binder_rpc_common.h"
+
+#define brpc_init_sema sema_init
+#define brpc_get_sema down_interruptible
+#define brpc_put_sema up
+
+enum binder_driver_command_protocol_ext {
+ BC_DEAD_BINDER_NOTIFY = _IOW('c', 100, struct brpc_dead_data),
+
+};
+
+struct binder_rpc_context brpc_ctx;
+
+static int brpc_rpctr_convert_tr(struct brpc_data *prpc_data, struct binder_transaction_data *tr);
+static struct brpc_data_entry *brpc_tr_convert_rpctr(struct binder_rpc_operations_info *ops_info,
+ void *ptr,
+ void *cookie);
+static int brpc_update_object_binder(struct brpc_data *prpc_data, uint32_t local_handle);
+static int brpc_chn_recv_proc(struct brpc_data *prpc_data);
+static int brpc_chn_write(struct brpc_rpmg_channel *chninfo, void *buf, unsigned int len);
+static int brpc_chn_receive_thread(void *argv);
+static int brpc_chn_create(struct binder_rpc_context *pbrpc_ctx);
+static int brpc_write_remote(struct brpc_data *data);
+static int brpc_send_trdata(struct brpc_data_entry *rpc_data_node);
+static int brpc_thread_enqueue_data(struct brpc_agent_thread_info *pagent_thread, struct brpc_data_entry *rpcdata_node);
+static int brpc_thread_write(void *brpc_proc,
+ binder_uintptr_t brpc_buffer, size_t size,
+ binder_size_t *consumed);
+static int brpc_agent_write_refs(struct binder_rpc_context *pbrpc_ctx);
+static void brpc_transaction(void *prpc_proc,
+ void *prpc_thread,
+ struct binder_transaction_data *tr, int reply,
+ binder_size_t extra_buffers_size,
+ binder_uintptr_t priv);
+
+static void brpc_uld_handle(struct binder_rpc_context *pbrpc_ctx, struct brpc_data *prpc_data);
+static void brpc_dld_handle(struct binder_rpc_context *pbrpc_ctx, struct brpc_data *prpc_data);
+static int brpc_agent_loop(void *argv);
+static int brpc_agent_create(struct binder_rpc_context *pbrpc_ctx);
+
+
+static int brpc_rpctr_convert_tr(struct brpc_data *prpc_data, struct binder_transaction_data *tr)
+{
+ struct brpc_transaction_data *prpc_tr = &prpc_data->rpc_tr;
+
+ tr->target.handle = prpc_tr->handle;
+ tr->cookie = prpc_tr->cookie;
+ tr->code = prpc_tr->code;
+ tr->flags = prpc_tr->flags;
+ tr->data_size = prpc_tr->data_size;
+ tr->offsets_size = prpc_tr->offsets_size;
+
+ tr->data.ptr.buffer = (void *)kzalloc(tr->data_size, GFP_KERNEL);
+ tr->data.ptr.offsets = (void *)kzalloc(tr->offsets_size, GFP_KERNEL);
+ memcpy(tr->data.ptr.buffer, prpc_tr->buffer, tr->data_size);
+ memcpy(tr->data.ptr.offsets, prpc_tr->offsets, tr->offsets_size);
+
+ return 0;
+}
+
+static struct brpc_data_entry *brpc_tr_convert_rpctr(struct binder_rpc_operations_info *ops_info,
+ void *ptr,
+ void *cookie)
+{
+ struct brpc_data_entry *rpc_data_node;
+ struct brpc_data *prpc_data;
+ struct brpc_transaction_data *prpc_tr;
+
+ uint32_t cmd = ops_info->cmd;
+ struct binder_transaction_data *tr = ops_info->tr;
+ binder_uintptr_t priv = ops_info->priv;
+
+ /*construct brpc_data*/
+ rpc_data_node = kzalloc(sizeof(*rpc_data_node), GFP_KERNEL);
+ if (rpc_data_node == NULL) {
+ brpc_err("kzalloc fial!!");
+ return NULL;
+ }
+
+ rpc_data_node->dir = BRPC_DIR_UPLINK;
+
+ prpc_data = &rpc_data_node->rpc_data;
+ prpc_data->cmd = cmd;
+
+ prpc_tr = &prpc_data->rpc_tr;
+ prpc_tr->priv = priv;
+ prpc_tr->handle = NULL == ptr ? tr->target.handle : ptr;
+ prpc_tr->cookie = NULL == cookie ? tr->cookie : cookie;
+ prpc_tr->code = tr->code;
+ prpc_tr->flags = tr->flags;
+ prpc_tr->data_size = tr->data_size;
+ prpc_tr->offsets_size = tr->offsets_size;
+
+ brpc_dbg("target.handle=%d code=%d ",prpc_tr->handle, prpc_tr->code);
+
+ if(prpc_tr->data_size >= BRPC_TR_BUFFER_SIZE_MAX || prpc_tr->offsets_size >= BRPC_TR_BUFFER_SIZE_MAX) {
+ brpc_err("data_size=%d offsets_size=%d ",prpc_tr->data_size,prpc_tr->offsets_size);
+ kfree(rpc_data_node);
+ return NULL;
+ }
+
+ if (copy_from_user(prpc_tr->buffer, tr->data.ptr.buffer, prpc_tr->data_size)) {
+ brpc_err("copy_from_user fail\n");
+ kfree(rpc_data_node);
+ return NULL;
+ }
+
+ if (copy_from_user(prpc_tr->offsets, tr->data.ptr.offsets, prpc_tr->offsets_size)) {
+ brpc_dbg("copy_from_user fail\n");
+ kfree(rpc_data_node);
+ return NULL;
+ }
+
+ return rpc_data_node;
+}
+
+
+static int brpc_update_object_binder(struct brpc_data *prpc_data, uint32_t local_handle)
+{
+ binder_size_t buffer_offset = 0;
+ binder_size_t off_start_offset, off_end_offset;
+ binder_size_t off_min;
+
+ struct brpc_transaction_data *prpc_tr = &prpc_data->rpc_tr;
+ size_t *offp, *off_end;
+
+ offp = (size_t *)prpc_tr->offsets;
+ off_end = (void *)offp + prpc_tr->offsets_size;
+
+ for (; offp < off_end; offp++) {
+ struct flat_binder_object *fp;
+ if (*offp > prpc_tr->data_size - sizeof(*fp) ||
+ prpc_tr->data_size < sizeof(*fp) ||
+ !IS_ALIGNED(*offp, sizeof(void *))) {
+ brpc_err("binder: got transaction with "
+ "invalid offset, %zd\n",
+ *offp);
+ return -1;
+ }
+ fp = (struct flat_binder_object *)(prpc_tr->buffer + *offp);
+ switch (fp->type) {
+ case BINDER_TYPE_BINDER:
+ case BINDER_TYPE_WEAK_BINDER: {
+ fp->binder = local_handle;
+ fp->cookie = 0;
+ brpc_info("fp->binder:%d",fp->binder);
+ } break;
+ case BINDER_TYPE_HANDLE:
+ case BINDER_TYPE_WEAK_HANDLE:
+ brpc_info("fp->handle:%d",fp->handle);
+ break;
+
+ case BINDER_TYPE_FD:
+ default:
+ brpc_err("got transaction with invalid object type, %x\n",fp->type);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+static int brpc_binder_return_error(struct binder_rpc_operations_info *ops_info, int reply)
+{
+ struct brpc_data_entry *rpc_data_node = NULL;
+
+ rpc_data_node = kzalloc(sizeof(*rpc_data_node), GFP_KERNEL);
+ if (rpc_data_node == NULL) {
+ brpc_err("kzalloc fial!!");
+ return -1;
+ }
+
+ rpc_data_node->dir = BRPC_DIR_UPLINK;
+ rpc_data_node->rpc_data.cmd = ops_info->cmd;
+ rpc_data_node->rpc_data.rpc_reply_error.priv = ops_info->priv;
+ rpc_data_node->rpc_data.rpc_reply_error.reply = reply;
+
+ brpc_send_trdata(rpc_data_node);
+ return 0;
+}
+static int brpc_binder_release(void *proc, void *node)
+{
+ struct brpc_data_entry *rpc_data_node = NULL;
+
+ rpc_data_node = kzalloc(sizeof(*rpc_data_node), GFP_KERNEL);
+ if (rpc_data_node == NULL) {
+ brpc_err("kzalloc fial!!");
+ return -1;
+ }
+
+ rpc_data_node->dir = BRPC_DIR_LOCAL;
+ rpc_data_node->rpc_data.rpc_local.proc = proc;
+ rpc_data_node->rpc_data.rpc_local.node = node;
+ brpc_send_trdata(rpc_data_node);
+ return 0;
+}
+static int brpc_binder_dead(uint32_t handle)
+{
+ struct brpc_data_entry *rpc_data_node = NULL;
+
+ rpc_data_node = kzalloc(sizeof(*rpc_data_node), GFP_KERNEL);
+ if (rpc_data_node == NULL) {
+ brpc_err("kzalloc fial!!");
+ return -1;
+ }
+
+ rpc_data_node->dir = BRPC_DIR_UPLINK;
+ rpc_data_node->rpc_data.cmd = BC_DEAD_BINDER_NOTIFY;
+ rpc_data_node->rpc_data.rpc_dead.handle = handle;
+ brpc_send_trdata(rpc_data_node);
+
+ return 0;
+}
+
+static int brpc_binder_transaction(struct binder_rpc_operations_info *ops_info,
+ uint32_t local_handle,
+ void *remote_ptr,
+ void *remote_cookie)
+{
+ struct brpc_data_entry *rpc_data_node = NULL;
+ struct brpc_data *prpc_data;
+ struct flat_binder_object *obj;
+ binder_size_t buffer_offset = 0;
+ binder_size_t off_start_offset, off_end_offset;
+ binder_size_t off_min;
+
+ uint32_t cmd = ops_info->cmd;
+ struct binder_transaction_data *tr = ops_info->tr;
+ binder_uintptr_t priv = ops_info->priv;
+
+ brpc_info("tr cmd:0x%x local_handle:%d handle:%d code:%d",cmd, local_handle, tr->target.handle, tr->code);
+ brpc_info("tr cmd:0x%x",tr->flags);
+ if(0 != tr->target.handle) {
+ rpc_data_node = brpc_tr_convert_rpctr(ops_info,remote_ptr,remote_cookie);
+ if(NULL == rpc_data_node) {
+ return -1;
+ }
+
+ if(0 != local_handle && brpc_update_object_binder(&rpc_data_node->rpc_data, local_handle)) {
+ brpc_err("brpc_update_object_binder(local_handle %d) fail.",local_handle);
+ kfree(rpc_data_node);
+ return -1;
+ }
+
+ brpc_send_trdata(rpc_data_node);
+ }
+
+ return 0;
+}
+
+static int brpc_binder_reply(struct binder_rpc_operations_info *ops_info, uint32_t local_handle)
+{
+ struct brpc_data_entry *rpc_data_node = NULL;
+ struct brpc_data *prpc_data;
+
+ uint32_t cmd = ops_info->cmd;
+ struct binder_transaction_data *tr = ops_info->tr;
+ binder_uintptr_t priv = ops_info->priv;
+
+ brpc_info("tr cmd:0x%x local_handle:%d handle:%d code:%d",cmd, local_handle, tr->target.handle, tr->code);
+
+ rpc_data_node = brpc_tr_convert_rpctr(ops_info, NULL ,NULL);
+ if(NULL == rpc_data_node) {
+ brpc_err("drop this tr.");
+ return -1;
+ }
+ if(0 != local_handle && brpc_update_object_binder(&rpc_data_node->rpc_data, local_handle)) {
+ brpc_err("brpc_update_object_binder(local_handle %d) fail.",local_handle);
+ kfree(rpc_data_node);
+ return -1;
+ }
+
+ brpc_send_trdata(rpc_data_node);
+
+ return 0;
+}
+
+static int brpc_binder_broadcast(struct binder_rpc_operations_info *ops_info, uint32_t local_handle)
+{
+ struct brpc_data_entry *rpc_data_node = NULL;
+ struct brpc_data *prpc_data;
+ struct flat_binder_object *obj;
+ binder_size_t buffer_offset = 0;
+ binder_size_t off_start_offset, off_end_offset;
+ binder_size_t off_min;
+
+ uint32_t cmd = ops_info->cmd;
+ struct binder_transaction_data *tr = ops_info->tr;
+ binder_uintptr_t priv = ops_info->priv;
+
+ brpc_info("tr handle:%d code:%d",tr->target.handle, tr->code);
+ /*broadcat add service*/
+ if(0 == tr->target.handle && ADD_SERVICE_TRANSACTION == tr->code) {
+ rpc_data_node = brpc_tr_convert_rpctr(ops_info, NULL, NULL);
+ if(NULL == rpc_data_node) {
+ brpc_err("brpc_tr_convert_rpctr fail.");
+ return -1;
+ }
+ if(brpc_update_object_binder(&rpc_data_node->rpc_data, local_handle)) {
+ brpc_err("brpc_update_object_binder fail.");
+ kfree(rpc_data_node);
+ return -1;
+ }
+
+ return brpc_send_trdata(rpc_data_node);
+ }
+
+ return 0;
+}
+
+static int brpc_chn_recv_proc(struct brpc_data *prpc_data)
+{
+ struct brpc_data_entry *rpc_data_node;
+
+ rpc_data_node = kzalloc(sizeof(*rpc_data_node), GFP_KERNEL);
+ if (rpc_data_node == NULL) {
+ return -1;
+ }
+ brpc_dbg("cmd=0x%x",prpc_data->cmd);
+ if(BC_TRANSACTION == prpc_data->cmd || BC_REPLY == prpc_data->cmd) {
+ brpc_dbg("target.handle=%d code=%d",prpc_data->rpc_tr.handle, prpc_data->rpc_tr.code);
+ brpc_dbg("data_size=%d offsets_size=%d",prpc_data->rpc_tr.data_size,prpc_data->rpc_tr.offsets_size);
+ }
+ else if(BC_DEAD_BINDER_NOTIFY == prpc_data->cmd) {
+ brpc_dbg("BC_DEAD_BINDER_NOTIFY handle=%d",prpc_data->rpc_dead.handle);
+ }
+ rpc_data_node->dir = BRPC_DIR_DOWNLINK;
+
+ memcpy(&rpc_data_node->rpc_data, prpc_data, sizeof(struct brpc_data));
+
+ return brpc_send_trdata(rpc_data_node);
+}
+
+/*·µ»ØÖµ´óÓÚµÈÓÚ0£¬±íʾдͨµÀ³É¹¦£»Ð¡ÓÚ0±íʾдͨµÀʧ°Ü*/
+static int brpc_chn_write(struct brpc_rpmg_channel *chninfo, void *buf, unsigned int len)
+{
+ T_ZDrvRpMsg_Msg msg;
+
+ if(NULL == buf) {
+ return -EINVAL;
+ }
+ memset(&msg, 0, sizeof(msg));
+ msg.actorID = chninfo->core_id;
+ msg.chID = chninfo->channel_id;
+ msg.flag |= RPMSG_WRITE_INT;
+ msg.buf = buf;
+ msg.len = len;
+
+ return binderWrite(&msg);
+}
+
+static int brpc_chn_receive_thread(void *argv)
+{
+ struct binder_rpc_context *pbrpc_ctx = (struct binder_rpc_context *)argv;
+ T_ZDrvRpMsg_Msg msg;
+ struct brpc_data data;
+
+ int ret;
+
+ memset(&msg, 0, sizeof(msg));
+ msg.actorID = pbrpc_ctx->chn.core_id;
+ msg.chID = pbrpc_ctx->chn.channel_id;
+ msg.flag = 0;
+
+ while(!pbrpc_ctx->chn.channel_stop) {
+ msg.buf = &data;
+ msg.len = sizeof(data);
+
+ ret = binderRead(&msg);
+ if(ret <= 0) {
+ brpc_warn("binderRead ret=%d ", ret);
+ msleep(10000);
+ continue;
+ }
+
+ if(pbrpc_ctx->chn.channel_stop) {
+ break;
+ }
+
+ brpc_chn_recv_proc(&data);
+ }
+
+ return 0;
+}
+
+static int brpc_chn_create(struct binder_rpc_context *pbrpc_ctx)
+{
+ struct task_struct *th = NULL;
+ int retval = 0;
+
+ retval = binderCreateChannel(pbrpc_ctx->chn.core_id, pbrpc_ctx->chn.channel_id, pbrpc_ctx->chn.channel_size);
+ if(retval != RPMSG_SUCCESS && retval != RPMSG_CHANNEL_ALREADY_EXIST) {
+ brpc_err("binderCreateChannel fail.");
+ return retval;
+ }
+
+ th = kthread_run(brpc_chn_receive_thread, (void *)pbrpc_ctx, "brpc-chn%d", pbrpc_ctx->chn.channel_id);
+ if (IS_ERR(th)) {
+ brpc_err("kthread_run fail.");
+ return PTR_ERR(th);
+ }
+ pbrpc_ctx->chn.rcv_thread = th;
+
+ return 0;
+}
+
+static int brpc_write_remote(struct brpc_data *data)
+{
+ struct binder_rpc_context *pbrpc_ctx = &brpc_ctx;
+
+ if(0 > brpc_chn_write(&(pbrpc_ctx->chn), data, sizeof(struct brpc_data))) {
+ brpc_err("brpc_channel_write fail.\n");
+ return -1;
+ }
+ return 0;
+}
+
+static int brpc_thread_enqueue_data(struct brpc_agent_thread_info *pagent_thread, struct brpc_data_entry *rpcdata_node)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&pagent_thread->p_transaction_lock,flags);
+ list_add_tail(&rpcdata_node->list, &pagent_thread->p_transaction_list);
+ spin_unlock_irqrestore(&pagent_thread->p_transaction_lock,flags);
+ brpc_put_sema(&pagent_thread->p_transaction_sem);
+
+ return 0;
+}
+
+static int brpc_send_trdata(struct brpc_data_entry *rpc_data_node)
+{
+ struct binder_rpc_context *pbrpc_ctx = &brpc_ctx;
+
+ return brpc_thread_enqueue_data(&pbrpc_ctx->agent_thread, rpc_data_node);
+}
+
+static int brpc_thread_write(void *brpc_proc,
+ binder_uintptr_t brpc_buffer, size_t size,
+ binder_size_t *consumed)
+{
+ struct binder_proc *proc = brpc_proc;
+ int ret;
+ mm_segment_t old_fs;
+
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+
+ ret = binder_rpc_thread_write(brpc_proc, brpc_buffer, size, consumed);
+
+ set_fs(old_fs);
+
+ return ret;
+}
+
+
+/*·¢ËÍBC_INCREFS/BC_ACQUIRE*/
+static int brpc_agent_write_refs(struct binder_rpc_context *pbrpc_ctx)
+{
+ int ret;
+ binder_size_t consumed = 0;
+ struct {
+ __u32 cmd;
+ __u32 handle;
+ } writebuf;
+
+ writebuf.cmd = BC_INCREFS;
+ writebuf.handle = 0;
+
+ ret = brpc_thread_write(pbrpc_ctx->brpc_proc, (binder_uintptr_t)&writebuf, sizeof(writebuf), &consumed);
+ if(ret) {
+ brpc_err("write BC_INCREFS fail, ret:%d",ret);
+ return -1;
+ }
+ brpc_dbg("BC_INCREFS consumed:%d ",consumed);
+
+ writebuf.cmd = BC_ACQUIRE;
+ writebuf.handle = 0;
+
+ ret = brpc_thread_write(pbrpc_ctx->brpc_proc, (binder_uintptr_t)&writebuf, sizeof(writebuf), &consumed);
+ if(ret) {
+ brpc_err("write BC_ACQUIRE fail, ret:%d",ret);
+ return -1;
+ }
+ brpc_dbg("BC_ACQUIRE consumed:%d ",consumed);
+
+ return 0;
+}
+
+static void brpc_transaction(void *prpc_proc,
+ void *prpc_thread,
+ struct binder_transaction_data *tr, int reply,
+ binder_size_t extra_buffers_size,
+ binder_uintptr_t priv)
+{
+ mm_segment_t old_fs;
+ const char __user *p, *q;
+
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+
+ p = (__force const char __user *)(tr->data.ptr.buffer);
+ q = (__force const char __user *)(tr->data.ptr.offsets);
+
+ binder_rpc_transaction(prpc_proc,
+ prpc_thread,
+ tr,
+ reply,
+ 0,
+ priv);
+
+ set_fs(old_fs);
+}
+
+static void brpc_uld_handle(struct binder_rpc_context *pbrpc_ctx, struct brpc_data *prpc_data)
+{
+ if(BC_TRANSACTION == prpc_data->cmd || BC_REPLY == prpc_data->cmd) {
+ brpc_dbg("BRPC_DIR_UPLINK cmd:0x%x priv:0x%x",prpc_data->cmd,prpc_data->rpc_tr.priv);
+ }
+ else if(BC_DEAD_BINDER_NOTIFY == prpc_data->cmd) {
+ brpc_dbg("BRPC_DIR_UPLINK cmd:0x%x handle:0x%x",prpc_data->cmd,prpc_data->rpc_dead.handle);
+ }
+ else if(BR_ERROR == prpc_data->cmd ||
+ BR_DEAD_REPLY == prpc_data->cmd ||
+ BR_TRANSACTION_COMPLETE == prpc_data->cmd ||
+ BR_DEAD_BINDER == prpc_data->cmd ||
+ BR_CLEAR_DEATH_NOTIFICATION_DONE == prpc_data->cmd ||
+ BR_FAILED_REPLY == prpc_data->cmd) {
+ brpc_dbg("BRPC_DIR_UPLINK cmd:0x%x priv:0x%x",prpc_data->cmd,prpc_data->rpc_reply_error.priv);
+ }
+ else {
+ brpc_err("unknow cmd 0x%x",prpc_data->cmd);
+ }
+ brpc_write_remote(prpc_data);
+}
+static void brpc_dld_handle(struct binder_rpc_context *pbrpc_ctx, struct brpc_data *prpc_data)
+{
+ struct binder_transaction_data tr;
+ struct brpc_transaction_data *prpc_tr = &prpc_data->rpc_tr;
+ binder_uintptr_t priv;
+
+ if(BC_TRANSACTION == prpc_data->cmd || BC_REPLY == prpc_data->cmd) {
+ brpc_dbg("BRPC_DIR_DOWNLINK cmd:0x%x priv:0x%x",prpc_data->cmd,prpc_data->rpc_tr.priv);
+ brpc_rpctr_convert_tr(prpc_data, &tr);
+
+ brpc_transaction(pbrpc_ctx->brpc_proc,
+ pbrpc_ctx->brpc_thread,
+ &tr,
+ BC_REPLY == prpc_data->cmd,
+ 0,
+ prpc_tr->priv);
+
+ if(0 != tr.data.ptr.buffer) {
+ kfree(tr.data.ptr.buffer);
+ }
+ if(0 != tr.data.ptr.offsets) {
+ kfree(tr.data.ptr.offsets);
+ }
+ }
+ else if(BC_DEAD_BINDER_NOTIFY == prpc_data->cmd) {
+ brpc_dbg("BRPC_DIR_DOWNLINK cmd:0x%x handle:0x%x",prpc_data->cmd,prpc_data->rpc_dead.handle);
+ binder_rpc_dead(pbrpc_ctx->brpc_proc, prpc_data->rpc_dead.handle);
+ }
+ else if(BR_ERROR == prpc_data->cmd ||
+ BR_DEAD_REPLY == prpc_data->cmd ||
+ BR_TRANSACTION_COMPLETE == prpc_data->cmd ||
+ BR_DEAD_BINDER == prpc_data->cmd ||
+ BR_CLEAR_DEATH_NOTIFICATION_DONE == prpc_data->cmd ||
+ BR_FAILED_REPLY == prpc_data->cmd) {
+ brpc_dbg("BRPC_DIR_DOWNLINK cmd:0x%x priv:0x%x",prpc_data->cmd,prpc_data->rpc_reply_error.priv);
+ binder_rpc_return_error(pbrpc_ctx->brpc_proc,
+ pbrpc_ctx->brpc_thread,
+ prpc_data->cmd,
+ prpc_data->rpc_reply_error.priv,
+ prpc_data->rpc_reply_error.reply);
+ }
+ else {
+ brpc_err("unknow cmd 0x%x",prpc_data->cmd);
+ }
+}
+
+static void brpc_local_handle(struct binder_rpc_context *pbrpc_ctx, struct brpc_data *prpc_data)
+{
+ binder_rpc_node_release(prpc_data->rpc_local.node);
+}
+
+static int brpc_agent_loop(void *argv)
+{
+ struct binder_rpc_context *pbrpc_ctx = (struct binder_rpc_context *)argv;
+ struct brpc_agent_thread_info *pagent_thread = &pbrpc_ctx->agent_thread;
+ struct list_head tmp_list;
+ struct brpc_data_entry *entry,*tmp_entry;
+ unsigned long flags;
+
+ pbrpc_ctx->brpc_thread = binder_rpc_get_thread(pbrpc_ctx->brpc_proc);
+
+ if(brpc_agent_write_refs(pbrpc_ctx)) {
+ brpc_err("brpc_agent_write_refs fail.");
+ return -1;
+ }
+ INIT_LIST_HEAD(&tmp_list);
+ while(!pagent_thread->bstop) {
+ brpc_get_sema(&pagent_thread->p_transaction_sem);
+
+ spin_lock_irqsave(&pagent_thread->p_transaction_lock,flags);
+ if (list_empty(&pagent_thread->p_transaction_list)) {
+ spin_unlock_irqrestore(&pagent_thread->p_transaction_lock,flags);
+ continue;
+ }
+ list_replace_init(&pagent_thread->p_transaction_list,&tmp_list);
+ list_del_init(&pagent_thread->p_transaction_list);
+ spin_unlock_irqrestore(&pagent_thread->p_transaction_lock,flags);
+
+ list_for_each_entry_safe(entry,tmp_entry,&tmp_list,list) {
+ if(!pagent_thread->bstop) {
+ if(BRPC_DIR_UPLINK == entry->dir) {
+ brpc_uld_handle(pbrpc_ctx, &entry->rpc_data);
+ }
+ else if(BRPC_DIR_DOWNLINK == entry->dir) {
+ brpc_dld_handle(pbrpc_ctx, &entry->rpc_data);
+ }
+ else if(BRPC_DIR_LOCAL == entry->dir) {
+ brpc_local_handle(pbrpc_ctx, &entry->rpc_data);
+ }
+ else {
+ brpc_warn("brpc data unknow dir(%d).",entry->dir);
+ }
+ }
+
+ list_del(&entry->list);
+ kfree(entry);
+ }
+ }
+
+ spin_lock_irqsave(&pagent_thread->p_transaction_lock,flags);
+ list_for_each_entry_safe(entry,tmp_entry,&pagent_thread->p_transaction_list,list) {
+ list_del(&entry->list);
+ kfree(entry);
+ }
+ spin_unlock_irqrestore(&pagent_thread->p_transaction_lock,flags);
+
+ brpc_err("the agnet loop stop!\n");
+
+ return 0;
+}
+
+static int brpc_agent_create(struct binder_rpc_context *pbrpc_ctx)
+{
+ struct brpc_agent_thread_info *pagent_thread = &pbrpc_ctx->agent_thread;
+ struct task_struct *th = NULL;
+ int retval = 0;
+
+ INIT_LIST_HEAD(&pagent_thread->p_transaction_list);
+ spin_lock_init(&pagent_thread->p_transaction_lock);
+ brpc_init_sema(&pagent_thread->p_transaction_sem, 0);
+
+ th = kthread_run(brpc_agent_loop, (void *)pbrpc_ctx, "brpc-agent");
+ if (IS_ERR(th)) {
+ brpc_err("kthread_run fail.");
+ return PTR_ERR(th);
+ }
+
+ pagent_thread->p_thread = th;
+
+ return 0;
+}
+
+int binder_rpc_init(void *proc, struct file *pfile, struct binder_rpc_operations_struct *cb)
+{
+ struct binder_rpc_context *pbrpc_ctx = &brpc_ctx;
+ int ret = 0;
+
+ memset(pbrpc_ctx, 0, sizeof(struct binder_rpc_context));
+
+ pbrpc_ctx->brpc_proc = proc;
+ pbrpc_ctx->prpc_file = pfile;
+
+ pbrpc_ctx->chn.core_id = CAP_ID;
+ pbrpc_ctx->chn.channel_id = ICP_CHN_BINDER_RPC;
+ pbrpc_ctx->chn.channel_size = ICP_CHN_BINDER_RPC_SIZE;
+
+ if(brpc_chn_create(pbrpc_ctx)) {
+ brpc_err("brpc_chn_create fail.");
+ return -1;
+ }
+
+ if(brpc_agent_create(pbrpc_ctx)) {
+ brpc_err("brpc_agent_create fail.");
+ return -1;
+ }
+
+ if(NULL != cb) {
+ memset(cb, 0, sizeof(struct binder_rpc_operations_struct));
+ cb->binder_transaction = brpc_binder_transaction;
+ cb->binder_broadcast = brpc_binder_broadcast;
+ cb->binder_reply = brpc_binder_reply;
+ cb->binder_return_error = brpc_binder_return_error;
+ cb->binder_release = brpc_binder_release;
+ cb->binder_dead_notify = brpc_binder_dead;
+ }
+
+ brpc_info("success!");
+
+ return 0;
+}
+
+int binder_rpc_deinit(struct vm_area_struct *vma)
+{
+ struct binder_rpc_context *pbrpc_ctx = &brpc_ctx;
+
+ pbrpc_ctx->chn.channel_stop = 1;
+ pbrpc_ctx->agent_thread.bstop = 1;
+
+ if(pbrpc_ctx->prpc_file) {
+ filp_close(pbrpc_ctx->prpc_file, current->files);
+
+ if(NULL != vma) {
+ do_munmap(current->mm, vma->vm_start, vma->vm_end - vma->vm_start);
+ }
+ }
+
+ brpc_info("success!");
+
+ return 0;
+}
+
diff --git a/ap/os/linux/linux-3.4.x/drivers/staging/android/binder_rpc.h b/ap/os/linux/linux-3.4.x/drivers/staging/android/binder_rpc.h
new file mode 100755
index 0000000..7315494
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/staging/android/binder_rpc.h
@@ -0,0 +1,51 @@
+#ifndef _LINUX_BINDER_RPC_H
+#define _LINUX_BINDER_RPC_H
+
+#include "binder.h"
+
+typedef __u32 binder_size_t;
+typedef __u32 binder_uintptr_t;
+
+enum {
+ GET_SERVICE_TRANSACTION = 0x00000001,
+ CHECK_SERVICE_TRANSACTION,
+ ADD_SERVICE_TRANSACTION,
+ LIST_SERVICES_TRANSACTION,
+};
+
+struct binder_rpc_operations_info {
+ uint32_t cmd;
+ struct binder_transaction_data *tr;
+ binder_uintptr_t priv;
+};
+
+struct binder_rpc_operations_struct {
+ int (*binder_broadcast)(struct binder_rpc_operations_info *ops_info, uint32_t local_handle);
+ int (*binder_reply)(struct binder_rpc_operations_info *ops_info, uint32_t local_handle);
+ int (*binder_transaction)(struct binder_rpc_operations_info *ops_info, uint32_t local_handle, void *remote_ptr, void *remote_cookie);
+ int (*binder_return_error)(struct binder_rpc_operations_info *ops_info, int reply);
+ int (*binder_release)(void *proc, void *node);
+ int (*binder_dead_notify)(uint32_t handle);
+};
+
+int binder_rpc_init(void *proc, struct file *pfile, struct binder_rpc_operations_struct *cb);
+int binder_rpc_deinit(struct vm_area_struct *vma);
+int binder_rpc_thread_write(void *brpc_proc,
+ binder_uintptr_t brpc_buffer, size_t size,
+ binder_size_t *consumed);
+void *binder_rpc_get_thread(void *brpc_proc);
+void binder_rpc_transaction(void *prpc_proc,
+ void *prpc_thread,
+ struct binder_transaction_data *tr, int reply,
+ binder_size_t extra_buffers_size,
+ binder_uintptr_t priv);
+void binder_rpc_node_release(void *node);
+void binder_rpc_dead(void *brpc_proc, uint32_t handle);
+void binder_rpc_return_error(void *brpc_proc,
+ void *prpc_thread,
+ uint32_t return_error,
+ binder_uintptr_t priv,
+ int reply);
+
+
+#endif /* _LINUX_BINDER_RPC_H*/
diff --git a/ap/os/linux/linux-3.4.x/drivers/staging/android/binder_rpc_common.h b/ap/os/linux/linux-3.4.x/drivers/staging/android/binder_rpc_common.h
new file mode 100755
index 0000000..5541022
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/staging/android/binder_rpc_common.h
@@ -0,0 +1,126 @@
+#ifndef _LINUX_BINDER_RPC_COMM_H
+#define _LINUX_BINDER_RPC_COMM_H
+
+#include <linux/interrupt.h>
+#include <linux/kthread.h>
+#include <linux/spinlock.h>
+#include <linux/semaphore.h>
+#include <linux/soc/zte/rpm/rpmsg.h>
+
+#include <binder.h>
+
+int brpc_debug = 0;
+module_param(brpc_debug,int,0644);
+
+#define brpc_dbg(format, arg...) if(brpc_debug == 1) \
+ printk(KERN_INFO " [brpc]<%s>: " format "\n" , __func__ , ## arg)
+#define brpc_info(format, arg...) if(brpc_debug == 1) \
+ printk(KERN_INFO " [brpc]<%s>: " format "\n" , __func__ , ## arg)
+
+#define brpc_err(format, arg...) printk(KERN_ERR " [brpc]<%s>: " format "\n" , \
+ __func__ , ## arg)
+
+#define brpc_warn(format, arg...) printk(KERN_WARNING " [brpc]<%s>: " format "\n" , \
+ __func__ , ## arg)
+
+/*local data ,to remote,need write rpmsg channel*/
+#define BRPC_DIR_UPLINK 1
+/*remote data ,to local,read from rpmsg channel*/
+#define BRPC_DIR_DOWNLINK 2
+#define BRPC_DIR_LOCAL 3
+
+#define ICP_CHN_BINDER_RPC 33
+#define ICP_CHN_BINDER_RPC_SIZE (8 * 1024 *2)
+#define binderCreateChannel zDrvRpMsg_CreateChannel_Cap
+#define binderWrite zDrvRpMsg_Write_Cap
+#define binderRead zDrvRpMsg_Read_Cap
+
+struct brpc_rpmg_channel {
+ T_ZDrvRpMsg_ActorID core_id;
+ T_ZDrvRpMsg_ChID channel_id;
+ unsigned int channel_size;
+ struct task_struct *rcv_thread;
+ int channel_stop;
+};
+
+/*thread proxy list*/
+struct brpc_agent_thread_info {
+ struct task_struct *p_thread;
+ struct list_head p_transaction_list;
+ struct spinlock p_transaction_lock;
+ struct semaphore p_transaction_sem;
+
+ int bstop;
+};
+
+struct binder_rpc_context {
+ void *brpc_proc;
+ void *brpc_thread;
+ struct file *prpc_file;
+ struct brpc_agent_thread_info agent_thread;
+ struct brpc_rpmg_channel chn;
+ //struct list_head svc_list;
+};
+
+struct brpc_transaction_data {
+ union {
+ /*cmd == BC_TRANSACTION*/
+ binder_uintptr_t local_tr;
+ /*cmd == BC_REPLY*/
+ binder_uintptr_t remote_tr;
+
+ binder_uintptr_t priv;
+ };
+ __u32 handle; /* target descriptor of command transaction */
+ binder_uintptr_t cookie; /* target object cookie */
+ __u32 code; /* transaction command */
+
+ /* General information about the transaction. */
+ __u32 flags;
+
+ binder_size_t data_size; /* number of bytes of data */
+ binder_size_t offsets_size; /* number of bytes of offsets */
+#define BRPC_TR_BUFFER_SIZE_MAX 256
+ char buffer[BRPC_TR_BUFFER_SIZE_MAX];
+ char offsets[BRPC_TR_BUFFER_SIZE_MAX];
+};
+
+struct brpc_ref_data {
+ uint32_t target;
+};
+
+struct brpc_local_data {
+ void *proc;
+ void *node;
+};
+
+struct brpc_dead_data {
+ uint32_t handle;
+};
+
+struct brpc_reply_error_data {
+ binder_uintptr_t priv;
+ int reply;
+};
+
+struct brpc_data {
+ /*BC_## command*/
+ uint32_t cmd;
+ union {
+ struct brpc_ref_data rpc_ref;
+ struct brpc_transaction_data rpc_tr;
+ struct brpc_local_data rpc_local;
+ struct brpc_dead_data rpc_dead;
+ struct brpc_reply_error_data rpc_reply_error;
+ };
+};
+
+struct brpc_data_entry {
+ struct list_head list;
+ /*BRPC_DIR_UPLINK / BRPC_DIR_DOWNLINK/*/
+ uint32_t dir;
+ struct brpc_data rpc_data;
+};
+
+#endif /* _LINUX_BINDER_RPC_COMM_H*/
+
diff --git a/ap/os/linux/linux-3.4.x/drivers/tty/serial/zx29_uart.c b/ap/os/linux/linux-3.4.x/drivers/tty/serial/zx29_uart.c
index eed941f..2c0496b 100755
--- a/ap/os/linux/linux-3.4.x/drivers/tty/serial/zx29_uart.c
+++ b/ap/os/linux/linux-3.4.x/drivers/tty/serial/zx29_uart.c
@@ -1825,10 +1825,10 @@
}
if(fifo_len){
- printk("qq >> fifo len %d.\n",fifo_len);
+ //printk("qq >> fifo len %d.\n",fifo_len);
fifo_count = tty_insert_flip_string(&zup->port.state->port,
fifo_buf, fifo_len);
- printk("qq >>fifo count %d,buf is %x %x %x .\n",fifo_count, fifo_buf[0],fifo_buf[1],fifo_buf[2]);
+ //printk("qq >>fifo count %d,buf is %x %x %x .\n",fifo_count, fifo_buf[0],fifo_buf[1],fifo_buf[2]);
fifo_buf[0] = '\0';
fifo_buf[1] = '\0';
fifo_buf[2] = '\0';
diff --git a/ap/os/linux/linux-3.4.x/drivers/usb/gadget/adb_server.c b/ap/os/linux/linux-3.4.x/drivers/usb/gadget/adb_server.c
index ff872df..a71960d 100755
--- a/ap/os/linux/linux-3.4.x/drivers/usb/gadget/adb_server.c
+++ b/ap/os/linux/linux-3.4.x/drivers/usb/gadget/adb_server.c
@@ -439,7 +439,7 @@
adb_server_plug_notify(USB_RPMSG_NOTIFY_ADB_ONLINE);
dev->agent_start = 1;
dev->agt_error = 0;
- //wake_up(&dev->agt_start_wait);
+ wake_up(&dev->agt_start_wait);
//wakeup adb read and return
//dev->rx_done = 1;
//wake_up(&dev->read_wq);
@@ -476,6 +476,10 @@
printk("adb_enable_rpmsg_agent, adb is NULL, fail\n");
return -1;
}
+ if(g_adb_agent->adb_ready == 0){
+ printk("adb_enable_rpmsg_agent, adb has not init ok, return\n");
+ return;
+ }
g_adb_agent->agent_state = ((flag != 0) ? 1 : 0);
atomic_set(&g_adb_agent->agent_switch, 1);
printk("adb_enable_rpmsg_agent,now %s adb agent\n", (g_adb_agent->agent_state == 1) ? "start" : "stop");
@@ -552,7 +556,7 @@
pr_debug("rpmsg_recv: failed to queue req %p (%d)\n", req, ret);
r = -EIO;
dev->agt_error = 1;
- printk("rpmsg_recv ep-queue fail ret:%d", r);
+ USBSTACK_DBG("rpmsg_recv ep-queue fail ret:%d", r);
goto done;
} else {
USBSTACK_DBG("rx %p queue\n", req);
diff --git a/ap/os/linux/linux-3.4.x/drivers/usb/gadget/f_adb.c b/ap/os/linux/linux-3.4.x/drivers/usb/gadget/f_adb.c
index 9561ca8..3a506fc 100755
--- a/ap/os/linux/linux-3.4.x/drivers/usb/gadget/f_adb.c
+++ b/ap/os/linux/linux-3.4.x/drivers/usb/gadget/f_adb.c
@@ -88,7 +88,9 @@
#endif
struct work_struct online_inform; /* online inform USB adb */
struct work_struct offline_inform; /* offline inform USB adb */
-
+
+ //this flag means adb is ok
+ int adb_ready;
#ifdef CONFIG_PM
u32 suspend_state;
#endif
@@ -734,9 +736,18 @@
usb_ep_disable(dev->ep_in);
return ret;
}
+
+ dev->adb_ready = 1;
+
#ifdef _USE_VEHICLE_DC
//maybe need clear adb server state
adb_agent_close();
+ if(usb_get_adb_agent() == 1){
+ //delay time is num of jiffies
+ printk("---adb_function_set_alt, switch to cap\n");
+ dev->online = 1;
+ schedule_delayed_work(&_adb_dev->agent_switch_work, 0);
+ }else
#endif
schedule_work(&dev->online_inform);
@@ -750,7 +761,6 @@
/* readers may be blocked waiting for us to go online */
wake_up(&dev->read_wq);
}
-
return 0;
}
@@ -761,6 +771,7 @@
USBSTACK_DBG("%s", __func__);
+ dev->adb_ready = 0;
if(atomic_read(&dev->enable_excl)==0)
return;
else
diff --git a/ap/os/linux/linux-3.4.x/drivers/usb/gadget/usb_netlink.c b/ap/os/linux/linux-3.4.x/drivers/usb/gadget/usb_netlink.c
index 7e53a63..b2f470f 100755
--- a/ap/os/linux/linux-3.4.x/drivers/usb/gadget/usb_netlink.c
+++ b/ap/os/linux/linux-3.4.x/drivers/usb/gadget/usb_netlink.c
@@ -1020,6 +1020,11 @@
switch_mode = USB_SWITCH_DEBUG;
usb_record_dbginfo(USB_SWITCH_TO_DEBUG, 0, 0);
schedule_work(&switch_usbmode);
+ //if boot from user mode, this flag doesn't set
+ if(adb_agent_state == 0){
+ printk("usb_parse_cap_notify,set debug mode, set adb_agent_state \n");
+ adb_agent_state =1;
+ }
break;
case USB_RPMSG_SWITCH_USER_MODE:
if(switch_mode == USB_SWITCH_USER){
diff --git a/ap/os/linux/linux-3.4.x/fs/open.c b/ap/os/linux/linux-3.4.x/fs/open.c
old mode 100644
new mode 100755
index cf1d34f..ece5fe5
--- a/ap/os/linux/linux-3.4.x/fs/open.c
+++ b/ap/os/linux/linux-3.4.x/fs/open.c
@@ -33,6 +33,10 @@
#include "internal.h"
+#ifdef CONFIG_SYSVIPC_CROSS_SHM
+#include <../ipc/shm_ctrl.h>
+#endif
+
int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs,
struct file *filp)
{
@@ -977,7 +981,9 @@
int lookup = build_open_flags(flags, mode, &op);
char *tmp = getname(filename);
int fd = PTR_ERR(tmp);
-
+#ifdef CONFIG_SYSVIPC_CROSS_SHM
+ char *ptr = NULL;
+#endif
if (!IS_ERR(tmp)) {
fd = get_unused_fd_flags(flags);
if (fd >= 0) {
@@ -988,6 +994,16 @@
} else {
fsnotify_open(f);
fd_install(fd, f);
+#ifdef CONFIG_SYSVIPC_CROSS_SHM
+ ptr = strrchr(tmp, '/');
+ if (ptr)
+ {
+ if (strncmp(ptr + 1, "remote-", strlen("remote-"))== 0)
+ {
+ f->shm_flags = SHM_REMOTE_POSIX_YES;
+ }
+ }
+#endif
}
}
putname(tmp);
diff --git a/ap/os/linux/linux-3.4.x/include/linux/fs.h b/ap/os/linux/linux-3.4.x/include/linux/fs.h
old mode 100644
new mode 100755
index 210c347..463df11
--- a/ap/os/linux/linux-3.4.x/include/linux/fs.h
+++ b/ap/os/linux/linux-3.4.x/include/linux/fs.h
@@ -1021,6 +1021,9 @@
#ifdef CONFIG_DEBUG_WRITECOUNT
unsigned long f_mnt_write_state;
#endif
+#ifdef CONFIG_SYSVIPC_CROSS_SHM
+ unsigned int shm_flags;
+#endif
};
struct file_handle {
diff --git a/ap/os/linux/linux-3.4.x/include/linux/net.h b/ap/os/linux/linux-3.4.x/include/linux/net.h
old mode 100644
new mode 100755
index 16b4996..f323b7d
--- a/ap/os/linux/linux-3.4.x/include/linux/net.h
+++ b/ap/os/linux/linux-3.4.x/include/linux/net.h
@@ -148,6 +148,10 @@
struct socket_wq __rcu *wq;
struct file *file;
+#ifdef CONFIG_IPC_SOCKET
+ int fd;
+ struct hlist_head peer;
+#endif
struct sock *sk;
const struct proto_ops *ops;
};
diff --git a/ap/os/linux/linux-3.4.x/include/linux/socket.h b/ap/os/linux/linux-3.4.x/include/linux/socket.h
old mode 100644
new mode 100755
index 9b54ebe..cc1afdc
--- a/ap/os/linux/linux-3.4.x/include/linux/socket.h
+++ b/ap/os/linux/linux-3.4.x/include/linux/socket.h
@@ -343,5 +343,6 @@
unsigned int flags, struct timespec *timeout);
extern int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg,
unsigned int vlen, unsigned int flags);
+
#endif /* not kernel and not glibc */
#endif /* _LINUX_SOCKET_H */
diff --git a/ap/os/linux/linux-3.4.x/include/linux/socket_rpmsg.h b/ap/os/linux/linux-3.4.x/include/linux/socket_rpmsg.h
new file mode 100755
index 0000000..c6a9292
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/include/linux/socket_rpmsg.h
@@ -0,0 +1,227 @@
+#ifndef SOCKET_RPMSG_H
+#define SOCKET_RPMSG_H
+
+#include <linux/interrupt.h>
+#include <linux/kthread.h>
+#include <linux/spinlock.h>
+#include <linux/semaphore.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/un.h>
+#include <linux/types.h>
+#include <linux/soc/zte/rpm/rpmsg.h>
+
+#include <net/sock.h>
+
+extern int socket_rpmsg_debug;
+
+#define sk_soc_dbg(format, arg...) if(socket_rpmsg_debug == 1) \
+ printk(KERN_DEBUG "[socket_rpmsg]<%s>: " format "\n" ,__func__ , ## arg)
+#define sk_soc_info(format, arg...) if(socket_rpmsg_debug == 1) \
+ printk(KERN_INFO "[socket_rpmsg]<%s>: " format "\n" ,__func__ , ## arg)
+
+#define sk_soc_err(format, arg...) printk(KERN_ERR "[socket_rpmsg]<%s>: " format "\n" , \
+ __func__ , ## arg)
+
+#define sk_soc_warn(format, arg...) printk(KERN_WARNING "[socket_rpmsg]<%s>: " format "\n" , \
+ __func__ , ## arg)
+
+
+
+#define ICP_CHANNEL_SIZE (16 * 1024)
+
+/*remote data ,to local,read from rpmsg channel*/
+#define DIR_UPLINK 1
+/*local data ,to remote,need write rpmsg channel*/
+#define DIR_DOWNLINK 2
+#define sockSocCreateChannel zDrvRpMsg_CreateChannel_Cap
+#define sockSocWrite zDrvRpMsg_Write_Cap
+#define sockSocRead zDrvRpMsg_Read_Cap
+
+#define SOCK_OP_RESULT 0
+
+extern spinlock_t sock_table_lock;
+extern spinlock_t sock_rpmsg_table_lock;
+extern spinlock_t sock_socket_table_lock;
+extern spinlock_t sock_release_table_lock;
+extern spinlock_t sock_release_lock;
+extern spinlock_t sock_release_peer_lock;
+typedef enum _soc_msg_type
+{
+ MSG_TYPE_FIND = 0,
+ MSG_TYPE_FIND_RESULT,
+ MSG_TYPE_ADD_WAIT_QUEUE,
+ MSG_TYPE_REMOVE_WAIT_QUEUE,
+ MSG_TYPE_SYNC_IPC_SOCKET,
+ MSG_TYPE_WAIT_FOR_PEER,
+ MSG_TYPE_DATA_READY,
+ MSG_TYPE_SEND_MSG,
+ MSG_TYPE_SET_PEER,
+ MSG_TYPE_UPDATE_PEER,
+ MSG_TYPE_SOCK_PUT,
+ MSG_TYPE_ADD_SKB_QUEUE_TAIL,
+ MSG_TYPE_RECVQ_FULL,
+ MSG_TYPE_RECVQ_FULL_RESULT,
+ MSG_TYPE_RECVQ_FULL_LOCKLESS_AND_DEAD,
+ MSG_TYPE_RECVQ_FULL_LOCKLESS_AND_DEAD_RESULT,
+ MSG_TYPE_PEER_CLEAR,
+ MSG_TYPE_WAKE_UP_INTERRUPTIBLE_POLL,
+ MSG_TYPE_TEST_FLAG,
+ MSG_TYPE_TEST_FLAG_RESULT,
+ MSG_TYPE_GET_SOCKET_STATES,
+ MSG_TYPE_GET_SOCKET_STATES_RESULT,
+ MSG_TYPE_STREAM_CONNECT, //21
+ MSG_TYPE_SOCKET_RELEASE, //22
+ MSG_TYPE_DGRAM_DISCONNECTED,
+ MSG_TYPE_STATE_LOCK,
+ MSG_TYPE_STATE_UNLOCK,
+ MSG_TYPE_SOCK_HOLD,
+ MSG_TYPE_RELEASE_PEER,
+ MSG_TYPE_NOTIFY_PROXY_CHANGE,
+}soc_msg_type;
+
+struct sock_thread_info {
+ struct task_struct *p_thread;
+ struct list_head p_sock_list;
+ struct spinlock p_sock_lock;
+ struct semaphore p_sock_sem;
+
+ int bstop;
+};
+
+struct sock_channel {
+ T_ZDrvRpMsg_ActorID core_id;
+ T_ZDrvRpMsg_ChID channel_id;
+ unsigned int channel_size;
+ //struct task_struct *rcv_thread;
+ //struct task_struct *main_thread;
+ struct sock_thread_info recv_thread_info;
+ struct sock_thread_info main_thread_info;
+};
+
+struct sock_elem_flag {
+ int sk_err;
+ int sk_error_report;
+ int skstate;
+ u8 skshutdown;
+};
+
+struct sock_rpmsg
+{
+ struct list_head list;
+ soc_msg_type msg_type;
+ uint32_t dir;
+ struct sockaddr_un sockaddr;
+ int addr_len;
+ int socktype;
+ unsigned int hash;
+ struct sock_elem_flag elem;
+ //struct sock sock;
+ int clientfd;
+ int serverfd;
+ int clientproxyfd;
+ int serverproxyfd;
+ int newclientfd;
+ void* clientsock; //ÀàÐÍΪstruct socket
+ void* serversock; //ÀàÐÍΪstruct socket
+ void* newsock;
+ void* clientproxysock; //ÀàÐÍΪstruct socket
+ void* serverproxysock; //ÀàÐÍΪstruct socket
+ int result;
+ enum sock_flags flag;
+ unsigned long flags;
+ long timeo;
+ unsigned int msg_flags;
+ int isfistfind;
+ void* key;
+ unsigned int index;
+ int data_len;
+ unsigned char data[0];
+};
+
+struct ipc_socket
+{
+ struct hlist_node hlist_node;
+ struct socket* socket;
+ struct sock* sock;
+ int socktype;
+ int localfd; //±¾µØ¿Í»§¶Ëfd
+ int sockfd; //±¾µØ´úÀísocketµÄfd
+ int remotefd; //¶ÔÓ¦Ô¶¶ËʵÌåµÄfd
+ int remoteproxyfd; //¶ÔÓ¦Ô¶¶Ë´úÀíµÄ fd
+ struct socket* localsocket; //±¾µØ¿Í»§¶Ësocket
+ struct socket* proxysocket; //±¾µØ´úÀísocket
+ struct socket* remotesocket; //¶ÔÓ¦Ô¶¶ËʵÌåµÄsocket
+ struct socket* remoteproxysocket; //¶ÔÓ¦Ô¶¶Ë´úÀíµÄsocket
+ void* key;
+};
+
+struct sock_rpmsg_info
+{
+ struct hlist_node hlist_node;
+ struct sock_rpmsg sock_rpmsg;
+ struct semaphore sock_sem;
+ struct ipc_socket * ipc_socket;
+ void* key; //±êʶrpmsgµÄ¹Ø¼ü×Ö
+};
+
+struct peer_sock_info
+{
+ int fd;
+ int peerfd;
+ struct sock* sock;
+ struct sock* peersock;
+ long timeo;
+};
+
+struct release_socket{
+ struct list_head list_node;
+#if 0
+ struct socket* sock;
+ int clientfd;
+ void* clientsock;
+#endif
+ int localfd; //¿Í»§¶Ëfd
+ int proxyfd; //±¾µØ´úÀísocketµÄfd
+ int remotefd; //¶ÔÓ¦Ô¶¶ËʵÌåµÄfd
+ struct socket* localsocket; //±¾µØ¿Í»§¶Ësocket
+ struct socket* proxysocket; //±¾µØ´úÀísocket
+ struct socket* remotesocket; //¶ÔÓ¦Ô¶¶ËʵÌåµÄsocket
+ struct socket* remoteproxysocket; //¶ÔÓ¦´úÀíµÄsocket
+};
+
+//´æ·ÅËùÓвÎÓë½»»¥µÄsocketµØÖ·
+struct socket_info{
+ struct hlist_node hlist_node;
+ struct socket* proxysocket;
+ struct socket* localsocket;
+};
+
+int sock_soc_recvq_full(const struct sock *sk);
+int sock_soc_set_peer(struct sock *sock, struct sock *other);
+int sock_soc_sock_put(struct sock *other);
+int sock_soc_msg_send(struct sock *sock, struct sock *other, struct msghdr *msg, size_t len);
+long sock_wait_for_peer(struct sock *sock, struct sock *other, long timeo);
+int sock_soc_sk_data_ready(struct sock *sk);
+int sock_sync_ipc_socket(struct sock_elem_flag* elem_flag, struct sock *other);
+void sock_soc_add_skb_queue_tail(struct sock *sock, struct sock *other);
+void sock_soc_add_wait_queue(struct sock *sock, struct sock *other);
+void sock_soc_remove_wait_queue(struct sock *sock, struct sock *other);
+struct sock *sock_soc_find_other(struct socket* socket,
+ struct sockaddr_un *sunname, int len,
+ int type, unsigned int hash, int *error);
+int unix_is_ipc_socket(struct sock *sock);
+int unix_is_ipc_local_socket(struct sock *sock);
+int sock_soc_test_flags(struct sock *other, enum sock_flags flag);
+int sock_soc_recvq_full_lockless_and_dead(const struct sock *other);
+int sock_soc_get_state(struct sock_elem_flag* elem_flag, struct sock *other);
+void sock_soc_stream_connect(struct sock *sock, struct sock *other, struct sockaddr_un *sunname, int len,int flags);
+int sock_soc_update_peer(struct socket *sock, struct socket *newsock);
+int sock_soc_dgram_disconnected(struct sock *sock, struct sock *other);
+void sock_soc_state_lock(struct sock *other);
+void sock_soc_state_unlock(struct sock *other);
+void sock_soc_delay_release(struct socket *sock);
+void sock_soc_sock_hold(struct sock *other);
+
+#endif
+
diff --git a/ap/os/linux/linux-3.4.x/include/net/af_unix.h b/ap/os/linux/linux-3.4.x/include/net/af_unix.h
old mode 100644
new mode 100755
index ca68e2c..d997e45
--- a/ap/os/linux/linux-3.4.x/include/net/af_unix.h
+++ b/ap/os/linux/linux-3.4.x/include/net/af_unix.h
@@ -5,6 +5,9 @@
#include <linux/un.h>
#include <linux/mutex.h>
#include <net/sock.h>
+#ifdef CONFIG_IPC_SOCKET
+#include <linux/socket_rpmsg.h>
+#endif
extern void unix_inflight(struct file *fp);
extern void unix_notinflight(struct file *fp);
@@ -60,6 +63,9 @@
unsigned int gc_maybe_cycle : 1;
unsigned char recursion_level;
struct socket_wq peer_wq;
+#ifdef CONFIG_IPC_SOCKET
+ struct release_socket rsock;
+#endif
};
#define unix_sk(__sk) ((struct unix_sock *)__sk)
diff --git a/ap/os/linux/linux-3.4.x/include/net/sock.h b/ap/os/linux/linux-3.4.x/include/net/sock.h
index efab120..7f2098b 100755
--- a/ap/os/linux/linux-3.4.x/include/net/sock.h
+++ b/ap/os/linux/linux-3.4.x/include/net/sock.h
@@ -85,6 +85,16 @@
{
}
#endif
+
+#ifdef CONFIG_IPC_SOCKET
+extern int socket_rpmsg_debug;
+
+#define sk_soc_dbg(format, arg...) if(socket_rpmsg_debug == 1) \
+ printk(KERN_DEBUG "[socket_rpmsg]<%s>: " format "\n" ,__func__ , ## arg)
+#define sk_soc_info(format, arg...) if(socket_rpmsg_debug == 1) \
+ printk(KERN_INFO "[socket_rpmsg]<%s>: " format "\n" ,__func__ , ## arg)
+
+#endif
/*
* This structure really needs to be cleaned up.
* Most of it is for TCP, and not used by any of
@@ -127,6 +137,15 @@
struct proto;
struct net;
+#ifdef CONFIG_IPC_SOCKET
+
+enum sock_flags;
+extern int unix_is_ipc_socket(struct sock *sock);
+extern int sock_soc_test_flags(struct sock *other, enum sock_flags flag);
+extern int sock_soc_sock_put(struct sock *other);
+extern void sock_soc_sock_hold(struct sock *other);
+
+#endif
/**
* struct sock_common - minimal network layer representation of sockets
* @skc_daddr: Foreign IPv4 addr
@@ -382,6 +401,12 @@
int (*sk_backlog_rcv)(struct sock *sk,
struct sk_buff *skb);
void (*sk_destruct)(struct sock *sk);
+#ifdef CONFIG_IPC_SOCKET
+ int ipc_flag;
+ int sk_fd;
+ struct sock* proxy_sock;
+ u8 closed;
+#endif
};
static inline int sk_peek_offset(struct sock *sk, int flags)
@@ -495,6 +520,9 @@
static inline void sock_hold(struct sock *sk)
{
atomic_inc(&sk->sk_refcnt);
+#ifdef CONFIG_IPC_SOCKET
+ sk_soc_dbg("sock_hold sk=%x, sk->sk_refcnt=%d\n", sk, sk->sk_refcnt);
+#endif
}
/* Ungrab socket in the context, which assumes that socket refcnt
@@ -502,6 +530,9 @@
*/
static inline void __sock_put(struct sock *sk)
{
+#ifdef CONFIG_IPC_SOCKET
+ sk_soc_dbg("__sock_put sk=%x, sk->sk_refcnt=%d\n",sk, sk->sk_refcnt);
+#endif
atomic_dec(&sk->sk_refcnt);
}
@@ -629,6 +660,10 @@
* Will use last 4 bytes of packet sent from
* user-space instead.
*/
+#ifdef CONFIG_IPC_SOCKET
+ SOCK_IPCSOCK, /*Indicates whether it is a cross core socket */
+ SOCK_IPC_LOCAL,
+#endif
};
static inline void sock_copy_flags(struct sock *nsk, struct sock *osk)
@@ -648,7 +683,16 @@
static inline int sock_flag(struct sock *sk, enum sock_flags flag)
{
+#ifdef CONFIG_IPC_SOCKET
+ if(unix_is_ipc_socket(sk)){
+ return sock_soc_test_flags(sk, flag);
+ }
+ else{
+#endif
return test_bit(flag, &sk->sk_flags);
+#ifdef CONFIG_IPC_SOCKET
+ }
+#endif
}
static inline void sk_acceptq_removed(struct sock *sk)
@@ -1586,7 +1630,10 @@
}
static inline void sk_set_socket(struct sock *sk, struct socket *sock)
-{
+{
+#ifdef CONFIG_IPC_SOCKET
+ sk_soc_dbg("sk_set_socket sk=%x, sock=%x \n", sk, sock);
+#endif
sk_tx_queue_clear(sk);
sk->sk_socket = sock;
}
diff --git a/ap/os/linux/linux-3.4.x/ipc/shm.c b/ap/os/linux/linux-3.4.x/ipc/shm.c
index 47d3255..8bf7f7b 100755
--- a/ap/os/linux/linux-3.4.x/ipc/shm.c
+++ b/ap/os/linux/linux-3.4.x/ipc/shm.c
@@ -72,11 +72,6 @@
static int sysvipc_shm_proc_show(struct seq_file *s, void *it);
#endif
-#ifdef CONFIG_SYSVIPC_CROSS_SHM
-extern int shm_remote_free_pages(struct vm_area_struct *unmap_vma);
-extern int shm_do_remote_map_vma(struct vm_area_struct *vma, key_t key);
-#endif
-
void shm_init_ns(struct ipc_namespace *ns)
{
ns->shm_ctlmax = SHMMAX;
@@ -150,20 +145,50 @@
}
#ifdef CONFIG_SYSVIPC_CROSS_SHM
-void shm_mmap_pagetable(struct vm_area_struct *vma, struct file *file)
+key_t shm_do_remote_analy_key(struct file *file)
{
- int ret = 0;
+ key_t key = 0;
+ char *shm_name = NULL;
struct shm_file_data *sfd;
struct shmid_kernel *shp;
+ struct path *shm_path = NULL;
+ struct dentry *shm_dentry = NULL;
- sfd = shm_file_data(file);
- shp = shm_lock(sfd->ns, sfd->id);
+ if (file && (file->shm_flags == SHM_REMOTE_SYSV_YES))
+ {
+ sfd = shm_file_data(file);
+ shp = shm_lock(sfd->ns, sfd->id);
+ key = shp->shm_perm.key;
+ shm_unlock(shp);
+ }
+ else if (file && (file->shm_flags == SHM_REMOTE_POSIX_YES))
+ {
+ shm_path = &file->f_path;
+
+ if(shm_path && (shm_path->dentry))
+ {
+ shm_name = shm_path->dentry->d_name.name;
+ if (!shm_name)
+ panic("shm_posix_mmap_pagetable name is NULL\n");
+ }
+ key = shm_hash_name_to_key(shm_name, strlen(shm_name));
+ }
+ return key;
+}
- ret = shm_do_remote_map_vma(vma, shp->shm_perm.key);
+int shm_ipc_mmap_pagetable(struct vm_area_struct *vma, struct file *file)
+{
+ int ret = 0;
+ key_t shm_key = 0;
+
+ shm_key = shm_do_remote_analy_key(file);
+ ret = shm_do_remote_map_vma(vma, shm_key);
if (ret < 0)
- printk("shm_mmap_pagetable Error");
-
- shm_unlock(shp);
+ {
+ printk("shm_ipc_mmap_pagetable Error: No Mem\n");
+ return -ENOMEM;
+ }
+ return ret;
}
#endif
@@ -266,10 +291,7 @@
shp->shm_lprid = task_tgid_vnr(current);
shp->shm_dtim = get_seconds();
shp->shm_nattch--;
-#ifdef CONFIG_SYSVIPC_CROSS_SHM
- if (shp->shm_perm.rpmflag == TRUE)
- shm_remote_free_pages(shp->shm_perm.key);
-#endif
+
if (shm_may_destroy(ns, shp))
shm_destroy(ns, shp);
else
@@ -548,10 +570,21 @@
shp->shm_file = file;
shp->shm_creator = current;
#ifdef CONFIG_SYSVIPC_CROSS_SHM
- if((key & SHM_REMOTE_ATTR_MASK) == SHM_REMOTE_ATTR_MASK)
- shp->shm_perm.rpmflag = TRUE;
+ if((key & SHM_REMOTE_SYSV_MASK) == SHM_REMOTE_SYSV_MASK)
+ {
+ error = shm_do_newseg_check(key, size);
+ if (error < 0)
+ {
+ printk("shm size error, should be the same PAGE_ALIGN size\n");
+ return error;
+ }
+ else
+ shp->shm_perm.rpmflag = TRUE;
+ }
else
+ {
shp->shm_perm.rpmflag = FALSE;
+ }
#endif
/*
* shmid gets reported as "inode#" in /proc/pid/maps.
@@ -1087,7 +1120,7 @@
sfd->vm_ops = NULL;
#ifdef CONFIG_SYSVIPC_CROSS_SHM
if(shp->shm_perm.rpmflag == TRUE)
- file->f_flags = SHM_REMOTE_ATTR_YES;
+ file->shm_flags = SHM_REMOTE_SYSV_YES;
#endif
down_write(¤t->mm->mmap_sem);
if (addr && !(shmflg & SHM_REMAP)) {
diff --git a/ap/os/linux/linux-3.4.x/ipc/shm_ctrl.c b/ap/os/linux/linux-3.4.x/ipc/shm_ctrl.c
index 598cb28..183a8bd 100755
--- a/ap/os/linux/linux-3.4.x/ipc/shm_ctrl.c
+++ b/ap/os/linux/linux-3.4.x/ipc/shm_ctrl.c
@@ -23,6 +23,10 @@
#define SHM_UNIT_BUFF_ORDER (12)
#define SHM_KEYS_STATUS_LEN (4*1024)
#define SHM_REMOTE_BUFF_LEN (128*1024)
+#define SHM_POSIX_HASH_CHARS (26)
+#define SHM_POSIX_HASH_BASE (62)
+#define SHM_POSIX_HASH_MASK (0x7FF)
+
#define SHM_BUFF_BASE_PHY_ADDR (g_shm_phyAddr)
#define SHM_UNIT_BUFF_SIZE (1UL<<SHM_UNIT_BUFF_ORDER) /*4KB*/
@@ -51,6 +55,36 @@
struct shm_entity *shm_remote_manager;
/*******************************************************************************
+* ¹¦ÄÜÃèÊö: shm_hash_name_to_key
+* ²ÎÊý˵Ã÷:
+* (´«Èë²ÎÊý) name: ¹²ÏíÄÚ´æÃû³Æ
+* (´«Èë²ÎÊý) len: ¹²ÏíÄÚ´æÃû³Æ³¤¶È
+* (´«³ö²ÎÊý) ÎÞ
+* ·µ »Ø Öµ:
+* ÆäËü˵Ã÷: This function is used for calc hash value of the name(-2048~-4096)
+*******************************************************************************/
+key_t shm_hash_name_to_key(const char *name, int len)
+{
+ int i = 0;
+ key_t tmp_key = 0;
+ key_t hash_key = 0;
+ unsigned long long id = 0;
+
+ for (; i < len; i++)
+ {
+ if (name[i] >= 'A' && name[i] <= 'Z')
+ id = id*SHM_POSIX_HASH_BASE + name[i]-'A';
+ else if (name[i] >= 'a' && name[i] <= 'z')
+ id = id*SHM_POSIX_HASH_BASE + name[i]-'a' + SHM_POSIX_HASH_CHARS;
+ else if (name[i] >= '0' && name[i] <= '9')
+ id = id*SHM_POSIX_HASH_BASE + name[i]-'0' + 2*SHM_POSIX_HASH_CHARS;
+ }
+ tmp_key =(id & SHM_POSIX_HASH_MASK) + (SHM_POSIX_HASH_MASK + 1);
+ hash_key = ~tmp_key + 1;
+ return hash_key;
+}
+
+/*******************************************************************************
* ¹¦ÄÜÃèÊö: shm_quary_keyArray
* ²ÎÊý˵Ã÷:
* (´«Èë²ÎÊý) void
@@ -330,6 +364,58 @@
}
/*******************************************************************************
+* ¹¦ÄÜÃèÊö: shm_do_newseg_check
+* ²ÎÊý˵Ã÷:
+* (´«Èë²ÎÊý) void
+* (´«³ö²ÎÊý) void
+* ·µ »Ø Öµ: SHM_CTRL_OK or SHM_CTRL_ERROR
+* ÆäËü˵Ã÷: This function is used for check key and len
+*******************************************************************************/
+int shm_do_newseg_check(key_t key, unsigned long len)
+{
+ int ret = 0;
+ int key_index = 0;
+ unsigned int shm_weight = 0;
+ unsigned int shm_pages = 0;
+ struct shm_key_node *key_node = NULL;
+
+ if(g_shm_region == NULL)
+ {
+ printk("shm_do_newsg_check:Shm region is not ready\n");
+ return SHM_CTRL_ERROR;
+ }
+ soft_spin_lock(SHM_SFLOCK);
+
+ key_index = shm_quary_keyArray(key);
+
+ if (key_index < 0)
+ {
+ soft_spin_unlock(SHM_SFLOCK);
+ return SHM_CTRL_OK;
+ }
+
+ if ((0 <= key_index) && (key_index < SHM_UNIT_NUM_BITS))
+ {
+ key_node = &shm_remote_manager->keys_info_head[key_index];
+ }
+ else
+ {
+ soft_spin_unlock(SHM_SFLOCK);
+ panic("key_index out of range: failed\n");
+ }
+
+ shm_pages = PAGE_ALIGN(len) >> PAGE_SHIFT;
+ shm_weight = bitmap_weight(key_node->shm_inuse_index, SHM_UNIT_NUM_BITS);
+ soft_spin_unlock(SHM_SFLOCK);
+
+ /*APºÍCAP¹²ÏíÄÚ´æ´óСӦƥÅä*/
+ if(shm_weight != shm_pages)
+ return -EINVAL;
+ else
+ return SHM_CTRL_OK;
+}
+
+/*******************************************************************************
* ¹¦ÄÜÃèÊö: shm_do_remote_map_vma
* ²ÎÊý˵Ã÷:
* (´«Èë²ÎÊý) void
@@ -374,9 +460,14 @@
vm_addr = vma->vm_start;
if ((0 <= key_index) && (key_index < SHM_UNIT_NUM_BITS))
+ {
key_node = &shm_remote_manager->keys_info_head[key_index];
+ }
else
+ {
+ soft_spin_unlock(SHM_SFLOCK);
panic("key_index out of range: failed\n");
+ }
memcpy(shm_inuse_tmp, key_node->shm_inuse_index, sizeof(shm_inuse_tmp));
diff --git a/ap/os/linux/linux-3.4.x/ipc/shm_ctrl.h b/ap/os/linux/linux-3.4.x/ipc/shm_ctrl.h
index 5a850a1..4726ea8 100755
--- a/ap/os/linux/linux-3.4.x/ipc/shm_ctrl.h
+++ b/ap/os/linux/linux-3.4.x/ipc/shm_ctrl.h
@@ -29,19 +29,24 @@
#include <mach/spinlock.h>
/**
- * Êý¾ÝÀàÐͶ¨Òå
- */
+ * ºê¶¨Òå
+*/
#define TRUE 1
#define FALSE 0
-#define SHM_REMOTE_ATTR_YES (0x594553) /*YES ASCIIÂë*/
-#define SHM_REMOTE_ATTR_MASK (0xFFFFF000)
+
#define SHM_CTRL_OK (0)
#define SHM_CTRL_ERROR (-1)
#define SHM_CTRL_VMA_LINK_NUM (2)
#define SHM_CTRL_MEMSYNC_CHANNEL (15)
#define SHM_CTRL_CHANNEL_SIZE (0x40)
#define SHM_CTRL_LONG_32BIT (32)
+#define SHM_REMOTE_SYSV_YES (0x73797376) /*SYSV ASCIIÂë*/
+#define SHM_REMOTE_POSIX_YES (0x706F7378) /*POSX ASCIIÂë*/
+#define SHM_REMOTE_SYSV_MASK (0xFFFFF800) /*(key:-1~-2047)*/
+/**
+ * Êý¾ÝÀàÐͶ¨Òå
+ */
struct shm_pool_msg
{
unsigned int shm_len;
@@ -50,7 +55,12 @@
phys_addr_t key_manage_phy;
};
-
+extern int shm_remote_free_pages(key_t key);
+extern key_t shm_hash_name_to_key(const char *name, int len);
+extern int shm_do_newseg_check(key_t key, unsigned long len);
+extern int shm_do_remote_map_vma(struct vm_area_struct *vma, key_t key);
+extern void shm_unmap_page_range(struct mm_struct *mm, struct vm_area_struct *vma,
+ unsigned long addr, unsigned long end);
#endif
#endif // _SHM_CTRL_H
diff --git a/ap/os/linux/linux-3.4.x/mm/mmap.c b/ap/os/linux/linux-3.4.x/mm/mmap.c
index 88d133b..702f65d 100755
--- a/ap/os/linux/linux-3.4.x/mm/mmap.c
+++ b/ap/os/linux/linux-3.4.x/mm/mmap.c
@@ -41,9 +41,11 @@
#ifdef CONFIG_SYSVIPC_CROSS_SHM
#include <../ipc/shm_ctrl.h>
-extern void shm_mmap_pagetable(struct vm_area_struct *vma, struct file *file);
-extern void shm_unmap_page_range(struct mm_struct *mm, struct vm_area_struct *vma,
- unsigned long addr, unsigned long end);
+extern key_t shm_do_remote_analy_key(struct file *file);
+extern int shm_ipc_mmap_pagetable(struct vm_area_struct *vma, struct file *file);
+static void shm_delete_vma_from_mm(struct vm_area_struct *vma);
+static void shm_delete_vma(struct mm_struct *mm, struct vm_area_struct *vma);
+
#define kenter(FMT, ...) \
no_printk(KERN_DEBUG "==> %s("FMT")\n", __func__, ##__VA_ARGS__)
#define kleave(FMT, ...) \
@@ -1435,11 +1437,18 @@
make_pages_present(addr, addr + len);
#ifdef CONFIG_SYSVIPC_CROSS_SHM
- /*Get real phy pgae*/
- if (file && (file->f_flags == SHM_REMOTE_ATTR_YES))
- {
- shm_mmap_pagetable(vma, file);
- }
+ if (file && ((file->shm_flags == SHM_REMOTE_SYSV_YES)
+ || (file->shm_flags == SHM_REMOTE_POSIX_YES))) {
+ /*Get real phy pgae*/
+ error = shm_ipc_mmap_pagetable(vma, file);
+ if (error < 0)
+ {
+ shm_delete_vma_from_mm(vma);
+ shm_delete_vma(mm, vma);
+ return error;
+ }
+ }
+
#endif
return addr;
@@ -2147,6 +2156,18 @@
}
#ifdef CONFIG_SYSVIPC_CROSS_SHM
+int shm_try_to_free_pages(struct file *file)
+{
+ int ret = 0;
+ key_t shm_key;
+
+ shm_key = shm_do_remote_analy_key(file);
+ ret = shm_remote_free_pages(shm_key);
+ if (ret < 0)
+ printk("shm_try_to_free_pages Error\n");
+ return ret;
+}
+
/*
* delete a VMA from its owning mm_struct and address space
*/
@@ -2270,7 +2291,8 @@
}
erase_whole_vma:
- shm_unmap_page_range(mm, vma, start, end);
+ shm_unmap_page_range(mm, vma, start, end);
+ shm_try_to_free_pages(vma->vm_file);
shm_delete_vma_from_mm(vma);
shm_delete_vma(mm, vma);
return 0;
@@ -2340,7 +2362,9 @@
vma = prev? prev->vm_next: mm->mmap;
#ifdef CONFIG_SYSVIPC_CROSS_SHM
- if (vma->vm_file && (vma->vm_file->f_flags == SHM_REMOTE_ATTR_YES)) {
+ if (vma->vm_file &&
+ ((vma->vm_file->shm_flags == SHM_REMOTE_SYSV_YES)
+ || (vma->vm_file->shm_flags == SHM_REMOTE_POSIX_YES))) {
shm_ctrl_do_munmap(mm, start, len);
return 0;
}
@@ -2527,7 +2551,8 @@
vma_shm = mm->mmap;
while (vma_shm) {
if ((vma_shm->vm_file) &&
- (vma_shm->vm_file->f_flags == SHM_REMOTE_ATTR_YES)) {
+ ((vma_shm->vm_file->shm_flags == SHM_REMOTE_SYSV_YES)
+ ||(vma_shm->vm_file->shm_flags == SHM_REMOTE_POSIX_YES))) {
vma = vma_shm->vm_next;
shm_ctrl_do_munmap(mm, vma_shm->vm_start, (vma_shm->vm_end - vma_shm->vm_start));
vma_shm = vma;
diff --git a/ap/os/linux/linux-3.4.x/net/Kconfig b/ap/os/linux/linux-3.4.x/net/Kconfig
old mode 100644
new mode 100755
index b3f685b..e3054f2
--- a/ap/os/linux/linux-3.4.x/net/Kconfig
+++ b/ap/os/linux/linux-3.4.x/net/Kconfig
@@ -382,5 +382,7 @@
source "net/ceph/Kconfig"
source "net/nfc/Kconfig"
-
+config IPC_SOCKET
+ bool "Config ipc socket"
+ default n
endif # if NET
diff --git a/ap/os/linux/linux-3.4.x/net/Makefile b/ap/os/linux/linux-3.4.x/net/Makefile
old mode 100644
new mode 100755
index 6865dab..3f9d8c1
--- a/ap/os/linux/linux-3.4.x/net/Makefile
+++ b/ap/os/linux/linux-3.4.x/net/Makefile
@@ -71,3 +71,4 @@
obj-$(CONFIG_NFC) += nfc/
obj-$(CONFIG_OPENVSWITCH) += openvswitch/
obj-$(CONFIG_NET_ACTIVITY_STATS) += activity_stats.o
+obj-$(CONFIG_IPC_SOCKET) += socket_rpmsg.o
diff --git a/ap/os/linux/linux-3.4.x/net/bridge/br_forward.c b/ap/os/linux/linux-3.4.x/net/bridge/br_forward.c
index b3dc65f..36cde04 100755
--- a/ap/os/linux/linux-3.4.x/net/bridge/br_forward.c
+++ b/ap/os/linux/linux-3.4.x/net/bridge/br_forward.c
@@ -267,8 +267,6 @@
void br_multicast_deliver(struct net_bridge_mdb_entry *mdst,
struct sk_buff *skb)
{
- if(br_multicast_off)
- return;
br_multicast_flood(mdst, skb, NULL, __br_deliver);
}
@@ -276,8 +274,6 @@
void br_multicast_forward(struct net_bridge_mdb_entry *mdst,
struct sk_buff *skb, struct sk_buff *skb2)
{
- if(br_multicast_off)
- return;
br_multicast_flood(mdst, skb, skb2, __br_forward);
}
#endif
diff --git a/ap/os/linux/linux-3.4.x/net/bridge/br_multicast.c b/ap/os/linux/linux-3.4.x/net/bridge/br_multicast.c
index 548920d..87ae8c3 100755
--- a/ap/os/linux/linux-3.4.x/net/bridge/br_multicast.c
+++ b/ap/os/linux/linux-3.4.x/net/bridge/br_multicast.c
@@ -38,7 +38,7 @@
static void br_multicast_add_router(struct net_bridge *br,
struct net_bridge_port *port);
-int br_multicast_off = 0;
+
#if IS_ENABLED(CONFIG_IPV6)
static inline int ipv6_is_transient_multicast(const struct in6_addr *addr)
{
@@ -140,8 +140,6 @@
struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br,
struct sk_buff *skb)
{
- if(br_multicast_off)
- return NULL;
struct net_bridge_mdb_htable *mdb = rcu_dereference(br->mdb);
struct br_ip ip;
@@ -228,8 +226,6 @@
static void br_multicast_group_expired(unsigned long data)
{
- if(br_multicast_off)
- return;
struct net_bridge_mdb_entry *mp = (void *)data;
struct net_bridge *br = mp->br;
struct net_bridge_mdb_htable *mdb;
@@ -291,8 +287,6 @@
static void br_multicast_port_group_expired(unsigned long data)
{
- if(br_multicast_off)
- return;
struct net_bridge_port_group *pg = (void *)data;
struct net_bridge *br = pg->port->br;
@@ -731,8 +725,6 @@
static void br_multicast_router_expired(unsigned long data)
{
- if(br_multicast_off)
- return;
struct net_bridge_port *port = (void *)data;
struct net_bridge *br = port->br;
@@ -801,8 +793,6 @@
static void br_multicast_port_query_expired(unsigned long data)
{
- if(br_multicast_off)
- return;
struct net_bridge_port *port = (void *)data;
struct net_bridge *br = port->br;
@@ -824,8 +814,6 @@
void br_multicast_add_port(struct net_bridge_port *port)
{
- if(br_multicast_off)
- return;
port->multicast_router = 1;
setup_timer(&port->multicast_router_timer, br_multicast_router_expired,
@@ -836,8 +824,6 @@
void br_multicast_del_port(struct net_bridge_port *port)
{
- if(br_multicast_off)
- return;
del_timer_sync(&port->multicast_router_timer);
}
@@ -853,8 +839,7 @@
void br_multicast_enable_port(struct net_bridge_port *port)
{
struct net_bridge *br = port->br;
- if(br_multicast_off)
- return;
+
spin_lock(&br->multicast_lock);
if (br->multicast_disabled || !netif_running(br->dev))
goto out;
@@ -872,8 +857,7 @@
struct net_bridge *br = port->br;
struct net_bridge_port_group *pg;
struct hlist_node *p, *n;
- if(br_multicast_off)
- return;
+
spin_lock(&br->multicast_lock);
hlist_for_each_entry_safe(pg, p, n, &port->mglist, mglist)
br_multicast_del_pg(br, pg);
@@ -1538,8 +1522,6 @@
int br_multicast_rcv(struct net_bridge *br, struct net_bridge_port *port,
struct sk_buff *skb)
{
- if(br_multicast_off)
- return 0;
BR_INPUT_SKB_CB(skb)->igmp = 0;
BR_INPUT_SKB_CB(skb)->mrouters_only = 0;
@@ -1561,8 +1543,7 @@
static void br_multicast_query_expired(unsigned long data)
{
struct net_bridge *br = (void *)data;
- if(br_multicast_off)
- return;
+
spin_lock(&br->multicast_lock);
if (br->multicast_startup_queries_sent <
br->multicast_startup_query_count)
@@ -1575,8 +1556,6 @@
void br_multicast_init(struct net_bridge *br)
{
- if(br_multicast_off)
- return;
br->hash_elasticity = 4;
br->hash_max = 512;
@@ -1602,8 +1581,6 @@
void br_multicast_open(struct net_bridge *br)
{
- if(br_multicast_off)
- return;
br->multicast_startup_queries_sent = 0;
if (br->multicast_disabled)
@@ -1619,8 +1596,7 @@
struct hlist_node *p, *n;
u32 ver;
int i;
- if(br_multicast_off)
- return;
+
del_timer_sync(&br->multicast_router_timer);
del_timer_sync(&br->multicast_querier_timer);
del_timer_sync(&br->multicast_query_timer);
diff --git a/ap/os/linux/linux-3.4.x/net/bridge/br_private.h b/ap/os/linux/linux-3.4.x/net/bridge/br_private.h
index bfb0f3d..6822ef1 100755
--- a/ap/os/linux/linux-3.4.x/net/bridge/br_private.h
+++ b/ap/os/linux/linux-3.4.x/net/bridge/br_private.h
@@ -421,11 +421,8 @@
extern int br_multicast_toggle(struct net_bridge *br, unsigned long val);
extern int br_multicast_set_hash_max(struct net_bridge *br, unsigned long val);
-extern int br_multicast_off;
static inline bool br_multicast_is_router(struct net_bridge *br)
{
- if(br_multicast_off)
- return 0;
return br->multicast_router == 2 ||
(br->multicast_router == 1 &&
timer_pending(&br->multicast_router_timer));
diff --git a/ap/os/linux/linux-3.4.x/net/core/fastproc/fast_common.c b/ap/os/linux/linux-3.4.x/net/core/fastproc/fast_common.c
index d3f740d..787b227 100755
--- a/ap/os/linux/linux-3.4.x/net/core/fastproc/fast_common.c
+++ b/ap/os/linux/linux-3.4.x/net/core/fastproc/fast_common.c
@@ -1801,24 +1801,24 @@
{
skb_num6++;
skb_bytes6 += skb->len;
-
+
//×é²¥µÄ¿ìËÙת·¢£¬´ýʵÏÖ£¬ÔÝʱֱ½Ó·µ»Ø¿ìËÙת·¢Ê§°Ü
if(ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr))
{
multicast_num6++;
return 0;
}
-
- if (skb->nfct_reasm && printk_ratelimit()) {
- printk("fast6_fw reasm \n");
+
+ if (skb->nfct_reasm) {
+ //printk("fast6_fw reasm\n");
return 0;
}
-
+
/* if (ipv6_hdr(skb)->nexthdr != IPPROTO_TCP && ipv6_hdr(skb)->nexthdr != IPPROTO_UDP){
// printk("wrong protocol v6 = %d\n", ipv6_hdr(skb)->nexthdr);
return 0;
}*/
-
+
if(!fast_iphdr_check(skb, ETH_P_IPV6))
{
ip6hdr_err_num++;
diff --git a/ap/os/linux/linux-3.4.x/net/core/fastproc/fast_track.c b/ap/os/linux/linux-3.4.x/net/core/fastproc/fast_track.c
index c118526..5d55426 100755
--- a/ap/os/linux/linux-3.4.x/net/core/fastproc/fast_track.c
+++ b/ap/os/linux/linux-3.4.x/net/core/fastproc/fast_track.c
@@ -1196,20 +1196,6 @@
.write = skb_debug_off_set,
};
-extern int br_multicast_off;
-static ssize_t br_multicast_off_set(struct file *file,
- const char __user *buffer, size_t count, loff_t *pos)
-{
- br_multicast_off = 1;
- printk("br_multicast_off\n");
- return count;
-}
-
-static const struct file_operations br_multicast_off_file_ops = {
- .owner = THIS_MODULE,
- .write = br_multicast_off_set,
-};
-
//¿ìËÙת·¢procÎļþµÄ³õʼ»¯
int fast_conntrack_init_proc(void)
{
@@ -1242,10 +1228,6 @@
//turn off skb debug
proc_create("skb_debug_off", 0440, init_net.proc_net, &skb_debug_off_file_ops);
-
- //turn off br multicast
- proc_create("br_multi_off", 0440, init_net.proc_net, &br_multicast_off_file_ops);
-
return 1;
}
diff --git a/ap/os/linux/linux-3.4.x/net/core/sock.c b/ap/os/linux/linux-3.4.x/net/core/sock.c
index 3204c53..5dec66d 100755
--- a/ap/os/linux/linux-3.4.x/net/core/sock.c
+++ b/ap/os/linux/linux-3.4.x/net/core/sock.c
@@ -137,6 +137,9 @@
#endif
#include <net/netfilter/nf_conntrack.h>
+#ifdef CONFIG_IPC_SOCKET
+#include <linux/socket_rpmsg.h>
+#endif
static DEFINE_MUTEX(proto_list_mutex);
@@ -2694,7 +2697,10 @@
extern void fast_sock_release(struct sock *sk);
void sock_put(struct sock *sk)
-{
+{
+#ifdef CONFIG_IPC_SOCKET
+ sk_soc_info("sock_put enter sk=%x, sk->sk_refcnt=%d\n", sk, sk->sk_refcnt);
+#endif
if (atomic_dec_and_test(&sk->sk_refcnt))
{
fast_sock_release(sk);
diff --git a/ap/os/linux/linux-3.4.x/net/ipv4/ping.c b/ap/os/linux/linux-3.4.x/net/ipv4/ping.c
old mode 100644
new mode 100755
index 5ff3ed1..0d2f13a
--- a/ap/os/linux/linux-3.4.x/net/ipv4/ping.c
+++ b/ap/os/linux/linux-3.4.x/net/ipv4/ping.c
@@ -135,16 +135,17 @@
{
struct inet_sock *isk = inet_sk(sk);
pr_debug("ping_v4_unhash(isk=%p,isk->num=%u)\n", isk, isk->inet_num);
+ //BDSA-2017-0084(CVE-2017-2671)
+ write_lock_bh(&ping_table.lock);
if (sk_hashed(sk)) {
- write_lock_bh(&ping_table.lock);
hlist_nulls_del(&sk->sk_nulls_node);
sk_nulls_node_init(&sk->sk_nulls_node);
sock_put(sk);
isk->inet_num = 0;
isk->inet_sport = 0;
sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1);
- write_unlock_bh(&ping_table.lock);
}
+ write_unlock_bh(&ping_table.lock);
}
static struct sock *ping_v4_lookup(struct net *net, __be32 saddr, __be32 daddr,
diff --git a/ap/os/linux/linux-3.4.x/net/socket.c b/ap/os/linux/linux-3.4.x/net/socket.c
index 5406a3d..7ea3abd 100755
--- a/ap/os/linux/linux-3.4.x/net/socket.c
+++ b/ap/os/linux/linux-3.4.x/net/socket.c
@@ -402,7 +402,9 @@
if (likely(fd >= 0))
fd_install(fd, newfile);
-
+#ifdef CONFIG_IPC_SOCKET
+ sock->fd = fd;
+#endif
return fd;
}
EXPORT_SYMBOL(sock_map_fd);
@@ -487,7 +489,9 @@
inode->i_mode = S_IFSOCK | S_IRWXUGO;
inode->i_uid = current_fsuid();
inode->i_gid = current_fsgid();
-
+#ifdef CONFIG_IPC_SOCKET
+ INIT_HLIST_HEAD(&sock->peer);
+#endif
percpu_add(sockets_in_use, 1);
return sock;
}
@@ -1379,7 +1383,7 @@
out_release:
sock_release(sock);
//return retval;
- return ERRNO_TRACK(retval);
+ return ERRNO_TRACK(retval);
}
/*
@@ -1572,7 +1576,9 @@
sock_release(newsock);
goto out_put;
}
-
+#ifdef CONFIG_IPC_SOCKET
+ newsock->fd = newfd;
+#endif
err = security_socket_accept(sock, newsock);
if (err)
goto out_fd;
diff --git a/ap/os/linux/linux-3.4.x/net/socket_rpmsg.c b/ap/os/linux/linux-3.4.x/net/socket_rpmsg.c
new file mode 100755
index 0000000..867b943
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/net/socket_rpmsg.c
@@ -0,0 +1,2662 @@
+/*******************************************************************************
+ * Include header files *
+ ******************************************************************************/
+#include <linux/module.h>
+#include <net/sock.h>
+#include <net/af_unix.h>
+#include <linux/syscalls.h>
+#include <linux/file.h>
+//#include "ram_config.h"
+#include <linux/socket_rpmsg.h>
+
+#define SOCK_DATA_ALIGN(X) ALIGN(X, SMP_CACHE_BYTES)
+#define SOCK_DATA_MAX_LEN 8*1024
+#define ICP_CHN_SOCKET 32
+#define sock_init_sema sema_init
+#define sock_get_sema down_interruptible
+#define sock_put_sema up
+
+struct sock_channel g_sock_chn_info;
+struct sock_rpmsg g_sock_rpmsg;
+struct ipc_socket *g_socket_ipc;
+
+struct semaphore g_sock_sem;
+unsigned int g_sock_timeout = 5*1000;
+//´æ·ÅÁ´Â·ÐÅÏ¢£¬Ò»¶Ësocket¹Ø±Õ£¬ÆäËùÓйØÁªµÄsocket¾ùɾ³ý£¬Á´Â·ÐÅÏ¢Öдæ·Å5Ôª×飨¿Í»§¶Ë¡¢·þÎñ¶Ë¡¢ºÍ´úÀí£©
+struct hlist_head g_ipc_sockets;
+struct hlist_head g_sock_rpmsg_info;
+struct hlist_head g_sockets_info;
+
+char* flag_value[] ={
+ "SOCK_DEAD",
+ "SOCK_DONE",
+ "SOCK_URGINLINE",
+ "SOCK_KEEPOPEN",
+ "SOCK_LINGER",
+ "SOCK_DESTROY",
+ "SOCK_BROADCAST",
+ "SOCK_TIMESTAMP",
+ "SOCK_ZAPPED",
+ "SOCK_USE_WRITE_QUEUE", /* whether to call sk->sk_write_space in sock_wfree */
+ "SOCK_DBG", /* %SO_DEBUG setting */
+ "SOCK_RCVTSTAMP", /* %SO_TIMESTAMP setting */
+ "SOCK_RCVTSTAMPNS", /* %SO_TIMESTAMPNS setting */
+ "SOCK_LOCALROUTE", /* route locally only, %SO_DONTROUTE setting */
+ "SOCK_QUEUE_SHRUNK", /* write queue has been shrunk recently */
+ "SOCK_TIMESTAMPING_TX_HARDWARE", /* %SOF_TIMESTAMPING_TX_HARDWARE */
+ "SOCK_TIMESTAMPING_TX_SOFTWARE", /* %SOF_TIMESTAMPING_TX_SOFTWARE */
+ "SOCK_TIMESTAMPING_RX_HARDWARE", /* %SOF_TIMESTAMPING_RX_HARDWARE */
+ "SOCK_TIMESTAMPING_RX_SOFTWARE", /* %SOF_TIMESTAMPING_RX_SOFTWARE */
+ "SOCK_TIMESTAMPING_SOFTWARE", /* %SOF_TIMESTAMPING_SOFTWARE */
+ "SOCK_TIMESTAMPING_RAW_HARDWARE", /* %SOF_TIMESTAMPING_RAW_HARDWARE */
+ "SOCK_TIMESTAMPING_SYS_HARDWARE", /* %SOF_TIMESTAMPING_SYS_HARDWARE */
+ "SOCK_FASYNC", /* fasync() active */
+ "SOCK_RXQ_OVFL",
+ "SOCK_ZEROCOPY", /* buffers from userspace */
+ "SOCK_WIFI_STATUS", /* push wifi status to userspace */
+ "SOCK_NOFCS",
+ "SOCK_IPCSOCK"
+};
+
+DEFINE_SPINLOCK(sock_table_lock);
+EXPORT_SYMBOL_GPL(sock_table_lock);
+
+DEFINE_SPINLOCK(sock_rpmsg_table_lock);
+EXPORT_SYMBOL_GPL(sock_rpmsg_table_lock);
+
+DEFINE_SPINLOCK(sock_socket_table_lock);
+EXPORT_SYMBOL_GPL(sock_socket_table_lock);
+
+DEFINE_SPINLOCK(sock_release_table_lock);
+EXPORT_SYMBOL_GPL(sock_release_table_lock);
+
+DEFINE_SPINLOCK(sock_release_lock);
+EXPORT_SYMBOL_GPL(sock_release_lock);
+
+DEFINE_SPINLOCK(sock_release_peer_lock);
+EXPORT_SYMBOL_GPL(sock_release_peer_lock);
+
+#define unix_peer(sk) (unix_sk(sk)->peer)
+
+extern struct sock *unix_find_other_proxy(struct net *net,
+ struct sockaddr_un *sunname, int len,
+ int type, unsigned int hash, int *error);
+
+extern int unix_dgram_peer_wake_connect_proxy(struct sock *sk, struct sock *other);
+
+extern void unix_dgram_peer_wake_disconnect_proxy(struct sock *sk, struct sock *other);
+
+extern void unix_dgram_peer_wake_disconnect_wakeup_proxy(struct sock *sk,
+ struct sock *other);
+extern long unix_wait_for_peer_proxy(struct sock *other, long timeo);
+extern int unix_recvq_full_proxy(const struct sock *sk);
+extern int unix_recvq_full_proxy_lockless_and_deadstate(const struct sock *other);
+extern int unix_stream_connect_proxy(struct socket *sock, struct sockaddr *uaddr,
+ int addr_len, int flags);
+extern void unix_dgram_disconnected_proxy(struct sock *sk, struct sock *other);
+extern int unix_mkname_proxy(struct sockaddr_un *sunaddr, int len, unsigned *hashp);
+extern void unix_release_sock_proxy(struct sock *sk);
+
+//static void delayed_release(struct work_struct *unused);
+int sock_soc_socket_is_valid(struct socket* proxysock, struct socket* localsock);
+int sock_soc_release_peer(struct release_socket* rsock);
+
+static LIST_HEAD(delayed_release_list);
+
+enum sock_flags_cap {
+ SOCK_DEAD_CAP,
+ SOCK_DONE_CAP,
+ SOCK_URGINLINE_CAP,
+ SOCK_KEEPOPEN_CAP,
+ SOCK_LINGER_CAP,
+ SOCK_DESTROY_CAP,
+ SOCK_BROADCAST_CAP,
+ SOCK_TIMESTAMP_CAP,
+ SOCK_ZAPPED_CAP,
+ SOCK_USE_WRITE_QUEUE_CAP, /* whether to call sk->sk_write_space in sock_wfree */
+ SOCK_DBG_CAP, /* %SO_DEBUG setting */
+ SOCK_RCVTSTAMP_CAP, /* %SO_TIMESTAMP setting */
+ SOCK_RCVTSTAMPNS_CAP, /* %SO_TIMESTAMPNS setting */
+ SOCK_LOCALROUTE_CAP, /* route locally only, %SO_DONTROUTE setting */
+ SOCK_MEMALLOC_CAP, /* VM depends on this socket for swapping */
+ SOCK_TIMESTAMPING_RX_SOFTWARE_CAP, /* %SOF_TIMESTAMPING_RX_SOFTWARE */
+ SOCK_FASYNC_CAP, /* fasync() active */
+ SOCK_RXQ_OVFL_CAP,
+ SOCK_ZEROCOPY_CAP, /* buffers from userspace */
+ SOCK_WIFI_STATUS_CAP, /* push wifi status to userspace */
+ SOCK_NOFCS_CAP, /* Tell NIC not to do the Ethernet FCS.
+ * Will use last 4 bytes of packet sent from
+ * user-space instead.
+ */
+ SOCK_FILTER_LOCKED_CAP, /* Filter cannot be changed anymore */
+ SOCK_SELECT_ERR_QUEUE_CAP, /* Wake select on error queue */
+ SOCK_RCU_FREE_CAP, /* wait rcu grace period in sk_destruct() */
+ SOCK_TXTIME_CAP,
+ SOCK_XDP_CAP, /* XDP is attached */
+ SOCK_TSTAMP_NEW_CAP, /* Indicates 64 bit timestamps always */
+
+ SOCK_IPCSOCK_CAP, /*Indicates whether it is a cross core socket */
+
+};
+
+
+enum sock_flags_cap convert_to_cap_sock_flag(enum sock_flags flag)
+{
+ switch(flag){
+ case SOCK_DEAD:
+ return SOCK_DEAD_CAP;
+ case SOCK_DONE:
+ return SOCK_DONE_CAP;
+ case SOCK_URGINLINE:
+ return SOCK_URGINLINE_CAP;
+ case SOCK_KEEPOPEN:
+ return SOCK_KEEPOPEN_CAP;
+ case SOCK_LINGER:
+ return SOCK_LINGER_CAP;
+ case SOCK_DESTROY:
+ return SOCK_DESTROY_CAP;
+ case SOCK_BROADCAST:
+ return SOCK_BROADCAST_CAP;
+ case SOCK_TIMESTAMP:
+ return SOCK_TIMESTAMP_CAP;
+ case SOCK_ZAPPED:
+ return SOCK_ZAPPED_CAP;
+ case SOCK_USE_WRITE_QUEUE:
+ return SOCK_USE_WRITE_QUEUE_CAP;
+ case SOCK_DBG:
+ return SOCK_DBG_CAP;
+ case SOCK_RCVTSTAMP:
+ return SOCK_RCVTSTAMP_CAP;
+ case SOCK_RCVTSTAMPNS:
+ return SOCK_RCVTSTAMPNS_CAP;
+ case SOCK_LOCALROUTE:
+ return SOCK_LOCALROUTE_CAP;
+ case SOCK_QUEUE_SHRUNK:
+ return -1;
+ case SOCK_TIMESTAMPING_TX_HARDWARE:
+ return -1;
+ case SOCK_TIMESTAMPING_TX_SOFTWARE:
+ return -1;
+ case SOCK_TIMESTAMPING_RX_HARDWARE:
+ return -1;
+ case SOCK_TIMESTAMPING_RX_SOFTWARE:
+ return SOCK_TIMESTAMPING_RX_SOFTWARE_CAP;
+ case SOCK_TIMESTAMPING_SOFTWARE:
+ return -1;
+ case SOCK_TIMESTAMPING_RAW_HARDWARE:
+ return -1;
+ case SOCK_TIMESTAMPING_SYS_HARDWARE:
+ return -1;
+ case SOCK_FASYNC:
+ return SOCK_FASYNC_CAP;
+ case SOCK_RXQ_OVFL:
+ return SOCK_RXQ_OVFL_CAP;
+ case SOCK_ZEROCOPY:
+ return SOCK_ZEROCOPY_CAP;
+ case SOCK_WIFI_STATUS:
+ return SOCK_WIFI_STATUS_CAP;
+ case SOCK_NOFCS:
+ return SOCK_NOFCS_CAP;
+ default:
+ return -1;
+ }
+}
+
+static int sock_soc_is_socket_peer(struct socket* socket, struct socket* peer)
+{
+ struct socket_info *p;
+ struct hlist_node *n, *pos;
+ spin_lock(&sock_release_peer_lock);
+ hlist_for_each_entry_safe(p, pos, n, &socket->peer, hlist_node) {
+ if(p->proxysocket == peer){
+ spin_unlock(&sock_release_peer_lock);
+ return 0;
+ }
+ }
+ spin_unlock(&sock_release_peer_lock);
+ return -1;
+}
+
+static inline void sock_soc_insert_socket_peer(struct socket* socket, struct socket* peer)
+{
+ struct socket_info *psock_socket_info = NULL;
+
+ //ÏȲ鿴peerÊÇ·ñÒѾÔÚsocketµÄpeer_listÖÐ
+ if(0 == sock_soc_is_socket_peer(socket, peer)){
+ sk_soc_info("sock_soc_insert_socket_peer, peer already exist");
+ return;
+ }
+ psock_socket_info = (struct socket_info *)kzalloc(sizeof(struct socket_info), GFP_ATOMIC);
+ if(psock_socket_info == NULL){
+ return;
+ }
+ memset(psock_socket_info, 0, sizeof(struct socket_info));
+ psock_socket_info->proxysocket = peer;
+ psock_socket_info->localsocket = socket;
+
+ sk_soc_info("sock_soc_insert_socket_peer sucess, proxysocket=%x, localsock=%x", psock_socket_info->proxysocket, psock_socket_info->localsocket);
+
+ spin_lock(&sock_release_peer_lock);
+ INIT_HLIST_NODE(&psock_socket_info->hlist_node);
+ hlist_add_head(&psock_socket_info->hlist_node, &socket->peer);
+ spin_unlock(&sock_release_peer_lock);
+}
+
+static int sock_soc_del_socket_peer(struct socket* socket, struct socket* peer)
+{
+ struct socket_info *p;
+ struct hlist_node *n, *pos;
+ spin_lock(&sock_release_peer_lock);
+ hlist_for_each_entry_safe(p, pos, n, &socket->peer, hlist_node) {
+ if(p->proxysocket == peer){
+ hlist_del(&p->hlist_node);
+ spin_unlock(&sock_release_peer_lock);
+ kfree(p);
+ return 0;
+ }
+ }
+ spin_unlock(&sock_release_peer_lock);
+ return -1;
+}
+
+static inline void sock_soc_insert_socket(struct hlist_node *list_node)
+{
+ spin_lock(&sock_table_lock);
+ hlist_add_head(list_node, &g_ipc_sockets);
+ spin_unlock(&sock_table_lock);
+}
+
+//ÓÃÓÚÅжϱ¾µØsocketÊÇ·ñÔÚipcÁбíÖУ¬¿ÉÄÜ´æÔÚ¶àÌõ¼Ç¼
+static struct ipc_socket *sock_soc_get_ipcsocket_by_localsocket(struct socket *localsocket)
+{
+ struct ipc_socket *p;
+ struct hlist_node *pos,*n;
+ spin_lock(&sock_table_lock);
+ if(hlist_empty(&g_ipc_sockets))
+ {
+ sk_soc_info("sock_soc_get_ipcsocket_by_proxysock g_ipc_sockets is empty");
+ spin_unlock(&sock_table_lock);
+ return NULL;
+ }
+ hlist_for_each_entry_safe(p, pos, n, &g_ipc_sockets, hlist_node) {
+ if(p->localsocket == localsocket){
+ spin_unlock(&sock_table_lock);
+ return p;
+ }
+ }
+ spin_unlock(&sock_table_lock);
+ return NULL;
+}
+
+//´Ë´¦µÄsockΪ´úÀísocket¶ÔÓ¦µÄsock£¬ÒòΪÿ¸ö´úÀísocketÔÚg_ipc_sockets±íÖÐÊÇΨһµÄ
+static struct ipc_socket *sock_soc_get_ipcsocket_by_proxysock(struct sock *s)
+{
+ struct ipc_socket *p;
+ struct hlist_node *pos,*n;
+ spin_lock(&sock_table_lock);
+ if(hlist_empty(&g_ipc_sockets))
+ {
+ sk_soc_info("sock_soc_get_ipcsocket_by_proxysock g_ipc_sockets is empty");
+ spin_unlock(&sock_table_lock);
+ return NULL;
+ }
+ hlist_for_each_entry_safe(p, pos, n, &g_ipc_sockets, hlist_node) {
+ if(p->sock == s){
+ spin_unlock(&sock_table_lock);
+ return p;
+ }
+ }
+ spin_unlock(&sock_table_lock);
+ return NULL;
+}
+
+//¸ù¾Ý¿Í»§¶ËsocketºÍ·þÎñ¶Ësocket²éÕÒ¶ÔÓ¦µÄipc_socket
+static struct ipc_socket *sock_get_ipcsocket_by_local_and_remote(void* localsock, void* remotesock)
+{
+ struct ipc_socket *p;
+ struct hlist_node *pos,*n;
+ spin_lock(&sock_table_lock);
+ if(hlist_empty(&g_ipc_sockets))
+ {
+ sk_soc_info("sock_get_ipcsocket_by_local_and_remote g_ipc_sockets is empty");
+ spin_unlock(&sock_table_lock);
+ return NULL;
+ }
+ hlist_for_each_entry_safe(p, pos, n, &g_ipc_sockets, hlist_node) {
+ if((p->localsocket == localsock)&&(p->remotesocket == remotesock)){
+ spin_unlock(&sock_table_lock);
+ return p;
+ }
+ }
+ spin_unlock(&sock_table_lock);
+ return NULL;
+}
+
+int sock_del_ipc_socket_by_proxysocket(struct socket* socket)
+{
+ struct ipc_socket *p;
+ struct hlist_node *pos, *n;
+ spin_lock(&sock_table_lock);
+ if(hlist_empty(&g_ipc_sockets))
+ {
+ sk_soc_info("sock_del_ipc_socket_by_proxysocket g_ipc_sockets is empty");
+ spin_unlock(&sock_table_lock);
+ return -1;
+ }
+ hlist_for_each_entry_safe(p, pos, n, &g_ipc_sockets, hlist_node) {
+ if(p->socket == socket){
+ hlist_del(&p->hlist_node);
+ spin_unlock(&sock_table_lock);
+ kfree(p);
+ return 0;
+ }
+ }
+ spin_unlock(&sock_table_lock);
+ return -1;
+}
+
+//ĿǰÏȸù¾Ý¿Í»§¶Ësocket¡¢±¾¶Ë´úÀísocketºÍ·þÎñ¶Ësocket½øÐÐÆ¥Åä
+int sock_is_valide_ipc_socket(struct socket* localsocket, struct socket* proxysocket, struct socket* remotesocket/*, struct socket* remoteproxysocket*/)
+{
+ struct ipc_socket *p;
+ struct hlist_node *pos, *n;
+ spin_lock(&sock_table_lock);
+ if(hlist_empty(&g_ipc_sockets))
+ {
+ sk_soc_info("sock_is_valide_ipc_socket g_ipc_sockets is empty");
+ spin_unlock(&sock_table_lock);
+ return -1;
+ }
+ hlist_for_each_entry_safe(p, pos, n, &g_ipc_sockets, hlist_node) {
+ if((p->localsocket == localsocket)&&(p->proxysocket == proxysocket)&&(p->remotesocket == remotesocket)/*&&(p->remoteproxysocket == remoteproxysocket)*/){
+
+ spin_unlock(&sock_table_lock);
+
+ return 0;
+ }
+ }
+ spin_unlock(&sock_table_lock);
+ sk_soc_info("sock_is_valide_ipc_socket failed, localsocket=%x, proxysocket=%x, remotesocket=%x", localsocket, proxysocket, remotesocket);
+ return -1;
+}
+
+struct socket *sock_get_local_socket(int fd, int *err)
+{
+ struct socket* sock;
+ sock = sockfd_lookup(fd, err);
+ if(NULL == sock){
+ return NULL;
+ }
+ sockfd_put(sock);
+ sk_soc_info("sock_get_local_socket fd=%d, file->f_count=%d ", fd, sock->file->f_count);
+ return sock;
+}
+
+static inline void sock_soc_insert_rpmsg_info(struct hlist_node *list_node)
+{
+ spin_lock(&sock_rpmsg_table_lock);
+ hlist_add_head(list_node, &g_sock_rpmsg_info);
+ spin_unlock(&sock_rpmsg_table_lock);
+}
+
+struct sock_rpmsg_info * sock_soc_create_rpmsg_info(void* key)
+{
+ struct sock_rpmsg_info *psock_sock_rpmsg_info = NULL;
+
+ psock_sock_rpmsg_info = (struct sock_rpmsg_info *)kzalloc(sizeof(struct sock_rpmsg_info), GFP_ATOMIC);
+ if(psock_sock_rpmsg_info == NULL){
+ sk_soc_info("sock_soc_create_rpmsg_info kzalloc failed \n");
+ return NULL;
+ }
+ memset(psock_sock_rpmsg_info, 0, sizeof(struct sock_rpmsg_info));
+ psock_sock_rpmsg_info->key = key;
+ sema_init(&psock_sock_rpmsg_info->sock_sem, 0);
+ sk_soc_info("sock_soc_create_rpmsg_info sucess, key=%x", key);
+ sock_soc_insert_rpmsg_info(&psock_sock_rpmsg_info->hlist_node);
+ return psock_sock_rpmsg_info;
+}
+
+struct sock_rpmsg_info * sock_soc_get_rpmsg_info(void* key)
+{
+ struct sock_rpmsg_info *p;
+ struct hlist_node *pos,*n;
+ //sk_soc_info("sock_soc_get_rpmsg_info key=%x \n", key);
+ spin_lock(&sock_rpmsg_table_lock);
+ hlist_for_each_entry_safe(p, pos, n, &g_sock_rpmsg_info, hlist_node) {
+ if(p->key == key){
+ spin_unlock(&sock_rpmsg_table_lock);
+ return p;
+ }
+ }
+ spin_unlock(&sock_rpmsg_table_lock);
+ return NULL;
+}
+
+struct sock_rpmsg_info * sock_soc_del_rpmsg_info(void* key)
+{
+ struct sock_rpmsg_info *p;
+ struct hlist_node *pos,*n;
+ //sk_soc_info("sock_soc_del_rpmsg_info key=%x \n", key);
+ spin_lock(&sock_rpmsg_table_lock);
+ hlist_for_each_entry_safe(p, pos, n, &g_sock_rpmsg_info, hlist_node) {
+ if(p->key == key){
+ hlist_del(&p->hlist_node);
+ spin_unlock(&sock_rpmsg_table_lock);
+ sk_soc_info("sock_soc_del_rpmsg_info sucess, key=%x \n", key);
+ kfree(p);
+ return 0;
+ }
+ }
+ spin_unlock(&sock_rpmsg_table_lock);
+ sk_soc_info("sock_soc_del_rpmsg_info failed, key=%x \n", key);
+ return -1;
+}
+
+static inline void sock_soc_insert_socket_info(struct hlist_node *list_node)
+{
+ spin_lock(&sock_socket_table_lock);
+ hlist_add_head(list_node, &g_sockets_info);
+ spin_unlock(&sock_socket_table_lock);
+}
+
+struct socket_info * sock_soc_set_socket_info(struct socket* proxysock, struct socket* localsock)
+{
+ struct socket_info *psock_socket_info = NULL;
+
+ if(0 == sock_soc_socket_is_valid(proxysock, localsock)){
+ sk_soc_info("sock_soc_socket_is_valid is true , do not add again");
+ return NULL;
+ }
+ psock_socket_info = (struct socket_info *)kzalloc(sizeof(struct socket_info), GFP_ATOMIC);
+ if(psock_socket_info == NULL){
+ return NULL;
+ }
+ memset(psock_socket_info, 0, sizeof(struct socket_info));
+ psock_socket_info->proxysocket = proxysock;
+ psock_socket_info->localsocket = localsock;
+ //sk_soc_info("sock_soc_set_socket_info sucess, key=%x", sock);
+ sock_soc_insert_socket_info(&psock_socket_info->hlist_node);
+ sk_soc_info("sock_soc_set_socket_info sucess, proxysocket=%x, localsock=%x", psock_socket_info->proxysocket, psock_socket_info->localsocket);
+ return psock_socket_info;
+}
+
+int sock_soc_socket_is_valid(struct socket* proxysock, struct socket* localsock)
+{
+ struct ipc_socket *p;
+ struct hlist_node *pos,*n;
+ spin_lock(&sock_table_lock);
+ if(hlist_empty(&g_ipc_sockets))
+ {
+ sk_soc_info("sock_soc_socket_is_valid g_ipc_sockets is empty");
+ spin_unlock(&sock_table_lock);
+ return -1;
+ }
+ hlist_for_each_entry_safe(p, pos, n, &g_ipc_sockets, hlist_node) {
+ if((p->proxysocket == proxysock)&&(p->localsocket == localsock)){
+ spin_unlock(&sock_table_lock);
+ return 0;
+ }
+ }
+ spin_unlock(&sock_table_lock);
+ return -1;
+}
+
+int sock_soc_del_socket_info(struct socket* proxysock, struct socket* localsock)
+{
+ struct ipc_socket *p;
+ struct hlist_node *pos,*n;
+ //sk_soc_info("sock_soc_del_socket_info key=%x \n", sock);
+ spin_lock(&sock_table_lock);
+ if(hlist_empty(&g_ipc_sockets))
+ {
+ sk_soc_info("sock_soc_del_socket_info g_ipc_sockets is empty");
+ spin_unlock(&sock_table_lock);
+ return -1;
+ }
+ hlist_for_each_entry_safe(p, pos, n, &g_ipc_sockets, hlist_node) {
+ if((p->proxysocket == proxysock)&&(p->localsocket == localsock)){
+ hlist_del(&p->hlist_node);
+ spin_unlock(&sock_table_lock);
+ sk_soc_info("sock_soc_del_socket_info sucess, proxysock=%x, localsock=%x \n", proxysock, localsock);
+ kfree(p);
+ return 0;
+ }
+ }
+ spin_unlock(&sock_table_lock);
+ sk_soc_info("sock_soc_del_socket_info failed, proxysock=%x,localsock=%x \n", proxysock, localsock);
+ return -1;
+}
+
+int sock_soc_socket_is_valid_other(struct socket* other)
+{
+ return 0;
+}
+
+int sock_soc_socket_is_valid_ipc(struct socket* localsocket, struct socket* remotesocket)
+{
+ struct ipc_socket *p;
+ struct hlist_node *pos,*n;
+ spin_lock(&sock_table_lock);
+ if(hlist_empty(&g_ipc_sockets))
+ {
+ sk_soc_info("sock_soc_socket_is_valid_ipc g_ipc_sockets is empty");
+ spin_unlock(&sock_table_lock);
+ return -1;
+ }
+ hlist_for_each_entry_safe(p, pos, n, &g_ipc_sockets, hlist_node) {
+ if((p->localsocket == localsocket)&&(p->remotesocket == remotesocket)){
+ spin_unlock(&sock_table_lock);
+ return 0;
+ }
+ }
+ spin_unlock(&sock_table_lock);
+ return -1;
+}
+
+struct sock_rpmsg_info * sock_soc_rsp_proc(struct sock_rpmsg* psock_rpmsg)
+{
+ struct sock_rpmsg_info *psock_rpmsg_info;
+ psock_rpmsg_info = sock_soc_get_rpmsg_info(psock_rpmsg->key);
+ if(NULL == psock_rpmsg_info){
+ sk_soc_err("sock_soc_get_rpmsg_info failed!");
+ return NULL;
+ }
+ memset(&psock_rpmsg_info->sock_rpmsg, 0, sizeof(struct sock_rpmsg));
+ memcpy(&psock_rpmsg_info->sock_rpmsg, psock_rpmsg, sizeof(struct sock_rpmsg));
+ up(&psock_rpmsg_info->sock_sem);
+ return psock_rpmsg_info;
+}
+int unix_is_ipc_socket(struct sock *sock)
+{
+ int result;
+ result = test_bit(SOCK_IPCSOCK, &sock->sk_flags);
+ //sk_soc_info("unix_is_ipc_socket result=%d", result);
+ return result;
+}
+EXPORT_SYMBOL_GPL(unix_is_ipc_socket);
+
+int unix_is_ipc_local_socket(struct sock *sock)
+{
+ int result;
+ result = test_bit(SOCK_IPC_LOCAL, &sock->sk_flags);
+ //sk_soc_info("unix_is_ipc_socket result=%d", result);
+ return result;
+}
+EXPORT_SYMBOL_GPL(unix_is_ipc_local_socket);
+
+/*·µ»ØÖµ´óÓÚµÈÓÚ0£¬±íʾдͨµÀ³É¹¦£»Ð¡ÓÚ0±íʾдͨµÀʧ°Ü*/
+static int sock_channel_write(struct sock_channel *chninfo, void *buf, unsigned int len)
+{
+ T_ZDrvRpMsg_Msg msg;
+
+ if(NULL == buf) {
+ return -EINVAL;
+ }
+ memset(&msg, 0, sizeof(msg));
+ msg.actorID = chninfo->core_id;
+ msg.chID = chninfo->channel_id;
+ msg.flag |= RPMSG_WRITE_INT; //| RPMSG_WRITE_IRQLOCK;
+ msg.buf = buf;
+ msg.len = len;
+ //sk_soc_info("sock_channel_write process, len=%d", len);
+ return sockSocWrite(&msg);
+}
+
+/*·µ»ØÖµ´óÓÚ0£¬±íʾ¶ÁȡͨµÀ³É¹¦£»Ð¡ÓÚµÈÓÚ0±íʾͨµÀÊý¾ÝΪ¿Õ»òʧ°Ü*/
+static int sock_channel_read(struct sock_channel *chninfo, void *buf, unsigned int len)
+{
+ T_ZDrvRpMsg_Msg msg;
+ int ret = 0;
+
+ if(NULL == buf) {
+ return -EINVAL;
+ }
+ sk_soc_info("sock_channel_read enter");
+ memset(&msg, 0, sizeof(msg));
+ msg.actorID = chninfo->core_id;
+ msg.chID = chninfo->channel_id;
+ msg.buf = buf;
+ msg.len = len;
+
+ ret = sockSocRead(&msg);
+ if (ret <= 0) {
+ sk_soc_err("rpm read err=%d!",ret);
+ return ret;
+ }
+
+ return ret;
+}
+
+static int sock_thread_enqueue_data(struct sock_rpmsg *sock_rpmsg)
+{
+ unsigned long flags;
+ struct sock_thread_info* p_main_thread_info;
+ p_main_thread_info = &g_sock_chn_info.main_thread_info;
+
+ spin_lock_irqsave(&p_main_thread_info->p_sock_lock,flags);
+ list_add_tail(&sock_rpmsg->list, &p_main_thread_info->p_sock_list);
+ spin_unlock_irqrestore(&p_main_thread_info->p_sock_lock,flags);
+ sock_put_sema(&p_main_thread_info->p_sock_sem);
+
+ return 0;
+}
+
+struct sock_rpmsg* sock_create_rpmsg(unsigned int size)
+{
+ struct sock_rpmsg* sock_rpmsg;
+
+ size = SOCK_DATA_ALIGN(size);
+ size += SOCK_DATA_ALIGN(sizeof(struct sock_rpmsg));
+ if(size > SOCK_DATA_MAX_LEN){
+ sk_soc_err("size of data is too large, max support size is %d", SOCK_DATA_MAX_LEN-sizeof(struct sock_rpmsg));
+ }
+ sock_rpmsg = kzalloc(size, GFP_KERNEL);
+ if (sock_rpmsg == NULL) {
+ sk_soc_err("kzalloc fial!!");
+ return NULL;
+ }
+ return sock_rpmsg;
+}
+
+static int sock_send_ipc_msg(struct sock_rpmsg* psock_rpmsg)
+{
+ struct sock_rpmsg* sock_rpmsg;
+ sock_rpmsg = sock_create_rpmsg(0);
+ if(NULL == sock_rpmsg){
+ sk_soc_err("kzalloc fial!!");
+ return -1;
+ }
+ memcpy(sock_rpmsg, psock_rpmsg, sizeof(struct sock_rpmsg));
+ sock_rpmsg->dir = DIR_DOWNLINK;
+ sock_thread_enqueue_data(sock_rpmsg);
+ //sk_soc_info("sock_send_ipc_msg write len=%d", len);
+ return 0;
+}
+
+static int sock_send_ipc_msg_data(struct sock_rpmsg* psock_rpmsg)
+{
+ if(NULL == psock_rpmsg){
+ sk_soc_err("psock_rpmsg is NULL!!");
+ return -1;
+ }
+
+ psock_rpmsg->dir = DIR_DOWNLINK;
+ sock_thread_enqueue_data(psock_rpmsg);
+ //sk_soc_info("sock_send_ipc_msg write len=%d", len);
+ return 0;
+}
+
+static int sock_recv_ipc_msg(struct sock_rpmsg* psock_rpmsg)
+{
+ struct sock_rpmsg* sock_rpmsg;
+ sk_soc_info("sock_receive_thread sock_rpmsg.msg_type=%d,index=%d", psock_rpmsg->msg_type, psock_rpmsg->index);
+ sock_rpmsg = sock_create_rpmsg(psock_rpmsg->data_len);
+ if(NULL == sock_rpmsg){
+ sk_soc_err("kzalloc fial!!");
+ return -1;
+ }
+ memcpy(sock_rpmsg, psock_rpmsg, psock_rpmsg->data_len+sizeof(struct sock_rpmsg));
+ sock_rpmsg->dir = DIR_UPLINK;
+ sock_thread_enqueue_data(sock_rpmsg);
+ //sk_soc_info("sock_send_ipc_msg write len=%d", len);
+ return 0;
+}
+
+int sock_lookup_fd_by_sock(struct sock *sock)
+{
+ struct socket *socket;
+ socket = sock->sk_socket;
+ sk_soc_info("sock_lookup_fd_by_sock socket=%x, socket->fd=%d\n", socket, socket->fd);
+ return socket->fd;
+}
+
+static int sock_channel_clear(struct sock_channel *chninfo)
+{
+ char *tbuf = NULL;
+ unsigned int tlen = chninfo->channel_size/2;
+ int ret = 0;
+
+ tbuf = (char *)kzalloc(tlen,GFP_ATOMIC);
+ if(IS_ERR(tbuf)) {
+ sk_soc_err("kzalloc fail! %d byte.", tlen);
+ return -ENOMEM;
+ }
+ ret = sock_channel_read(chninfo, tbuf, tlen);
+ if(ret < 0) {
+ sk_soc_err("zvnet_channel_read fail!");
+ ret = 0;
+ }
+ kfree(tbuf);
+ sk_soc_err("Drop channel data. %d byte.",ret);
+
+ return ret;
+}
+
+void usock_print(struct unix_sock* usock){
+ sk_soc_info("usock->rsock.localfd=%d", usock->rsock.localfd);
+ sk_soc_info("usock->rsock.localsocket=%x", usock->rsock.localsocket);
+ sk_soc_info("usock->rsock.proxyfd=%d", usock->rsock.proxyfd);
+ sk_soc_info("usock->rsock.proxysocket=%x", usock->rsock.proxysocket);
+ sk_soc_info("usock->rsock.remotefd=%d", usock->rsock.remotefd);
+ sk_soc_info("usock->rsock.remotesocket=%x", usock->rsock.remotesocket);
+}
+
+void usock_init(struct sock* sock, int localfd, struct socket* localsocket, int proxyfd, struct socket* proxysocket, int remotefd, struct socket* remotesocket){
+ struct unix_sock* usock;
+ if(NULL == sock){
+ return;
+ }
+ usock = unix_sk(sock);
+ usock->rsock.localfd = localfd;
+ usock->rsock.localsocket = localsocket;
+ usock->rsock.proxyfd = proxyfd;
+ usock->rsock.proxysocket = proxysocket;
+ usock->rsock.remotefd = remotefd;
+ usock->rsock.remotesocket = remotesocket;
+}
+
+void usock_update_remote_proxy_socket(struct sock* sock, struct socket* remoteproxysocket)
+{
+ struct unix_sock* usock;
+ usock = unix_sk(sock);
+ usock->rsock.remoteproxysocket = remoteproxysocket;
+}
+
+static struct ipc_socket * sock_create_proxy_socket_server(struct sock_rpmsg* psock_rpmsg)
+{
+ struct ipc_socket *psocket_ipc = NULL;
+ struct socket *sock;
+
+ int err;
+
+ sk_soc_info("clientsock=%x, serversock=%x!\n", psock_rpmsg->clientsock, psock_rpmsg->serversock);
+ psocket_ipc = sock_get_ipcsocket_by_local_and_remote(psock_rpmsg->clientsock, psock_rpmsg->serversock);
+ if(NULL != psocket_ipc) { //Èç¹ûÒѾ´´½¨¹ýͬһ·þÎñ¶ËµÄ´úÀí£¬Ôò²»ÔÙÖØ¸´´´½¨
+ sk_soc_info("socket_server already exist, do not create again!\n");
+ sock_hold(psocket_ipc->sock); //0705
+ return psocket_ipc;
+ }
+
+ psocket_ipc = (struct ipc_socket *)kzalloc(sizeof(struct ipc_socket), GFP_ATOMIC);
+ if(NULL == psocket_ipc){
+ sk_soc_err("kzalloc failed!\n");
+ return NULL;
+ }
+ psocket_ipc->sockfd = sys_socket(AF_UNIX, psock_rpmsg->socktype, 0); //´´½¨·þÎñ¶Ësocket´úÀí
+ sk_soc_info("sock_create_proxy_socket_server socktype=%d, socket->fd=%d", psock_rpmsg->socktype, psocket_ipc->sockfd);
+ //memcpy(&psocket_ipc->sock, &g_sock_rpmsg.sock, sizeof(struct sock));
+ //psocket_ipc->socket.sk = &psocket_ipc->sock;
+ psocket_ipc->socket = sock_get_local_socket(psocket_ipc->sockfd, &err);
+ if(NULL != psocket_ipc->socket){
+ sk_soc_info("sock_create_proxy_socket_server sucess\n");
+ psocket_ipc->sock = psocket_ipc->socket->sk;
+ psocket_ipc->proxysocket = psocket_ipc->socket;
+ psocket_ipc->socktype = psock_rpmsg->socktype;
+ set_bit(SOCK_IPCSOCK,&psocket_ipc->sock->sk_flags);
+ psocket_ipc->sock->ipc_flag = 1;
+ psocket_ipc->sock->sk_fd = psocket_ipc->sockfd;
+ //sock_soc_set_socket_info(psocket_ipc->socket, psock_rpmsg->clientsock);
+ sock_hold(psocket_ipc->sock); //0704
+ //³õʼ»¯´úÀísocketµÄusockÐÅÏ¢
+ usock_init(psocket_ipc->sock, psock_rpmsg->clientfd, psock_rpmsg->clientsock, psocket_ipc->sockfd, psocket_ipc->socket, psock_rpmsg->serverfd, psock_rpmsg->serversock);
+ usock_update_remote_proxy_socket(psocket_ipc->sock, psock_rpmsg->serverproxysock);
+ //usock_print(usock);
+ }
+ else{
+ sk_soc_info("sock_create_proxy_socket_server failed, socket = NULL\n");
+ }
+ //ͬ²½·þÎñÆ÷¶ËÅäÖÃ
+ //psocket_ipc->sock->sk_flags = g_sock_rpmsg.sock.sk_flags;
+ //psocket_ipc->sock->sk_state = g_sock_rpmsg.sock.sk_state;
+ //psocket_ipc->sock->sk_shutdown = g_sock_rpmsg.sock.sk_shutdown;
+ //psocket_ipc->sock->sk_receive_queue.qlen = g_sock_rpmsg.sock.sk_receive_queue.qlen;
+ //psocket_ipc->sock->sk_max_ack_backlog = g_sock_rpmsg.sock.sk_max_ack_backlog;
+ psocket_ipc->localfd = psock_rpmsg->clientfd;
+ psocket_ipc->localsocket = psock_rpmsg->clientsock;
+ psocket_ipc->remotefd = psock_rpmsg->serverfd;
+ psocket_ipc->remotesocket = psock_rpmsg->serversock;
+ psocket_ipc->remoteproxyfd = psock_rpmsg->serverproxyfd;
+ psocket_ipc->remoteproxysocket = psock_rpmsg->serverproxysock;
+ psocket_ipc->key = psock_rpmsg->serversock;
+ sk_soc_info("sock_create_proxy_socket_server sockfd=%d, remotefd=%d, key=%x\n", psocket_ipc->sockfd, psocket_ipc->remotefd, psocket_ipc->key);
+ INIT_HLIST_NODE(&psocket_ipc->hlist_node);
+ sock_soc_insert_socket(&psocket_ipc->hlist_node);
+ return psocket_ipc;
+}
+
+static struct ipc_socket * sock_create_proxy_socket_client(struct sock_rpmsg* psock_rpmsg)
+{
+ struct ipc_socket *psocket_ipc = NULL;
+ struct socket *sock;
+ struct unix_sock* usock;
+ int err;
+ //½öƾÕâÁ½¸ö²ÎÊý»¹²»ÄÜÈ·¶¨ÊÇ·ñͬһ¿Í»§¶ËµÄ´úÀí£¬ÒòΪ¶Ô¶Ë¿ÉÄܹرղ¢ÖØÐÂÉú³ÉÒ»¸öÏàͬµØÖ·µÄsocket
+ if(0 == psock_rpmsg->isfistfind){
+ psocket_ipc = sock_get_ipcsocket_by_local_and_remote(psock_rpmsg->serversock, psock_rpmsg->clientsock);
+ if(NULL != psocket_ipc) { //Èç¹ûÒѾ´´½¨¹ýͬһ¿Í»§¶ËµÄ´úÀí£¬Ôò²»ÔÙÖØ¸´´´½¨
+ //sock_hold(psocket_ipc->sock); //0703
+ return psocket_ipc;
+ }
+ }
+
+ psocket_ipc = (struct ipc_socket *)kzalloc(sizeof(struct ipc_socket), GFP_ATOMIC);
+ if(NULL == psocket_ipc){
+ sk_soc_err("kzalloc failed!\n");
+ return NULL;
+ }
+ sk_soc_info("sock_create_proxy_socket_client socktype=%d\n", psock_rpmsg->socktype);
+ psocket_ipc->sockfd = sys_socket(AF_UNIX, psock_rpmsg->socktype, 0); //´´½¨¿Í»§¶Ësocket´úÀí
+ sk_soc_info("sock_create_proxy_socket_client socket->fd=%d\n", psocket_ipc->sockfd);
+ psocket_ipc->socket = sock_get_local_socket(psocket_ipc->sockfd, &err);
+
+ //usock_print(usock);
+
+ if(NULL != psocket_ipc->socket){
+ sk_soc_info("sockfd_lookup sucess, socket=%x \n", psocket_ipc->socket);
+ //³õʼ»¯´úÀísocketµÄusockÐÅÏ¢
+ usock_init(psocket_ipc->socket->sk, psock_rpmsg->serverfd, psock_rpmsg->serversock, psocket_ipc->sockfd, psocket_ipc->socket, psock_rpmsg->clientfd, psock_rpmsg->clientsock);
+
+ psocket_ipc->sock = psocket_ipc->socket->sk;
+ set_bit(SOCK_IPCSOCK,&psocket_ipc->sock->sk_flags);
+ psocket_ipc->sock->ipc_flag = 1;
+ psocket_ipc->sock->sk_fd = psocket_ipc->sockfd;
+ //sock_hold(psocket_ipc->sock); //todo: clientÊDz»ÊDz»Ó¦¸Ãµ÷ÓÃsock_hold?
+ }
+ else{
+ sk_soc_info("server socket = NULL");
+ }
+ //ÒòΪ´Ëʱ¶Ô¶ËµÄ´úÀísocket»¹Î´´´½¨£¬ËùÒÔÎÞ·¨»ñÈ¡remoteproxyfdºÍremoteproxysocket
+ psocket_ipc->localfd = psock_rpmsg->serverfd;
+ psocket_ipc->localsocket = psock_rpmsg->serversock;
+ psocket_ipc->remotefd = psock_rpmsg->clientfd;
+ psocket_ipc->remotesocket = psock_rpmsg->clientsock;
+ psocket_ipc->proxysocket = psocket_ipc->socket;
+
+ psocket_ipc->key = psock_rpmsg->clientsock;
+ sk_soc_info("sock_create_proxy_socket_client sockfd=%d,remotefd=%d,key=%x", psocket_ipc->sockfd, psocket_ipc->remotefd,psocket_ipc->key);
+ INIT_HLIST_NODE(&psocket_ipc->hlist_node);
+ sock_soc_insert_socket(&psocket_ipc->hlist_node);
+ return psocket_ipc;
+}
+
+int sock_soc_recvq_full(const struct sock *other)
+{
+ struct sock_rpmsg sock_rpmsg = {0};
+ struct ipc_socket * ipc_socket;
+ struct sock_rpmsg_info *psock_rpmsg_info;
+ int sockfd;
+ int result;
+ sk_soc_info("sock_soc_recvq_full enter");
+ sock_rpmsg.msg_type = MSG_TYPE_RECVQ_FULL;
+ sockfd = sock_lookup_fd_by_sock(other);
+ //sock_rpmsg.serverfd = sock_lookup_serverfd_by_clientfd(sockfd);
+ //ipc_socket = sock_lookup_server_by_clientfd(sockfd);
+ ipc_socket = sock_soc_get_ipcsocket_by_proxysock(other);
+ if(NULL == ipc_socket){
+ sk_soc_info("sock_soc_recvq_full get ipc_socket faild \n");
+ return -1;
+ }
+ sock_rpmsg.serverfd = ipc_socket->remotefd;
+ sock_rpmsg.serversock = ipc_socket->remotesocket;
+ sock_rpmsg.clientsock = ipc_socket->localsocket;
+ sock_rpmsg.key = other;
+ psock_rpmsg_info = sock_soc_create_rpmsg_info(sock_rpmsg.key);
+ if(NULL == psock_rpmsg_info){
+ sk_soc_info("sock_soc_recvq_full create rpmsg faild \n");
+ return -1;
+ }
+ sock_send_ipc_msg(&sock_rpmsg);
+ down_timeout(&psock_rpmsg_info->sock_sem, msecs_to_jiffies(g_sock_timeout));
+ result = psock_rpmsg_info->sock_rpmsg.result;
+ sock_soc_del_rpmsg_info(sock_rpmsg.key);
+ return result;
+}
+EXPORT_SYMBOL_GPL(sock_soc_recvq_full);
+
+int sock_soc_recvq_full_proc(struct sock_rpmsg* psock_rpmsg)
+{
+ struct ipc_socket* ipcsocket;
+ struct socket *other;
+ int err;
+ int result;
+ struct sock_rpmsg sock_rpmsg = {0};
+ sk_soc_info("sock_soc_recvq_full_proc serverfd=%d", psock_rpmsg->serverfd);
+ sock_rpmsg.msg_type = MSG_TYPE_RECVQ_FULL_RESULT;
+ sock_rpmsg.key = psock_rpmsg->key;
+ //other = sock_get_local_socket(psock_rpmsg->serverfd, &err);
+ other = (struct socket*)psock_rpmsg->serversock;
+ if(sock_soc_socket_is_valid_ipc(other, psock_rpmsg->clientsock) == -1){ //serversockÒѹرÕ
+ sk_soc_info("sock_soc_socket_is_valid is false \n");
+ sock_send_ipc_msg(&sock_rpmsg);
+ return -1;
+ }
+ sock_rpmsg.result = unix_recvq_full_proxy(other->sk);
+ sk_soc_info("sock_soc_recvq_full_proc result=%d\n", sock_rpmsg.result);
+ sock_rpmsg.serverfd = other->fd; //sock_lookup_fd_by_sock(other->sk);
+ sock_send_ipc_msg(&sock_rpmsg);
+ return 0;
+}
+
+int sock_soc_recvq_full_result_proc(struct sock_rpmsg* psock_rpmsg)
+{
+ sk_soc_info("sock_soc_recvq_full_result_proc\n");
+ sock_soc_rsp_proc(psock_rpmsg);
+ return 0;
+}
+
+int sock_soc_recvq_full_lockless_and_dead(const struct sock *other)
+{
+ struct sock_rpmsg sock_rpmsg = {0};
+ struct ipc_socket *ipc_socket;
+ struct sock_rpmsg_info *psock_rpmsg_info;
+ int sockfd;
+ int result;
+ sk_soc_info("sock_soc_recvq_full_lockless_and_dead\n");
+ sock_rpmsg.msg_type = MSG_TYPE_RECVQ_FULL_LOCKLESS_AND_DEAD;
+ sockfd = sock_lookup_fd_by_sock(other);
+ //sock_rpmsg.serverfd = sock_lookup_serverfd_by_clientfd(sockfd);
+ //ipc_socket = sock_lookup_server_by_clientfd(sockfd);
+ ipc_socket = sock_soc_get_ipcsocket_by_proxysock(other);
+ if(NULL == ipc_socket){
+ sk_soc_info("sock_soc_recvq_full_lockless_and_dead get ipc_socket faild \n");
+ return -1;
+ }
+ sock_rpmsg.serverfd = ipc_socket->remotefd;
+ sock_rpmsg.serversock = ipc_socket->remotesocket;
+ sock_rpmsg.clientsock = ipc_socket->localsocket;
+ sock_rpmsg.key = other;
+ psock_rpmsg_info = sock_soc_create_rpmsg_info(sock_rpmsg.key);
+ if(NULL == psock_rpmsg_info){
+ sk_soc_info("sock_soc_recvq_full_lockless_and_dead create rpmsg faild \n");
+ return -1;
+ }
+ sock_send_ipc_msg(&sock_rpmsg);
+ down_timeout(&psock_rpmsg_info->sock_sem, msecs_to_jiffies(g_sock_timeout));
+ result = psock_rpmsg_info->sock_rpmsg.result;
+ sock_soc_del_rpmsg_info(sock_rpmsg.key);
+ return result;
+}
+EXPORT_SYMBOL_GPL(sock_soc_recvq_full_lockless_and_dead);
+
+int sock_soc_recvq_full_lockless_and_dead_proc(struct sock_rpmsg* psock_rpmsg)
+{
+ struct ipc_socket* ipcsocket;
+ struct socket *other;
+ int err;
+ int result;
+ struct sock_rpmsg sock_rpmsg = {0};
+ sk_soc_info("sock_soc_recvq_full_lockless_and_dead_proc");
+ sock_rpmsg.msg_type = MSG_TYPE_RECVQ_FULL_LOCKLESS_AND_DEAD_RESULT;
+ sock_rpmsg.key = psock_rpmsg->key;
+ //other = sock_get_local_socket(psock_rpmsg->serverfd, &err);
+ other = (struct socket*)psock_rpmsg->serversock;
+ if(sock_soc_socket_is_valid_ipc(other, psock_rpmsg->clientsock) == -1){ //serversockÒѹرÕ
+ sk_soc_info("sock_soc_socket_is_valid is false \n");
+ sock_send_ipc_msg(&sock_rpmsg);
+ return -1;
+ }
+ sock_rpmsg.result = unix_recvq_full_proxy_lockless_and_deadstate(other->sk);
+ sock_rpmsg.serverfd = sock_lookup_fd_by_sock(other->sk);
+ sock_send_ipc_msg(&sock_rpmsg);
+ return 0;
+}
+
+int sock_soc_recvq_full_lockless_and_dead_result_proc(struct sock_rpmsg* psock_rpmsg)
+{
+ sk_soc_info("sock_soc_recvq_full_lockless_and_dead_result_proc");
+ sock_soc_rsp_proc(psock_rpmsg);
+ return 0;
+}
+/*
+** sock: ±¾µØsocket
+** other:¶Ô¶ËsocketµÄ±¾µØ´úÀí
+*/
+int sock_soc_set_peer(struct sock *sock, struct sock *other)
+{
+ struct sock_rpmsg sock_rpmsg = {0};
+ struct ipc_socket *ipc_socket;
+ int sockfd;
+ sock_rpmsg.msg_type = MSG_TYPE_SET_PEER;
+ sock_rpmsg.clientfd = sock_lookup_fd_by_sock(sock);
+ sock_rpmsg.clientsock = sock->sk_socket;
+ sockfd = sock_lookup_fd_by_sock(other);
+ //sock_rpmsg.serverfd = sock_lookup_serverfd_by_clientfd(sockfd);
+ //ipc_socket = sock_lookup_server_by_clientfd(sockfd);
+ ipc_socket = sock_soc_get_ipcsocket_by_proxysock(other);
+ if(NULL == ipc_socket){
+ sk_soc_info("sock_soc_set_peer get ipc_socket faild \n");
+ return -1;
+ }
+ sock_rpmsg.serverfd = ipc_socket->remotefd;
+ sock_rpmsg.serversock = ipc_socket->remotesocket;
+ sk_soc_info("sock_soc_set_peer clientfd=%d, serverfd=%d\n", sock_rpmsg.clientfd, sock_rpmsg.serverfd);
+
+ unix_peer(sock) = other;
+ sock_send_ipc_msg(&sock_rpmsg);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(sock_soc_set_peer);
+
+int sock_soc_set_peer_proc(struct sock_rpmsg* psock_rpmsg)
+{
+ struct ipc_socket* ipcsocket;
+ struct socket *clientsocket;
+ struct socket *serversocket;
+ struct sock *sock;
+ struct sock *other;
+ int err;
+ sk_soc_info("sock_soc_set_peer_proc clientfd=%d, serverfd=%d", psock_rpmsg->clientfd, psock_rpmsg->serverfd);
+ //¶ÔÓÚ·þÎñ¶ËÀ´Ëµ,serversockÊôÓÚ±¾µØsocket£¬clientsockÊôÓÚÔ¶¶Ësocket
+ ipcsocket = sock_get_ipcsocket_by_local_and_remote(psock_rpmsg->serversock, psock_rpmsg->clientsock);
+ if(ipcsocket == NULL){
+ sk_soc_info("sock_soc_set_peer_proc failed, clientfd=%d,clientsock=%x\n ", psock_rpmsg->clientfd, psock_rpmsg->clientsock);
+ return -1;
+ }
+ //clientsocket = (struct socket*)psock_rpmsg->clientsock;
+ sock = ipcsocket->sock;
+ //serversocket = sock_get_local_socket(psock_rpmsg->serverfd, &err);
+ serversocket = (struct socket*)psock_rpmsg->serversock;
+ if(sock_soc_socket_is_valid_ipc(serversocket, psock_rpmsg->clientsock) == -1){ //serversockÒѹرÕ
+ sk_soc_info("sock_soc_socket_is_valid is false \n");
+ return -1;
+ }
+ other = serversocket->sk;
+
+ unix_peer(sock) = other;
+ sock_hold(other);
+ //unix_peer(other) = sock; //0703
+ return 0;
+}
+
+/*½«ËùÓÐsocket->peer==sockµÄsocket,È«²¿¸üÐÂΪsocket->peer=newsock*/
+//¸Ã½Ó¿ÚÓÃÓÚ·þÎñ¶Ë֪ͨ¿Í»§¶Ë
+int sock_soc_update_peer(struct socket *sock, struct socket *newsock)
+{
+ struct sock_rpmsg sock_rpmsg = {0};
+ struct sock* proxysock;
+ struct ipc_socket* ipcsocket;
+ int sockfd;
+ struct unix_sock* usock;
+ //newsock->sk->peerÖ¸ÏòµÄÊǿͻ§¶Ë´úÀísock
+ proxysock = unix_peer(newsock->sk);
+ usock = unix_sk(proxysock);
+ usock->rsock.localsocket = newsock;
+ ipcsocket = sock_soc_get_ipcsocket_by_proxysock(proxysock);
+ if(NULL != ipcsocket){
+ sock_rpmsg.serversock = ipcsocket->remotesocket;
+ ipcsocket->localsocket = newsock;
+ sk_soc_info("remotesocket=%x, localsocket=%x", ipcsocket->remotesocket, ipcsocket->localsocket);
+ }else{
+ sk_soc_info("sock_soc_get_ipcsocket_by_proxysock failed, sock=%x", sock);
+ return -1;
+ }
+ sk_soc_info("sock=%x, newsock=%x", sock, newsock);
+ sock_rpmsg.msg_type = MSG_TYPE_UPDATE_PEER;
+ sock_rpmsg.clientfd = sock->fd;
+ sock_rpmsg.clientsock = sock;
+ sock_rpmsg.newclientfd = newsock->fd;
+ sock_rpmsg.newsock = newsock;
+ sock_soc_del_socket_peer(sock, ipcsocket->proxysocket);
+ sock_soc_insert_socket_peer(newsock, ipcsocket->proxysocket);
+ //newsock->peer = sock->peer; //0706
+ //sock->peer = NULL; //0706
+ sock_rpmsg.key = sock_rpmsg.serversock;
+ sk_soc_info("clientfd=%d, newclientfd=%d\n", sock_rpmsg.clientfd, sock_rpmsg.newclientfd);
+ //sock_soc_del_socket_info(proxysock->sk_socket, sock); //ɾ³ý¾ÉµÄÐÅÏ¢
+ //sock_soc_set_socket_info(proxysock->sk_socket, newsock); //Ìí¼ÓеÄÐÅÏ¢
+ sock_send_ipc_msg(&sock_rpmsg);
+ return 0;
+}
+
+EXPORT_SYMBOL_GPL(sock_soc_update_peer);
+
+int sock_soc_update_peer_proc(struct sock_rpmsg* psock_rpmsg)
+{
+ struct ipc_socket* ipcsocket;
+ struct socket *clientsocket;
+ struct socket *serversocket;
+ struct sock *sock;
+ struct sock *other;
+ struct unix_sock* usock;
+ int err;
+ sk_soc_info("sock_soc_update_peer_proc clientfd=%d, newclientfd=%d", psock_rpmsg->clientfd, psock_rpmsg->newclientfd);
+ ipcsocket = sock_get_ipcsocket_by_local_and_remote(psock_rpmsg->serversock, psock_rpmsg->clientsock);
+ if(ipcsocket == NULL){
+ sk_soc_info("sock_soc_update_peer_proc failed, clientfd=%d,clientsock=%x\n ", psock_rpmsg->clientfd, psock_rpmsg->clientsock);
+ return -1;
+ }
+ sk_soc_info("sock_soc_update_peer_proc sock=%x, newsock=%x", ipcsocket->remotesocket, psock_rpmsg->newsock);
+ ipcsocket->remotefd = psock_rpmsg->newclientfd;
+ ipcsocket->remotesocket = psock_rpmsg->newsock;
+ ipcsocket->key = psock_rpmsg->newsock;
+ usock = unix_sk(ipcsocket->proxysocket->sk);
+ usock->rsock.remotefd = psock_rpmsg->newclientfd;
+ usock->rsock.remotesocket = psock_rpmsg->newsock;
+ sock_soc_rsp_proc(psock_rpmsg);//ÊÍ·ÅconnectµÈ´ýµÄÐźÅÁ¿
+ return 0;
+}
+
+void sock_soc_sock_hold(struct sock *other)
+{
+ struct ipc_socket *psocket_ipc = NULL;
+ struct sock_rpmsg sock_rpmsg = {0};
+ sock_rpmsg.msg_type = MSG_TYPE_SOCK_HOLD;
+ //dump_stack();
+ //²éÕÒ·þÎñÆ÷¶Ë´úÀísocketÏà¹ØÐÅÏ¢
+ psocket_ipc = sock_soc_get_ipcsocket_by_proxysock(other);
+ if(psocket_ipc == NULL){
+ sk_soc_info("sock_soc_sock_hold failed, other->fd=%d\n ", other->sk_fd);
+ return;
+ }
+ //·þÎñÆ÷¶Ësocket fd
+ sock_rpmsg.serverfd = psocket_ipc->remotefd;
+ sock_rpmsg.serversock = psocket_ipc->remotesocket;
+ sock_rpmsg.clientsock = psocket_ipc->localsocket;
+ sk_soc_info("sock_soc_sock_hold serverfd=%d \n", sock_rpmsg.serverfd);
+ sock_send_ipc_msg(&sock_rpmsg);
+}
+
+int sock_soc_sock_hold_proc(struct sock_rpmsg* psock_rpmsg)
+{
+ struct socket* serversocket;
+ struct sock* other;
+
+ serversocket = (struct socket*)psock_rpmsg->serversock;
+ if(sock_soc_socket_is_valid_ipc(serversocket, psock_rpmsg->clientsock) == -1){ //serversockÒѹرÕ
+ sk_soc_info("sock_soc_socket_is_valid is false \n");
+ return -1;
+ }
+ other = serversocket->sk;
+
+ sk_soc_info("sock_soc_sock_hold_proc serverfd=%d \n", psock_rpmsg->serverfd);
+ sock_hold(other);
+ return 0;
+}
+
+int sock_soc_sock_put(struct sock *other)
+{
+ struct sock_rpmsg sock_rpmsg = {0};
+ int sockfd;
+ struct ipc_socket *ipc_socket;
+ sock_rpmsg.msg_type = MSG_TYPE_SOCK_PUT;
+ //other->sk_socket¿ÉÄÜÒѱ»ÖÃΪnull
+ if(!other->sk_socket){
+ sockfd = other->sk_fd;
+ }
+ else{
+ sockfd = sock_lookup_fd_by_sock(other);
+ }
+
+ //sock_rpmsg.serverfd = sock_lookup_serverfd_by_clientfd(sockfd);
+ //ipc_socket = sock_lookup_server_by_clientfd(sockfd);
+ ipc_socket = sock_soc_get_ipcsocket_by_proxysock(other);
+ if(NULL == ipc_socket){
+ sk_soc_info("sock_soc_sock_put get ipc_socket faild \n");
+ return -1;
+ }
+ sock_rpmsg.serverfd = ipc_socket->remotefd;
+ sock_rpmsg.serversock = ipc_socket->remotesocket;
+ sock_rpmsg.clientsock = ipc_socket->localsocket;
+ sk_soc_info("sock_soc_sock_put serverfd=%d\n", sock_rpmsg.serverfd);
+ sock_send_ipc_msg(&sock_rpmsg);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(sock_soc_sock_put);
+
+int sock_soc_sock_put_proc(struct sock_rpmsg* psock_rpmsg)
+{
+ struct socket *other;
+ int err;
+ //other = sock_get_local_socket(psock_rpmsg->serverfd, &err);
+ other = (struct socket*)psock_rpmsg->serversock;
+ if(sock_soc_socket_is_valid_ipc(other, psock_rpmsg->clientsock) == -1){ //serversockÒѹرÕ
+ sk_soc_info("sock_soc_socket_is_valid is false \n");
+ return -1;
+ }
+ sk_soc_info("sock_soc_sock_put_proc serversock=%x, serverfd=%d",other, psock_rpmsg->serverfd);
+ if(other->sk){
+ sock_put(other->sk);
+ }
+
+ return 0;
+}
+
+int sock_soc_msg_send(struct sock *sock, struct sock *other, struct msghdr *msg, size_t len)
+{
+ struct ipc_socket *psocket_ipc = NULL;
+ //struct sock_rpmsg sock_rpmsg = {0};
+ //sock_rpmsg.msg_type = MSG_TYPE_SEND_MSG;
+ struct sock_rpmsg* psock_rpmsg =NULL;
+
+ psock_rpmsg = sock_create_rpmsg(len);
+ if(psock_rpmsg == NULL){
+ sk_soc_err("sock_soc_msg_send failed, sock_create_rpmsg failed\n ");
+ return -1;
+ }
+ psock_rpmsg->msg_type = MSG_TYPE_SEND_MSG;
+ //¿Í»§¶Ësocket fd
+ psock_rpmsg->clientfd = sock_lookup_fd_by_sock(sock);
+ psock_rpmsg->clientsock = sock->sk_socket;
+ //²éÕÒ·þÎñÆ÷¶Ë´úÀísocketÏà¹ØÐÅÏ¢
+ psocket_ipc = sock_soc_get_ipcsocket_by_proxysock(other);
+ if(psocket_ipc == NULL){
+ sk_soc_info("sock_soc_msg_send failed, other->sk_fd=%d\n ", other->sk_fd);
+ kfree(psock_rpmsg);
+ return -1;
+ }
+ //·þÎñÆ÷¶Ësocket fd
+ psock_rpmsg->serverfd = psocket_ipc->remotefd;
+ psock_rpmsg->serversock = psocket_ipc->remotesocket;
+ psock_rpmsg->clientsock = psocket_ipc->localsocket;
+
+ psock_rpmsg->msg_flags = msg->msg_flags;
+ //¿½±´·¢Ë͵ÄÊý¾Ý
+ memcpy_fromiovec(psock_rpmsg->data, msg->msg_iov, len);
+ psock_rpmsg->data_len = len;
+ //strcpy(sock_rpmsg.data, "test");
+ //sock_rpmsg.data_len = 4;
+ //¿½±´socketµØÖ·
+ if(msg->msg_namelen > 0){
+ memcpy(&psock_rpmsg->sockaddr, (struct sockaddr_un*)msg->msg_name, msg->msg_namelen);
+ }
+ psock_rpmsg->addr_len = msg->msg_namelen;
+ sk_soc_info("sock_soc_msg_send clientfd=%d, serverfd=%d, data=%s, len=%d\n", psock_rpmsg->clientfd, psock_rpmsg->serverfd, psock_rpmsg->data, len);
+ sock_send_ipc_msg_data(psock_rpmsg);
+ return 0;
+}
+
+int sock_soc_msg_send_proc(struct sock_rpmsg* psock_rpmsg)
+{
+ struct ipc_socket* clientsocket;
+ struct socket* serversocket;
+ struct sock* sock;
+ struct sock* other;
+ char __user * p,q;
+ mm_segment_t old_fs;
+ struct msghdr msg;
+ unsigned int msg_flags;
+ struct iovec iov;
+ int err;
+
+ //serversocket = sock_get_local_socket(psock_rpmsg->serverfd, &err);
+ serversocket = (struct socket*)psock_rpmsg->serversock;
+ if(sock_soc_socket_is_valid_ipc(serversocket, psock_rpmsg->clientsock) == -1){ //serversockÒѹرÕ
+ sk_soc_info("sock_soc_socket_is_valid is false \n");
+ return -1;
+ }
+ other = serversocket->sk;
+
+ clientsocket = sock_get_ipcsocket_by_local_and_remote(psock_rpmsg->serversock, psock_rpmsg->clientsock);
+ if(clientsocket == NULL){
+ sk_soc_info("sock_soc_msg_send_proc failed, serversock=%x,clientsock=%x\n ", psock_rpmsg->serversock, psock_rpmsg->clientsock);
+ return -1;
+ }
+ sk_soc_info("sock_soc_msg_send_proc, serversock=%x,clientsock=%x\n ", psock_rpmsg->serversock, psock_rpmsg->clientsock);
+ sock = clientsocket->sock;
+
+ sk_soc_info("sock_soc_msg_send_proc clientfd=%d, serverfd=%d, len=%d", psock_rpmsg->clientfd, psock_rpmsg->serverfd, psock_rpmsg->data_len);
+
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ if(psock_rpmsg->addr_len > 0){
+ p = (__force struct sockaddr_un __user *)(&psock_rpmsg->sockaddr);
+ }
+ q = (__force const char __user *)(psock_rpmsg->data);
+ //sys_sendto(psock_rpmsg->serverfd, psock_rpmsg->data, psock_rpmsg->data_len, psock_rpmsg->msg_flags, NULL, 0);
+ if(psock_rpmsg->addr_len > 0){
+ sys_sendto(clientsocket->sockfd, psock_rpmsg->data, psock_rpmsg->data_len, psock_rpmsg->msg_flags, &psock_rpmsg->sockaddr, psock_rpmsg->addr_len);
+ }else{
+ sys_sendto(clientsocket->sockfd, psock_rpmsg->data, psock_rpmsg->data_len, psock_rpmsg->msg_flags, NULL, 0);
+ }
+ set_fs(old_fs);
+ //other->sk_data_ready(other, psock_rpmsg->data_len);
+ //sock_put(other);
+ return 0;
+}
+
+long sock_wait_for_peer(struct sock *sock, struct sock *other, long timeo)
+{
+ struct ipc_socket * ipcsocket;
+ struct sock_rpmsg sock_rpmsg = {0};
+ sock_rpmsg.clientfd = sock_lookup_fd_by_sock(sock);
+ sock_rpmsg.clientsock = sock->sk_socket;
+ ipcsocket = sock_soc_get_ipcsocket_by_proxysock(other);
+ if(ipcsocket == NULL){
+ sk_soc_info("sock_wait_for_peer failed, other->fd=%d\n ", other->sk_fd);
+ return -1;
+ }
+ sock_rpmsg.serverfd = ipcsocket->remotefd;
+ sock_rpmsg.serversock = ipcsocket->remotesocket;
+ sock_rpmsg.msg_type = MSG_TYPE_WAIT_FOR_PEER;
+ sock_rpmsg.timeo = timeo;
+ sk_soc_info("sock_wait_for_peer clientfd=%d, serverfd=%d", sock_rpmsg.clientfd, sock_rpmsg.serverfd);
+ sock_send_ipc_msg(&sock_rpmsg);
+ return 0;
+}
+
+static int sock_wait_for_peer_thread(void *argv)
+{
+ struct peer_sock_info* peer_info = (struct peer_sock_info*)argv;
+ sk_soc_info("sock_wait_for_peer_thread enter");
+ unix_wait_for_peer_proxy(peer_info->peersock, peer_info->timeo);
+ return 0;
+}
+
+int sock_wait_for_peer_proc(struct sock_rpmsg* psock_rpmsg)
+{
+ struct ipc_socket *socket_ipc;
+ struct task_struct *th = NULL;
+ struct socket* clientsocket;
+ struct socket* serversocket;
+ int err;
+ socket_ipc = sock_get_ipcsocket_by_local_and_remote(psock_rpmsg->serversock, psock_rpmsg->clientsock);
+ if(socket_ipc == NULL){
+ sk_soc_info("sock_wait_for_peer_proc failed, clientfd=%d,clientsock=%x\n ", psock_rpmsg->clientfd, psock_rpmsg->clientsock);
+ return -1;
+ }
+ struct peer_sock_info* peer_info = (struct peer_sock_info *)kzalloc(sizeof(struct peer_sock_info), GFP_ATOMIC);
+ if(NULL == peer_info){
+ sk_soc_err("kzalloc failed!");
+ return -1;
+ }
+ peer_info->timeo = psock_rpmsg->timeo;
+ clientsocket= sock_get_local_socket(socket_ipc->sockfd, &err);
+ if(NULL == clientsocket){
+ kfree(peer_info);
+ sk_soc_err("clientsocket is NULL!");
+ return -1;
+ }
+ //clientsocket = (struct socket*)psock_rpmsg->clientsock;
+ peer_info->sock = clientsocket->sk;
+ //serversocket = sock_get_local_socket(psock_rpmsg->serverfd, &err);
+ serversocket = (struct socket*)psock_rpmsg->serversock;
+ if(sock_soc_socket_is_valid_other(serversocket) == -1){ //serversockÒѹرÕ
+ sk_soc_info("sock_soc_socket_is_valid is false \n");
+ return -1;
+ }
+ peer_info->peersock = serversocket->sk;
+ sk_soc_info("sock_wait_for_peer_proc clientfd=%d, serverfd=%d", socket_ipc->sockfd, psock_rpmsg->serverfd);
+ th = kthread_run(sock_wait_for_peer_thread, peer_info, "wait_for_peer");
+ if (IS_ERR(th)) {
+ sk_soc_err("Unable to start receive thread.");
+ return PTR_ERR(th);
+ }
+ return 0;
+}
+
+int sock_soc_unix_peer_clear(struct sock *sk)
+{
+ struct sock_rpmsg sock_rpmsg = {0};
+ struct ipc_socket *socket_ipc;
+ sk_soc_info("sock_soc_unix_peer_clear enter\n");
+ //socket_ipc = sock_soc_get_ipcsocket_by_fd(psock_rpmsg->clientfd, psock_rpmsg->clientsock);
+ sock_rpmsg.clientfd = sock_lookup_fd_by_sock(sk);
+ sock_rpmsg.clientsock = sk->sk_socket;
+ sock_rpmsg.msg_type = MSG_TYPE_PEER_CLEAR;
+ sock_send_ipc_msg(&sock_rpmsg);
+ return 0;
+}
+
+int sock_soc_unix_peer_clear_proc(struct sock_rpmsg* psock_rpmsg)
+{
+ struct socket* socket;
+ struct sock* sock;
+ int err;
+ sk_soc_info("sock_soc_unix_peer_clear_proc enter");
+ //socket = sock_get_local_socket(psock_rpmsg->serverfd, &err);
+ socket = (struct socket*)psock_rpmsg->serversock;
+ if(sock_soc_socket_is_valid_other(socket) == -1){ //serversockÒѹرÕ
+ sk_soc_info("sock_soc_socket_is_valid is false \n");
+ return -1;
+ }
+ sock = socket->sk;
+ if(sock == NULL){
+ sk_soc_info("sock_soc_unix_peer_clear_proc sock is NULL");
+ return -1;
+ }
+ unix_sk(sock)->peer = NULL;
+ return 0;
+}
+
+int sock_soc_wake_up_interruptible_poll(struct sock *sk)
+{
+ struct sock_rpmsg sock_rpmsg = {0};
+
+ sock_rpmsg.clientfd = sock_lookup_fd_by_sock(sk);
+ sock_rpmsg.clientsock = sk->sk_socket;
+ sock_rpmsg.msg_type = MSG_TYPE_WAKE_UP_INTERRUPTIBLE_POLL;
+ sk_soc_info("sock_soc_wake_up_interruptible_poll clientfd=%d", sock_rpmsg.clientfd);
+ sock_send_ipc_msg(&sock_rpmsg);
+ return 0;
+}
+
+int sock_soc_wake_up_interruptible_poll_proc(struct sock_rpmsg* psock_rpmsg)
+{
+ struct socket* socket;
+ struct sock* sock;
+ int err;
+ //serverfd = sock_lookup_serverfd_by_clientfd(psock_rpmsg->clientfd);
+ //socket = sock_get_local_socket(serverfd, &err);
+ socket = (struct socket*)psock_rpmsg->serversock;
+ if(sock_soc_socket_is_valid_other(socket) == -1){ //serversockÒѹرÕ
+ sk_soc_info("sock_soc_socket_is_valid is false \n");
+ return -1;
+ }
+ sock = socket->sk;
+ if(sock == NULL){
+ sk_soc_info("sock_soc_wake_up_interruptible_poll_proc sock is NULL");
+ return -1;
+ }
+
+ wake_up_interruptible_poll(sk_sleep(sock),
+ POLLOUT |
+ POLLWRNORM |
+ POLLWRBAND);
+ return 0;
+}
+
+int sock_soc_sk_data_ready(struct sock *sk)
+{
+ struct sock_rpmsg sock_rpmsg = {0};
+ struct ipc_socket * ipcsocket;
+ ipcsocket = sock_soc_get_ipcsocket_by_proxysock(sk);
+ if(ipcsocket == NULL){
+ sk_soc_info("sock_soc_sk_data_ready failed, sk->fd=%d\n ", sk->sk_fd);
+ return -1;
+ }
+ sock_rpmsg.serverfd = ipcsocket->remotefd;
+ sock_rpmsg.serversock = ipcsocket->remotesocket;
+ sock_rpmsg.clientsock = ipcsocket->localsocket;
+ sk_soc_info("sock_soc_sk_data_ready serverfd=%d", sock_rpmsg.serverfd);
+ sock_rpmsg.msg_type = MSG_TYPE_DATA_READY;
+ sock_send_ipc_msg(&sock_rpmsg);
+ return 0;
+}
+
+int sock_soc_sk_data_ready_proc(struct sock_rpmsg* psock_rpmsg)
+{
+ struct socket* socket;
+ struct sock* sock;
+ int err;
+ //socket = sock_get_local_socket(psock_rpmsg->serverfd, &err);
+ socket = (struct socket*)psock_rpmsg->serversock;
+ if(sock_soc_socket_is_valid_ipc(socket, psock_rpmsg->clientsock) == -1){ //serversockÒѹرÕ
+ sk_soc_info("sock_soc_socket_is_valid is false \n");
+ return -1;
+ }
+ sk_soc_info("sock_soc_sk_data_ready_proc serverfd=%d", psock_rpmsg->serverfd);
+ sock = socket->sk;
+ if(sock == NULL){
+ sk_soc_info("sock_soc_sk_data_ready_proc sock is NULL");
+ return -1;
+ }
+ sock->sk_data_ready(sock, 1);
+ return 0;
+}
+
+int sock_sync_ipc_socket(struct sock_elem_flag* elem_flag, struct sock *other)
+{
+ struct sock_rpmsg sock_rpmsg = {0};
+ struct ipc_socket * ipcsocket;
+ sock_rpmsg.msg_type = MSG_TYPE_SYNC_IPC_SOCKET;
+ memcpy(&sock_rpmsg.elem, elem_flag, sizeof(struct sock_elem_flag));
+ //memcpy(&sock_rpmsg.sock, other, sizeof(struct sock));
+ ipcsocket = sock_soc_get_ipcsocket_by_proxysock(other);
+ if(ipcsocket == NULL){
+ sk_soc_info("sock_sync_ipc_socket failed, other->fd=%d\n ", other->sk_fd);
+ return -1;
+ }
+ sock_rpmsg.serverfd = ipcsocket->remotefd;
+ sock_rpmsg.serversock = ipcsocket->remotesocket;
+ sock_rpmsg.clientsock = ipcsocket->localsocket;
+ sk_soc_info("sock_sync_ipc_socket serverfd=%d", sock_rpmsg.serverfd);
+ sock_send_ipc_msg(&sock_rpmsg);
+
+ return 0;
+}
+
+int sock_sync_ipc_socket_proc(struct sock_rpmsg* psock_rpmsg)
+{
+ struct socket* socket;
+ struct sock *other;
+ int err;
+ //socket = sock_get_local_socket(psock_rpmsg->serverfd, &err);
+ socket = (struct socket*)psock_rpmsg->serversock;
+ if(NULL == socket){
+ return -1;
+ }
+ if(sock_soc_socket_is_valid_ipc(socket, psock_rpmsg->clientsock) == -1){ //serversockÒѹرÕ
+ sk_soc_info("sock_soc_socket_is_valid is false \n");
+ return -1;
+ }
+ other = socket->sk;
+ if(other == NULL){
+ sk_soc_info("sock_sync_ipc_socket_proc other is NULL");
+ return -1;
+ }
+ sk_soc_info("sock_sync_ipc_socket_proc serverfd=%d", psock_rpmsg->serverfd);
+ if(psock_rpmsg->elem.sk_err){
+ //other->sk_err = psock_rpmsg->sock.sk_err;
+ }
+
+ if(psock_rpmsg->elem.sk_error_report){
+ other->sk_error_report(other);
+ }
+
+ return 0;
+}
+
+int sock_soc_get_state(struct sock_elem_flag* elem_flag, struct sock *other)
+{
+ struct sock_rpmsg sock_rpmsg = {0};
+ struct ipc_socket * ipcsocket;
+ struct sock_rpmsg_info *psock_rpmsg_info;
+ sock_rpmsg.msg_type = MSG_TYPE_GET_SOCKET_STATES;
+ memcpy(&sock_rpmsg.elem, elem_flag, sizeof(struct sock_elem_flag));
+ ipcsocket = sock_soc_get_ipcsocket_by_proxysock(other);
+ if(ipcsocket == NULL){
+ sk_soc_info("sock_soc_get_state failed, other->fd=%d\n ", other->sk_fd);
+ return -1;
+ }
+ sock_rpmsg.serverfd = ipcsocket->remotefd;
+ sock_rpmsg.serversock = ipcsocket->remotesocket;
+ sock_rpmsg.clientsock = ipcsocket->localsocket;
+ sock_rpmsg.key = other;
+ sk_soc_info("sock_soc_get_state serverfd=%d", sock_rpmsg.serverfd);
+
+ psock_rpmsg_info = sock_soc_create_rpmsg_info(sock_rpmsg.key);
+ if(NULL == psock_rpmsg_info){
+ sk_soc_info("sock_soc_get_state create rpmsg faild \n");
+ return -1;
+ }
+ sock_send_ipc_msg(&sock_rpmsg);
+ down_timeout(&psock_rpmsg_info->sock_sem, msecs_to_jiffies(g_sock_timeout));
+
+ if(psock_rpmsg_info->sock_rpmsg.elem.skstate){
+ other->sk_state = psock_rpmsg_info->sock_rpmsg.elem.skstate;
+ sk_soc_info("sk_state=%d", other->sk_state);
+ }
+
+ if(psock_rpmsg_info->sock_rpmsg.elem.skshutdown){
+ other->sk_shutdown = psock_rpmsg_info->sock_rpmsg.elem.skshutdown;
+ sk_soc_info("sk_shutdown=%d", other->sk_shutdown);
+ }
+ sock_soc_del_rpmsg_info(sock_rpmsg.key);
+ sk_soc_info("sock_soc_get_state end");
+ return 0;
+}
+
+int sock_soc_get_state_proc(struct sock_rpmsg* psock_rpmsg)
+{
+ struct socket* socket;
+ struct sock *other;
+ struct sock_rpmsg sock_rpmsg = {0};
+ int err;
+ sock_rpmsg.msg_type = MSG_TYPE_GET_SOCKET_STATES_RESULT;
+ sock_rpmsg.key = psock_rpmsg->key;
+ sk_soc_info("sock_soc_get_state_proc serverfd=%d", psock_rpmsg->serverfd);
+ //socket = sock_get_local_socket(psock_rpmsg->serverfd, &err);
+ socket = (struct socket*)psock_rpmsg->serversock;
+ if(sock_soc_socket_is_valid_ipc(socket, psock_rpmsg->clientsock) == -1){ //serversockÒѹرÕ
+ sk_soc_info("sock_soc_socket_is_valid is false \n");
+ sock_send_ipc_msg(&sock_rpmsg);
+ return -1;
+ }
+ if(NULL != socket){
+ sk_soc_info("sock_soc_get_state_proc sucess");
+ other = socket->sk;
+ if(other == NULL){
+ sk_soc_info("sock_soc_get_state_proc other is NULL");
+ sock_send_ipc_msg(&sock_rpmsg);
+ return -1;
+ }
+ if(psock_rpmsg->elem.skstate){
+ sock_rpmsg.elem.skstate = other->sk_state;
+ sk_soc_info("sk_state=%d", other->sk_state);
+ }
+
+ if(psock_rpmsg->elem.skshutdown){
+ sock_rpmsg.elem.skshutdown = other->sk_shutdown;
+ sk_soc_info("sk_shutdown=%d", other->sk_shutdown);
+ }
+ }
+ else
+ {
+ sk_soc_info("sock_soc_get_state_proc failed");
+ }
+ sock_send_ipc_msg(&sock_rpmsg);
+ return 0;
+}
+
+int sock_soc_get_state_result_proc(struct sock_rpmsg* psock_rpmsg)
+{
+ sk_soc_info("sock_soc_find_other_result_proc");
+ sock_soc_rsp_proc(psock_rpmsg);
+ return 0;
+}
+
+int sock_soc_test_flags(struct sock *other, enum sock_flags flag)
+{
+ struct sock_rpmsg sock_rpmsg = {0};
+ struct ipc_socket * ipcsocket;
+ struct sock_rpmsg_info *psock_rpmsg_info;
+ int result;
+ sock_rpmsg.msg_type = MSG_TYPE_TEST_FLAG;
+ ipcsocket = sock_soc_get_ipcsocket_by_proxysock(other);
+ if(ipcsocket == NULL){
+ sk_soc_info("sock_soc_test_flags failed, other->fd=%d\n ", other->sk_fd);
+ return -1;
+ }
+ sock_rpmsg.serverfd = ipcsocket->remotefd;
+ sock_rpmsg.serversock = ipcsocket->remotesocket;
+ sock_rpmsg.clientsock = ipcsocket->localsocket;
+ //sock_rpmsg.flag = flag;
+ sock_rpmsg.flag = convert_to_cap_sock_flag(flag);
+ if(sock_rpmsg.flag == -1)
+ {
+ sk_soc_info("cap do not support flag=%s ", flag_value[flag]);
+ return 0;
+ }
+ sock_rpmsg.key = other;
+ sk_soc_info("sock_soc_test_flags serverfd=%d", sock_rpmsg.serverfd);
+
+ psock_rpmsg_info = sock_soc_create_rpmsg_info(sock_rpmsg.key);
+ if(NULL == psock_rpmsg_info){
+ sk_soc_info("sock_soc_get_state create rpmsg faild \n");
+ return -1;
+ }
+ sock_send_ipc_msg(&sock_rpmsg);
+ down_timeout(&psock_rpmsg_info->sock_sem, msecs_to_jiffies(g_sock_timeout));
+ sk_soc_info("sock_soc_test_flags flag=%s, result=%d\n",flag_value[flag], g_sock_rpmsg.result);
+ result = psock_rpmsg_info->sock_rpmsg.result;
+ sock_soc_del_rpmsg_info(sock_rpmsg.key);
+ return result;
+}
+EXPORT_SYMBOL_GPL(sock_soc_test_flags);
+
+int sock_soc_test_flags_proc(struct sock_rpmsg* psock_rpmsg)
+{
+ struct sock_rpmsg sock_rpmsg = {0};
+ struct socket* socket;
+ struct sock *other;
+ int err;
+ //socket = sock_get_local_socket(psock_rpmsg->serverfd, &err);
+ sock_rpmsg.msg_type = MSG_TYPE_TEST_FLAG_RESULT;
+ sock_rpmsg.key = psock_rpmsg->key;
+ socket = (struct socket*)psock_rpmsg->serversock;
+ if(sock_soc_socket_is_valid_ipc(socket, psock_rpmsg->clientsock) == -1){ //serversockÒѹرÕ
+ sk_soc_info("sock_soc_socket_is_valid is false \n");
+ sock_send_ipc_msg(&sock_rpmsg);
+ return -1;
+ }
+ if(NULL == socket){
+ sk_soc_info("sock_soc_test_flags_proc failed, flag=%s", flag_value[psock_rpmsg->flag]);
+ sock_send_ipc_msg(&sock_rpmsg);
+ return -1;
+ }
+ other = socket->sk;
+ if(other == NULL){
+ sock_send_ipc_msg(&sock_rpmsg);
+ return -1;
+ }
+ sock_rpmsg.result = test_bit(psock_rpmsg->flag, &other->sk_flags);
+ sk_soc_info("sock_soc_test_flags_proc flag=%s, result=%d", flag_value[psock_rpmsg->flag], sock_rpmsg.result);
+ sock_send_ipc_msg(&sock_rpmsg);
+ return 0;
+}
+
+int sock_soc_test_flags_result_proc(struct sock_rpmsg* psock_rpmsg)
+{
+ sk_soc_info("sock_soc_test_flags_result_proc enter");
+ sock_soc_rsp_proc(psock_rpmsg);
+
+ return 0;
+}
+
+void sock_soc_add_skb_queue_tail(struct sock *sock, struct sock *other)
+{
+ struct ipc_socket * ipcsocket;
+ struct sock_rpmsg sock_rpmsg = {0};
+ sock_rpmsg.clientfd = sock_lookup_fd_by_sock(sock);
+ sock_rpmsg.clientsock = sock->sk_socket;
+ ipcsocket = sock_soc_get_ipcsocket_by_proxysock(other);
+ if(ipcsocket == NULL){
+ sk_soc_info("sock_soc_add_skb_queue_tail failed, other->fd=%d\n ", other->sk_fd);
+ return;
+ }
+ sock_rpmsg.serverfd = ipcsocket->remotefd;
+ sock_rpmsg.serversock = ipcsocket->remotesocket;
+ sock_rpmsg.clientsock = ipcsocket->localsocket;
+ sock_rpmsg.msg_type = MSG_TYPE_ADD_SKB_QUEUE_TAIL;
+ sk_soc_info("sock_soc_add_skb_queue_tail clientfd=%d, serverfd=%d", sock_rpmsg.clientfd, sock_rpmsg.serverfd);
+ sock_send_ipc_msg(&sock_rpmsg);
+}
+
+void sock_soc_add_skb_queue_tail_proc(struct sock_rpmsg* psock_rpmsg)
+{
+ struct ipc_socket * ipcsocket;
+ struct socket* other;
+ struct sk_buff *skb = NULL;
+ int err;
+ //¸ù¾ÝclientfdÕÒµ½±¾µØ´úÀísocket
+ ipcsocket = sock_get_ipcsocket_by_local_and_remote(psock_rpmsg->serversock, psock_rpmsg->clientsock);
+ if(ipcsocket == NULL){
+ sk_soc_info("sock_soc_add_skb_queue_tail_proc failed, clientfd=%d,clientsock=%x\n ", psock_rpmsg->clientfd, psock_rpmsg->clientsock);
+ return;
+ }
+ //other = sockfd_lookup(psock_rpmsg->serverfd, &err);
+ other = (struct socket*)psock_rpmsg->serversock;
+ if(sock_soc_socket_is_valid_ipc(other, psock_rpmsg->clientsock) == -1){ //serversockÒѹرÕ
+ sk_soc_info("sock_soc_socket_is_valid is false \n");
+ return;
+ }
+ sk_soc_info("sock_soc_add_skb_queue_tail clientfd=%d, serverfd=%d", psock_rpmsg->clientfd, psock_rpmsg->serverfd);
+ if((NULL != ipcsocket) && (NULL != other)){
+ /* Allocate skb for sending to listening sock */
+ skb = sock_wmalloc(ipcsocket->sock, 1, 0, GFP_KERNEL);
+ if (skb == NULL)
+ {
+ return;
+ }
+
+ __skb_queue_tail(&other->sk->sk_receive_queue, skb);
+ sk_soc_info("sock_soc_add_skb_queue_tail sucess! \n");
+ }
+}
+
+void sock_soc_stream_connect(struct sock *sock, struct sock *other, struct sockaddr_un *sunname, int len,int flags)
+{
+ struct ipc_socket * ipcsocket;
+ struct sock_rpmsg sock_rpmsg = {0};
+ struct sock_rpmsg_info *psock_rpmsg_info;
+ if(len > 0){
+ memcpy(&sock_rpmsg.sockaddr, sunname, sizeof(struct sockaddr_un));
+ sk_soc_info("sock_soc_stream_connect sockaddr=%s", sock_rpmsg.sockaddr.sun_path);
+ sock_rpmsg.addr_len = len;
+ }
+ sock_rpmsg.flags = flags;
+ sock_rpmsg.clientfd = sock_lookup_fd_by_sock(sock);
+ sock_rpmsg.clientsock = sock->sk_socket;
+ ipcsocket = sock_soc_get_ipcsocket_by_proxysock(other);
+ if(ipcsocket == NULL){
+ sk_soc_info("sock_soc_stream_connect failed, other->fd=%d\n ", other->sk_fd);
+ return;
+ }
+ sock_rpmsg.serverfd = ipcsocket->remotefd;
+ sock_rpmsg.serversock = ipcsocket->remotesocket;
+ sock_rpmsg.msg_type = MSG_TYPE_STREAM_CONNECT;
+ sock_rpmsg.key = sock_rpmsg.clientsock;
+ psock_rpmsg_info = sock_soc_create_rpmsg_info(sock_rpmsg.key);
+ if(NULL == psock_rpmsg_info){
+ sk_soc_info("sock_soc_stream_connect create rpmsg faild \n");
+ return;
+ }
+ sock_send_ipc_msg(&sock_rpmsg);
+ //ÒªµÈµ½ÊÕµ½update_peer²ÅÄÜ·µ»Ø
+ down_timeout(&psock_rpmsg_info->sock_sem, msecs_to_jiffies(g_sock_timeout));
+ sk_soc_info("sock_soc_stream_connect clientfd=%d, serverfd=%d\n", sock_rpmsg.clientfd, sock_rpmsg.serverfd);
+ sock_soc_del_rpmsg_info(sock_rpmsg.key);
+}
+
+void sock_soc_stream_connect_proc(struct sock_rpmsg* psock_rpmsg)
+{
+ struct ipc_socket * ipcsocket;
+ struct socket* other;
+ struct sk_buff *skb = NULL;
+ struct sock *newsk = NULL;
+ int result = -1;
+ int err;
+ //¸ù¾ÝclientfdÕÒµ½±¾µØ´úÀísocket
+ ipcsocket = sock_get_ipcsocket_by_local_and_remote(psock_rpmsg->serversock, psock_rpmsg->clientsock);
+ if(ipcsocket == NULL){
+ sk_soc_info("sock_soc_stream_connect_proc failed, clientfd=%d,clientsock=%x\n ", psock_rpmsg->clientfd, psock_rpmsg->clientsock);
+ return;
+ }
+ //other = sockfd_lookup(psock_rpmsg->serverfd, &err);
+ other = (struct socket*)psock_rpmsg->serversock;
+
+ sk_soc_info("sock_soc_stream_connect_proc clientfd=%d, serverfd=%d\n", psock_rpmsg->clientfd, psock_rpmsg->serverfd);
+ if((NULL != ipcsocket) && (NULL != other)){
+ sk_soc_info("sockaddr=%s", psock_rpmsg->sockaddr.sun_path);
+ result = unix_stream_connect_proxy(ipcsocket->socket, (struct sockaddr *)&psock_rpmsg->sockaddr, psock_rpmsg->addr_len, psock_rpmsg->flags);
+ if(0 == result){
+ sk_soc_info("sock_soc_stream_connect_proc sucess! ");
+ }else{
+ sk_soc_info("sock_soc_stream_connect_proc failed! ");
+ }
+ }
+}
+
+void sock_soc_add_wait_queue(struct sock *sock, struct sock *other)
+{
+ struct ipc_socket * ipcsocket;
+ struct sock_rpmsg sock_rpmsg = {0};
+ sock_rpmsg.clientfd = sock_lookup_fd_by_sock(sock);
+ sock_rpmsg.clientsock = sock->sk_socket;
+ ipcsocket = sock_soc_get_ipcsocket_by_proxysock(other);
+ if(ipcsocket == NULL){
+ sk_soc_info("sock_soc_add_wait_queue failed, other->fd=%d\n ", other->sk_fd);
+ return;
+ }
+ sock_rpmsg.serverfd = ipcsocket->remotefd;
+ sock_rpmsg.serversock = ipcsocket->remotesocket;
+ sock_rpmsg.msg_type = MSG_TYPE_ADD_WAIT_QUEUE;
+ sk_soc_info("sock_soc_add_wait_queue enter");
+ sock_send_ipc_msg(&sock_rpmsg);
+}
+
+void sock_soc_add_wait_queue_proc(struct sock_rpmsg* psock_rpmsg)
+{
+ struct ipc_socket * ipcsocket;
+ struct socket* socket;
+ int err;
+ //¸ù¾ÝclientfdÕÒµ½±¾µØ´úÀísocket
+ ipcsocket = sock_get_ipcsocket_by_local_and_remote(psock_rpmsg->serversock, psock_rpmsg->clientsock);
+ if(ipcsocket == NULL){
+ sk_soc_info("sock_soc_add_wait_queue_proc failed, clientfd=%d,clientsock=%x\n ", psock_rpmsg->clientfd, psock_rpmsg->clientsock);
+ return;
+ }
+ //socket = sockfd_lookup(psock_rpmsg->serverfd, &err);
+ socket = (struct socket*)psock_rpmsg->serversock;
+
+ sk_soc_info("sock_soc_add_wait_queue_proc clientfd=%d, serverfd=%d", psock_rpmsg->clientfd, psock_rpmsg->serverfd);
+ if((NULL != ipcsocket) && (NULL != socket)){
+ unix_dgram_peer_wake_connect_proxy(ipcsocket->sock, socket->sk);
+ }
+}
+
+void sock_soc_remove_wait_queue(struct sock *sock, struct sock *other)
+{
+ struct ipc_socket * ipcsocket;
+ struct sock_rpmsg sock_rpmsg = {0};
+ sock_rpmsg.clientfd = sock_lookup_fd_by_sock(sock);
+ sock_rpmsg.clientsock = sock->sk_socket;
+ ipcsocket = sock_soc_get_ipcsocket_by_proxysock(other);
+ if(ipcsocket == NULL){
+ sk_soc_info("sock_soc_remove_wait_queue failed, other->fd=%d\n ", other->sk_fd);
+ return;
+ }
+ sock_rpmsg.serverfd = ipcsocket->remotefd;
+ sock_rpmsg.serversock = ipcsocket->remotesocket;
+ sock_rpmsg.msg_type = MSG_TYPE_REMOVE_WAIT_QUEUE;
+ sk_soc_info("sock_soc_remove_wait_queue clientfd=%d, serverfd=%d", sock_rpmsg.clientfd, sock_rpmsg.serverfd);
+ sock_send_ipc_msg(&sock_rpmsg);
+}
+
+void sock_soc_remove_wait_queue_proc(struct sock_rpmsg* psock_rpmsg)
+{
+ struct ipc_socket * ipcsocket;
+ struct socket* socket;
+ int err;
+ //¸ù¾ÝclientfdÕÒµ½±¾µØ´úÀísocket
+ ipcsocket = sock_get_ipcsocket_by_local_and_remote(psock_rpmsg->serversock, psock_rpmsg->clientsock);
+ if(ipcsocket == NULL){
+ sk_soc_info("sock_soc_remove_wait_queue_proc failed, clientfd=%d,clientsock=%x\n ", psock_rpmsg->clientfd, psock_rpmsg->clientsock);
+ return;
+ }
+ //socket = sockfd_lookup(psock_rpmsg->serverfd, &err);
+ socket = (struct socket*)psock_rpmsg->serversock;
+
+ sk_soc_info("sock_soc_remove_wait_queue_proc clientfd=%d, serverfd=%d", psock_rpmsg->clientfd, psock_rpmsg->serverfd);
+ if((NULL != ipcsocket) && (NULL != socket)){
+ unix_dgram_peer_wake_connect_proxy(ipcsocket->sock, socket->sk);
+ }
+}
+
+void sock_soc_notify_proxy_change_to_server(struct socket* proxysocket, struct socket* remoteproxysocket)
+{
+ struct sock_rpmsg sock_rpmsg = {0};
+ sock_rpmsg.clientproxyfd = proxysocket->fd;
+ sock_rpmsg.clientproxysock = proxysocket;
+ sock_rpmsg.serverproxysock = remoteproxysocket;
+ sock_rpmsg.msg_type = MSG_TYPE_NOTIFY_PROXY_CHANGE;
+ sk_soc_info("sock_soc_notify_proxy_change_to_server clientproxysock=%x, serverproxysock=%x", sock_rpmsg.clientproxysock, sock_rpmsg.serverproxysock);
+ sock_send_ipc_msg(&sock_rpmsg);
+}
+
+void sock_soc_notify_proxy_change_to_server_proc(struct sock_rpmsg* psock_rpmsg)
+{
+ struct ipc_socket* ipc_socket;
+ struct socket* serverproxysock;
+ ipc_socket = sock_soc_get_ipcsocket_by_proxysock(psock_rpmsg->serverproxysock);
+ if(NULL != ipc_socket){
+ sk_soc_info("sock_soc_notify_proxy_change_to_server_proc remoteproxysocket=%x", psock_rpmsg->clientproxysock);
+ ipc_socket->remoteproxyfd = psock_rpmsg->clientproxyfd;
+ ipc_socket->remoteproxysocket = psock_rpmsg->clientproxysock;
+ serverproxysock = (struct socket*)psock_rpmsg->serverproxysock;
+ usock_update_remote_proxy_socket(serverproxysock->sk, psock_rpmsg->clientproxysock);
+ }
+}
+
+struct sock *sock_soc_find_other(struct socket * socket/*int fd*/,
+ struct sockaddr_un *sunname, int len,
+ int type, unsigned int hash, int *error)
+{
+ struct sock_rpmsg sock_rpmsg = {0};
+ struct ipc_socket *psocket_ipc = NULL;
+ struct sock_rpmsg_info *psock_rpmsg_info = NULL;
+ int err;
+ //struct socket *clisocket = sock_get_local_socket(fd, &err);
+ memcpy(&sock_rpmsg.sockaddr, sunname, sizeof(struct sockaddr_un));
+ sock_rpmsg.addr_len = len;
+ sock_rpmsg.socktype = type;
+ sock_rpmsg.hash = hash;
+ sock_rpmsg.clientfd = socket->fd;
+ sock_rpmsg.clientsock = socket;
+ sock_rpmsg.key = socket;
+ sock_rpmsg.msg_type = MSG_TYPE_FIND;
+ sock_rpmsg.isfistfind = 0;
+
+ if(sock_soc_get_ipcsocket_by_localsocket(socket) == NULL){ //˵Ã÷ÊǵÚÒ»´Î·¢Æð²éÕÒ
+ sock_rpmsg.isfistfind = 1;
+ }
+
+ psock_rpmsg_info = sock_soc_create_rpmsg_info(sock_rpmsg.key);
+ sk_soc_info("sock_soc_find_other clientfd=%d, key=%x", sock_rpmsg.clientfd, sock_rpmsg.key);
+ sock_send_ipc_msg(&sock_rpmsg);
+ down_timeout(&psock_rpmsg_info->sock_sem, msecs_to_jiffies(g_sock_timeout));
+
+ if(test_bit(SOCK_OP_RESULT, &psock_rpmsg_info->sock_rpmsg.flags)){
+ sk_soc_info("sock_soc_find_other sucess serverfd=%d", psock_rpmsg_info->sock_rpmsg.serverfd);
+ psocket_ipc = psock_rpmsg_info->ipc_socket;
+ sk_soc_info("sock_soc_find_other sockfd=%d, remotefd=%d", psocket_ipc->sockfd, psocket_ipc->remotefd);
+ //socket->peer = psocket_ipc->socket;
+ sock_soc_insert_socket_peer(socket, psocket_ipc->proxysocket);
+ sock_soc_del_rpmsg_info(sock_rpmsg.key);
+ sock_soc_notify_proxy_change_to_server(psocket_ipc->proxysocket, psocket_ipc->remoteproxysocket);
+ //sock_soc_set_socket_info(psocket_ipc->socket, socket);
+ return psocket_ipc->sock;
+ } else {
+ sk_soc_info("sock_soc_find_other failed, no matched socket");
+ }
+ sock_soc_del_rpmsg_info(sock_rpmsg.key);
+
+ return NULL;
+}
+
+int sock_soc_find_other_proc(struct sock_rpmsg* psock_rpmsg)
+{
+ struct sock *u;
+ struct ipc_socket *psocket_ipc = NULL;
+ //struct net tmpnet={0};
+ struct sock_rpmsg sock_rpmsg = {0};
+ int serverfd;
+ int error = -1;
+ unsigned int hash;
+ sk_soc_info("sock_soc_find_other_proc index=%d", psock_rpmsg->index);
+ if((NULL == psock_rpmsg) || (psock_rpmsg->msg_type != MSG_TYPE_FIND)){
+ sk_soc_info("sock_soc_find_other_proc failed, NULL == psock_rpmsg");
+ return -1;
+ }
+ sock_rpmsg.msg_type = MSG_TYPE_FIND_RESULT;
+ sk_soc_info("sockaddr=%s,socktype=%d, hash=%d",psock_rpmsg->sockaddr.sun_path,psock_rpmsg->socktype,psock_rpmsg->hash);
+ error = unix_mkname_proxy(&psock_rpmsg->sockaddr, psock_rpmsg->addr_len, &hash);
+ if (error < 0){
+ sk_soc_info("unix_mkname_proxy failed, error=%d", error);
+ }
+ sk_soc_info("unix_mkname_proxy sucess, hash=%d", hash);
+ //init_net
+ u = unix_find_other_proxy(&init_net, &psock_rpmsg->sockaddr, psock_rpmsg->addr_len, psock_rpmsg->socktype, hash, &error);
+ if(u){
+ sk_soc_info("find_other_proc: u(%x)->sk_socket=%x\n", u, u->sk_socket);
+ serverfd = sock_lookup_fd_by_sock(u);
+ psock_rpmsg->serverfd = serverfd;
+ psock_rpmsg->serversock = u->sk_socket;
+ psocket_ipc = sock_create_proxy_socket_client(psock_rpmsg);
+ if(NULL != psocket_ipc){
+ psocket_ipc->localsocket = u->sk_socket;
+ set_bit(SOCK_OP_RESULT, &sock_rpmsg.flags);
+ //memcpy(&sock_rpmsg.sock, u, sizeof(struct sock));
+ sock_rpmsg.serverfd = serverfd;
+ sock_rpmsg.serversock = u->sk_socket;
+ sock_rpmsg.socktype = u->sk_socket->type;
+ sock_rpmsg.serverproxyfd = psocket_ipc->sockfd;
+ sock_rpmsg.serverproxysock = psocket_ipc->proxysocket;
+ //u->sk_socket->peer = psocket_ipc->socket; //TODO:u¿ÉÄܱ»¶à¸ö¿Í»§¶Ë²éÕÒ£¬´Ë´¦peerÖ¸Ïò´úÀísocketÓÐÎÊÌ⣬ÒòΪ¿ÉÄÜ´æÔÚ¶à¸ö´úÀísocket
+ sock_soc_insert_socket_peer(u->sk_socket, psocket_ipc->proxysocket);
+ }
+
+ sock_put(u); //0707
+ sk_soc_info("sock_soc_find_other_proc success, socktype=%d, serverfd=%d, key=%x, index=%d\n", sock_rpmsg.socktype, sock_rpmsg.serverfd, psock_rpmsg->key, psock_rpmsg->index);
+ }
+ else
+ {
+ sk_soc_info("sock_soc_find_other_proc failed, error=%d", error);
+ }
+ sock_rpmsg.key = psock_rpmsg->key;
+ sock_rpmsg.clientfd = psock_rpmsg->clientfd;
+ sock_rpmsg.clientsock = psock_rpmsg->clientsock;
+ sock_rpmsg.index = psock_rpmsg->index;
+ sock_send_ipc_msg(&sock_rpmsg);
+
+ return 0;
+}
+
+int sock_soc_find_other_result_proc(struct sock_rpmsg* psock_rpmsg)
+{
+ struct sock_rpmsg_info *psock_rpmsg_info = NULL;
+
+ psock_rpmsg_info = sock_soc_get_rpmsg_info(psock_rpmsg->key);
+ if(NULL == psock_rpmsg_info){
+ sk_soc_info("sock_soc_find_other_result_proc failed\n");
+ return -1;
+ }
+ memset(&psock_rpmsg_info->sock_rpmsg, 0, sizeof(struct sock_rpmsg));
+ memcpy(&psock_rpmsg_info->sock_rpmsg, psock_rpmsg, sizeof(struct sock_rpmsg));
+ if(test_bit(SOCK_OP_RESULT, &psock_rpmsg->flags)){
+ psock_rpmsg_info->ipc_socket = sock_create_proxy_socket_server(psock_rpmsg);
+ }
+ up(&psock_rpmsg_info->sock_sem);
+ return 0;
+}
+
+static void delayed_release(struct work_struct *unused)
+{
+ //struct llist_node *node = llist_del_all(&delayed_release_list);
+ struct release_socket *rsock, *t;
+ sk_soc_info("delayed_release enter\n");
+ spin_lock(&sock_release_table_lock);
+ list_for_each_entry_safe(rsock, t, &delayed_release_list, list_node){
+ //sock_soc_release_sock(rsock);
+ sock_soc_release_peer(rsock);
+ list_del(&rsock->list_node);
+ kfree(rsock);
+ }
+ spin_unlock(&sock_release_table_lock);
+}
+
+static DECLARE_DELAYED_WORK(delayed_release_work, delayed_release);
+
+void sock_soc_delay_release(struct socket *sock)
+{
+ struct release_socket* prelease_socket = NULL;
+ struct unix_sock* usock;
+ struct socket_info *p;
+ struct hlist_node *pos,*n;
+ if(!hlist_empty(&sock->peer)){
+ spin_lock(&sock_release_peer_lock);
+ hlist_for_each_entry_safe(p, pos, n, &sock->peer, hlist_node) {
+ usock = unix_sk(p->proxysocket->sk);
+ //ÅжÏusockÐÅÏ¢ÊÇ·ñ»¹ÔÚ´úÀíÁ´±íÖÐ
+ if(0 != sock_is_valide_ipc_socket(usock->rsock.localsocket, usock->rsock.proxysocket, usock->rsock.remotesocket)){
+ sk_soc_info("sock_soc_delay_release failed \n");
+ continue;
+ }
+ prelease_socket = (struct release_socket *)kzalloc(sizeof(struct release_socket), GFP_ATOMIC);
+ if(NULL == prelease_socket){
+ sk_soc_info("kzalloc failed \n");
+ continue;
+ }
+ memcpy(prelease_socket, &usock->rsock, sizeof(struct release_socket));
+ list_add(&prelease_socket->list_node, &delayed_release_list);
+ sock_soc_del_socket_info(p->proxysocket, sock);
+ }
+
+ //sock_put(sock->sk); /* It may now die */
+
+ INIT_HLIST_HEAD(&sock->peer);
+ spin_unlock(&sock_release_peer_lock);
+ schedule_delayed_work(&delayed_release_work, 1);
+ //}
+ }
+
+}
+
+int sock_soc_release_peer(struct release_socket* rsock)
+{
+ struct sock_rpmsg sock_rpmsg = {0};
+ struct socket* peersocket;
+ struct ipc_socket * ipcsocket;
+ struct sock* proxy_sock = NULL;
+ //ɾ³ý±¾µØ¶ÔÓ¦µÄ´úÀísocket
+ if(rsock->proxysocket){
+ sk_soc_info("sock_soc_release_peer close fd=%d \n", rsock->proxysocket->fd);
+ sock_rpmsg.socktype = rsock->proxysocket->type;
+ //ipcsocket = sock_soc_get_ipcsocket(rsock->sock->sk); //0706¸ù¾Ý±¾µØ´úÀísocket,ÕÒµ½¶ÔÓ¦·þÎñ¶Ësocket
+ if(NULL != rsock->remotesocket){
+ sock_rpmsg.serverfd = rsock->remotefd;
+ sock_rpmsg.serversock = rsock->remotesocket;
+ }else{
+ sk_soc_info("sock_soc_get_ipcsocket_by_proxysock failed \n");
+ }
+
+ spin_lock(&sock_release_lock);
+
+ rsock->proxysocket->sk->closed = 1;
+ proxy_sock = rsock->proxysocket->sk->proxy_sock;
+ sys_close(rsock->proxysocket->fd);
+ if(proxy_sock != NULL){ //0706
+ unix_release_sock_proxy(proxy_sock);
+ }
+ //Ç°ÃæÒѾɾ³ý¹ýÁË
+ //sock_del_ipc_socket_by_proxysocket(rsock->proxysocket);
+ spin_unlock(&sock_release_lock);
+ }
+ sock_rpmsg.clientfd = rsock->localfd;
+ sock_rpmsg.clientsock = rsock->localsocket;
+ sock_rpmsg.serversock = rsock->remotesocket;
+ sock_rpmsg.serverproxysock = rsock->remoteproxysocket;
+ sock_rpmsg.msg_type = MSG_TYPE_RELEASE_PEER;
+ sk_soc_info("sock_soc_release_peer clientfd=%d \n", sock_rpmsg.clientfd);
+ sock_send_ipc_msg(&sock_rpmsg);
+ return 0;
+}
+
+int sock_soc_release_peer_proc(struct sock_rpmsg* psock_rpmsg)
+{
+ struct ipc_socket * ipcsocket;
+ struct socket* proxysocket;
+ struct socket* serversocket;
+ struct sock* skpair;
+ int type;
+ int closefd;
+ int err;
+ sk_soc_info("sock_soc_release_peer_proc clientfd=%d \n", psock_rpmsg->clientfd);
+ //¸ù¾ÝclientfdÕÒµ½±¾µØ´úÀísocket
+ spin_lock(&sock_release_lock);
+ //ÅжÏsocketÐÅÏ¢ÊÇ·ñ»¹ÔÚ´úÀíÁ´±íÖÐ
+ if(0 != sock_is_valide_ipc_socket(psock_rpmsg->serversock, psock_rpmsg->serverproxysock, psock_rpmsg->clientsock)){
+ sk_soc_info("sock_soc_release_peer_proc failed, sock_is_valide_ipc_socket=false \n");
+ spin_unlock(&sock_release_lock);
+ return -1;
+ }
+
+ ipcsocket = sock_get_ipcsocket_by_local_and_remote(psock_rpmsg->serversock, psock_rpmsg->clientsock);
+ if(ipcsocket != NULL){
+ type = psock_rpmsg->socktype;
+ sk_soc_info("sock_soc_release_peer_proc close sockfd=%d, socktype=%d\n", ipcsocket->sockfd, type);
+ //sock_soc_del_socket_info(ipcsocket->socket, ipcsocket->localsocket); //0706 ½«´úÀísocket´ÓsocketsÁбíÖÐɾ³ý
+
+ serversocket = (struct socket*)psock_rpmsg->serversock;
+ proxysocket = (struct socket*)ipcsocket->proxysocket;
+ //ĿǰSOCK_STREAMºÍSOCK_DGRAMÊÍ·ÅÁ÷³ÌÓÐÇø±ð
+ if(type == SOCK_STREAM){
+ //sock_del_ipc_socket_by_socket(ipcsocket->proxysocket);
+ skpair = serversocket->sk;
+ unix_state_lock(skpair);
+ /* No more writes */
+ skpair->sk_shutdown = SHUTDOWN_MASK;
+ //if (!skb_queue_empty(&sk->sk_receive_queue) || embrion)
+ // serversocket->sk_err = ECONNRESET;
+ unix_state_unlock(skpair);
+ skpair->sk_state_change(skpair);
+ sk_wake_async(skpair, SOCK_WAKE_WAITD, POLL_HUP);
+ }else if(type == SOCK_DGRAM){
+
+ sock_soc_del_socket_peer(serversocket, proxysocket);
+ ipcsocket->sock->closed = 1;
+ closefd = ipcsocket->sockfd;
+ sock_soc_del_socket_info(ipcsocket->socket, ipcsocket->localsocket); //0706 ½«´úÀísocket´ÓsocketsÁбíÖÐɾ³ý
+
+ sys_close(closefd);
+ }
+ }else{
+ sk_soc_info("sock_soc_release_peer_proc failed, localsock=%x, remotesock=%x", psock_rpmsg->serversock, psock_rpmsg->clientsock);
+
+ }
+ spin_unlock(&sock_release_lock);
+ return 0;
+}
+
+int sock_soc_dgram_disconnected(struct sock *sock, struct sock *other)
+{
+ struct ipc_socket *psocket_ipc = NULL;
+ struct sock_rpmsg sock_rpmsg = {0};
+ sock_rpmsg.msg_type = MSG_TYPE_DGRAM_DISCONNECTED;
+
+ //¿Í»§¶Ësocket fd
+ sock_rpmsg.clientfd = sock_lookup_fd_by_sock(sock);
+ sock_rpmsg.clientsock = sock->sk_socket;
+ //²éÕÒ·þÎñÆ÷¶Ë´úÀísocketÏà¹ØÐÅÏ¢
+ psocket_ipc = sock_soc_get_ipcsocket_by_proxysock(other);
+ if(psocket_ipc == NULL){
+ sk_soc_info("sock_soc_remove_wait_queue failed, other->fd=%d\n ", other->sk_fd);
+ return -1;
+ }
+ //·þÎñÆ÷¶Ësocket fd
+ sock_rpmsg.serverfd = psocket_ipc->remotefd;
+ sock_rpmsg.serversock = psocket_ipc->remotesocket;
+ sk_soc_info("sock_soc_dgram_disconnected clientfd=%d, serverfd=%d \n", sock_rpmsg.clientfd, sock_rpmsg.serverfd);
+ sock_send_ipc_msg(&sock_rpmsg);
+ return 0;
+}
+
+int sock_soc_dgram_disconnected_proc(struct sock_rpmsg* psock_rpmsg)
+{
+ struct ipc_socket* clientsocket;
+ struct socket* serversocket;
+ struct sock* sock;
+ struct sock* other;
+
+ serversocket = (struct socket*)psock_rpmsg->serversock;
+ if(sock_soc_socket_is_valid_ipc(serversocket, psock_rpmsg->clientsock) == -1){ //serversockÒѹرÕ
+ sk_soc_info("sock_soc_socket_is_valid is false \n");
+ return -1;
+ }
+ other = serversocket->sk;
+
+ clientsocket = sock_get_ipcsocket_by_local_and_remote(psock_rpmsg->serversock, psock_rpmsg->clientsock);
+ if(clientsocket == NULL){
+ sk_soc_info("sock_soc_dgram_disconnected_proc failed, clientfd=%d,clientsock=%x\n ", psock_rpmsg->clientfd, psock_rpmsg->clientsock);
+ return -1;
+ }
+ sock = clientsocket->sock;
+
+ sk_soc_info("sock_soc_dgram_disconnected_proc clientfd=%d, serverfd=%d \n", psock_rpmsg->clientfd, psock_rpmsg->serverfd);
+ unix_dgram_disconnected_proxy(sock, other);
+ return 0;
+}
+
+void sock_soc_state_lock(struct sock *other)
+{
+ struct ipc_socket *psocket_ipc = NULL;
+ struct sock_rpmsg sock_rpmsg = {0};
+ sock_rpmsg.msg_type = MSG_TYPE_STATE_LOCK;
+
+ //²éÕÒ·þÎñÆ÷¶Ë´úÀísocketÏà¹ØÐÅÏ¢
+ psocket_ipc = sock_soc_get_ipcsocket_by_proxysock(other);
+ if(psocket_ipc == NULL){
+ sk_soc_info("sock_soc_state_lock failed, other->fd=%d\n ", other->sk_fd);
+ return;
+ }
+ //·þÎñÆ÷¶Ësocket fd
+ sock_rpmsg.serverfd = psocket_ipc->remotefd;
+ sock_rpmsg.serversock = psocket_ipc->remotesocket;
+ sock_rpmsg.clientsock = psocket_ipc->localsocket;
+ sk_soc_info("sock_soc_state_lock serverfd=%d \n", sock_rpmsg.serverfd);
+ sock_send_ipc_msg(&sock_rpmsg);
+}
+
+int sock_soc_state_lock_proc(struct sock_rpmsg* psock_rpmsg)
+{
+ struct socket* serversocket;
+ struct sock* other;
+
+ serversocket = (struct socket*)psock_rpmsg->serversock;
+ if(sock_soc_socket_is_valid_ipc(serversocket, psock_rpmsg->clientsock) == -1){ //serversockÒѹرÕ
+ sk_soc_info("sock_soc_socket_is_valid is false \n");
+ return -1;
+ }
+ other = serversocket->sk;
+
+ sk_soc_info("sock_soc_state_lock_proc serverfd=%d \n", psock_rpmsg->serverfd);
+ unix_state_lock(other);
+ return 0;
+}
+
+void sock_soc_state_unlock(struct sock *other)
+{
+ struct ipc_socket *psocket_ipc = NULL;
+ struct sock_rpmsg sock_rpmsg = {0};
+ sock_rpmsg.msg_type = MSG_TYPE_STATE_UNLOCK;
+
+ //²éÕÒ·þÎñÆ÷¶Ë´úÀísocketÏà¹ØÐÅÏ¢
+ psocket_ipc = sock_soc_get_ipcsocket_by_proxysock(other);
+ if(psocket_ipc == NULL){
+ sk_soc_info("sock_soc_state_unlock failed, other->fd=%d\n ", other->sk_fd);
+ return;
+ }
+ //·þÎñÆ÷¶Ësocket fd
+ sock_rpmsg.serverfd = psocket_ipc->remotefd;
+ sock_rpmsg.serversock = psocket_ipc->remotesocket;
+ sock_rpmsg.clientsock = psocket_ipc->localsocket;
+ sk_soc_info("sock_soc_state_unlock serverfd=%d \n", sock_rpmsg.serverfd);
+ sock_send_ipc_msg(&sock_rpmsg);
+}
+
+int sock_soc_state_unlock_proc(struct sock_rpmsg* psock_rpmsg)
+{
+ struct socket* serversocket;
+ struct sock* other;
+
+ serversocket = (struct socket*)psock_rpmsg->serversock;
+ if(sock_soc_socket_is_valid_ipc(serversocket, psock_rpmsg->clientsock) == -1){ //serversockÒѹرÕ
+ sk_soc_info("sock_soc_socket_is_valid is false \n");
+ return -1;
+ }
+ other = serversocket->sk;
+
+ sk_soc_info("sock_soc_state_unlock_proc serverfd=%d \n", psock_rpmsg->serverfd);
+ unix_state_lock(other);
+ return 0;
+}
+
+static int sock_create_icp_channel(T_ZDrvRpMsg_ActorID core_id, T_ZDrvRpMsg_ChID channel_id, unsigned int channel_size)
+{
+ int retval;
+
+ retval = sockSocCreateChannel (core_id, channel_id, channel_size);
+ if(retval != RPMSG_SUCCESS && retval != RPMSG_CHANNEL_ALREADY_EXIST)
+ goto out;
+
+ sk_soc_info("sock_create_icp_channel success");
+ return retval;
+
+out:
+ sk_soc_err("could not create channel.");
+ return retval;
+}
+
+static void sock_dld_handle(struct sock_rpmsg* sock_rpmsg)
+{
+ int len;
+ len = sock_channel_write(&g_sock_chn_info, sock_rpmsg, sock_rpmsg->data_len + sizeof(struct sock_rpmsg));
+ sk_soc_info("sock_dld_handle len=%d, index=%d", len, sock_rpmsg->index);
+ return;
+}
+static void sock_uld_handle(struct sock_rpmsg* sock_rpmsg)
+{
+ if(NULL == sock_rpmsg){
+ return;
+ }
+
+ switch(sock_rpmsg->msg_type) {
+ case MSG_TYPE_FIND:
+ sock_soc_find_other_proc(sock_rpmsg);
+ break;
+ case MSG_TYPE_FIND_RESULT:
+ sock_soc_find_other_result_proc(sock_rpmsg);
+ break;
+ case MSG_TYPE_ADD_WAIT_QUEUE:
+ sock_soc_add_wait_queue_proc(sock_rpmsg);
+ break;
+ case MSG_TYPE_REMOVE_WAIT_QUEUE:
+ sock_soc_remove_wait_queue_proc(sock_rpmsg);
+ break;
+ case MSG_TYPE_SYNC_IPC_SOCKET:
+ sock_sync_ipc_socket_proc(sock_rpmsg);
+ break;
+ case MSG_TYPE_WAIT_FOR_PEER:
+ sock_wait_for_peer_proc(sock_rpmsg);
+ break;
+ case MSG_TYPE_DATA_READY:
+ sock_soc_sk_data_ready_proc(sock_rpmsg);
+ break;
+ case MSG_TYPE_SEND_MSG:
+ sock_soc_msg_send_proc(sock_rpmsg);
+ break;
+ case MSG_TYPE_ADD_SKB_QUEUE_TAIL:
+ sock_soc_add_skb_queue_tail_proc(sock_rpmsg);
+ break;
+ case MSG_TYPE_SET_PEER:
+ sock_soc_set_peer_proc(sock_rpmsg);
+ break;
+ case MSG_TYPE_RECVQ_FULL:
+ sock_soc_recvq_full_proc(sock_rpmsg);
+ break;
+ case MSG_TYPE_RECVQ_FULL_RESULT:
+ sock_soc_recvq_full_result_proc(sock_rpmsg);
+ break;
+ case MSG_TYPE_PEER_CLEAR:
+ sock_soc_unix_peer_clear_proc(sock_rpmsg);
+ break;
+ case MSG_TYPE_WAKE_UP_INTERRUPTIBLE_POLL:
+ sock_soc_wake_up_interruptible_poll_proc(sock_rpmsg);
+ break;
+ case MSG_TYPE_RECVQ_FULL_LOCKLESS_AND_DEAD:
+ sock_soc_recvq_full_lockless_and_dead_proc(sock_rpmsg);
+ break;
+ case MSG_TYPE_RECVQ_FULL_LOCKLESS_AND_DEAD_RESULT:
+ sock_soc_recvq_full_lockless_and_dead_result_proc(sock_rpmsg);
+ break;
+ case MSG_TYPE_TEST_FLAG:
+ sock_soc_test_flags_proc(sock_rpmsg);
+ break;
+ case MSG_TYPE_TEST_FLAG_RESULT:
+ sock_soc_test_flags_result_proc(sock_rpmsg);
+ break;
+ case MSG_TYPE_SOCK_PUT:
+ sock_soc_sock_put_proc(sock_rpmsg);
+ break;
+ case MSG_TYPE_GET_SOCKET_STATES:
+ sock_soc_get_state_proc(sock_rpmsg);
+ break;
+ case MSG_TYPE_GET_SOCKET_STATES_RESULT:
+ sock_soc_get_state_result_proc(sock_rpmsg);
+ break;
+ case MSG_TYPE_STREAM_CONNECT:
+ sock_soc_stream_connect_proc(sock_rpmsg);
+ break;
+ case MSG_TYPE_UPDATE_PEER:
+ sock_soc_update_peer_proc(sock_rpmsg);
+ break;
+ case MSG_TYPE_DGRAM_DISCONNECTED:
+ sock_soc_dgram_disconnected_proc(sock_rpmsg);
+ break;
+ case MSG_TYPE_STATE_LOCK:
+ sock_soc_state_lock_proc(sock_rpmsg);
+ break;
+ case MSG_TYPE_STATE_UNLOCK:
+ sock_soc_state_unlock_proc(sock_rpmsg);
+ break;
+ case MSG_TYPE_SOCK_HOLD:
+ sock_soc_sock_hold_proc(sock_rpmsg);
+ break;
+ case MSG_TYPE_RELEASE_PEER:
+ sock_soc_release_peer_proc(sock_rpmsg);
+ break;
+ case MSG_TYPE_NOTIFY_PROXY_CHANGE:
+ sock_soc_notify_proxy_change_to_server_proc(sock_rpmsg);
+ break;
+ default:
+ break;
+ }
+}
+
+static int sock_receive_thread(void *argv)
+{
+ int index,ret_len,i,num;
+ unsigned long flags;
+ //static struct sock_rpmsg sock_rpmsg = {0};
+ static char recvbuf[SOCK_DATA_MAX_LEN] = {0};
+ sk_soc_info("sock_receive_thread process");
+ while(1){
+ if(0 < sock_channel_read(&g_sock_chn_info, recvbuf, sizeof(recvbuf))) {
+ //sk_soc_info("sock_receive_thread sock_rpmsg.msg_type=%d,index=%d", sock_rpmsg.msg_type, sock_rpmsg.index);
+#if 1
+ sock_recv_ipc_msg((struct sock_rpmsg*)recvbuf);
+#else
+ switch(sock_rpmsg.msg_type) {
+ case MSG_TYPE_FIND:
+ sock_soc_find_other_proc(&sock_rpmsg);
+ break;
+ case MSG_TYPE_FIND_RESULT:
+ sock_soc_find_other_result_proc(&sock_rpmsg);
+ break;
+ case MSG_TYPE_ADD_WAIT_QUEUE:
+ sock_soc_add_wait_queue_proc(&sock_rpmsg);
+ break;
+ case MSG_TYPE_REMOVE_WAIT_QUEUE:
+ sock_soc_remove_wait_queue_proc(&sock_rpmsg);
+ break;
+ case MSG_TYPE_SYNC_IPC_SOCKET:
+ sock_sync_ipc_socket_proc(&sock_rpmsg);
+ break;
+ case MSG_TYPE_WAIT_FOR_PEER:
+ sock_wait_for_peer_proc(&sock_rpmsg);
+ break;
+ case MSG_TYPE_DATA_READY:
+ sock_soc_sk_data_ready_proc(&sock_rpmsg);
+ break;
+ case MSG_TYPE_SEND_MSG:
+ sock_soc_msg_send_proc(&sock_rpmsg);
+ break;
+ case MSG_TYPE_ADD_SKB_QUEUE_TAIL:
+ sock_soc_add_skb_queue_tail_proc(&sock_rpmsg);
+ break;
+ case MSG_TYPE_SET_PEER:
+ sock_soc_set_peer_proc(&sock_rpmsg);
+ break;
+ case MSG_TYPE_RECVQ_FULL:
+ sock_soc_recvq_full_proc(&sock_rpmsg);
+ break;
+ case MSG_TYPE_RECVQ_FULL_RESULT:
+ sock_soc_recvq_full_result_proc(&sock_rpmsg);
+ break;
+ case MSG_TYPE_PEER_CLEAR:
+ sock_soc_unix_peer_clear_proc(&sock_rpmsg);
+ break;
+ case MSG_TYPE_WAKE_UP_INTERRUPTIBLE_POLL:
+ sock_soc_wake_up_interruptible_poll_proc(&sock_rpmsg);
+ break;
+ case MSG_TYPE_RECVQ_FULL_LOCKLESS_AND_DEAD:
+ sock_soc_recvq_full_lockless_and_dead_proc(&sock_rpmsg);
+ break;
+ case MSG_TYPE_RECVQ_FULL_LOCKLESS_AND_DEAD_RESULT:
+ sock_soc_recvq_full_lockless_and_dead_result_proc(&sock_rpmsg);
+ break;
+ case MSG_TYPE_TEST_FLAG:
+ sock_soc_test_flags_proc(&sock_rpmsg);
+ break;
+ case MSG_TYPE_TEST_FLAG_RESULT:
+ sock_soc_test_flags_result_proc(&sock_rpmsg);
+ break;
+ case MSG_TYPE_SOCK_PUT:
+ sock_soc_sock_put_proc(&sock_rpmsg);
+ break;
+ case MSG_TYPE_GET_SOCKET_STATES:
+ sock_soc_get_state_proc(&sock_rpmsg);
+ break;
+ case MSG_TYPE_GET_SOCKET_STATES_RESULT:
+ sock_soc_get_state_result_proc(&sock_rpmsg);
+ break;
+ case MSG_TYPE_STREAM_CONNECT:
+ sock_soc_stream_connect_proc(&sock_rpmsg);
+ break;
+ case MSG_TYPE_UPDATE_PEER:
+ sock_soc_update_peer_proc(&sock_rpmsg);
+ break;
+ case MSG_TYPE_SOCKET_RELEASE:
+ sock_soc_release_sock_proc(&sock_rpmsg);
+ break;
+ case MSG_TYPE_DGRAM_DISCONNECTED:
+ sock_soc_dgram_disconnected_proc(&sock_rpmsg);
+ break;
+ case MSG_TYPE_STATE_LOCK:
+ sock_soc_state_lock_proc(&sock_rpmsg);
+ break;
+ case MSG_TYPE_STATE_UNLOCK:
+ sock_soc_state_unlock_proc(&sock_rpmsg);
+ break;
+ case MSG_TYPE_SOCK_HOLD:
+ sock_soc_sock_hold_proc(&sock_rpmsg);
+ break;
+ case MSG_TYPE_RELEASE_PEER:
+ sock_soc_release_peer_proc(&sock_rpmsg);
+ break;
+ case MSG_TYPE_NOTIFY_PROXY_CHANGE:
+ sock_soc_notify_proxy_change_to_server_proc(&sock_rpmsg);
+ break;
+ default:
+ break;
+ }
+#endif
+ }
+ else {
+ sk_soc_err("sock_channel_read fail.");
+ msleep(1000);
+ continue;
+ }
+
+ }
+
+ sk_soc_err("The receive thread exit!");
+ return 0;
+}
+
+static int sock_main_thread(void *argv)
+{
+ struct list_head tmp_list;
+ struct sock_rpmsg *entry,*tmp_entry;
+ unsigned long flags;
+ struct sock_thread_info* p_main_thread_info;
+ p_main_thread_info = &g_sock_chn_info.main_thread_info;
+
+ while(!p_main_thread_info->bstop) {
+ sock_get_sema(&p_main_thread_info->p_sock_sem);
+
+ spin_lock_irqsave(&p_main_thread_info->p_sock_lock,flags);
+ if (list_empty(&p_main_thread_info->p_sock_list)) {
+ spin_unlock_irqrestore(&p_main_thread_info->p_sock_lock,flags);
+ continue;
+ }
+ list_replace_init(&p_main_thread_info->p_sock_list,&tmp_list);
+ list_del_init(&p_main_thread_info->p_sock_list);
+ spin_unlock_irqrestore(&p_main_thread_info->p_sock_lock,flags);
+
+ list_for_each_entry_safe(entry,tmp_entry,&tmp_list,list) {
+ if(DIR_DOWNLINK == entry->dir) {
+ sock_dld_handle(entry);
+ }
+ else if(DIR_UPLINK == entry->dir) {
+ sock_uld_handle(entry);
+ }
+ else {
+ sk_soc_warn("sock data unknow dir(%d).",entry->dir);
+ }
+ list_del(&entry->list);
+ kfree(entry);
+ }
+ }
+
+ sk_soc_err("the sock_main_thread stop!\n");
+ return 0;
+}
+
+static int __init sock_soc_init(void)
+{
+ struct task_struct *th = NULL;
+ int retval = 0;
+ struct sock_thread_info* p_main_thread_info;
+
+ sema_init(&g_sock_sem, 0);
+ g_sock_chn_info.core_id = CAP_ID;
+ g_sock_chn_info.channel_id = ICP_CHN_SOCKET;
+ g_sock_chn_info.channel_size = ICP_CHANNEL_SIZE;
+
+ sk_soc_info("sock_soc_init process");
+ INIT_HLIST_HEAD(&g_ipc_sockets);
+ INIT_HLIST_HEAD(&g_sock_rpmsg_info);
+ INIT_HLIST_HEAD(&g_sockets_info);
+ retval = sock_create_icp_channel(CAP_ID, ICP_CHN_SOCKET, ICP_CHANNEL_SIZE);
+ if(retval < 0) {
+ sk_soc_err("Create IcpChannel channel_32 fail.");
+ return retval;
+ }
+
+ p_main_thread_info = &g_sock_chn_info.main_thread_info;
+
+ INIT_LIST_HEAD(&p_main_thread_info->p_sock_list);
+ spin_lock_init(&p_main_thread_info->p_sock_lock);
+ sema_init(&p_main_thread_info->p_sock_sem, 0);
+
+ th = kthread_run(sock_main_thread, 0, "sock-soc-main%d", ICP_CHN_SOCKET);
+ if (IS_ERR(th)) {
+ sk_soc_err("Unable to start receive thread.");
+ return PTR_ERR(th);
+ }
+ g_sock_chn_info.main_thread_info.p_thread = th;
+
+ th = kthread_run(sock_receive_thread, 0, "sock-soc-recv%d", ICP_CHN_SOCKET);
+ if (IS_ERR(th)) {
+ sk_soc_err("Unable to start receive thread.");
+ return PTR_ERR(th);
+ }
+ g_sock_chn_info.recv_thread_info.p_thread = th;
+
+ return 0;
+}
+
+static void __exit sock_soc_exit(void)
+{
+ memset(&g_sock_chn_info, 0, sizeof(struct sock_channel));
+ sk_soc_warn("success.\n");
+}
+
+late_initcall(sock_soc_init);
+module_exit(sock_soc_exit);
+
+MODULE_AUTHOR("ZXIC");
+MODULE_DESCRIPTION("ZXIC CAP LAN NET DEVICE");
+MODULE_LICENSE("GPL");
+
diff --git a/ap/os/linux/linux-3.4.x/net/unix/af_unix.c b/ap/os/linux/linux-3.4.x/net/unix/af_unix.c
index 2ff802c..013b685 100755
--- a/ap/os/linux/linux-3.4.x/net/unix/af_unix.c
+++ b/ap/os/linux/linux-3.4.x/net/unix/af_unix.c
@@ -115,6 +115,11 @@
#include <net/checksum.h>
#include <linux/security.h>
+#ifdef CONFIG_IPC_SOCKET
+#include <linux/socket_rpmsg.h>
+int socket_rpmsg_debug = 0;
+module_param(socket_rpmsg_debug, int, 0644);
+#endif
struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1];
EXPORT_SYMBOL_GPL(unix_socket_table);
DEFINE_SPINLOCK(unix_table_lock);
@@ -171,6 +176,12 @@
static inline int unix_recvq_full(struct sock const *sk)
{
+#ifdef CONFIG_IPC_SOCKET
+ if(unix_is_ipc_socket(sk)){
+ return sock_soc_recvq_full(sk);
+ }
+#endif
+
return skb_queue_len(&sk->sk_receive_queue) > sk->sk_max_ack_backlog;
}
@@ -345,6 +356,11 @@
other->sk_error_report(other);
}
}
+#ifdef CONFIG_IPC_SOCKET
+ if(unix_is_ipc_socket(other)){ //Èç¹ûotherÊÇ´úÀísocket£¬Ôò֪ͨÆä¶ÔÓ¦µÄʵÌåÖ´ÐÐÏàͬ²Ù×÷
+ sock_soc_dgram_disconnected(sk, other);
+ }
+#endif
}
static void unix_sock_destructor(struct sock *sk)
@@ -695,7 +711,14 @@
if (!sk)
return 0;
-
+#ifdef CONFIG_IPC_SOCKET //ÊͷŸÃsocket¶ÔÓ¦µÄ´úÀí
+ if(!hlist_empty(&sock->peer)){
+
+ sock_soc_delay_release(sock);
+ }else{
+ sk_soc_info("sock->peer is null \n");
+ }
+#endif
unix_release_sock(sk, 0);
sock->sk = NULL;
@@ -986,9 +1009,16 @@
restart:
other = unix_find_other(net, sunaddr, alen, sock->type, hash, &err);
- if (!other)
- goto out;
-
+ if (!other) {
+#ifdef CONFIG_IPC_SOCKET
+ sk_soc_dbg("unix_dgram_connect sock_soc_find_other");
+ /*±¾µØ²éÕÒ²»µ½£¬Ôò½øÐпçºË²éÕÒ*/
+ other = sock_soc_find_other(sock, sunaddr, alen, sock->type, hash, &err);
+
+ if (!other)
+#endif
+ goto out;
+ }
unix_state_double_lock(sk, other);
/* Apparently VFS overslept socket death. Retry. */
@@ -1027,6 +1057,12 @@
sock_put(old_peer);
} else {
unix_peer(sk) = other;
+#ifdef CONFIG_IPC_SOCKET
+ if(unix_is_ipc_socket(other)){ //Èç¹ûotherÊÇ´úÀísocket£¬Ôò֪ͨÆä¶ÔÓ¦µÄʵÌåÖ´ÐÐÏàͬ²Ù×÷
+ sk_soc_dbg("unix_dgram_connect sock_soc_set_peer");
+ sock_soc_set_peer(sk, other);
+ }
+#endif
unix_state_double_unlock(sk, other);
}
return 0;
@@ -1105,8 +1141,16 @@
restart:
/* Find listening sock. */
other = unix_find_other(net, sunaddr, addr_len, sk->sk_type, hash, &err);
- if (!other)
- goto out;
+ if (!other){
+#ifdef CONFIG_IPC_SOCKET
+ sk_soc_dbg("unix_stream_connect sock_soc_find_other");
+ /*±¾µØ²éÕÒ²»µ½£¬Ôò½øÐпçºË²éÕÒ*/
+ other = sock_soc_find_other(sock, sunaddr, addr_len, sock->type, hash, &err);
+
+ if (!other)
+#endif
+ goto out;
+ }
/* Latch state of peer */
unix_state_lock(other);
@@ -1119,6 +1163,16 @@
}
err = -ECONNREFUSED;
+#ifdef CONFIG_IPC_SOCKET
+ if(unix_is_ipc_socket(other)){
+ struct sock_elem_flag elem_flag = {0};
+ elem_flag.skstate = 1;
+ elem_flag.skshutdown = 1;
+ sock_soc_get_state(&elem_flag, other);
+ }
+ sk_soc_dbg("unix_stream_connect other->sk_state=%d, other->sk_shutdown=%d", other->sk_state, other->sk_shutdown);
+#endif
+
if (other->sk_state != TCP_LISTEN)
goto out_unlock;
if (other->sk_shutdown & RCV_SHUTDOWN)
@@ -1129,6 +1183,11 @@
if (!timeo)
goto out_unlock;
+#ifdef CONFIG_IPC_SOCKET
+ if(unix_is_ipc_socket(other)){ //Èç¹ûotherÊÇ´úÀísocket£¬Ôò֪ͨÆä¶ÔÓ¦µÄʵÌåÖ´ÐÐÏàͬ²Ù×÷
+ sock_wait_for_peer(sk, other, timeo);
+ }
+#endif
timeo = unix_wait_for_peer(other, timeo);
err = sock_intr_errno(timeo);
@@ -1214,10 +1273,36 @@
/* take ten and and send info to listening sock */
spin_lock(&other->sk_receive_queue.lock);
+#ifdef CONFIG_IPC_SOCKET
+ if(unix_is_ipc_socket(other)){
+ set_bit(SOCK_IPC_LOCAL,&newsk->sk_flags);
+ newsk->proxy_sock = other;
+ other->proxy_sock = newsk;
+ sock_soc_stream_connect(sk, other, uaddr, addr_len, flags);
+ //ÊÍ·Åskb
+ kfree_skb(skb);
+ }
+ else{
+#endif
__skb_queue_tail(&other->sk_receive_queue, skb);
+
+#ifdef CONFIG_IPC_SOCKET
+ }
+#endif
spin_unlock(&other->sk_receive_queue.lock);
+#ifdef CONFIG_IPC_SOCKET
+ unix_state_unlock(other);
+
+ if(unix_is_ipc_socket(other)){
+ sock_soc_sk_data_ready(other);
+ }
+ else{
+#endif
unix_state_unlock(other);
other->sk_data_ready(other, 0);
+#ifdef CONFIG_IPC_SOCKET
+ }
+#endif
sock_put(other);
return 0;
@@ -1300,6 +1385,9 @@
newsock->state = SS_CONNECTED;
unix_sock_inherit_flags(sock, newsock);
sock_graft(tsk, newsock);
+#ifdef CONFIG_IPC_SOCKET
+ sock_soc_update_peer(sock, newsock);
+#endif
unix_state_unlock(tsk);
return 0;
@@ -1503,10 +1591,12 @@
unix_get_secdata(siocb->scm, skb);
skb_reset_transport_header(skb);
+#ifndef CONFIG_IPC_SOCKET
err = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len);
if (err)
goto out_free;
+#endif
timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT);
restart:
@@ -1517,10 +1607,31 @@
other = unix_find_other(net, sunaddr, namelen, sk->sk_type,
hash, &err);
- if (other == NULL)
- goto out_free;
+ if (other == NULL) {
+#ifdef CONFIG_IPC_SOCKET
+ sk_soc_dbg("unix_find_other fail, call sock_soc_find_other");
+ /*±¾µØ²éÕÒ²»µ½£¬Ôò½øÐпçºË²éÕÒ*/
+ other = sock_soc_find_other(sock, sunaddr, namelen, sk->sk_type, hash, &err);
+
+ if (other == NULL)
+#endif
+ goto out_free;
+ }
+
}
+#ifdef CONFIG_IPC_SOCKET
+ if(unix_is_ipc_socket(other)){ //Èç¹û¿çºËsocket£¬ÔòÖ±½Ó½«Êý¾Ý·¢Ë͸ø¿çºËsocket´¦Àí
+ printk("other is ipc socket, do nothing\n");
+ }
+ else{
+ err = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len);
+ if (err)
+ goto out_free;
+
+ }
+#endif
+
if (sk_filter(other, skb) < 0) {
/* Toss the packet but do not return any error to the sender */
err = len;
@@ -1584,6 +1695,16 @@
goto restart;
}
+#ifdef CONFIG_IPC_SOCKET
+ if(unix_is_ipc_socket(other)){ //Èç¹û¿çºËsocket£¬ÔòÖ±½Ó½«Êý¾Ý·¢Ë͸ø¿çºËsocket´¦Àí
+ sk_soc_dbg("send to other core, len=%d", len);
+ sock_soc_msg_send(sk, other, msg, len);
+ unix_state_unlock(other);
+ sock_put(other);
+ kfree_skb(skb);
+ }
+ else{ //·Ç¿çºË×ßÕý³£Á÷³Ì
+#endif
if (sock_flag(other, SOCK_RCVTSTAMP))
__net_timestamp(skb);
maybe_add_creds(skb, sock, other);
@@ -1593,6 +1714,9 @@
unix_state_unlock(other);
other->sk_data_ready(other, len);
sock_put(other);
+#ifdef CONFIG_IPC_SOCKET
+ }
+#endif
scm_destroy(siocb->scm);
return len;
@@ -1620,13 +1744,25 @@
struct scm_cookie tmp_scm;
bool fds_sent = false;
int max_level;
-
+#ifdef CONFIG_IPC_SOCKET
+ char* data;
+ char* data_buf;
+#endif
+
+
if (NULL == siocb->scm)
siocb->scm = &tmp_scm;
wait_for_unix_gc();
err = scm_send(sock, msg, siocb->scm, false);
if (err < 0)
return err;
+#ifdef CONFIG_IPC_SOCKET
+ if(unix_is_ipc_socket(sk)){ //Èç¹û´Ë´¦µÄsockÊÇ´úÀísocket£¬Ôò½«skÌæ»»Îªconnectʱ·ÖÅäµÄnewsk
+ if(sk->proxy_sock){
+ sk = sk->proxy_sock;
+ }
+ }
+#endif
err = -EOPNOTSUPP;
if (msg->msg_flags&MSG_OOB)
@@ -1688,8 +1824,16 @@
}
max_level = err + 1;
fds_sent = true;
-
+#ifdef CONFIG_IPC_SOCKET
+ if(unix_is_ipc_socket(other) || unix_is_ipc_local_socket(other)){
+ //do nothing
+ } else {
+#endif
+
err = memcpy_fromiovec(skb_put(skb, size), msg->msg_iov, size);
+#ifdef CONFIG_IPC_SOCKET
+ }
+#endif
if (err) {
kfree_skb(skb);
goto out_err;
@@ -1701,6 +1845,25 @@
(other->sk_shutdown & RCV_SHUTDOWN))
goto pipe_err_free;
+#ifdef CONFIG_IPC_SOCKET
+ if(unix_is_ipc_socket(other)){ //Èç¹û¿çºËsocket£¬ÔòÖ±½Ó½«Êý¾Ý·¢Ë͸ø¿çºËsocket´¦Àí
+ sk_soc_dbg("sock_soc_msg_send");
+ unix_state_unlock(other);
+
+ sock_soc_msg_send(sk, other, msg, size);
+ sent += size;
+ kfree_skb(skb);
+ }
+ else if(unix_is_ipc_local_socket(other)){
+ sk_soc_dbg("sock_soc_msg_send to proxy_sock");
+ unix_state_unlock(other);
+
+ sock_soc_msg_send(sk, other->proxy_sock, msg, size);
+ sent += size;
+ kfree_skb(skb);
+ }
+ else{ //·Ç¿çºË×ßÕý³£Á÷³Ì
+#endif
maybe_add_creds(skb, sock, other);
skb_queue_tail(&other->sk_receive_queue, skb);
if (max_level > unix_sk(other)->recursion_level)
@@ -1708,6 +1871,9 @@
unix_state_unlock(other);
other->sk_data_ready(other, size);
sent += size;
+#ifdef CONFIG_IPC_SOCKET
+ }
+#endif
}
scm_destroy(siocb->scm);
@@ -2386,6 +2552,73 @@
#endif
+#ifdef CONFIG_IPC_SOCKET
+struct sock *unix_find_other_proxy(struct net *net,
+ struct sockaddr_un *sunname, int len,
+ int type, unsigned int hash, int *error)
+{
+ return unix_find_other(net, sunname, len, type, hash, error);
+}
+
+int unix_dgram_peer_wake_connect_proxy(struct sock *sk, struct sock *other)
+{
+ //return unix_dgram_peer_wake_connect(sk, other);
+ return 0;
+}
+
+void unix_dgram_peer_wake_disconnect_proxy(struct sock *sk, struct sock *other)
+{
+ //unix_dgram_peer_wake_disconnect(sk, other);
+}
+
+void unix_dgram_peer_wake_disconnect_wakeup_proxy(struct sock *sk,
+ struct sock *other)
+{
+ //unix_dgram_peer_wake_disconnect(sk, other);
+ wake_up_interruptible_poll(sk_sleep(sk),
+ POLLOUT |
+ POLLWRNORM |
+ POLLWRBAND);
+}
+
+long unix_wait_for_peer_proxy(struct sock *other, long timeo)
+{
+ return unix_wait_for_peer(other, timeo);
+}
+
+int unix_recvq_full_proxy(const struct sock *sk)
+{
+ return unix_recvq_full(sk);
+}
+
+int unix_recvq_full_proxy_lockless_and_deadstate(const struct sock *other)
+{
+ //return unix_recvq_full_lockless(other) && !sock_flag(other, SOCK_DEAD);
+ return 0;
+}
+
+int unix_stream_connect_proxy(struct socket *sock, struct sockaddr *uaddr,
+ int addr_len, int flags)
+{
+ return unix_stream_connect(sock, uaddr, addr_len, flags);
+}
+
+void unix_dgram_disconnected_proxy(struct sock *sk, struct sock *other)
+{
+ unix_dgram_disconnected(sk, other);
+}
+
+int unix_mkname_proxy(struct sockaddr_un *sunaddr, int len, unsigned *hashp){
+ return unix_mkname(sunaddr, len, hashp);
+}
+
+void unix_release_sock_proxy(struct sock *sk)
+{
+ unix_release_sock(sk, 0);
+}
+
+#endif
+
static const struct net_proto_family unix_family_ops = {
.family = PF_UNIX,
.create = unix_create,
diff --git a/ap/os/linux/linux-3.4.x/net/xfrm/xfrm_user.c b/ap/os/linux/linux-3.4.x/net/xfrm/xfrm_user.c
index ccf0f6e..0889855 100755
--- a/ap/os/linux/linux-3.4.x/net/xfrm/xfrm_user.c
+++ b/ap/os/linux/linux-3.4.x/net/xfrm/xfrm_user.c
@@ -858,7 +858,7 @@
static int xfrm_dump_sa_done(struct netlink_callback *cb)
{
struct xfrm_state_walk *walk = (struct xfrm_state_walk *) &cb->args[1];
- if(walk)
+ if(cb->args[1])
xfrm_state_walk_done(walk);
return 0;
}
@@ -869,7 +869,7 @@
struct xfrm_state_walk *walk = (struct xfrm_state_walk *) &cb->args[1];
struct xfrm_dump_info info;
- if(walk == NULL)
+ if(cb->args[1] == 0)
return 0;
BUILD_BUG_ON(sizeof(struct xfrm_state_walk) >
sizeof(cb->args) - sizeof(cb->args[0]));
@@ -1538,7 +1538,7 @@
static int xfrm_dump_policy_done(struct netlink_callback *cb)
{
struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *) &cb->args[1];
- if(walk)
+ if(cb->args[1])
xfrm_policy_walk_done(walk);
return 0;
}
@@ -1549,7 +1549,7 @@
struct xfrm_policy_walk *walk = (struct xfrm_policy_walk *) &cb->args[1];
struct xfrm_dump_info info;
- if(walk == NULL)
+ if(cb->args[1] == 0)
return 0;
BUILD_BUG_ON(sizeof(struct xfrm_policy_walk) >
sizeof(cb->args) - sizeof(cb->args[0]));
diff --git a/ap/os/linux/linux-3.4.x/sound/soc/sanechips/zx297520v3_dummy.c b/ap/os/linux/linux-3.4.x/sound/soc/sanechips/zx297520v3_dummy.c
index 0124154..5c0257c 100755
--- a/ap/os/linux/linux-3.4.x/sound/soc/sanechips/zx297520v3_dummy.c
+++ b/ap/os/linux/linux-3.4.x/sound/soc/sanechips/zx297520v3_dummy.c
@@ -425,6 +425,24 @@
{
unsigned int i2s_top_reg;
int ret = 0;
+
+
+
+#ifdef _ALSA_CODEC_IN_CAP
+ print_audio("Alsa mc zx29_i2s_top_reg_cfg: ZX29_I2S_LOOP_CFG=0x%x \n",ZX29_I2S_LOOP_CFG);
+
+ // inter loop
+ i2s_top_reg = zx_read_reg(ZX29_I2S_LOOP_CFG);
+ i2s_top_reg &= 0xfffffe07;
+ i2s_top_reg |= 0x000000a8; // inter arm_i2s2--afe i2s
+ zx_write_reg(ZX29_I2S_LOOP_CFG, i2s_top_reg);
+
+ print_audio("Alsa %s i2s loop cfg reg=%x\n",__func__, zx_read_reg(ZX29_I2S_LOOP_CFG));
+ print_audio("Alsa mc %s: defined _ALSA_CODEC_IN_CAP,i2s top cfg return\n", __func__);
+
+ return;
+
+#endif
#ifdef CONFIG_USE_PIN_I2S0
ret = gpio_request(PIN_I2S0_WS, "i2s0_ws");
@@ -474,12 +492,7 @@
zx_write_reg(ZX29_I2S_LOOP_CFG, i2s_top_reg);
#endif
- // inter loop
- i2s_top_reg = zx_read_reg(ZX29_I2S_LOOP_CFG);
- i2s_top_reg &= 0xfffffe07;
- i2s_top_reg |= 0x000000a8; // inter arm_i2s2--afe i2s
- zx_write_reg(ZX29_I2S_LOOP_CFG, i2s_top_reg);
-
+
// print_audio("Alsa %s i2s loop cfg reg=%x\n",__func__, zx_read_reg(ZX29_I2S_LOOP_CFG));
}
@@ -585,9 +598,8 @@
print_audio("Alsa zx297520v3_dummy SoC Audio driver\n");
-#ifndef _ALSA_CODEC_IN_CAP
zx29_i2s_top_reg_cfg();
-#endif
+
zx297520v3_dummy_snd_device = platform_device_alloc("soc-audio", -1);
if (!zx297520v3_dummy_snd_device) {
printk(KERN_ERR "Alsa zx297520v3_dummy SoC Audio: Unable to register\n");