1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2012 by Amaury Pouly
*
* 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 software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "hwstub.h"
#include <string.h>
#include <stdlib.h>
#ifndef MIN
#define MIN(a,b) ((a) < (b) ? (a) : (b))
#endif
struct hwstub_device_t
{
libusb_device_handle *handle;
int intf;
int bulk_in;
int bulk_out;
int int_in;
};
struct hwstub_device_t *hwstub_open(libusb_device_handle *handle)
{
struct hwstub_device_t *dev = malloc(sizeof(struct hwstub_device_t));
memset(dev, 0, sizeof(struct hwstub_device_t));
dev->handle = handle;
libusb_device *mydev = libusb_get_device(dev->handle);
int config_id;
libusb_get_configuration(dev->handle, &config_id);
struct libusb_device_descriptor dev_desc;
libusb_get_device_descriptor(mydev, &dev_desc);
if(dev_desc.bDeviceClass != HWSTUB_CLASS ||
dev_desc.bDeviceSubClass != HWSTUB_SUBCLASS ||
dev_desc.bDeviceProtocol != HWSTUB_PROTOCOL)
goto Lerr;
return dev;
Lerr:
free(dev);
return NULL;
}
int hwstub_release(struct hwstub_device_t *dev)
{
free(dev);
return 0;
}
int hwstub_get_desc(struct hwstub_device_t *dev, uint16_t desc, void *info, size_t sz)
{
return libusb_control_transfer(dev->handle,
LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN,
LIBUSB_REQUEST_GET_DESCRIPTOR, desc << 8, 0, info, sz, 1000);
}
int hwstub_get_log(struct hwstub_device_t *dev, void *buf, size_t sz)
{
return libusb_control_transfer(dev->handle,
LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN,
HWSTUB_GET_LOG, 0, 0, buf, sz, 1000);
}
int hwstub_rw_mem(struct hwstub_device_t *dev, int read, uint32_t addr, void *buf, size_t sz)
{
size_t tot_sz = 0;
while(sz)
{
uint16_t xfer = MIN(1 * 1024, sz);
int ret = libusb_control_transfer(dev->handle,
LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_DEVICE |
(read ? LIBUSB_ENDPOINT_IN : LIBUSB_ENDPOINT_OUT),
HWSTUB_RW_MEM, addr & 0xffff, addr >> 16, buf, xfer, 1000);
if(ret != xfer)
return ret;
sz -= xfer;
addr += xfer;
buf += xfer;
tot_sz += xfer;
}
return tot_sz;
}
int hwstub_call(struct hwstub_device_t *dev, uint32_t addr)
{
return libusb_control_transfer(dev->handle,
LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_DEVICE |
LIBUSB_ENDPOINT_OUT, HWSTUB_CALL, addr & 0xffff, addr >> 16, NULL, 0,
1000);
}
int hwstub_jump(struct hwstub_device_t *dev, uint32_t addr)
{
return libusb_control_transfer(dev->handle,
LIBUSB_REQUEST_TYPE_CLASS | LIBUSB_RECIPIENT_DEVICE |
LIBUSB_ENDPOINT_OUT, HWSTUB_JUMP, addr & 0xffff, addr >> 16, NULL, 0,
1000);
}
|