commit a3625e6879576c6a95fb3064e0db3fa6fdd225eb Author: cuynu Date: Mon Oct 21 00:31:22 2024 +0700 push phoenixsuit binaries and drivers diff --git a/LangPlg.dll b/LangPlg.dll new file mode 100644 index 0000000..ca34f01 Binary files /dev/null and b/LangPlg.dll differ diff --git a/LiveProc.Plg b/LiveProc.Plg new file mode 100644 index 0000000..19cac9d Binary files /dev/null and b/LiveProc.Plg differ diff --git a/README.md b/README.md new file mode 100644 index 0000000..832f8f1 --- /dev/null +++ b/README.md @@ -0,0 +1,322 @@ +# PhoenixSuit CLI for Linux +This is a copy of PhoenixSuit tool downloaded from Allwinner developer page, it has no QT interface as old LiveSuit v3.06 does and only supports x86_64. + +# Usages +``` +sudo ./phoenixsuit {path to firmware image *.img} +``` + +# Known issues +- Newer firmware images format such as firmware of T95 Super with Android 10+ and super partition are unable to flash as it fail and can't handle when trying to verify `super` partition, idk why. PhoenixSuit on Windows are still able to handle this format somehow. (Android 9 or older firmware format should be fine!) +- Do not run phoenixsuit without arguments, as it will return with `Segmentation fault (core dumped)` error. +- Run without root permission will lead to Get Device stage error. + +# Kernel module installation to make sure device can be recognized +- If you using Debian or Fedora based distro, simply install *.deb or *.rpm on drivers folder. If you are using Arch/EndeavourOS or other distros, use following command to compile and install manually kernel module : + +``` +git clone https://gitlab.com/cuynu/phoenixsuit-linux.git +cd phoenixsuit-linux/drivers/awusb +sudo make +sudo make install +sudo depmod -a +sudo modprobe awusb +cd .. +``` + +# Example of good flash logs : + +``` +sudo ./phoenixsuit '/home/cuynu/Downloads/H3_7.1_rom ATV _Vinabox.img' +library file path: /home/cuynu/phoenixsuit-linux/plgvector.dll +library file path: /home/cuynu/phoenixsuit-linux/LiveProc.Plg +library file path: /home/cuynu/phoenixsuit-linux/plgvector.dll +library file path: /home/cuynu/phoenixsuit-linux/luaeFex.dll +Register./luaBase.dll l_RegAllFun Sucess! +Register./luaeFex.dll l_RegAllFun Sucess! +Register./luadec.dll l_RegAllFun Sucess! +IMAGEWTY +ItemTableSize = 1048576 +Closing image now! + +Clos image OK! + +Dev Plugin The Device Path is: /dev/aw_efex0 +Begin Burn the image! +0%Register./luaBase.dll l_RegAllFun Sucess! +Register./luaeFex.dll l_RegAllFun Sucess! +Register./luadec.dll l_RegAllFun Sucess! +IMAGEWTY +ItemTableSize = 1048576 +Closing image now! + +Clos image OK! + +--------------Init Called------------------ +workDir /home/cuynu/phoenixsuit-linux/phoenixsuit +ImgLenHigh 0 +ImgLenLow 996468736 +Mode 8 +hWnd 0 +imgFilePath /home/cuynu/Downloads/H3_7.1_rom ATV _Vinabox.img +[TL_MSG]:Mode = 8, ImgLenHigh=0, ImgLenLow = 3b64e800, imgFilePath = /home/cuynu/Downloads/H3_7.1_rom ATV _Vinabox.img + +IMAGEWTY +ItemTableSize = 1048576 +[TL_MSG]:Tools Open Img + +---fun end--- +--------------entry-fel2fes Called----------- +felDevName /dev/aw_efex0 +[TL_MSG]:Hi, I'm fel, dev=/dev/aw_efex0 + +[TL_MSG]:To down and Run fes1-1 + +[TL_MSG]:fes1 down addr = 0x8000, retAddr =0x7210 + +[TL_MSG]:To clear fes aide log + +[TL_FEX]:fel UP addr=0x7210, len=136 + +[TL_MSG]:SYS_PARA_LOG read = 0x4d415244 + +[TL_MSG]:dram paras[0]: 0x240 + +[TL_MSG]:dram paras[1]: 0x3 + +[TL_MSG]:dram paras[2]: 0x3b3bfb + +[TL_MSG]:dram paras[3]: 0x1 + +[TL_MSG]:dram paras[4]: 0x11040800 + +[TL_MSG]:dram paras[5]: 0x1 + +[TL_MSG]:dram paras[6]: 0x1c70 + +[TL_MSG]:dram paras[7]: 0x40 + +[TL_MSG]:dram paras[8]: 0x18 + +[TL_MSG]:dram paras[9]: 0x0 + +[TL_MSG]:dram paras[10]: 0x47a150 + +[TL_MSG]:dram paras[11]: 0x1c2414b + +[TL_MSG]:dram paras[12]: 0x65046 + +[TL_MSG]:dram paras[13]: 0x0 + +[TL_MSG]:dram paras[14]: 0x0 + +[TL_MSG]:dram paras[15]: 0x2108a000 + +[TL_MSG]:dram paras[16]: 0x64 + +[TL_MSG]:dram paras[17]: 0x13890240 + +[TL_MSG]:dram paras[18]: 0x0 + +[TL_MSG]:dram paras[19]: 0x0 + +[TL_MSG]:dram paras[20]: 0x0 + +[TL_MSG]:dram paras[21]: 0x6aaa0000 + +[TL_MSG]:dram paras[22]: 0x7979 + +[TL_MSG]:dram paras[23]: 0x1800801 + +[TL_MSG]:dram paras[24]: 0x0 + +[TL_MSG]:dram paras[25]: 0x0 + +[TL_MSG]:dram paras[26]: 0x0 + +[TL_MSG]:dram paras[27]: 0x0 + +[TL_MSG]:dram paras[28]: 0x0 + +[TL_MSG]:dram paras[29]: 0x0 + +[TL_MSG]:dram paras[30]: 0x0 + +[TL_MSG]:dram paras[31]: 0x0 + +[TL_MSG]:To down and Run uboot + +[TL_MSG]:u-boot down addr = 0x4a000000 + +[TL_MSG]:workmode = 0x10 + +[TL_MSG]:dtb down addr = 0x4a200000 + +[TL_MSG]:sysconfig down addr = 0x4a300000 + +---fun end--- +Fel Thread Finished! +Dev Plugout The Device Path is: /dev/aw_efex0 +Dev Plugout The Device Path is: /dev/aw_efex0 +Dev Plugin The Device Path is: /dev/aw_efex0 +--------------entry fes_thread Called--------- +portId 0 +fesDevName /dev/aw_efex0 +hubId 0 +DeviceId 1 +[TL_MSG]:enter FES--/dev/aw_efex0 + +[TL_MSG]:Verify: media crc = 0 + +3%[TL_MSG]:save item to mem :(12345678,1234567890___MBR) realLen(65536) + +l_calc_crc32, pBuffer = 0x74afc80130a4, nLen = 16380, crc32 = 715738120[TL_MSG]:name = bootloader, keydata = 0 + +[TL_MSG]:name = env, keydata = 0 + +[TL_MSG]:name = boot, keydata = 0 + +[TL_MSG]:name = system, keydata = 0 + +[TL_MSG]:name = verity_block, keydata = 0 + +[TL_MSG]:name = misc, keydata = 0 + +[TL_MSG]:name = recovery, keydata = 0 + +[TL_MSG]:name = private, keydata = 8000 + +[TL_MSG]:name = alog, keydata = 0 + +[TL_MSG]:name = Reserve0, keydata = 0 + +[TL_MSG]:name = Reserve1, keydata = 0 + +[TL_MSG]:name = Reserve2, keydata = 0 + +[TL_MSG]:name = cache, keydata = 0 + +[TL_MSG]:name = UDISK, keydata = 0 + +[TL_MSG]:name = , keydata = 0 + +[TL_MSG]:Verify: media crc = 0 + +[TL_MSG]:down mbr success!!! + +4%[TL_MSG]:storge type is 2 (0:nand 1-2:card 3:spinor) + +[TL_MSG]:dl file :save item to mem :(12345678,1234567890DLINFO) realLen(16384) + +l_calc_crc32, pBuffer = 0x74afc861c174, nLen = 16380, crc32 = 766562264[TL_MSG]:------------dlmap dump-------------- + +[TL_MSG]:crc32 = 0x2db0cfd8 + +[TL_MSG]:version = 0x200 + +[TL_MSG]:magic = softw411 + +[TL_MSG]:part_cnt = 7 + +[TL_MSG]:flash size is : 30539776 Sectors + +[TL_MSG]:name = bootloader addrhi=0x0 addrlo = 0x8000 lenhi = 0x0 lenlo = 0x8000 file = BOOTLOADER_FEX00, en=0,vf=1 + +18%[TL_MSG]:need verify:1,VBOOTLOADER_FEX0 + +[TL_FEX]:8000, 7c1c00 + +[TL_MSG]:Verify:start = 8000 ,size = 7c1c00 ,pc_crc = f693ac56, media crc = f693ac56 + +[TL_MSG]:name = env addrhi=0x0 addrlo = 0x10000 lenhi = 0x0 lenlo = 0x8000 file = ENV_FEX000000000, en=0,vf=1 + +32%[TL_MSG]:need verify:1,VENV_FEX00000000 + +[TL_FEX]:10000, 20000 + +[TL_MSG]:Verify:start = 10000 ,size = 20000 ,pc_crc = e9d64f18, media crc = e9d64f18 + +[TL_MSG]:name = boot addrhi=0x0 addrlo = 0x18000 lenhi = 0x0 lenlo = 0x10000 file = BOOT_FEX00000000, en=0,vf=1 + +45%[TL_MSG]:need verify:1,VBOOT_FEX0000000 + +[TL_FEX]:18000, 128b800 + +[TL_MSG]:Verify:start = 18000 ,size = 128b800 ,pc_crc = be7fd5f7, media crc = be7fd5f7 + +[TL_MSG]:name = system addrhi=0x0 addrlo = 0x28000 lenhi = 0x0 lenlo = 0x300000 file = SYSTEM_FEX000000, en=0,vf=1 + +[TL_MSG]:find a sparse format part,SYSTEM_FEX000000 + +[TL_MSG]:item size :898 M + +[TL_MSG]:magic = ed26ff3a + +[TL_MSG]:blk_size = 1000 + +[TL_MSG]:total_chunk = efa + +[TL_MSG]:tlBufImg size = 600000 + +Fes Device Plugin before Timeout! +Kill Timer! +57%[TL_MSG]:handled chunk = efa total_chunk = efa + +[TL_MSG]:name = verity_block addrhi=0x0 addrlo = 0x328000 lenhi = 0x0 lenlo = 0x8000 file = VERITY_BLOCK_FEX, en=0,vf=1 + +70%[TL_MSG]:need verify:1,VVERITY_BLOCK_FE + +[TL_FEX]:328000, 110b3c + +[TL_MSG]:Verify:start = 328000 ,size = 110b3c ,pc_crc = 79579903, media crc = 79579903 + +[TL_MSG]:name = recovery addrhi=0x0 addrlo = 0x338000 lenhi = 0x0 lenlo = 0x10000 file = RECOVERY_FEX0000, en=0,vf=1 + +84%[TL_MSG]:need verify:1,VRECOVERY_FEX000 + +[TL_FEX]:338000, 14d7800 + +[TL_MSG]:Verify:start = 338000 ,size = 14d7800 ,pc_crc = d42a18e8, media crc = d42a18e8 + +[TL_MSG]:name = UDISK addrhi=0x0 addrlo = 0x510000 lenhi = 0x0 lenlo = 0x0 file = DISKFS_FEX000000, en=0,vf=0 + +[TL_MSG]:work mode update ,udisk part ignore !!!! + +96%[TL_MSG]:storge type is 2 (0:nand 1-2:card 3:spinor) + +[TL_MSG]:bootpackage_mode : 4 + +[TL_MSG]:save item to mem :(12345678,BOOTPKG-00000000) realLen(1933312) + +[TL_MSG]:Verify: media crc = 0 + +[TL_MSG]:down uboot success!!! + +97%[TL_MSG]:storge type is 2 (0:nand 1-2:card 3:spinor) + +[TL_MSG]:bootpackage_mode : 4 + +[TL_MSG]:save item to mem :(12345678,1234567890BOOT_0) realLen(32768) + +[TL_MSG]:Verify: media crc = 0 + +[TL_MSG]:down boot0 success!!! + +100% +Burn Finish; +[TL_MSG]:---fun end----- + +---------------Exit Called----------------- +Closing image now! + +Clos image OK! + +[TL_MSG]:Tools Close Img ... + +---fun end--- +L302, Finished to call Tools.entry_fes_thread. +Dev Plugout The Device Path is: /dev/aw_efex0 +Dev Plugout The Device Path is: /dev/aw_efex0 +---------------Exit Called----------------- +---fun end--- +``` diff --git a/common_fun.lua b/common_fun.lua new file mode 100644 index 0000000..ec7d029 Binary files /dev/null and b/common_fun.lua differ diff --git a/config/10-local.rules b/config/10-local.rules new file mode 100644 index 0000000..189d5f5 --- /dev/null +++ b/config/10-local.rules @@ -0,0 +1,3 @@ +ACTION!="add",GOTO="cfgend" +KERNEL=="aw_efex*",GROUP="xxx",OWNER="xxx",MODE="666" +LABEL="cfgend" diff --git a/config/udev.conf b/config/udev.conf new file mode 100644 index 0000000..dd26d44 --- /dev/null +++ b/config/udev.conf @@ -0,0 +1,9 @@ +# see udev.conf(5) for details +# +# udevd is started in the initramfs, so when this file is modified the +# initramfs should be rebuilt. + +#udev_log="info" +udev_root="/dev/" +udev_rules="/etc/udev/rules.d/" +udev_log="err" diff --git a/drivers/awdev-0.5-1dkms.noarch.rpm b/drivers/awdev-0.5-1dkms.noarch.rpm new file mode 100644 index 0000000..3f31b10 Binary files /dev/null and b/drivers/awdev-0.5-1dkms.noarch.rpm differ diff --git a/drivers/awdev-dkms_0.5_amd64.deb b/drivers/awdev-dkms_0.5_amd64.deb new file mode 100644 index 0000000..a8be0ea Binary files /dev/null and b/drivers/awdev-dkms_0.5_amd64.deb differ diff --git a/drivers/awusb/50-awusb.rules b/drivers/awusb/50-awusb.rules new file mode 100644 index 0000000..dfc5e41 --- /dev/null +++ b/drivers/awusb/50-awusb.rules @@ -0,0 +1,5 @@ +SUBSYSTEM!="usb_device",ACTION!="add",GOTO="objdev_rules_end" +#USBasp +ATTRS{idVendor}=="1f3a",ATTRS{idProduct}=="efe8",GROUP="1000",MODE="0666" +LABEL="objdev_rules_end" +KERNEL=="aw_efex[0-9]*", MODE="0666" diff --git a/drivers/awusb/Makefile b/drivers/awusb/Makefile new file mode 100644 index 0000000..d2dadfd --- /dev/null +++ b/drivers/awusb/Makefile @@ -0,0 +1,15 @@ +KVERS?=$(shell uname -r) +obj-m := awusb.o +KDIR := /lib/modules/${KVERS}/build +PWD := $(shell pwd) + +default: + $(MAKE) -C $(KDIR) M=$(PWD) modules + +clean: + $(MAKE) -C $(KDIR) M=$(PWD) clean + rm -rf Module.markers module.order module.sysvers + +install: awusb.ko + install -d /lib/modules/${KVERS}/kernel/extra/ + install $< /lib/modules/${KVERS}/kernel/extra/ diff --git a/drivers/awusb/awusb.c b/drivers/awusb/awusb.c new file mode 100644 index 0000000..ca40da5 --- /dev/null +++ b/drivers/awusb/awusb.c @@ -0,0 +1,645 @@ +/* -*- linux-c -*- */ + +/* + * Driver for AW USB which is for downloading firmware + * + * Cesc + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * + * Changelog: + * + * */ + +#include +#include +#include +#include +#include // +#include +#include +#include +#include +#include +#include +#include +#include + +/* by Cesc */ +#include +#include //? + +#include +/* + * Version Information + */ +#define DRIVER_VERSION "v0.5" +#define DRIVER_AUTHOR "Jojo" +#define DRIVER_DESC "AW USB driver" + +#define AW_MINOR 64 + +/* stall/wait timeout for AWUSB */ +#define NAK_TIMEOUT (HZ) + +/* Size of the AW buffer */ +#define OBUF_SIZE 0x10000 +#define IBUF_SIZE 0x500 +#define MAX_TIME_WAIT 6000000 + +#define USB_AW_VENDOR_ID 0x1f3a +#define USB_AW_PRODUCT_ID 0xefe8 + +struct allwinner_usb { + struct usb_device *aw_dev; /* init: probe_aw */ + struct usb_interface *aw_intf; //store interface to get endpoint + unsigned int ifnum; /* Interface number of the USB device */ + int isopen; /* nz if open */ + int present; /* Device is present on the bus */ + char *obuf, *ibuf; /* transfer buffers */ + size_t bulk_in_size; /* the size of the receive buffer */ + unsigned char bulk_in_endpointAddr; /* Endpoint assignments */ + unsigned char bulk_out_endpointAddr; /* Endpoint assignments */ + wait_queue_head_t wait_q; /* for timeouts */ + struct mutex lock; /* general race avoidance */ +}; + +/* by Cesc */ +struct usb_param { + unsigned test_num; + unsigned p1; /* parameter 1 */ + unsigned p2; + unsigned p3; +}; + +struct aw_command { + int value; + int length; + void __user *buffer; //? by Cesc +}; + +#define AWUSB_IOC_MAGIC 's' + +#define AWUSB_IOCRESET _IO(AWUSB_IOC_MAGIC, 0) +#define AWUSB_IOCSET _IOW(AWUSB_IOC_MAGIC, 1, struct usb_param) +#define AWUSB_IOCGET _IOR(AWUSB_IOC_MAGIC, 2, struct usb_param) +#define AWUSB_IOCSEND _IOW(AWUSB_IOC_MAGIC, 3, struct aw_command) +#define AWUSB_IOCRECV _IOR(AWUSB_IOC_MAGIC, 4, struct aw_command) +#define AWUSB_IOCSEND_RECV _IOWR(AWUSB_IOC_MAGIC, 5, struct aw_command) //how to implement it? + +/* table of devices that work with this driver */ +static const struct usb_device_id aw_table[] = { + { USB_DEVICE(USB_AW_VENDOR_ID, USB_AW_PRODUCT_ID) }, + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE(usb, aw_table); + +static int probe_aw(struct usb_interface *intf, + const struct usb_device_id *id); +static void disconnect_aw(struct usb_interface *intf); + +static struct usb_driver aw_driver = { + .name = "allwinner", + .probe = probe_aw, + .disconnect = disconnect_aw, + .id_table = aw_table, +}; + +static struct allwinner_usb aw_instance; + +static int open_aw(struct inode *inode, struct file *file) +{ + struct allwinner_usb *aw = &aw_instance; + struct usb_interface* intf;// = aw->aw_intf; + struct usb_host_interface *iface_desc; + struct usb_endpoint_descriptor *endpoint; + int subminor; + int i; + + if (aw->isopen || !aw->present) { + mutex_unlock(&(aw->lock)); + return -EBUSY; + } + + subminor = iminor(inode); + intf = usb_find_interface(&aw_driver, subminor);; + if(intf == NULL) + return -ENODEV; + + iface_desc = intf->cur_altsetting; + aw->bulk_in_endpointAddr = 0; + aw->bulk_out_endpointAddr = 0; + for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { + endpoint = &iface_desc->endpoint[i].desc; + + if ( !aw->bulk_in_endpointAddr && usb_endpoint_is_bulk_in(endpoint)) { + /* we found a bulk in endpoint */ + aw->bulk_in_endpointAddr = endpoint->bEndpointAddress; + printk(KERN_DEBUG"bulk_in_endpointAddr = %d\n", endpoint->bEndpointAddress); + } + + if ( !aw->bulk_out_endpointAddr && usb_endpoint_is_bulk_out(endpoint)) { + /* we found a bulk out endpoint */ + aw->bulk_out_endpointAddr = endpoint->bEndpointAddress; + printk(KERN_DEBUG"bulk_out_endpointAddr = %d\n", endpoint->bEndpointAddress); + } + } + + if (!(aw->bulk_in_endpointAddr && aw->bulk_out_endpointAddr)) { + printk(KERN_ERR"Could not find both bulk-in and bulk-out endpoints"); + return -EPIPE; + } + + aw->isopen = 1; + init_waitqueue_head(&aw->wait_q); + + return 0; +} + +static int close_aw(struct inode *inode, struct file *file) +{ + struct allwinner_usb *aw = &aw_instance; + + aw->isopen = 0; + + return 0; +} + +static long ioctl_aw(struct file *file, unsigned int cmd, unsigned long arg) +{ + struct allwinner_usb *aw = &aw_instance; + int retval=0; + struct usb_param param_tmp; + + struct aw_command aw_cmd; + void __user *data; + int value = 0; + int buffer_len = 0; + + int result = 0; + int actual_len = 0; + unsigned int nPipe = 0; + + mutex_lock(&(aw->lock)); + if (aw->present == 0 || aw->aw_dev == NULL) { + retval = -ENODEV; + goto err_out; + } + + param_tmp.test_num = 0; + param_tmp.p1 = 0; + param_tmp.p2 = 0; + param_tmp.p3 = 0; + + + switch (cmd) { + case AWUSB_IOCRESET: + printk(KERN_DEBUG"ioctl_aw--AWUSB_IOCRESET\n"); + break; + + case AWUSB_IOCSET: + + if (copy_from_user(¶m_tmp, (void __user *)arg, sizeof(param_tmp))) + retval= -EFAULT; + + printk(KERN_DEBUG"param_tmp.test_num = %d\n", param_tmp.test_num); + printk(KERN_DEBUG"param_tmp.p1 = %d\n", param_tmp.p1); + printk(KERN_DEBUG"param_tmp.p2 = %d\n", param_tmp.p2); + printk(KERN_DEBUG"param_tmp.p3 = %d\n", param_tmp.p3); + + break; + + case AWUSB_IOCGET: + + param_tmp.test_num = 3; + param_tmp.p1 = 4; + param_tmp.p2 = 5; + param_tmp.p3 = 6; + + if (copy_to_user((void __user *)arg, ¶m_tmp, sizeof(param_tmp))) + retval= -EFAULT; + + break; + + case AWUSB_IOCSEND: + + data = (void __user *) arg; + if (data == NULL) + break; + + if (copy_from_user(&aw_cmd, data, sizeof(struct aw_command))) { + retval = -EFAULT; + goto err_out; + } + + buffer_len = aw_cmd.length; + value = aw_cmd.value; + + if (buffer_len > OBUF_SIZE) { + retval = - EINVAL; + goto err_out; + } + + // stage 1, get data from app + if (copy_from_user(aw->obuf, aw_cmd.buffer, aw_cmd.length)) { + retval = -EFAULT; + goto err_out; + } + + //stage 2, send data to usb device + nPipe = usb_sndbulkpipe(aw->aw_dev, aw->bulk_out_endpointAddr); + result = usb_bulk_msg(aw->aw_dev, nPipe, + aw->obuf, buffer_len, &actual_len, MAX_TIME_WAIT); + if (result) { + printk(KERN_ERR"Write Whoops - %d", (int)result); + printk(KERN_ERR"send pipe - %u", nPipe); + retval = result; + goto err_out; + } + + break; + + case AWUSB_IOCRECV: + + data = (void __user *) arg; + if (data == NULL) + break; + if (copy_from_user(&aw_cmd,data, sizeof(struct aw_command))) { + retval = -EFAULT; + goto err_out; + } + if (aw_cmd.length < 0) { + retval = - EINVAL; + goto err_out; + } + buffer_len = aw_cmd.length; + value = aw_cmd.value; + + if (buffer_len > aw->bulk_in_size) { + retval = - EINVAL; + goto err_out; + } + + memset(aw->ibuf, 0x00, aw->bulk_in_size); + + // stage 1, get data from usb device + nPipe = usb_rcvbulkpipe(aw->aw_dev, aw->bulk_in_endpointAddr); + result = usb_bulk_msg(aw->aw_dev, nPipe, + aw->ibuf, buffer_len, &actual_len, MAX_TIME_WAIT); + + if (result) { + printk(KERN_ERR"Read Whoops - %d", result); + printk(KERN_ERR"Receive pipe - %u", nPipe); + retval = result; + goto err_out; + } + + // stage 2, copy data to app in user space + if (copy_to_user(aw_cmd.buffer, aw->ibuf, aw_cmd.length)) { + retval = - EFAULT; + goto err_out; + } + break; + + case AWUSB_IOCSEND_RECV: + printk(KERN_DEBUG"ioctl_aw--AWUSB_IOCSEND_RECV\n"); + + break; + + default: + retval = -ENOTTY; + break; + } + +err_out: + mutex_unlock(&(aw->lock)); + return retval; + +} + + static ssize_t +write_aw(struct file *file, const char __user *buffer, + size_t count, loff_t * ppos) +{ + DEFINE_WAIT(wait); + struct allwinner_usb *aw = &aw_instance; + + unsigned long copy_size; + unsigned long bytes_written = 0; + unsigned int partial; + + int result = 0; + int maxretry; + int errn = 0; + int intr; + + intr = mutex_lock_interruptible(&(aw->lock)); + if (intr) + return -EINTR; + /* Sanity check to make sure aw is connected, powered, etc */ + if (aw->present == 0 || aw->aw_dev == NULL) { + mutex_unlock(&(aw->lock)); + return -ENODEV; + } + + + + do { + unsigned long thistime; + char *obuf = aw->obuf; + + thistime = copy_size = + (count >= OBUF_SIZE) ? OBUF_SIZE : count; + if (copy_from_user(aw->obuf, buffer, copy_size)) { + errn = -EFAULT; + goto error; + } + maxretry = 5; + while (thistime) { + if (!aw->aw_dev) { + errn = -ENODEV; + goto error; + } + if (signal_pending(current)) { + mutex_unlock(&(aw->lock)); + return bytes_written ? bytes_written : -EINTR; + } + + result = usb_bulk_msg(aw->aw_dev, + usb_sndbulkpipe(aw->aw_dev, aw->bulk_out_endpointAddr), + obuf, thistime, &partial, MAX_TIME_WAIT); + + printk(KERN_DEBUG"write stats: result:%d thistime:%lu partial:%u", + result, thistime, partial); + + if (result == -ETIMEDOUT) { /* NAK - so hold for a while */ + if (!maxretry--) { + errn = -ETIME; + goto error; + } + prepare_to_wait(&aw->wait_q, &wait, TASK_INTERRUPTIBLE); + schedule_timeout(NAK_TIMEOUT); + finish_wait(&aw->wait_q, &wait); + continue; + } else if (!result && partial) { + obuf += partial; + thistime -= partial; + } else + break; + }; + if (result) { + printk(KERN_ERR"Write Whoops - %x", result); + errn = -EIO; + goto error; + } + bytes_written += copy_size; + count -= copy_size; + buffer += copy_size; + } while (count > 0); + + mutex_unlock(&(aw->lock)); + + return bytes_written ? bytes_written : -EIO; + +error: + mutex_unlock(&(aw->lock)); + return errn; +} + +static ssize_t +read_aw(struct file *file, char __user *buffer, size_t count, loff_t * ppos) +{ + DEFINE_WAIT(wait); + struct allwinner_usb *aw = &aw_instance; + ssize_t read_count; + unsigned int partial; + int this_read; + int result; + int maxretry = 10; + char *ibuf; + int intr; + + intr = mutex_lock_interruptible(&(aw->lock)); + if (intr) + return -EINTR; + /* Sanity check to make sure aw is connected, powered, etc */ + if (aw->present == 0 || aw->aw_dev == NULL) { + mutex_unlock(&(aw->lock)); + return -ENODEV; + } + + ibuf = aw->ibuf; + + read_count = 0; + + + while (count > 0) { + if (signal_pending(current)) { + mutex_unlock(&(aw->lock)); + return read_count ? read_count : -EINTR; + } + if (!aw->aw_dev) { + mutex_unlock(&(aw->lock)); + return -ENODEV; + } + this_read = (count >= aw->bulk_in_size) ? aw->bulk_in_size : count; + + result = usb_bulk_msg(aw->aw_dev, + usb_rcvbulkpipe(aw->aw_dev, aw->bulk_in_endpointAddr), + ibuf, this_read, &partial, + MAX_TIME_WAIT); + + printk(KERN_DEBUG"read stats: result:%d this_read:%u partial:%u", + result, this_read, partial); + + if (partial) { + count = this_read = partial; + } else if (result == -ETIMEDOUT || result == 15) { /* FIXME: 15 ??? */ + if (!maxretry--) { + mutex_unlock(&(aw->lock)); + printk(KERN_ERR"read_aw: maxretry timeout"); + return -ETIME; + } + prepare_to_wait(&aw->wait_q, &wait, TASK_INTERRUPTIBLE); + schedule_timeout(NAK_TIMEOUT); + finish_wait(&aw->wait_q, &wait); + continue; + } else if (result != -EREMOTEIO) { + mutex_unlock(&(aw->lock)); + printk(KERN_ERR"Read Whoops - result:%u partial:%u this_read:%u", + result, partial, this_read); + return -EIO; + } else { + mutex_unlock(&(aw->lock)); + return (0); + } + + if (this_read) { + if (copy_to_user(buffer, ibuf, this_read)) { + mutex_unlock(&(aw->lock)); + return -EFAULT; + } + count -= this_read; + read_count += this_read; + buffer += this_read; + } + } + mutex_unlock(&(aw->lock)); + return read_count; +} + +static const struct file_operations usb_aw_fops = { + .owner = THIS_MODULE, + .read = read_aw, + .write = write_aw, + .unlocked_ioctl = ioctl_aw, + .open = open_aw, + .release = close_aw, +}; + +static struct usb_class_driver usb_aw_class = { + .name = "aw_efex%d", + .fops = &usb_aw_fops, + .minor_base = AW_MINOR, +}; + +static int probe_aw(struct usb_interface *intf, + const struct usb_device_id *id) +{ + struct usb_device *dev = interface_to_usbdev(intf); + struct allwinner_usb *aw = &aw_instance; + int retval; +#if 0 + struct usb_host_interface *iface_desc; + struct usb_endpoint_descriptor *endpoint; + size_t buffer_size; + int i; + + iface_desc = intf->cur_altsetting; + for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { + endpoint = &iface_desc->endpoint[i].desc; + + if (!aw->bulk_in_endpointAddr && + usb_endpoint_is_bulk_in(endpoint)) { + /* we found a bulk in endpoint */ + buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); + aw->bulk_in_size = IBUF_SIZE; + aw->bulk_in_endpointAddr = endpoint->bEndpointAddress; + printk(KERN_DEBUG"bulk_in_endpointAddr = %d\n", endpoint->bEndpointAddress); + } + + if (!aw->bulk_out_endpointAddr && + usb_endpoint_is_bulk_out(endpoint)) { + /* we found a bulk out endpoint */ + aw->bulk_out_endpointAddr = endpoint->bEndpointAddress; + printk(KERN_DEBUG"bulk_out_endpointAddr = %d\n", endpoint->bEndpointAddress); + } + } + if (!(aw->bulk_in_endpointAddr && aw->bulk_out_endpointAddr)) { + err("Could not find both bulk-in and bulk-out endpoints"); + return -EPIPE; + } + +#endif + retval = usb_register_dev(intf, &usb_aw_class); + if (retval) { + printk(KERN_ERR"Not able to get a minor for this device."); + return -ENOMEM; + } + + aw->aw_dev = dev; + aw->aw_intf = intf; + aw->bulk_in_size = IBUF_SIZE; + + if (!(aw->obuf = kmalloc(OBUF_SIZE, GFP_KERNEL))) { + printk(KERN_ERR"probe_aw: Not enough memory for the output buffer"); + usb_deregister_dev(intf, &usb_aw_class); + return -ENOMEM; + } + + if (!(aw->ibuf = kmalloc(aw->bulk_in_size, GFP_KERNEL))) { + printk(KERN_ERR"probe_aw: Not enough memory for the input buffer"); + usb_deregister_dev(intf, &usb_aw_class); + kfree(aw->obuf); + return -ENOMEM; + } + + mutex_init(&(aw->lock)); + + usb_set_intfdata (intf, aw); + aw->present = 1; + + return 0; +} + +static void disconnect_aw(struct usb_interface *intf) +{ + struct allwinner_usb *aw = usb_get_intfdata (intf); + + usb_set_intfdata (intf, NULL); + if (aw) { + usb_deregister_dev(intf, &usb_aw_class); + + mutex_lock(&(aw->lock)); + if (aw->isopen) { + aw->isopen = 0; + /* better let it finish - the release will do whats needed */ + aw->aw_dev = NULL; + mutex_unlock(&(aw->lock)); + return; + } + kfree(aw->ibuf); + kfree(aw->obuf); + + dev_info(&intf->dev, "USB aw disconnected.\n"); + + aw->present = 0; + mutex_unlock(&(aw->lock)); + } +} + +static int __init usb_aw_init(void) +{ + int retval; + retval = usb_register(&aw_driver); + if (retval) + goto out; + + printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":" + DRIVER_DESC "\n"); + +out: + return retval; +} + + +static void __exit usb_aw_cleanup(void) +{ + struct allwinner_usb *aw = &aw_instance; + + aw->present = 0; + usb_deregister(&aw_driver); + + +} + +module_init(usb_aw_init); +module_exit(usb_aw_cleanup); + +MODULE_AUTHOR( DRIVER_AUTHOR ); +MODULE_DESCRIPTION( DRIVER_DESC ); +MODULE_LICENSE("GPL"); + diff --git a/drivers/awusb/dkms.conf b/drivers/awusb/dkms.conf new file mode 100644 index 0000000..74c48a9 --- /dev/null +++ b/drivers/awusb/dkms.conf @@ -0,0 +1,7 @@ +PACKAGE_NAME="awdev" +PACKAGE_VERSION="0.5" +CLEAN="make clean" +MAKE[0]="make default KERNELVERSION=$kernelver" +BUILT_MODULE_NAME[0]="awusb" +DEST_MODULE_LOCATION[0]="/updates" +AUTOINSTALL="yes" diff --git a/imgdec_fun.lua b/imgdec_fun.lua new file mode 100644 index 0000000..28b9a90 Binary files /dev/null and b/imgdec_fun.lua differ diff --git a/ini_fun.lua b/ini_fun.lua new file mode 100644 index 0000000..83770bd Binary files /dev/null and b/ini_fun.lua differ diff --git a/liblua.so b/liblua.so new file mode 100644 index 0000000..6bead25 Binary files /dev/null and b/liblua.so differ diff --git a/luaBase.dll b/luaBase.dll new file mode 100644 index 0000000..5c385a7 Binary files /dev/null and b/luaBase.dll differ diff --git a/luadec.dll b/luadec.dll new file mode 100644 index 0000000..de0cefb Binary files /dev/null and b/luadec.dll differ diff --git a/luaeFex.dll b/luaeFex.dll new file mode 100644 index 0000000..14ae5af Binary files /dev/null and b/luaeFex.dll differ diff --git a/phoenixsuit b/phoenixsuit new file mode 100755 index 0000000..1a89856 Binary files /dev/null and b/phoenixsuit differ diff --git a/plgvector.dll b/plgvector.dll new file mode 100644 index 0000000..6e14be3 Binary files /dev/null and b/plgvector.dll differ diff --git a/regbasefun.lua b/regbasefun.lua new file mode 100644 index 0000000..fd899d5 Binary files /dev/null and b/regbasefun.lua differ diff --git a/regdecode.lua b/regdecode.lua new file mode 100644 index 0000000..80ed55c Binary files /dev/null and b/regdecode.lua differ diff --git a/regdemo.lua b/regdemo.lua new file mode 100644 index 0000000..27471cb Binary files /dev/null and b/regdemo.lua differ