This repository has been archived by the owner on Aug 2, 2018. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
fraucheky.c
196 lines (171 loc) · 6.19 KB
/
fraucheky.c
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
/*
* flaucheky.c -- the USB Mass Storage Class device
*
* Copyright (C) 2013, 2015, 2016, 2017
* Free Software Initiative of Japan
* Author: NIIBE Yutaka <gniibe@fsij.org>
*
* This file is a part of Fraucheky, making sure to have GNU GPL on a
* USB thumb drive
*
* Fraucheky 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 3 of the License,
* or (at your option) any later version.
*
* Fraucheky 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, see <http://www.gnu.org/licenses/>.
*
*/
#include <stdint.h>
#include <stdlib.h>
#include "usb_lld.h"
#include "config.h"
/* MSC BULK_IN, BULK_OUT */
/* EP6: 64-byte, 64-byte */
#define ENDP6_TXADDR (0x180)
#define ENDP6_RXADDR (0x1c0)
#define USB_INITIAL_FEATURE 0x80 /* bmAttributes: bus powered */
#define MSC_GET_MAX_LUN_COMMAND 0xFE
#define MSC_MASS_STORAGE_RESET_COMMAND 0xFF
/* USB Standard Device Descriptor */
static const uint8_t device_desc[] = {
18, /* bLength */
DEVICE_DESCRIPTOR, /* bDescriptorType */
0x10, 0x01, /* bcdUSB = 1.1 */
0x00, /* bDeviceClass: 0 means deferred to interface */
0x00, /* bDeviceSubClass */
0x00, /* bDeviceProtocol */
0x40, /* bMaxPacketSize0 */
#include "fraucheky-vid-pid-ver.c.inc"
1, /* Index of string descriptor describing manufacturer */
2, /* Index of string descriptor describing product */
3, /* Index of string descriptor describing the device's serial number */
1 /* bNumConfigurations */
};
#define MSC_TOTAL_LENGTH (9+7+7)
/* Configuation Descriptor */
static const uint8_t config_desc[] = {
9, /* bLength: Configuation Descriptor size */
CONFIG_DESCRIPTOR, /* bDescriptorType: Configuration */
(9+9+7+7), 0x00, /* wTotalLength:no of returned bytes */
1, /* bNumInterfaces: */
0x01, /* bConfigurationValue: Configuration value */
0x00, /* iConfiguration. */
USB_INITIAL_FEATURE, /* bmAttributes*/
50, /* MaxPower 100 mA */
/* Interface Descriptor.*/
9, /* bLength: Interface Descriptor size */
INTERFACE_DESCRIPTOR, /* bDescriptorType: Interface */
0, /* bInterfaceNumber. */
0x00, /* bAlternateSetting. */
0x02, /* bNumEndpoints. */
0x08, /* bInterfaceClass (Mass Stprage). */
0x06, /* bInterfaceSubClass (SCSI
transparent command set, MSCO
chapter 2). */
0x50, /* bInterfaceProtocol (Bulk-Only
Mass Storage, MSCO chapter 3). */
0x00, /* iInterface. */
/* Endpoint Descriptor.*/
7, /* bLength: Endpoint Descriptor size */
ENDPOINT_DESCRIPTOR, /* bDescriptorType: Endpoint */
0x86, /* bEndpointAddress: (IN6) */
0x02, /* bmAttributes (Bulk). */
0x40, 0x00, /* wMaxPacketSize. */
0x00, /* bInterval (ignored for bulk). */
/* Endpoint Descriptor.*/
7, /* bLength: Endpoint Descriptor size */
ENDPOINT_DESCRIPTOR, /* bDescriptorType: Endpoint */
0x06, /* bEndpointAddress: (OUT6) */
0x02, /* bmAttributes (Bulk). */
0x40, 0x00, /* wMaxPacketSize. */
0x00, /* bInterval (ignored for bulk). */
};
/* USB String Descriptors */
static const uint8_t string_lang_id[] = {
4, /* bLength */
STRING_DESCRIPTOR,
0x09, 0x04 /* LangID = 0x0409: US-English */
};
#include "fraucheky-usb-strings.c.inc"
static const uint8_t string_serial[] = {
8*2+2, /* bLength */
STRING_DESCRIPTOR, /* bDescriptorType */
/* Serial number: "FSIJ-0.0" */
'F', 0, 'S', 0, 'I', 0, 'J', 0, '-', 0, '0', 0, '.', 0, '0', 0,
};
struct desc { const uint8_t *desc; uint16_t size; };
static const struct desc string_descriptors[] = {
{string_lang_id, sizeof (string_lang_id)},
{string_vendor, sizeof (string_vendor)},
{string_product, sizeof (string_product)},
{string_serial, sizeof (string_serial)},
};
void
fraucheky_setup_endpoints_for_interface (struct usb_dev *dev, int stop)
{
extern void fraucheky_reset (void);
if (!stop)
{
#ifdef GNU_LINUX_EMULATION
usb_lld_setup_endp (dev, ENDP6, 1, 1);
#else
(void)dev;
usb_lld_setup_endpoint (ENDP6, EP_BULK, 0, ENDP6_RXADDR, ENDP6_TXADDR, 64);
#endif
fraucheky_reset ();
}
else
{
usb_lld_stall_tx (ENDP6);
usb_lld_stall_rx (ENDP6);
}
}
int
fraucheky_setup (struct usb_dev *dev)
{
struct device_req *arg = &dev->dev_req;
static const uint8_t lun_table[] = { 0, 0, 0, 0, };
if (USB_SETUP_GET (arg->type))
{
if (arg->request == MSC_GET_MAX_LUN_COMMAND)
return usb_lld_ctrl_send (dev, lun_table, sizeof (lun_table));
}
else /* SETUP_SET */
if (arg->request == MSC_MASS_STORAGE_RESET_COMMAND)
return usb_lld_ctrl_ack (dev);
return -1;
}
int
fraucheky_get_descriptor (struct usb_dev *dev)
{
struct device_req *arg = &dev->dev_req;
uint8_t rcp = arg->type & RECIPIENT;
uint8_t desc_type = (arg->value >> 8);
uint8_t desc_index = (arg->value & 0xff);
if (rcp == DEVICE_RECIPIENT)
{
if (desc_type == DEVICE_DESCRIPTOR && arg->index == 0)
return usb_lld_ctrl_send (dev, device_desc, sizeof (device_desc));
else if (desc_type == CONFIG_DESCRIPTOR && arg->index == 0)
return usb_lld_ctrl_send (dev, config_desc, sizeof (config_desc));
else if (desc_type == STRING_DESCRIPTOR)
{
if (desc_index >= sizeof (string_descriptors) / sizeof (struct desc)
|| !((arg->index == 0 && desc_index == 0)
|| arg->index == 0x0409))
/* We only provide string in English. */
return -1;
return usb_lld_ctrl_send (dev,
string_descriptors[desc_index].desc,
string_descriptors[desc_index].size);
}
}
return -1;
}