1 // SPDX-License-Identifier: GPL-2.0+
5 * Eddie Cai <eddie.cai.linux@gmail.com>
12 #include <linux/usb/ch9.h>
13 #include <linux/usb/gadget.h>
14 #include <linux/usb/composite.h>
15 #include <linux/compiler.h>
18 #include <asm/arch/f_rockusb.h>
20 static inline struct f_rockusb
*func_to_rockusb(struct usb_function
*f
)
22 return container_of(f
, struct f_rockusb
, usb_function
);
25 static struct usb_endpoint_descriptor fs_ep_in
= {
26 .bLength
= USB_DT_ENDPOINT_SIZE
,
27 .bDescriptorType
= USB_DT_ENDPOINT
,
28 .bEndpointAddress
= USB_DIR_IN
,
29 .bmAttributes
= USB_ENDPOINT_XFER_BULK
,
30 .wMaxPacketSize
= cpu_to_le16(64),
33 static struct usb_endpoint_descriptor fs_ep_out
= {
34 .bLength
= USB_DT_ENDPOINT_SIZE
,
35 .bDescriptorType
= USB_DT_ENDPOINT
,
36 .bEndpointAddress
= USB_DIR_OUT
,
37 .bmAttributes
= USB_ENDPOINT_XFER_BULK
,
38 .wMaxPacketSize
= cpu_to_le16(64),
41 static struct usb_endpoint_descriptor hs_ep_in
= {
42 .bLength
= USB_DT_ENDPOINT_SIZE
,
43 .bDescriptorType
= USB_DT_ENDPOINT
,
44 .bEndpointAddress
= USB_DIR_IN
,
45 .bmAttributes
= USB_ENDPOINT_XFER_BULK
,
46 .wMaxPacketSize
= cpu_to_le16(512),
49 static struct usb_endpoint_descriptor hs_ep_out
= {
50 .bLength
= USB_DT_ENDPOINT_SIZE
,
51 .bDescriptorType
= USB_DT_ENDPOINT
,
52 .bEndpointAddress
= USB_DIR_OUT
,
53 .bmAttributes
= USB_ENDPOINT_XFER_BULK
,
54 .wMaxPacketSize
= cpu_to_le16(512),
57 static struct usb_interface_descriptor interface_desc
= {
58 .bLength
= USB_DT_INTERFACE_SIZE
,
59 .bDescriptorType
= USB_DT_INTERFACE
,
60 .bInterfaceNumber
= 0x00,
61 .bAlternateSetting
= 0x00,
62 .bNumEndpoints
= 0x02,
63 .bInterfaceClass
= ROCKUSB_INTERFACE_CLASS
,
64 .bInterfaceSubClass
= ROCKUSB_INTERFACE_SUB_CLASS
,
65 .bInterfaceProtocol
= ROCKUSB_INTERFACE_PROTOCOL
,
68 static struct usb_descriptor_header
*rkusb_fs_function
[] = {
69 (struct usb_descriptor_header
*)&interface_desc
,
70 (struct usb_descriptor_header
*)&fs_ep_in
,
71 (struct usb_descriptor_header
*)&fs_ep_out
,
74 static struct usb_descriptor_header
*rkusb_hs_function
[] = {
75 (struct usb_descriptor_header
*)&interface_desc
,
76 (struct usb_descriptor_header
*)&hs_ep_in
,
77 (struct usb_descriptor_header
*)&hs_ep_out
,
81 static const char rkusb_name
[] = "Rockchip Rockusb";
83 static struct usb_string rkusb_string_defs
[] = {
88 static struct usb_gadget_strings stringtab_rkusb
= {
89 .language
= 0x0409, /* en-us */
90 .strings
= rkusb_string_defs
,
93 static struct usb_gadget_strings
*rkusb_strings
[] = {
98 static struct f_rockusb
*rockusb_func
;
99 static void rx_handler_command(struct usb_ep
*ep
, struct usb_request
*req
);
100 static int rockusb_tx_write_csw(u32 tag
, int residue
, u8 status
, int size
);
102 struct f_rockusb
*get_rkusb(void)
104 struct f_rockusb
*f_rkusb
= rockusb_func
;
107 f_rkusb
= memalign(CONFIG_SYS_CACHELINE_SIZE
, sizeof(*f_rkusb
));
111 rockusb_func
= f_rkusb
;
112 memset(f_rkusb
, 0, sizeof(*f_rkusb
));
115 if (!f_rkusb
->buf_head
) {
116 f_rkusb
->buf_head
= memalign(CONFIG_SYS_CACHELINE_SIZE
,
118 if (!f_rkusb
->buf_head
)
121 f_rkusb
->buf
= f_rkusb
->buf_head
;
122 memset(f_rkusb
->buf_head
, 0, RKUSB_BUF_SIZE
);
127 static struct usb_endpoint_descriptor
*rkusb_ep_desc(
128 struct usb_gadget
*g
,
129 struct usb_endpoint_descriptor
*fs
,
130 struct usb_endpoint_descriptor
*hs
)
132 if (gadget_is_dualspeed(g
) && g
->speed
== USB_SPEED_HIGH
)
137 static void rockusb_complete(struct usb_ep
*ep
, struct usb_request
*req
)
139 int status
= req
->status
;
143 debug("status: %d ep '%s' trans: %d\n", status
, ep
->name
, req
->actual
);
146 /* config the rockusb device*/
147 static int rockusb_bind(struct usb_configuration
*c
, struct usb_function
*f
)
150 struct usb_gadget
*gadget
= c
->cdev
->gadget
;
151 struct f_rockusb
*f_rkusb
= func_to_rockusb(f
);
154 id
= usb_interface_id(c
, f
);
157 interface_desc
.bInterfaceNumber
= id
;
159 id
= usb_string_id(c
->cdev
);
163 rkusb_string_defs
[0].id
= id
;
164 interface_desc
.iInterface
= id
;
166 f_rkusb
->in_ep
= usb_ep_autoconfig(gadget
, &fs_ep_in
);
169 f_rkusb
->in_ep
->driver_data
= c
->cdev
;
171 f_rkusb
->out_ep
= usb_ep_autoconfig(gadget
, &fs_ep_out
);
172 if (!f_rkusb
->out_ep
)
174 f_rkusb
->out_ep
->driver_data
= c
->cdev
;
176 f
->descriptors
= rkusb_fs_function
;
178 if (gadget_is_dualspeed(gadget
)) {
179 hs_ep_in
.bEndpointAddress
= fs_ep_in
.bEndpointAddress
;
180 hs_ep_out
.bEndpointAddress
= fs_ep_out
.bEndpointAddress
;
181 f
->hs_descriptors
= rkusb_hs_function
;
184 s
= env_get("serial#");
186 g_dnl_set_serialnumber((char *)s
);
191 static void rockusb_unbind(struct usb_configuration
*c
, struct usb_function
*f
)
193 /* clear the configuration*/
194 memset(rockusb_func
, 0, sizeof(*rockusb_func
));
197 static void rockusb_disable(struct usb_function
*f
)
199 struct f_rockusb
*f_rkusb
= func_to_rockusb(f
);
201 usb_ep_disable(f_rkusb
->out_ep
);
202 usb_ep_disable(f_rkusb
->in_ep
);
204 if (f_rkusb
->out_req
) {
205 free(f_rkusb
->out_req
->buf
);
206 usb_ep_free_request(f_rkusb
->out_ep
, f_rkusb
->out_req
);
207 f_rkusb
->out_req
= NULL
;
209 if (f_rkusb
->in_req
) {
210 free(f_rkusb
->in_req
->buf
);
211 usb_ep_free_request(f_rkusb
->in_ep
, f_rkusb
->in_req
);
212 f_rkusb
->in_req
= NULL
;
214 if (f_rkusb
->buf_head
) {
215 free(f_rkusb
->buf_head
);
216 f_rkusb
->buf_head
= NULL
;
221 static struct usb_request
*rockusb_start_ep(struct usb_ep
*ep
)
223 struct usb_request
*req
;
225 req
= usb_ep_alloc_request(ep
, 0);
229 req
->length
= EP_BUFFER_SIZE
;
230 req
->buf
= memalign(CONFIG_SYS_CACHELINE_SIZE
, EP_BUFFER_SIZE
);
232 usb_ep_free_request(ep
, req
);
235 memset(req
->buf
, 0, req
->length
);
240 static int rockusb_set_alt(struct usb_function
*f
, unsigned int interface
,
244 struct usb_composite_dev
*cdev
= f
->config
->cdev
;
245 struct usb_gadget
*gadget
= cdev
->gadget
;
246 struct f_rockusb
*f_rkusb
= func_to_rockusb(f
);
247 const struct usb_endpoint_descriptor
*d
;
249 debug("%s: func: %s intf: %d alt: %d\n",
250 __func__
, f
->name
, interface
, alt
);
252 d
= rkusb_ep_desc(gadget
, &fs_ep_out
, &hs_ep_out
);
253 ret
= usb_ep_enable(f_rkusb
->out_ep
, d
);
255 printf("failed to enable out ep\n");
259 f_rkusb
->out_req
= rockusb_start_ep(f_rkusb
->out_ep
);
260 if (!f_rkusb
->out_req
) {
261 printf("failed to alloc out req\n");
265 f_rkusb
->out_req
->complete
= rx_handler_command
;
267 d
= rkusb_ep_desc(gadget
, &fs_ep_in
, &hs_ep_in
);
268 ret
= usb_ep_enable(f_rkusb
->in_ep
, d
);
270 printf("failed to enable in ep\n");
274 f_rkusb
->in_req
= rockusb_start_ep(f_rkusb
->in_ep
);
275 if (!f_rkusb
->in_req
) {
276 printf("failed alloc req in\n");
280 f_rkusb
->in_req
->complete
= rockusb_complete
;
282 ret
= usb_ep_queue(f_rkusb
->out_ep
, f_rkusb
->out_req
, 0);
292 static int rockusb_add(struct usb_configuration
*c
)
294 struct f_rockusb
*f_rkusb
= get_rkusb();
297 debug("%s: cdev: 0x%p\n", __func__
, c
->cdev
);
299 f_rkusb
->usb_function
.name
= "f_rockusb";
300 f_rkusb
->usb_function
.bind
= rockusb_bind
;
301 f_rkusb
->usb_function
.unbind
= rockusb_unbind
;
302 f_rkusb
->usb_function
.set_alt
= rockusb_set_alt
;
303 f_rkusb
->usb_function
.disable
= rockusb_disable
;
304 f_rkusb
->usb_function
.strings
= rkusb_strings
;
306 status
= usb_add_function(c
, &f_rkusb
->usb_function
);
309 rockusb_func
= f_rkusb
;
314 void rockusb_dev_init(char *dev_type
, int dev_index
)
316 struct f_rockusb
*f_rkusb
= get_rkusb();
318 f_rkusb
->dev_type
= dev_type
;
319 f_rkusb
->dev_index
= dev_index
;
322 DECLARE_GADGET_BIND_CALLBACK(usb_dnl_rockusb
, rockusb_add
);
324 static int rockusb_tx_write(const char *buffer
, unsigned int buffer_size
)
326 struct usb_request
*in_req
= rockusb_func
->in_req
;
329 memcpy(in_req
->buf
, buffer
, buffer_size
);
330 in_req
->length
= buffer_size
;
331 debug("Transferring 0x%x bytes\n", buffer_size
);
332 usb_ep_dequeue(rockusb_func
->in_ep
, in_req
);
333 ret
= usb_ep_queue(rockusb_func
->in_ep
, in_req
, 0);
335 printf("Error %d on queue\n", ret
);
339 static int rockusb_tx_write_str(const char *buffer
)
341 return rockusb_tx_write(buffer
, strlen(buffer
));
345 static void printcbw(char *buf
)
347 ALLOC_CACHE_ALIGN_BUFFER(struct fsg_bulk_cb_wrap
, cbw
,
348 sizeof(struct fsg_bulk_cb_wrap
));
350 memcpy((char *)cbw
, buf
, USB_BULK_CB_WRAP_LEN
);
352 debug("cbw: signature:%x\n", cbw
->signature
);
353 debug("cbw: tag=%x\n", cbw
->tag
);
354 debug("cbw: data_transfer_length=%d\n", cbw
->data_transfer_length
);
355 debug("cbw: flags=%x\n", cbw
->flags
);
356 debug("cbw: lun=%d\n", cbw
->lun
);
357 debug("cbw: length=%d\n", cbw
->length
);
358 debug("cbw: ucOperCode=%x\n", cbw
->CDB
[0]);
359 debug("cbw: ucReserved=%x\n", cbw
->CDB
[1]);
360 debug("cbw: dwAddress:%x %x %x %x\n", cbw
->CDB
[5], cbw
->CDB
[4],
361 cbw
->CDB
[3], cbw
->CDB
[2]);
362 debug("cbw: ucReserved2=%x\n", cbw
->CDB
[6]);
363 debug("cbw: uslength:%x %x\n", cbw
->CDB
[8], cbw
->CDB
[7]);
366 static void printcsw(char *buf
)
368 ALLOC_CACHE_ALIGN_BUFFER(struct bulk_cs_wrap
, csw
,
369 sizeof(struct bulk_cs_wrap
));
370 memcpy((char *)csw
, buf
, USB_BULK_CS_WRAP_LEN
);
371 debug("csw: signature:%x\n", csw
->signature
);
372 debug("csw: tag:%x\n", csw
->tag
);
373 debug("csw: residue:%x\n", csw
->residue
);
374 debug("csw: status:%x\n", csw
->status
);
378 static int rockusb_tx_write_csw(u32 tag
, int residue
, u8 status
, int size
)
380 ALLOC_CACHE_ALIGN_BUFFER(struct bulk_cs_wrap
, csw
,
381 sizeof(struct bulk_cs_wrap
));
382 csw
->signature
= cpu_to_le32(USB_BULK_CS_SIG
);
384 csw
->residue
= cpu_to_be32(residue
);
385 csw
->status
= status
;
387 printcsw((char *)&csw
);
389 return rockusb_tx_write((char *)csw
, size
);
392 static void tx_handler_send_csw(struct usb_ep
*ep
, struct usb_request
*req
)
394 struct f_rockusb
*f_rkusb
= get_rkusb();
395 int status
= req
->status
;
398 debug("status: %d ep '%s' trans: %d\n",
399 status
, ep
->name
, req
->actual
);
401 /* Return back to default in_req complete function after sending CSW */
402 req
->complete
= rockusb_complete
;
403 rockusb_tx_write_csw(f_rkusb
->tag
, 0, CSW_GOOD
, USB_BULK_CS_WRAP_LEN
);
406 static unsigned int rx_bytes_expected(struct usb_ep
*ep
)
408 struct f_rockusb
*f_rkusb
= get_rkusb();
409 int rx_remain
= f_rkusb
->dl_size
- f_rkusb
->dl_bytes
;
411 unsigned int maxpacket
= ep
->maxpacket
;
415 else if (rx_remain
> EP_BUFFER_SIZE
)
416 return EP_BUFFER_SIZE
;
418 rem
= rx_remain
% maxpacket
;
420 rx_remain
= rx_remain
+ (maxpacket
- rem
);
425 /* usb_request complete call back to handle upload image */
426 static void tx_handler_ul_image(struct usb_ep
*ep
, struct usb_request
*req
)
428 ALLOC_CACHE_ALIGN_BUFFER(char, rbuffer
, RKBLOCK_BUF_SIZE
);
429 struct f_rockusb
*f_rkusb
= get_rkusb();
430 struct usb_request
*in_req
= rockusb_func
->in_req
;
433 /* Print error status of previous transfer */
435 debug("status: %d ep '%s' trans: %d len %d\n", req
->status
,
436 ep
->name
, req
->actual
, req
->length
);
438 /* On transfer complete reset in_req and feedback host with CSW_GOOD */
439 if (f_rkusb
->ul_bytes
>= f_rkusb
->ul_size
) {
441 in_req
->complete
= rockusb_complete
;
443 rockusb_tx_write_csw(f_rkusb
->tag
, 0, CSW_GOOD
,
444 USB_BULK_CS_WRAP_LEN
);
448 /* Proceed with current chunk */
449 unsigned int transfer_size
= f_rkusb
->ul_size
- f_rkusb
->ul_bytes
;
451 if (transfer_size
> RKBLOCK_BUF_SIZE
)
452 transfer_size
= RKBLOCK_BUF_SIZE
;
453 /* Read at least one block */
454 unsigned int blkcount
= (transfer_size
+ f_rkusb
->desc
->blksz
- 1) /
455 f_rkusb
->desc
->blksz
;
457 debug("ul %x bytes, %x blks, read lba %x, ul_size:%x, ul_bytes:%x, ",
458 transfer_size
, blkcount
, f_rkusb
->lba
,
459 f_rkusb
->ul_size
, f_rkusb
->ul_bytes
);
461 int blks
= blk_dread(f_rkusb
->desc
, f_rkusb
->lba
, blkcount
, rbuffer
);
463 if (blks
!= blkcount
) {
464 printf("failed reading from device %s: %d\n",
465 f_rkusb
->dev_type
, f_rkusb
->dev_index
);
466 rockusb_tx_write_csw(f_rkusb
->tag
, 0, CSW_FAIL
,
467 USB_BULK_CS_WRAP_LEN
);
470 f_rkusb
->lba
+= blkcount
;
471 f_rkusb
->ul_bytes
+= transfer_size
;
473 /* Proceed with USB request */
474 memcpy(in_req
->buf
, rbuffer
, transfer_size
);
475 in_req
->length
= transfer_size
;
476 in_req
->complete
= tx_handler_ul_image
;
477 debug("Uploading 0x%x bytes\n", transfer_size
);
478 usb_ep_dequeue(rockusb_func
->in_ep
, in_req
);
479 ret
= usb_ep_queue(rockusb_func
->in_ep
, in_req
, 0);
481 printf("Error %d on queue\n", ret
);
484 /* usb_request complete call back to handle down load image */
485 static void rx_handler_dl_image(struct usb_ep
*ep
, struct usb_request
*req
)
487 struct f_rockusb
*f_rkusb
= get_rkusb();
488 unsigned int transfer_size
= 0;
489 const unsigned char *buffer
= req
->buf
;
490 unsigned int buffer_size
= req
->actual
;
492 transfer_size
= f_rkusb
->dl_size
- f_rkusb
->dl_bytes
;
493 if (!f_rkusb
->desc
) {
494 char *type
= f_rkusb
->dev_type
;
495 int index
= f_rkusb
->dev_index
;
497 f_rkusb
->desc
= blk_get_dev(type
, index
);
498 if (!f_rkusb
->desc
||
499 f_rkusb
->desc
->type
== DEV_TYPE_UNKNOWN
) {
500 puts("invalid mmc device\n");
501 rockusb_tx_write_csw(f_rkusb
->tag
, 0, CSW_FAIL
,
502 USB_BULK_CS_WRAP_LEN
);
507 if (req
->status
!= 0) {
508 printf("Bad status: %d\n", req
->status
);
509 rockusb_tx_write_csw(f_rkusb
->tag
, 0, CSW_FAIL
,
510 USB_BULK_CS_WRAP_LEN
);
514 if (buffer_size
< transfer_size
)
515 transfer_size
= buffer_size
;
517 memcpy((void *)f_rkusb
->buf
, buffer
, transfer_size
);
518 f_rkusb
->dl_bytes
+= transfer_size
;
519 int blks
= 0, blkcnt
= transfer_size
/ 512;
521 debug("dl %x bytes, %x blks, write lba %x, dl_size:%x, dl_bytes:%x, ",
522 transfer_size
, blkcnt
, f_rkusb
->lba
, f_rkusb
->dl_size
,
524 blks
= blk_dwrite(f_rkusb
->desc
, f_rkusb
->lba
, blkcnt
, f_rkusb
->buf
);
525 if (blks
!= blkcnt
) {
526 printf("failed writing to device %s: %d\n", f_rkusb
->dev_type
,
528 rockusb_tx_write_csw(f_rkusb
->tag
, 0, CSW_FAIL
,
529 USB_BULK_CS_WRAP_LEN
);
532 f_rkusb
->lba
+= blkcnt
;
534 /* Check if transfer is done */
535 if (f_rkusb
->dl_bytes
>= f_rkusb
->dl_size
) {
536 req
->complete
= rx_handler_command
;
537 req
->length
= EP_BUFFER_SIZE
;
538 f_rkusb
->buf
= f_rkusb
->buf_head
;
539 debug("transfer 0x%x bytes done\n", f_rkusb
->dl_size
);
540 f_rkusb
->dl_size
= 0;
541 rockusb_tx_write_csw(f_rkusb
->tag
, 0, CSW_GOOD
,
542 USB_BULK_CS_WRAP_LEN
);
544 req
->length
= rx_bytes_expected(ep
);
545 if (f_rkusb
->buf
== f_rkusb
->buf_head
)
546 f_rkusb
->buf
= f_rkusb
->buf_head
+ EP_BUFFER_SIZE
;
548 f_rkusb
->buf
= f_rkusb
->buf_head
;
550 debug("remain %x bytes, %x sectors\n", req
->length
,
555 usb_ep_queue(ep
, req
, 0);
558 static void cb_test_unit_ready(struct usb_ep
*ep
, struct usb_request
*req
)
560 ALLOC_CACHE_ALIGN_BUFFER(struct fsg_bulk_cb_wrap
, cbw
,
561 sizeof(struct fsg_bulk_cb_wrap
));
563 memcpy((char *)cbw
, req
->buf
, USB_BULK_CB_WRAP_LEN
);
565 rockusb_tx_write_csw(cbw
->tag
, cbw
->data_transfer_length
,
566 CSW_GOOD
, USB_BULK_CS_WRAP_LEN
);
569 static void cb_read_storage_id(struct usb_ep
*ep
, struct usb_request
*req
)
571 ALLOC_CACHE_ALIGN_BUFFER(struct fsg_bulk_cb_wrap
, cbw
,
572 sizeof(struct fsg_bulk_cb_wrap
));
573 struct f_rockusb
*f_rkusb
= get_rkusb();
574 char emmc_id
[] = "EMMC ";
576 printf("read storage id\n");
577 memcpy((char *)cbw
, req
->buf
, USB_BULK_CB_WRAP_LEN
);
579 /* Prepare for sending subsequent CSW_GOOD */
580 f_rkusb
->tag
= cbw
->tag
;
581 f_rkusb
->in_req
->complete
= tx_handler_send_csw
;
583 rockusb_tx_write_str(emmc_id
);
586 int __weak
rk_get_bootrom_chip_version(unsigned int *chip_info
, int size
)
591 static void cb_get_chip_version(struct usb_ep
*ep
, struct usb_request
*req
)
593 ALLOC_CACHE_ALIGN_BUFFER(struct fsg_bulk_cb_wrap
, cbw
,
594 sizeof(struct fsg_bulk_cb_wrap
));
595 struct f_rockusb
*f_rkusb
= get_rkusb();
596 unsigned int chip_info
[4], i
;
598 memset(chip_info
, 0, sizeof(chip_info
));
599 rk_get_bootrom_chip_version(chip_info
, 4);
602 * Chip Version is a string saved in BOOTROM address space Little Endian
604 * Ex for rk3288: 0x33323041 0x32303134 0x30383133 0x56323030
605 * which brings: 320A20140813V200
607 * Note that memory version do invert MSB/LSB so printing the char
608 * buffer will show: A02341023180002V
610 printf("read chip version: ");
611 for (i
= 0; i
< 4; i
++) {
613 (chip_info
[i
] >> 24) & 0xFF,
614 (chip_info
[i
] >> 16) & 0xFF,
615 (chip_info
[i
] >> 8) & 0xFF,
616 (chip_info
[i
] >> 0) & 0xFF);
619 memcpy((char *)cbw
, req
->buf
, USB_BULK_CB_WRAP_LEN
);
621 /* Prepare for sending subsequent CSW_GOOD */
622 f_rkusb
->tag
= cbw
->tag
;
623 f_rkusb
->in_req
->complete
= tx_handler_send_csw
;
625 rockusb_tx_write((char *)chip_info
, sizeof(chip_info
));
628 static void cb_read_lba(struct usb_ep
*ep
, struct usb_request
*req
)
630 ALLOC_CACHE_ALIGN_BUFFER(struct fsg_bulk_cb_wrap
, cbw
,
631 sizeof(struct fsg_bulk_cb_wrap
));
632 struct f_rockusb
*f_rkusb
= get_rkusb();
635 memcpy((char *)cbw
, req
->buf
, USB_BULK_CB_WRAP_LEN
);
636 sector_count
= (int)get_unaligned_be16(&cbw
->CDB
[7]);
637 f_rkusb
->tag
= cbw
->tag
;
639 if (!f_rkusb
->desc
) {
640 char *type
= f_rkusb
->dev_type
;
641 int index
= f_rkusb
->dev_index
;
643 f_rkusb
->desc
= blk_get_dev(type
, index
);
644 if (!f_rkusb
->desc
||
645 f_rkusb
->desc
->type
== DEV_TYPE_UNKNOWN
) {
646 printf("invalid device \"%s\", %d\n", type
, index
);
647 rockusb_tx_write_csw(f_rkusb
->tag
, 0, CSW_FAIL
,
648 USB_BULK_CS_WRAP_LEN
);
653 f_rkusb
->lba
= get_unaligned_be32(&cbw
->CDB
[2]);
654 f_rkusb
->ul_size
= sector_count
* f_rkusb
->desc
->blksz
;
655 f_rkusb
->ul_bytes
= 0;
657 debug("require read %x bytes, %x sectors from lba %x\n",
658 f_rkusb
->ul_size
, sector_count
, f_rkusb
->lba
);
660 if (f_rkusb
->ul_size
== 0) {
661 rockusb_tx_write_csw(cbw
->tag
, cbw
->data_transfer_length
,
662 CSW_FAIL
, USB_BULK_CS_WRAP_LEN
);
666 /* Start right now sending first chunk */
667 tx_handler_ul_image(ep
, req
);
670 static void cb_write_lba(struct usb_ep
*ep
, struct usb_request
*req
)
672 ALLOC_CACHE_ALIGN_BUFFER(struct fsg_bulk_cb_wrap
, cbw
,
673 sizeof(struct fsg_bulk_cb_wrap
));
674 struct f_rockusb
*f_rkusb
= get_rkusb();
677 memcpy((char *)cbw
, req
->buf
, USB_BULK_CB_WRAP_LEN
);
678 sector_count
= (int)get_unaligned_be16(&cbw
->CDB
[7]);
679 f_rkusb
->lba
= get_unaligned_be32(&cbw
->CDB
[2]);
680 f_rkusb
->dl_size
= sector_count
* 512;
681 f_rkusb
->dl_bytes
= 0;
682 f_rkusb
->tag
= cbw
->tag
;
683 debug("require write %x bytes, %x sectors to lba %x\n",
684 f_rkusb
->dl_size
, sector_count
, f_rkusb
->lba
);
686 if (f_rkusb
->dl_size
== 0) {
687 rockusb_tx_write_csw(cbw
->tag
, cbw
->data_transfer_length
,
688 CSW_FAIL
, USB_BULK_CS_WRAP_LEN
);
690 req
->complete
= rx_handler_dl_image
;
691 req
->length
= rx_bytes_expected(ep
);
695 static void cb_erase_lba(struct usb_ep
*ep
, struct usb_request
*req
)
697 ALLOC_CACHE_ALIGN_BUFFER(struct fsg_bulk_cb_wrap
, cbw
,
698 sizeof(struct fsg_bulk_cb_wrap
));
699 struct f_rockusb
*f_rkusb
= get_rkusb();
700 int sector_count
, lba
, blks
;
702 memcpy((char *)cbw
, req
->buf
, USB_BULK_CB_WRAP_LEN
);
703 sector_count
= (int)get_unaligned_be16(&cbw
->CDB
[7]);
704 f_rkusb
->tag
= cbw
->tag
;
706 if (!f_rkusb
->desc
) {
707 char *type
= f_rkusb
->dev_type
;
708 int index
= f_rkusb
->dev_index
;
710 f_rkusb
->desc
= blk_get_dev(type
, index
);
711 if (!f_rkusb
->desc
||
712 f_rkusb
->desc
->type
== DEV_TYPE_UNKNOWN
) {
713 printf("invalid device \"%s\", %d\n", type
, index
);
714 rockusb_tx_write_csw(f_rkusb
->tag
, 0, CSW_FAIL
,
715 USB_BULK_CS_WRAP_LEN
);
720 lba
= get_unaligned_be32(&cbw
->CDB
[2]);
722 debug("require erase %x sectors from lba %x\n",
725 blks
= blk_derase(f_rkusb
->desc
, lba
, sector_count
);
726 if (blks
!= sector_count
) {
727 printf("failed erasing device %s: %d\n", f_rkusb
->dev_type
,
729 rockusb_tx_write_csw(f_rkusb
->tag
,
730 cbw
->data_transfer_length
, CSW_FAIL
,
731 USB_BULK_CS_WRAP_LEN
);
735 rockusb_tx_write_csw(cbw
->tag
, cbw
->data_transfer_length
, CSW_GOOD
,
736 USB_BULK_CS_WRAP_LEN
);
739 void __weak
rkusb_set_reboot_flag(int flag
)
741 struct f_rockusb
*f_rkusb
= get_rkusb();
743 printf("rockkusb set reboot flag: %d\n", f_rkusb
->reboot_flag
);
746 static void compl_do_reset(struct usb_ep
*ep
, struct usb_request
*req
)
748 struct f_rockusb
*f_rkusb
= get_rkusb();
750 rkusb_set_reboot_flag(f_rkusb
->reboot_flag
);
751 do_reset(NULL
, 0, 0, NULL
);
754 static void cb_reboot(struct usb_ep
*ep
, struct usb_request
*req
)
756 ALLOC_CACHE_ALIGN_BUFFER(struct fsg_bulk_cb_wrap
, cbw
,
757 sizeof(struct fsg_bulk_cb_wrap
));
758 struct f_rockusb
*f_rkusb
= get_rkusb();
760 memcpy((char *)cbw
, req
->buf
, USB_BULK_CB_WRAP_LEN
);
761 f_rkusb
->reboot_flag
= cbw
->CDB
[1];
762 rockusb_func
->in_req
->complete
= compl_do_reset
;
763 rockusb_tx_write_csw(cbw
->tag
, cbw
->data_transfer_length
, CSW_GOOD
,
764 USB_BULK_CS_WRAP_LEN
);
767 static void cb_not_support(struct usb_ep
*ep
, struct usb_request
*req
)
769 ALLOC_CACHE_ALIGN_BUFFER(struct fsg_bulk_cb_wrap
, cbw
,
770 sizeof(struct fsg_bulk_cb_wrap
));
772 memcpy((char *)cbw
, req
->buf
, USB_BULK_CB_WRAP_LEN
);
773 printf("Rockusb command %x not support yet\n", cbw
->CDB
[0]);
774 rockusb_tx_write_csw(cbw
->tag
, 0, CSW_FAIL
, USB_BULK_CS_WRAP_LEN
);
777 static const struct cmd_dispatch_info cmd_dispatch_info
[] = {
779 .cmd
= K_FW_TEST_UNIT_READY
,
780 .cb
= cb_test_unit_ready
,
783 .cmd
= K_FW_READ_FLASH_ID
,
784 .cb
= cb_read_storage_id
,
787 .cmd
= K_FW_SET_DEVICE_ID
,
788 .cb
= cb_not_support
,
791 .cmd
= K_FW_TEST_BAD_BLOCK
,
792 .cb
= cb_not_support
,
796 .cb
= cb_not_support
,
799 .cmd
= K_FW_WRITE_10
,
800 .cb
= cb_not_support
,
803 .cmd
= K_FW_ERASE_10
,
804 .cb
= cb_not_support
,
807 .cmd
= K_FW_WRITE_SPARE
,
808 .cb
= cb_not_support
,
811 .cmd
= K_FW_READ_SPARE
,
812 .cb
= cb_not_support
,
815 .cmd
= K_FW_ERASE_10_FORCE
,
816 .cb
= cb_not_support
,
819 .cmd
= K_FW_GET_VERSION
,
820 .cb
= cb_not_support
,
823 .cmd
= K_FW_LBA_READ_10
,
827 .cmd
= K_FW_LBA_WRITE_10
,
831 .cmd
= K_FW_ERASE_SYS_DISK
,
832 .cb
= cb_not_support
,
835 .cmd
= K_FW_SDRAM_READ_10
,
836 .cb
= cb_not_support
,
839 .cmd
= K_FW_SDRAM_WRITE_10
,
840 .cb
= cb_not_support
,
843 .cmd
= K_FW_SDRAM_EXECUTE
,
844 .cb
= cb_not_support
,
847 .cmd
= K_FW_READ_FLASH_INFO
,
848 .cb
= cb_not_support
,
851 .cmd
= K_FW_GET_CHIP_VER
,
852 .cb
= cb_get_chip_version
,
855 .cmd
= K_FW_LOW_FORMAT
,
856 .cb
= cb_not_support
,
859 .cmd
= K_FW_SET_RESET_FLAG
,
860 .cb
= cb_not_support
,
863 .cmd
= K_FW_SPI_READ_10
,
864 .cb
= cb_not_support
,
867 .cmd
= K_FW_SPI_WRITE_10
,
868 .cb
= cb_not_support
,
871 .cmd
= K_FW_LBA_ERASE_10
,
876 .cb
= cb_not_support
,
884 static void rx_handler_command(struct usb_ep
*ep
, struct usb_request
*req
)
886 void (*func_cb
)(struct usb_ep
*ep
, struct usb_request
*req
) = NULL
;
888 ALLOC_CACHE_ALIGN_BUFFER(struct fsg_bulk_cb_wrap
, cbw
,
889 sizeof(struct fsg_bulk_cb_wrap
));
890 char *cmdbuf
= req
->buf
;
893 if (req
->status
|| req
->length
== 0)
896 memcpy((char *)cbw
, req
->buf
, USB_BULK_CB_WRAP_LEN
);
901 for (i
= 0; i
< ARRAY_SIZE(cmd_dispatch_info
); i
++) {
902 if (cmd_dispatch_info
[i
].cmd
== cbw
->CDB
[0]) {
903 func_cb
= cmd_dispatch_info
[i
].cb
;
909 printf("unknown command: %s\n", (char *)req
->buf
);
910 rockusb_tx_write_str("FAILunknown command");
912 if (req
->actual
< req
->length
) {
913 u8
*buf
= (u8
*)req
->buf
;
915 buf
[req
->actual
] = 0;
918 puts("buffer overflow\n");
919 rockusb_tx_write_str("FAILbuffer overflow");
925 usb_ep_queue(ep
, req
, 0);