2 * (C) Copyright 2015 Google, Inc
3 * Written by Simon Glass <sjg@chromium.org>
5 * SPDX-License-Identifier: GPL-2.0+
14 DECLARE_GLOBAL_DATA_PTR
;
17 * This driver emulates a flash stick using the UFI command specification and
18 * the BBB (bulk/bulk/bulk) protocol. It supports only a single logical unit
23 SANDBOX_FLASH_EP_OUT
= 1, /* endpoints */
24 SANDBOX_FLASH_EP_IN
= 2,
25 SANDBOX_FLASH_BLOCK_LEN
= 512,
35 STRINGID_MANUFACTURER
= 1,
43 * struct sandbox_flash_priv - private state for this driver
45 * @error: true if there is an error condition
46 * @alloc_len: Allocation length from the last incoming command
47 * @transfer_len: Transfer length from CBW header
48 * @read_len: Number of blocks of data left in the current read command
49 * @tag: Tag value from last command
50 * @fd: File descriptor of backing file
51 * @file_size: Size of file in bytes
52 * @status_buff: Data buffer for outgoing status
53 * @buff_used: Number of bytes ready to transfer back to host
54 * @buff: Data buffer for outgoing data
56 struct sandbox_flash_priv
{
65 struct umass_bbb_csw status
;
70 struct sandbox_flash_plat
{
72 struct usb_string flash_strings
[STRINGID_COUNT
];
75 struct scsi_inquiry_resp
{
87 struct scsi_read_capacity_resp
{
92 struct __packed scsi_read10_req
{
101 static struct usb_device_descriptor flash_device_desc
= {
102 .bLength
= sizeof(flash_device_desc
),
103 .bDescriptorType
= USB_DT_DEVICE
,
105 .bcdUSB
= __constant_cpu_to_le16(0x0200),
108 .bDeviceSubClass
= 0,
109 .bDeviceProtocol
= 0,
111 .idVendor
= __constant_cpu_to_le16(0x1234),
112 .idProduct
= __constant_cpu_to_le16(0x5678),
113 .iManufacturer
= STRINGID_MANUFACTURER
,
114 .iProduct
= STRINGID_PRODUCT
,
115 .iSerialNumber
= STRINGID_SERIAL
,
116 .bNumConfigurations
= 1,
119 static struct usb_config_descriptor flash_config0
= {
120 .bLength
= sizeof(flash_config0
),
121 .bDescriptorType
= USB_DT_CONFIG
,
123 /* wTotalLength is set up by usb-emul-uclass */
125 .bConfigurationValue
= 0,
127 .bmAttributes
= 1 << 7,
131 static struct usb_interface_descriptor flash_interface0
= {
132 .bLength
= sizeof(flash_interface0
),
133 .bDescriptorType
= USB_DT_INTERFACE
,
135 .bInterfaceNumber
= 0,
136 .bAlternateSetting
= 0,
138 .bInterfaceClass
= USB_CLASS_MASS_STORAGE
,
139 .bInterfaceSubClass
= US_SC_UFI
,
140 .bInterfaceProtocol
= US_PR_BULK
,
144 static struct usb_endpoint_descriptor flash_endpoint0_out
= {
145 .bLength
= USB_DT_ENDPOINT_SIZE
,
146 .bDescriptorType
= USB_DT_ENDPOINT
,
148 .bEndpointAddress
= SANDBOX_FLASH_EP_OUT
,
149 .bmAttributes
= USB_ENDPOINT_XFER_BULK
,
150 .wMaxPacketSize
= __constant_cpu_to_le16(1024),
154 static struct usb_endpoint_descriptor flash_endpoint1_in
= {
155 .bLength
= USB_DT_ENDPOINT_SIZE
,
156 .bDescriptorType
= USB_DT_ENDPOINT
,
158 .bEndpointAddress
= SANDBOX_FLASH_EP_IN
| USB_ENDPOINT_DIR_MASK
,
159 .bmAttributes
= USB_ENDPOINT_XFER_BULK
,
160 .wMaxPacketSize
= __constant_cpu_to_le16(1024),
164 static void *flash_desc_list
[] = {
168 &flash_endpoint0_out
,
173 static int sandbox_flash_control(struct udevice
*dev
, struct usb_device
*udev
,
174 unsigned long pipe
, void *buff
, int len
,
175 struct devrequest
*setup
)
177 struct sandbox_flash_priv
*priv
= dev_get_priv(dev
);
179 if (pipe
== usb_rcvctrlpipe(udev
, 0)) {
180 switch (setup
->request
) {
184 case US_BBB_GET_MAX_LUN
:
185 *(char *)buff
= '\0';
188 debug("request=%x\n", setup
->request
);
192 debug("pipe=%lx\n", pipe
);
197 static void setup_fail_response(struct sandbox_flash_priv
*priv
)
199 struct umass_bbb_csw
*csw
= &priv
->status
;
201 csw
->dCSWSignature
= CSWSIGNATURE
;
202 csw
->dCSWTag
= priv
->tag
;
203 csw
->dCSWDataResidue
= 0;
204 csw
->bCSWStatus
= CSWSTATUS_FAILED
;
209 * setup_response() - set up a response to send back to the host
211 * @priv: Sandbox flash private data
212 * @resp: Response to send, or NULL if none
213 * @size: Size of response
215 static void setup_response(struct sandbox_flash_priv
*priv
, void *resp
,
218 struct umass_bbb_csw
*csw
= &priv
->status
;
220 csw
->dCSWSignature
= CSWSIGNATURE
;
221 csw
->dCSWTag
= priv
->tag
;
222 csw
->dCSWDataResidue
= 0;
223 csw
->bCSWStatus
= CSWSTATUS_GOOD
;
225 assert(!resp
|| resp
== priv
->buff
);
226 priv
->buff_used
= size
;
229 static void handle_read(struct sandbox_flash_priv
*priv
, ulong lba
,
232 debug("%s: lba=%lx, transfer_len=%lx\n", __func__
, lba
, transfer_len
);
233 if (priv
->fd
!= -1) {
234 os_lseek(priv
->fd
, lba
* SANDBOX_FLASH_BLOCK_LEN
, OS_SEEK_SET
);
235 priv
->read_len
= transfer_len
;
236 setup_response(priv
, priv
->buff
,
237 transfer_len
* SANDBOX_FLASH_BLOCK_LEN
);
239 setup_fail_response(priv
);
243 static int handle_ufi_command(struct sandbox_flash_plat
*plat
,
244 struct sandbox_flash_priv
*priv
, const void *buff
,
247 const struct scsi_cmd
*req
= buff
;
251 struct scsi_inquiry_resp
*resp
= (void *)priv
->buff
;
253 priv
->alloc_len
= req
->cmd
[4];
254 memset(resp
, '\0', sizeof(*resp
));
255 resp
->data_format
= 1;
256 resp
->additional_len
= 0x1f;
257 strncpy(resp
->vendor
,
258 plat
->flash_strings
[STRINGID_MANUFACTURER
- 1].s
,
259 sizeof(resp
->vendor
));
260 strncpy(resp
->product
,
261 plat
->flash_strings
[STRINGID_PRODUCT
- 1].s
,
262 sizeof(resp
->product
));
263 strncpy(resp
->revision
, "1.0", sizeof(resp
->revision
));
264 setup_response(priv
, resp
, sizeof(*resp
));
268 setup_response(priv
, NULL
, 0);
270 case SCSI_RD_CAPAC
: {
271 struct scsi_read_capacity_resp
*resp
= (void *)priv
->buff
;
275 blocks
= priv
->file_size
/ SANDBOX_FLASH_BLOCK_LEN
- 1;
278 resp
->last_block_addr
= cpu_to_be32(blocks
);
279 resp
->block_len
= cpu_to_be32(SANDBOX_FLASH_BLOCK_LEN
);
280 setup_response(priv
, resp
, sizeof(*resp
));
284 struct scsi_read10_req
*req
= (void *)buff
;
286 handle_read(priv
, be32_to_cpu(req
->lba
),
287 be16_to_cpu(req
->transfer_len
));
291 debug("Command not supported: %x\n", req
->cmd
[0]);
292 return -EPROTONOSUPPORT
;
295 priv
->phase
= priv
->transfer_len
? PHASE_DATA
: PHASE_STATUS
;
299 static int sandbox_flash_bulk(struct udevice
*dev
, struct usb_device
*udev
,
300 unsigned long pipe
, void *buff
, int len
)
302 struct sandbox_flash_plat
*plat
= dev_get_platdata(dev
);
303 struct sandbox_flash_priv
*priv
= dev_get_priv(dev
);
304 int ep
= usb_pipeendpoint(pipe
);
305 struct umass_bbb_cbw
*cbw
= buff
;
307 debug("%s: dev=%s, pipe=%lx, ep=%x, len=%x, phase=%d\n", __func__
,
308 dev
->name
, pipe
, ep
, len
, priv
->phase
);
310 case SANDBOX_FLASH_EP_OUT
:
311 switch (priv
->phase
) {
315 if (priv
->error
|| len
!= UMASS_BBB_CBW_SIZE
||
316 cbw
->dCBWSignature
!= CBWSIGNATURE
)
318 if ((cbw
->bCBWFlags
& CBWFLAGS_SBZ
) ||
321 if (cbw
->bCDBLength
< 1 || cbw
->bCDBLength
>= 0x10)
323 priv
->transfer_len
= cbw
->dCBWDataTransferLength
;
324 priv
->tag
= cbw
->dCBWTag
;
325 return handle_ufi_command(plat
, priv
, cbw
->CBWCDB
,
333 case SANDBOX_FLASH_EP_IN
:
334 switch (priv
->phase
) {
336 debug("data in, len=%x, alloc_len=%x, priv->read_len=%x\n",
337 len
, priv
->alloc_len
, priv
->read_len
);
338 if (priv
->read_len
) {
341 bytes_read
= os_read(priv
->fd
, buff
, len
);
342 if (bytes_read
!= len
)
344 priv
->read_len
-= len
/ SANDBOX_FLASH_BLOCK_LEN
;
346 priv
->phase
= PHASE_STATUS
;
348 if (priv
->alloc_len
&& len
> priv
->alloc_len
)
349 len
= priv
->alloc_len
;
350 memcpy(buff
, priv
->buff
, len
);
351 priv
->phase
= PHASE_STATUS
;
355 debug("status in, len=%x\n", len
);
356 if (len
> sizeof(priv
->status
))
357 len
= sizeof(priv
->status
);
358 memcpy(buff
, &priv
->status
, len
);
359 priv
->phase
= PHASE_START
;
367 debug("%s: Detected transfer error\n", __func__
);
371 static int sandbox_flash_ofdata_to_platdata(struct udevice
*dev
)
373 struct sandbox_flash_plat
*plat
= dev_get_platdata(dev
);
375 plat
->pathname
= dev_read_string(dev
, "sandbox,filepath");
380 static int sandbox_flash_bind(struct udevice
*dev
)
382 struct sandbox_flash_plat
*plat
= dev_get_platdata(dev
);
383 struct usb_string
*fs
;
385 fs
= plat
->flash_strings
;
386 fs
[0].id
= STRINGID_MANUFACTURER
;
388 fs
[1].id
= STRINGID_PRODUCT
;
390 fs
[2].id
= STRINGID_SERIAL
;
393 return usb_emul_setup_device(dev
, plat
->flash_strings
, flash_desc_list
);
396 static int sandbox_flash_probe(struct udevice
*dev
)
398 struct sandbox_flash_plat
*plat
= dev_get_platdata(dev
);
399 struct sandbox_flash_priv
*priv
= dev_get_priv(dev
);
401 priv
->fd
= os_open(plat
->pathname
, OS_O_RDONLY
);
403 return os_get_filesize(plat
->pathname
, &priv
->file_size
);
408 static const struct dm_usb_ops sandbox_usb_flash_ops
= {
409 .control
= sandbox_flash_control
,
410 .bulk
= sandbox_flash_bulk
,
413 static const struct udevice_id sandbox_usb_flash_ids
[] = {
414 { .compatible
= "sandbox,usb-flash" },
418 U_BOOT_DRIVER(usb_sandbox_flash
) = {
419 .name
= "usb_sandbox_flash",
420 .id
= UCLASS_USB_EMUL
,
421 .of_match
= sandbox_usb_flash_ids
,
422 .bind
= sandbox_flash_bind
,
423 .probe
= sandbox_flash_probe
,
424 .ofdata_to_platdata
= sandbox_flash_ofdata_to_platdata
,
425 .ops
= &sandbox_usb_flash_ops
,
426 .priv_auto_alloc_size
= sizeof(struct sandbox_flash_priv
),
427 .platdata_auto_alloc_size
= sizeof(struct sandbox_flash_plat
),