1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2015 Google, Inc
4  * Written by Simon Glass <sjg@chromium.org>
5  */
6 
7 #define LOG_CATEGORY	UCLASS_USB
8 
9 #include <dm.h>
10 #include <log.h>
11 #include <malloc.h>
12 #include <os.h>
13 #include <scsi.h>
14 #include <scsi_emul.h>
15 #include <usb.h>
16 
17 /*
18  * This driver emulates a flash stick using the UFI command specification and
19  * the BBB (bulk/bulk/bulk) protocol. It supports only a single logical unit
20  * number (LUN 0).
21  */
22 
23 enum {
24 	SANDBOX_FLASH_EP_OUT		= 1,	/* endpoints */
25 	SANDBOX_FLASH_EP_IN		= 2,
26 	SANDBOX_FLASH_BLOCK_LEN		= 512,
27 	SANDBOX_FLASH_BUF_SIZE		= 512,
28 };
29 
30 enum {
31 	STRINGID_MANUFACTURER = 1,
32 	STRINGID_PRODUCT,
33 	STRINGID_SERIAL,
34 
35 	STRINGID_COUNT,
36 };
37 
38 /**
39  * struct sandbox_flash_priv - private state for this driver
40  *
41  * @eminfo:	emulator state
42  * @error:	true if there is an error condition
43  * @tag:	Tag value from last command
44  * @fd:		File descriptor of backing file
45  * @file_size:	Size of file in bytes
46  * @status_buff:	Data buffer for outgoing status
47  */
48 struct sandbox_flash_priv {
49 	struct scsi_emul_info eminfo;
50 	bool error;
51 	u32 tag;
52 	int fd;
53 	struct umass_bbb_csw status;
54 };
55 
56 struct sandbox_flash_plat {
57 	const char *pathname;
58 	struct usb_string flash_strings[STRINGID_COUNT];
59 };
60 
61 static struct usb_device_descriptor flash_device_desc = {
62 	.bLength =		sizeof(flash_device_desc),
63 	.bDescriptorType =	USB_DT_DEVICE,
64 
65 	.bcdUSB =		__constant_cpu_to_le16(0x0200),
66 
67 	.bDeviceClass =		0,
68 	.bDeviceSubClass =	0,
69 	.bDeviceProtocol =	0,
70 
71 	.idVendor =		__constant_cpu_to_le16(0x1234),
72 	.idProduct =		__constant_cpu_to_le16(0x5678),
73 	.iManufacturer =	STRINGID_MANUFACTURER,
74 	.iProduct =		STRINGID_PRODUCT,
75 	.iSerialNumber =	STRINGID_SERIAL,
76 	.bNumConfigurations =	1,
77 };
78 
79 static struct usb_config_descriptor flash_config0 = {
80 	.bLength		= sizeof(flash_config0),
81 	.bDescriptorType	= USB_DT_CONFIG,
82 
83 	/* wTotalLength is set up by usb-emul-uclass */
84 	.bNumInterfaces		= 1,
85 	.bConfigurationValue	= 0,
86 	.iConfiguration		= 0,
87 	.bmAttributes		= 1 << 7,
88 	.bMaxPower		= 50,
89 };
90 
91 static struct usb_interface_descriptor flash_interface0 = {
92 	.bLength		= sizeof(flash_interface0),
93 	.bDescriptorType	= USB_DT_INTERFACE,
94 
95 	.bInterfaceNumber	= 0,
96 	.bAlternateSetting	= 0,
97 	.bNumEndpoints		= 2,
98 	.bInterfaceClass	= USB_CLASS_MASS_STORAGE,
99 	.bInterfaceSubClass	= US_SC_UFI,
100 	.bInterfaceProtocol	= US_PR_BULK,
101 	.iInterface		= 0,
102 };
103 
104 static struct usb_endpoint_descriptor flash_endpoint0_out = {
105 	.bLength		= USB_DT_ENDPOINT_SIZE,
106 	.bDescriptorType	= USB_DT_ENDPOINT,
107 
108 	.bEndpointAddress	= SANDBOX_FLASH_EP_OUT,
109 	.bmAttributes		= USB_ENDPOINT_XFER_BULK,
110 	.wMaxPacketSize		= __constant_cpu_to_le16(1024),
111 	.bInterval		= 0,
112 };
113 
114 static struct usb_endpoint_descriptor flash_endpoint1_in = {
115 	.bLength		= USB_DT_ENDPOINT_SIZE,
116 	.bDescriptorType	= USB_DT_ENDPOINT,
117 
118 	.bEndpointAddress	= SANDBOX_FLASH_EP_IN | USB_ENDPOINT_DIR_MASK,
119 	.bmAttributes		= USB_ENDPOINT_XFER_BULK,
120 	.wMaxPacketSize		= __constant_cpu_to_le16(1024),
121 	.bInterval		= 0,
122 };
123 
124 static void *flash_desc_list[] = {
125 	&flash_device_desc,
126 	&flash_config0,
127 	&flash_interface0,
128 	&flash_endpoint0_out,
129 	&flash_endpoint1_in,
130 	NULL,
131 };
132 
sandbox_flash_control(struct udevice * dev,struct usb_device * udev,unsigned long pipe,void * buff,int len,struct devrequest * setup)133 static int sandbox_flash_control(struct udevice *dev, struct usb_device *udev,
134 				 unsigned long pipe, void *buff, int len,
135 				 struct devrequest *setup)
136 {
137 	struct sandbox_flash_priv *priv = dev_get_priv(dev);
138 
139 	if (pipe == usb_rcvctrlpipe(udev, 0)) {
140 		switch (setup->request) {
141 		case US_BBB_RESET:
142 			priv->error = false;
143 			return 0;
144 		case US_BBB_GET_MAX_LUN:
145 			*(char *)buff = '\0';
146 			return 1;
147 		default:
148 			debug("request=%x\n", setup->request);
149 			break;
150 		}
151 	}
152 	debug("pipe=%lx\n", pipe);
153 
154 	return -EIO;
155 }
156 
setup_fail_response(struct sandbox_flash_priv * priv)157 static void setup_fail_response(struct sandbox_flash_priv *priv)
158 {
159 	struct umass_bbb_csw *csw = &priv->status;
160 
161 	csw->dCSWSignature = CSWSIGNATURE;
162 	csw->dCSWTag = priv->tag;
163 	csw->dCSWDataResidue = 0;
164 	csw->bCSWStatus = CSWSTATUS_FAILED;
165 }
166 
167 /**
168  * setup_response() - set up a response to send back to the host
169  *
170  * @priv:	Sandbox flash private data
171  * @resp:	Response to send, or NULL if none
172  * @size:	Size of response
173  */
setup_response(struct sandbox_flash_priv * priv)174 static void setup_response(struct sandbox_flash_priv *priv)
175 {
176 	struct umass_bbb_csw *csw = &priv->status;
177 
178 	csw->dCSWSignature = CSWSIGNATURE;
179 	csw->dCSWTag = priv->tag;
180 	csw->dCSWDataResidue = 0;
181 	csw->bCSWStatus = CSWSTATUS_GOOD;
182 }
183 
handle_ufi_command(struct sandbox_flash_priv * priv,const void * buff,int len)184 static int handle_ufi_command(struct sandbox_flash_priv *priv, const void *buff,
185 			      int len)
186 {
187 	struct scsi_emul_info *info = &priv->eminfo;
188 	const struct scsi_cmd *req = buff;
189 	int ret;
190 	off_t offset;
191 
192 	ret = sb_scsi_emul_command(info, req, len);
193 	if (!ret) {
194 		setup_response(priv);
195 	} else if ((ret == SCSI_EMUL_DO_READ || ret == SCSI_EMUL_DO_WRITE) &&
196 		   priv->fd != -1) {
197 		offset = os_lseek(priv->fd, info->seek_block * info->block_size,
198 				  OS_SEEK_SET);
199 		if (offset < 0)
200 			setup_fail_response(priv);
201 		else
202 			setup_response(priv);
203 	} else {
204 		setup_fail_response(priv);
205 	}
206 
207 	return 0;
208 }
209 
sandbox_flash_bulk(struct udevice * dev,struct usb_device * udev,unsigned long pipe,void * buff,int len)210 static int sandbox_flash_bulk(struct udevice *dev, struct usb_device *udev,
211 			      unsigned long pipe, void *buff, int len)
212 {
213 	struct sandbox_flash_priv *priv = dev_get_priv(dev);
214 	struct scsi_emul_info *info = &priv->eminfo;
215 	int ep = usb_pipeendpoint(pipe);
216 	struct umass_bbb_cbw *cbw = buff;
217 
218 	debug("%s: dev=%s, pipe=%lx, ep=%x, len=%x, phase=%d\n", __func__,
219 	      dev->name, pipe, ep, len, info->phase);
220 	switch (ep) {
221 	case SANDBOX_FLASH_EP_OUT:
222 		switch (info->phase) {
223 		case SCSIPH_START:
224 			info->alloc_len = 0;
225 			info->read_len = 0;
226 			info->write_len = 0;
227 			if (priv->error || len != UMASS_BBB_CBW_SIZE ||
228 			    cbw->dCBWSignature != CBWSIGNATURE)
229 				goto err;
230 			if ((cbw->bCBWFlags & CBWFLAGS_SBZ) ||
231 			    cbw->bCBWLUN != 0)
232 				goto err;
233 			if (cbw->bCDBLength < 1 || cbw->bCDBLength >= 0x10)
234 				goto err;
235 			info->transfer_len = cbw->dCBWDataTransferLength;
236 			priv->tag = cbw->dCBWTag;
237 			return handle_ufi_command(priv, cbw->CBWCDB,
238 						  cbw->bCDBLength);
239 		case SCSIPH_DATA:
240 			log_debug("data out, len=%x, info->write_len=%x\n", len,
241 				  info->write_len);
242 			info->transfer_len = cbw->dCBWDataTransferLength;
243 			priv->tag = cbw->dCBWTag;
244 			if (!info->write_len)
245 				return 0;
246 			if (priv->fd != -1) {
247 				ulong bytes_written;
248 
249 				bytes_written = os_write(priv->fd, buff, len);
250 				log_debug("bytes_written=%lx", bytes_written);
251 				if (bytes_written != len)
252 					return -EIO;
253 				info->write_len -= len / info->block_size;
254 				if (!info->write_len)
255 					info->phase = SCSIPH_STATUS;
256 			} else {
257 				if (info->alloc_len && len > info->alloc_len)
258 					len = info->alloc_len;
259 				if (len > SANDBOX_FLASH_BUF_SIZE)
260 					len = SANDBOX_FLASH_BUF_SIZE;
261 				memcpy(info->buff, buff, len);
262 				info->phase = SCSIPH_STATUS;
263 			}
264 			return len;
265 		default:
266 			break;
267 		}
268 		break;
269 	case SANDBOX_FLASH_EP_IN:
270 		switch (info->phase) {
271 		case SCSIPH_DATA:
272 			debug("data in, len=%x, alloc_len=%x, info->read_len=%x\n",
273 			      len, info->alloc_len, info->read_len);
274 			if (info->read_len) {
275 				ulong bytes_read;
276 
277 				if (priv->fd == -1)
278 					return -EIO;
279 
280 				bytes_read = os_read(priv->fd, buff, len);
281 				if (bytes_read != len)
282 					return -EIO;
283 				info->read_len -= len / info->block_size;
284 				if (!info->read_len)
285 					info->phase = SCSIPH_STATUS;
286 			} else {
287 				if (info->alloc_len && len > info->alloc_len)
288 					len = info->alloc_len;
289 				if (len > SANDBOX_FLASH_BUF_SIZE)
290 					len = SANDBOX_FLASH_BUF_SIZE;
291 				memcpy(buff, info->buff, len);
292 				info->phase = SCSIPH_STATUS;
293 			}
294 			return len;
295 		case SCSIPH_STATUS:
296 			debug("status in, len=%x\n", len);
297 			if (len > sizeof(priv->status))
298 				len = sizeof(priv->status);
299 			memcpy(buff, &priv->status, len);
300 			info->phase = SCSIPH_START;
301 			return len;
302 		default:
303 			break;
304 		}
305 	}
306 err:
307 	priv->error = true;
308 	debug("%s: Detected transfer error\n", __func__);
309 	return 0;
310 }
311 
sandbox_flash_of_to_plat(struct udevice * dev)312 static int sandbox_flash_of_to_plat(struct udevice *dev)
313 {
314 	struct sandbox_flash_plat *plat = dev_get_plat(dev);
315 
316 	plat->pathname = dev_read_string(dev, "sandbox,filepath");
317 
318 	return 0;
319 }
320 
sandbox_flash_bind(struct udevice * dev)321 static int sandbox_flash_bind(struct udevice *dev)
322 {
323 	struct sandbox_flash_plat *plat = dev_get_plat(dev);
324 	struct usb_string *fs;
325 
326 	fs = plat->flash_strings;
327 	fs[0].id = STRINGID_MANUFACTURER;
328 	fs[0].s = "sandbox";
329 	fs[1].id = STRINGID_PRODUCT;
330 	fs[1].s = "flash";
331 	fs[2].id = STRINGID_SERIAL;
332 	fs[2].s = dev->name;
333 
334 	return usb_emul_setup_device(dev, plat->flash_strings, flash_desc_list);
335 }
336 
sandbox_flash_probe(struct udevice * dev)337 static int sandbox_flash_probe(struct udevice *dev)
338 {
339 	struct sandbox_flash_plat *plat = dev_get_plat(dev);
340 	struct sandbox_flash_priv *priv = dev_get_priv(dev);
341 	struct scsi_emul_info *info = &priv->eminfo;
342 	int ret;
343 
344 	priv->fd = os_open(plat->pathname, OS_O_RDWR);
345 	if (priv->fd != -1) {
346 		ret = os_get_filesize(plat->pathname, &info->file_size);
347 		if (ret)
348 			return log_msg_ret("sz", ret);
349 	}
350 	info->buff = malloc(SANDBOX_FLASH_BUF_SIZE);
351 	if (!info->buff)
352 		return log_ret(-ENOMEM);
353 	info->vendor = plat->flash_strings[STRINGID_MANUFACTURER -  1].s;
354 	info->product = plat->flash_strings[STRINGID_PRODUCT - 1].s;
355 	info->block_size = SANDBOX_FLASH_BLOCK_LEN;
356 
357 	return 0;
358 }
359 
sandbox_flash_remove(struct udevice * dev)360 static int sandbox_flash_remove(struct udevice *dev)
361 {
362 	struct sandbox_flash_priv *priv = dev_get_priv(dev);
363 	struct scsi_emul_info *info = &priv->eminfo;
364 
365 	free(info->buff);
366 
367 	return 0;
368 }
369 
370 static const struct dm_usb_ops sandbox_usb_flash_ops = {
371 	.control	= sandbox_flash_control,
372 	.bulk		= sandbox_flash_bulk,
373 };
374 
375 static const struct udevice_id sandbox_usb_flash_ids[] = {
376 	{ .compatible = "sandbox,usb-flash" },
377 	{ }
378 };
379 
380 U_BOOT_DRIVER(usb_sandbox_flash) = {
381 	.name	= "usb_sandbox_flash",
382 	.id	= UCLASS_USB_EMUL,
383 	.of_match = sandbox_usb_flash_ids,
384 	.bind	= sandbox_flash_bind,
385 	.probe	= sandbox_flash_probe,
386 	.remove	= sandbox_flash_remove,
387 	.of_to_plat = sandbox_flash_of_to_plat,
388 	.ops	= &sandbox_usb_flash_ops,
389 	.priv_auto	= sizeof(struct sandbox_flash_priv),
390 	.plat_auto	= sizeof(struct sandbox_flash_plat),
391 };
392