push phoenixsuit binaries and drivers

This commit is contained in:
Cuynu 2024-10-21 00:31:22 +07:00
commit a3625e6879
23 changed files with 1006 additions and 0 deletions

BIN
LangPlg.dll Normal file

Binary file not shown.

BIN
LiveProc.Plg Normal file

Binary file not shown.

322
README.md Normal file
View file

@ -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---
```

BIN
common_fun.lua Normal file

Binary file not shown.

3
config/10-local.rules Normal file
View file

@ -0,0 +1,3 @@
ACTION!="add",GOTO="cfgend"
KERNEL=="aw_efex*",GROUP="xxx",OWNER="xxx",MODE="666"
LABEL="cfgend"

9
config/udev.conf Normal file
View file

@ -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"

Binary file not shown.

Binary file not shown.

View file

@ -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"

15
drivers/awusb/Makefile Normal file
View file

@ -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/

645
drivers/awusb/awusb.c Normal file
View file

@ -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 <linux/module.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/hardirq.h> //<linux/smp_lock.h>
#include <linux/errno.h>
#include <linux/random.h>
#include <linux/poll.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/usb.h>
#include <linux/wait.h>
/* by Cesc */
#include <linux/ioctl.h>
#include <linux/mutex.h> //?
#include <linux/sched/signal.h>
/*
* 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(&param_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, &param_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");

7
drivers/awusb/dkms.conf Normal file
View file

@ -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"

BIN
imgdec_fun.lua Normal file

Binary file not shown.

BIN
ini_fun.lua Normal file

Binary file not shown.

BIN
liblua.so Normal file

Binary file not shown.

BIN
luaBase.dll Normal file

Binary file not shown.

BIN
luadec.dll Normal file

Binary file not shown.

BIN
luaeFex.dll Normal file

Binary file not shown.

BIN
phoenixsuit Executable file

Binary file not shown.

BIN
plgvector.dll Normal file

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show more