aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/usb/dwc3/core.h142
-rw-r--r--drivers/usb/dwc3/ep0.c34
-rw-r--r--drivers/usb/dwc3/gadget.c83
3 files changed, 97 insertions, 162 deletions
diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
index 4dac9828577e..696b20a8b1fa 100644
--- a/drivers/usb/dwc3/core.h
+++ b/drivers/usb/dwc3/core.h
@@ -301,7 +301,7 @@
301 301
302/* Structures */ 302/* Structures */
303 303
304struct dwc3_trb_hw; 304struct dwc3_trb;
305 305
306/** 306/**
307 * struct dwc3_event_buffer - Software event buffer representation 307 * struct dwc3_event_buffer - Software event buffer representation
@@ -356,7 +356,7 @@ struct dwc3_ep {
356 struct list_head request_list; 356 struct list_head request_list;
357 struct list_head req_queued; 357 struct list_head req_queued;
358 358
359 struct dwc3_trb_hw *trb_pool; 359 struct dwc3_trb *trb_pool;
360 dma_addr_t trb_pool_dma; 360 dma_addr_t trb_pool_dma;
361 u32 free_slot; 361 u32 free_slot;
362 u32 busy_slot; 362 u32 busy_slot;
@@ -431,102 +431,49 @@ enum dwc3_device_state {
431 DWC3_CONFIGURED_STATE, 431 DWC3_CONFIGURED_STATE,
432}; 432};
433 433
434/** 434/* TRB Length, PCM and Status */
435 * struct dwc3_trb - transfer request block 435#define DWC3_TRB_SIZE_MASK (0x00ffffff)
436 * @bpl: lower 32bit of the buffer 436#define DWC3_TRB_SIZE_LENGTH(n) ((n) & DWC3_TRB_SIZE_MASK)
437 * @bph: higher 32bit of the buffer 437#define DWC3_TRB_SIZE_PCM1(n) (((n) & 0x03) << 24)
438 * @length: buffer size (up to 16mb - 1) 438#define DWC3_TRB_SIZE_TRBSTS(n) (((n) & (0x0f << 28) >> 28))
439 * @pcm1: packet count m1 439
440 * @trbsts: trb status 440#define DWC3_TRBSTS_OK 0
441 * 0 = ok 441#define DWC3_TRBSTS_MISSED_ISOC 1
442 * 1 = missed isoc 442#define DWC3_TRBSTS_SETUP_PENDING 2
443 * 2 = setup pending 443
444 * @hwo: hardware owner of descriptor 444/* TRB Control */
445 * @lst: last trb 445#define DWC3_TRB_CTRL_HWO (1 << 0)
446 * @chn: chain buffers 446#define DWC3_TRB_CTRL_LST (1 << 1)
447 * @csp: continue on short packets (only supported on isoc eps) 447#define DWC3_TRB_CTRL_CHN (1 << 2)
448 * @trbctl: trb control 448#define DWC3_TRB_CTRL_CSP (1 << 3)
449 * 1 = normal 449#define DWC3_TRB_CTRL_TRBCTL(n) (((n) & 0x3f) << 4)
450 * 2 = control-setup 450#define DWC3_TRB_CTRL_ISP_IMI (1 << 10)
451 * 3 = control-status-2 451#define DWC3_TRB_CTRL_IOC (1 << 11)
452 * 4 = control-status-3 452#define DWC3_TRB_CTRL_SID_SOFN(n) (((n) & 0xffff) << 14)
453 * 5 = control-data (first trb of data stage) 453
454 * 6 = isochronous-first (first trb of service interval) 454#define DWC3_TRBCTL_NORMAL DWC3_TRB_CTRL_TRBCTL(1)
455 * 7 = isochronous 455#define DWC3_TRBCTL_CONTROL_SETUP DWC3_TRB_CTRL_TRBCTL(2)
456 * 8 = link trb 456#define DWC3_TRBCTL_CONTROL_STATUS2 DWC3_TRB_CTRL_TRBCTL(3)
457 * others = reserved 457#define DWC3_TRBCTL_CONTROL_STATUS3 DWC3_TRB_CTRL_TRBCTL(4)
458 * @isp_imi: interrupt on short packet / interrupt on missed isoc 458#define DWC3_TRBCTL_CONTROL_DATA DWC3_TRB_CTRL_TRBCTL(5)
459 * @ioc: interrupt on complete 459#define DWC3_TRBCTL_ISOCHRONOUS_FIRST DWC3_TRB_CTRL_TRBCTL(6)
460 * @sid_sofn: Stream ID / SOF Number 460#define DWC3_TRBCTL_ISOCHRONOUS DWC3_TRB_CTRL_TRBCTL(7)
461 */ 461#define DWC3_TRBCTL_LINK_TRB DWC3_TRB_CTRL_TRBCTL(8)
462struct dwc3_trb {
463 u64 bplh;
464
465 union {
466 struct {
467 u32 length:24;
468 u32 pcm1:2;
469 u32 reserved27_26:2;
470 u32 trbsts:4;
471#define DWC3_TRB_STS_OKAY 0
472#define DWC3_TRB_STS_MISSED_ISOC 1
473#define DWC3_TRB_STS_SETUP_PENDING 2
474 };
475 u32 len_pcm;
476 };
477
478 union {
479 struct {
480 u32 hwo:1;
481 u32 lst:1;
482 u32 chn:1;
483 u32 csp:1;
484 u32 trbctl:6;
485 u32 isp_imi:1;
486 u32 ioc:1;
487 u32 reserved13_12:2;
488 u32 sid_sofn:16;
489 u32 reserved31_30:2;
490 };
491 u32 control;
492 };
493} __packed;
494 462
495/** 463/**
496 * struct dwc3_trb_hw - transfer request block (hw format) 464 * struct dwc3_trb - transfer request block (hw format)
497 * @bpl: DW0-3 465 * @bpl: DW0-3
498 * @bph: DW4-7 466 * @bph: DW4-7
499 * @size: DW8-B 467 * @size: DW8-B
500 * @trl: DWC-F 468 * @trl: DWC-F
501 */ 469 */
502struct dwc3_trb_hw { 470struct dwc3_trb {
503 __le32 bpl; 471 u32 bpl;
504 __le32 bph; 472 u32 bph;
505 __le32 size; 473 u32 size;
506 __le32 ctrl; 474 u32 ctrl;
507} __packed; 475} __packed;
508 476
509static inline void dwc3_trb_to_hw(struct dwc3_trb *nat, struct dwc3_trb_hw *hw)
510{
511 hw->bpl = cpu_to_le32(lower_32_bits(nat->bplh));
512 hw->bph = cpu_to_le32(upper_32_bits(nat->bplh));
513 hw->size = cpu_to_le32p(&nat->len_pcm);
514 /* HWO is written last */
515 hw->ctrl = cpu_to_le32p(&nat->control);
516}
517
518static inline void dwc3_trb_to_nat(struct dwc3_trb_hw *hw, struct dwc3_trb *nat)
519{
520 u64 bplh;
521
522 bplh = le32_to_cpup(&hw->bpl);
523 bplh |= (u64) le32_to_cpup(&hw->bph) << 32;
524 nat->bplh = bplh;
525
526 nat->len_pcm = le32_to_cpup(&hw->size);
527 nat->control = le32_to_cpup(&hw->ctrl);
528}
529
530/** 477/**
531 * dwc3_hwparams - copy of HWPARAMS registers 478 * dwc3_hwparams - copy of HWPARAMS registers
532 * @hwparams0 - GHWPARAMS0 479 * @hwparams0 - GHWPARAMS0
@@ -573,7 +520,7 @@ struct dwc3_request {
573 struct dwc3_ep *dep; 520 struct dwc3_ep *dep;
574 521
575 u8 epnum; 522 u8 epnum;
576 struct dwc3_trb_hw *trb; 523 struct dwc3_trb *trb;
577 dma_addr_t trb_dma; 524 dma_addr_t trb_dma;
578 525
579 unsigned direction:1; 526 unsigned direction:1;
@@ -624,7 +571,7 @@ struct dwc3_request {
624 */ 571 */
625struct dwc3 { 572struct dwc3 {
626 struct usb_ctrlrequest *ctrl_req; 573 struct usb_ctrlrequest *ctrl_req;
627 struct dwc3_trb_hw *ep0_trb; 574 struct dwc3_trb *ep0_trb;
628 void *ep0_bounce; 575 void *ep0_bounce;
629 u8 *setup_buf; 576 u8 *setup_buf;
630 dma_addr_t ctrl_req_addr; 577 dma_addr_t ctrl_req_addr;
@@ -691,19 +638,6 @@ struct dwc3 {
691 638
692/* -------------------------------------------------------------------------- */ 639/* -------------------------------------------------------------------------- */
693 640
694#define DWC3_TRBSTS_OK 0
695#define DWC3_TRBSTS_MISSED_ISOC 1
696#define DWC3_TRBSTS_SETUP_PENDING 2
697
698#define DWC3_TRBCTL_NORMAL 1
699#define DWC3_TRBCTL_CONTROL_SETUP 2
700#define DWC3_TRBCTL_CONTROL_STATUS2 3
701#define DWC3_TRBCTL_CONTROL_STATUS3 4
702#define DWC3_TRBCTL_CONTROL_DATA 5
703#define DWC3_TRBCTL_ISOCHRONOUS_FIRST 6
704#define DWC3_TRBCTL_ISOCHRONOUS 7
705#define DWC3_TRBCTL_LINK_TRB 8
706
707/* -------------------------------------------------------------------------- */ 641/* -------------------------------------------------------------------------- */
708 642
709struct dwc3_event_type { 643struct dwc3_event_type {
diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
index c20e30c8b695..5a067090f27e 100644
--- a/drivers/usb/dwc3/ep0.c
+++ b/drivers/usb/dwc3/ep0.c
@@ -76,8 +76,7 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma,
76 u32 len, u32 type) 76 u32 len, u32 type)
77{ 77{
78 struct dwc3_gadget_ep_cmd_params params; 78 struct dwc3_gadget_ep_cmd_params params;
79 struct dwc3_trb_hw *trb_hw; 79 struct dwc3_trb *trb;
80 struct dwc3_trb trb;
81 struct dwc3_ep *dep; 80 struct dwc3_ep *dep;
82 81
83 int ret; 82 int ret;
@@ -88,19 +87,17 @@ static int dwc3_ep0_start_trans(struct dwc3 *dwc, u8 epnum, dma_addr_t buf_dma,
88 return 0; 87 return 0;
89 } 88 }
90 89
91 trb_hw = dwc->ep0_trb; 90 trb = dwc->ep0_trb;
92 memset(&trb, 0, sizeof(trb));
93 91
94 trb.trbctl = type; 92 trb->bpl = lower_32_bits(buf_dma);
95 trb.bplh = buf_dma; 93 trb->bph = upper_32_bits(buf_dma);
96 trb.length = len; 94 trb->size = len;
95 trb->ctrl = type;
97 96
98 trb.hwo = 1; 97 trb->ctrl |= (DWC3_TRB_CTRL_HWO
99 trb.lst = 1; 98 | DWC3_TRB_CTRL_LST
100 trb.ioc = 1; 99 | DWC3_TRB_CTRL_IOC
101 trb.isp_imi = 1; 100 | DWC3_TRB_CTRL_ISP_IMI);
102
103 dwc3_trb_to_hw(&trb, trb_hw);
104 101
105 memset(&params, 0, sizeof(params)); 102 memset(&params, 0, sizeof(params));
106 params.param0 = upper_32_bits(dwc->ep0_trb_addr); 103 params.param0 = upper_32_bits(dwc->ep0_trb_addr);
@@ -544,9 +541,10 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
544{ 541{
545 struct dwc3_request *r = NULL; 542 struct dwc3_request *r = NULL;
546 struct usb_request *ur; 543 struct usb_request *ur;
547 struct dwc3_trb trb; 544 struct dwc3_trb *trb;
548 struct dwc3_ep *ep0; 545 struct dwc3_ep *ep0;
549 u32 transferred; 546 u32 transferred;
547 u32 length;
550 u8 epnum; 548 u8 epnum;
551 549
552 epnum = event->endpoint_number; 550 epnum = event->endpoint_number;
@@ -557,16 +555,16 @@ static void dwc3_ep0_complete_data(struct dwc3 *dwc,
557 r = next_request(&ep0->request_list); 555 r = next_request(&ep0->request_list);
558 ur = &r->request; 556 ur = &r->request;
559 557
560 dwc3_trb_to_nat(dwc->ep0_trb, &trb); 558 trb = dwc->ep0_trb;
559 length = trb->size & DWC3_TRB_SIZE_MASK;
561 560
562 if (dwc->ep0_bounced) { 561 if (dwc->ep0_bounced) {
563
564 transferred = min_t(u32, ur->length, 562 transferred = min_t(u32, ur->length,
565 ep0->endpoint.maxpacket - trb.length); 563 ep0->endpoint.maxpacket - length);
566 memcpy(ur->buf, dwc->ep0_bounce, transferred); 564 memcpy(ur->buf, dwc->ep0_bounce, transferred);
567 dwc->ep0_bounced = false; 565 dwc->ep0_bounced = false;
568 } else { 566 } else {
569 transferred = ur->length - trb.length; 567 transferred = ur->length - length;
570 ur->actual += transferred; 568 ur->actual += transferred;
571 } 569 }
572 570
diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
index 76327005d54c..eeba2227c28f 100644
--- a/drivers/usb/dwc3/gadget.c
+++ b/drivers/usb/dwc3/gadget.c
@@ -378,7 +378,7 @@ int dwc3_send_gadget_ep_cmd(struct dwc3 *dwc, unsigned ep,
378} 378}
379 379
380static dma_addr_t dwc3_trb_dma_offset(struct dwc3_ep *dep, 380static dma_addr_t dwc3_trb_dma_offset(struct dwc3_ep *dep,
381 struct dwc3_trb_hw *trb) 381 struct dwc3_trb *trb)
382{ 382{
383 u32 offset = (char *) trb - (char *) dep->trb_pool; 383 u32 offset = (char *) trb - (char *) dep->trb_pool;
384 384
@@ -527,9 +527,8 @@ static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep,
527 return ret; 527 return ret;
528 528
529 if (!(dep->flags & DWC3_EP_ENABLED)) { 529 if (!(dep->flags & DWC3_EP_ENABLED)) {
530 struct dwc3_trb_hw *trb_st_hw; 530 struct dwc3_trb *trb_st_hw;
531 struct dwc3_trb_hw *trb_link_hw; 531 struct dwc3_trb *trb_link;
532 struct dwc3_trb trb_link;
533 532
534 ret = dwc3_gadget_set_xfer_resource(dwc, dep); 533 ret = dwc3_gadget_set_xfer_resource(dwc, dep);
535 if (ret) 534 if (ret)
@@ -552,12 +551,12 @@ static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep,
552 /* Link TRB for ISOC. The HWO but is never reset */ 551 /* Link TRB for ISOC. The HWO but is never reset */
553 trb_st_hw = &dep->trb_pool[0]; 552 trb_st_hw = &dep->trb_pool[0];
554 553
555 trb_link.bplh = dwc3_trb_dma_offset(dep, trb_st_hw); 554 trb_link = &dep->trb_pool[DWC3_TRB_NUM - 1];
556 trb_link.trbctl = DWC3_TRBCTL_LINK_TRB;
557 trb_link.hwo = true;
558 555
559 trb_link_hw = &dep->trb_pool[DWC3_TRB_NUM - 1]; 556 trb_link->bpl = lower_32_bits(dwc3_trb_dma_offset(dep, trb_st_hw));
560 dwc3_trb_to_hw(&trb_link, trb_link_hw); 557 trb_link->bph = upper_32_bits(dwc3_trb_dma_offset(dep, trb_st_hw));
558 trb_link->ctrl |= DWC3_TRBCTL_LINK_TRB;
559 trb_link->ctrl |= DWC3_TRB_CTRL_HWO;
561 } 560 }
562 561
563 return 0; 562 return 0;
@@ -744,8 +743,7 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
744 unsigned length, unsigned last, unsigned chain) 743 unsigned length, unsigned last, unsigned chain)
745{ 744{
746 struct dwc3 *dwc = dep->dwc; 745 struct dwc3 *dwc = dep->dwc;
747 struct dwc3_trb_hw *trb_hw; 746 struct dwc3_trb *trb;
748 struct dwc3_trb trb;
749 747
750 unsigned int cur_slot; 748 unsigned int cur_slot;
751 749
@@ -754,7 +752,7 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
754 length, last ? " last" : "", 752 length, last ? " last" : "",
755 chain ? " chain" : ""); 753 chain ? " chain" : "");
756 754
757 trb_hw = &dep->trb_pool[dep->free_slot & DWC3_TRB_MASK]; 755 trb = &dep->trb_pool[dep->free_slot & DWC3_TRB_MASK];
758 cur_slot = dep->free_slot; 756 cur_slot = dep->free_slot;
759 dep->free_slot++; 757 dep->free_slot++;
760 758
@@ -763,40 +761,32 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
763 usb_endpoint_xfer_isoc(dep->desc)) 761 usb_endpoint_xfer_isoc(dep->desc))
764 return; 762 return;
765 763
766 memset(&trb, 0, sizeof(trb));
767 if (!req->trb) { 764 if (!req->trb) {
768 dwc3_gadget_move_request_queued(req); 765 dwc3_gadget_move_request_queued(req);
769 req->trb = trb_hw; 766 req->trb = trb;
770 req->trb_dma = dwc3_trb_dma_offset(dep, trb_hw); 767 req->trb_dma = dwc3_trb_dma_offset(dep, trb);
771 } 768 }
772 769
773 if (usb_endpoint_xfer_isoc(dep->desc)) { 770 trb->size = DWC3_TRB_SIZE_LENGTH(length);
774 trb.isp_imi = true; 771 trb->bpl = lower_32_bits(dma);
775 trb.csp = true; 772 trb->bph = upper_32_bits(dma);
776 } else {
777 trb.chn = chain;
778 trb.lst = last;
779 }
780
781 if (usb_endpoint_xfer_bulk(dep->desc) && dep->stream_capable)
782 trb.sid_sofn = req->request.stream_id;
783 773
784 switch (usb_endpoint_type(dep->desc)) { 774 switch (usb_endpoint_type(dep->desc)) {
785 case USB_ENDPOINT_XFER_CONTROL: 775 case USB_ENDPOINT_XFER_CONTROL:
786 trb.trbctl = DWC3_TRBCTL_CONTROL_SETUP; 776 trb->ctrl = DWC3_TRBCTL_CONTROL_SETUP;
787 break; 777 break;
788 778
789 case USB_ENDPOINT_XFER_ISOC: 779 case USB_ENDPOINT_XFER_ISOC:
790 trb.trbctl = DWC3_TRBCTL_ISOCHRONOUS_FIRST; 780 trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS_FIRST;
791 781
792 /* IOC every DWC3_TRB_NUM / 4 so we can refill */ 782 /* IOC every DWC3_TRB_NUM / 4 so we can refill */
793 if (!(cur_slot % (DWC3_TRB_NUM / 4))) 783 if (!(cur_slot % (DWC3_TRB_NUM / 4)))
794 trb.ioc = last; 784 trb->ctrl |= DWC3_TRB_CTRL_IOC;
795 break; 785 break;
796 786
797 case USB_ENDPOINT_XFER_BULK: 787 case USB_ENDPOINT_XFER_BULK:
798 case USB_ENDPOINT_XFER_INT: 788 case USB_ENDPOINT_XFER_INT:
799 trb.trbctl = DWC3_TRBCTL_NORMAL; 789 trb->ctrl = DWC3_TRBCTL_NORMAL;
800 break; 790 break;
801 default: 791 default:
802 /* 792 /*
@@ -806,11 +796,21 @@ static void dwc3_prepare_one_trb(struct dwc3_ep *dep,
806 BUG(); 796 BUG();
807 } 797 }
808 798
809 trb.length = length; 799 if (usb_endpoint_xfer_isoc(dep->desc)) {
810 trb.bplh = dma; 800 trb->ctrl |= DWC3_TRB_CTRL_ISP_IMI;
811 trb.hwo = true; 801 trb->ctrl |= DWC3_TRB_CTRL_CSP;
802 } else {
803 if (chain)
804 trb->ctrl |= DWC3_TRB_CTRL_CHN;
805
806 if (last)
807 trb->ctrl |= DWC3_TRB_CTRL_LST;
808 }
809
810 if (usb_endpoint_xfer_bulk(dep->desc) && dep->stream_capable)
811 trb->ctrl |= DWC3_TRB_CTRL_SID_SOFN(req->request.stream_id);
812 812
813 dwc3_trb_to_hw(&trb, trb_hw); 813 trb->ctrl |= DWC3_TRB_CTRL_HWO;
814} 814}
815 815
816/* 816/*
@@ -1542,7 +1542,7 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep,
1542 const struct dwc3_event_depevt *event, int status) 1542 const struct dwc3_event_depevt *event, int status)
1543{ 1543{
1544 struct dwc3_request *req; 1544 struct dwc3_request *req;
1545 struct dwc3_trb trb; 1545 struct dwc3_trb *trb;
1546 unsigned int count; 1546 unsigned int count;
1547 unsigned int s_pkt = 0; 1547 unsigned int s_pkt = 0;
1548 1548
@@ -1553,9 +1553,9 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep,
1553 return 1; 1553 return 1;
1554 } 1554 }
1555 1555
1556 dwc3_trb_to_nat(req->trb, &trb); 1556 trb = req->trb;
1557 1557
1558 if (trb.hwo && status != -ESHUTDOWN) 1558 if ((trb->ctrl & DWC3_TRB_CTRL_HWO) && status != -ESHUTDOWN)
1559 /* 1559 /*
1560 * We continue despite the error. There is not much we 1560 * We continue despite the error. There is not much we
1561 * can do. If we don't clean in up we loop for ever. If 1561 * can do. If we don't clean in up we loop for ever. If
@@ -1566,7 +1566,7 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep,
1566 */ 1566 */
1567 dev_err(dwc->dev, "%s's TRB (%p) still owned by HW\n", 1567 dev_err(dwc->dev, "%s's TRB (%p) still owned by HW\n",
1568 dep->name, req->trb); 1568 dep->name, req->trb);
1569 count = trb.length; 1569 count = trb->size & DWC3_TRB_SIZE_MASK;
1570 1570
1571 if (dep->direction) { 1571 if (dep->direction) {
1572 if (count) { 1572 if (count) {
@@ -1590,13 +1590,16 @@ static int dwc3_cleanup_done_reqs(struct dwc3 *dwc, struct dwc3_ep *dep,
1590 dwc3_gadget_giveback(dep, req, status); 1590 dwc3_gadget_giveback(dep, req, status);
1591 if (s_pkt) 1591 if (s_pkt)
1592 break; 1592 break;
1593 if ((event->status & DEPEVT_STATUS_LST) && trb.lst) 1593 if ((event->status & DEPEVT_STATUS_LST) &&
1594 (trb->ctrl & DWC3_TRB_CTRL_LST))
1594 break; 1595 break;
1595 if ((event->status & DEPEVT_STATUS_IOC) && trb.ioc) 1596 if ((event->status & DEPEVT_STATUS_IOC) &&
1597 (trb->ctrl & DWC3_TRB_CTRL_IOC))
1596 break; 1598 break;
1597 } while (1); 1599 } while (1);
1598 1600
1599 if ((event->status & DEPEVT_STATUS_IOC) && trb.ioc) 1601 if ((event->status & DEPEVT_STATUS_IOC) &&
1602 (trb->ctrl & DWC3_TRB_CTRL_IOC))
1600 return 0; 1603 return 0;
1601 return 1; 1604 return 1;
1602} 1605}