fwohci.c (110593) | fwohci.c (110798) |
---|---|
1/* 2 * Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 16 unchanged lines hidden (view full) --- 25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 29 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 30 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 * | 1/* 2 * Copyright (c) 1998-2002 Katsushi Kobayashi and Hidetoshi Shimokawa 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 16 unchanged lines hidden (view full) --- 25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 29 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 30 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 * |
33 * $FreeBSD: head/sys/dev/firewire/fwohci.c 110593 2003-02-09 17:11:55Z simokawa $ | 33 * $FreeBSD: head/sys/dev/firewire/fwohci.c 110798 2003-02-13 13:35:57Z simokawa $ |
34 * 35 */ 36 37#define ATRQ_CH 0 38#define ATRS_CH 1 39#define ARRQ_CH 2 40#define ARRS_CH 3 41#define ITX_CH 4 --- 1727 unchanged lines hidden (view full) --- 1769 OWRITE(sc, FWOHCI_INTMASKCLR, OHCI_INT_CYC_LOST); 1770 OWRITE(sc, OHCI_LNKCTLCLR, OHCI_CNTL_CYCSRC); 1771 1772 OWRITE(sc, OHCI_ATQCTLCLR, OHCI_CNTL_DMA_RUN); 1773 sc->atrq.xferq.flag &= ~FWXFERQ_RUNNING; 1774 OWRITE(sc, OHCI_ATSCTLCLR, OHCI_CNTL_DMA_RUN); 1775 sc->atrs.xferq.flag &= ~FWXFERQ_RUNNING; 1776 | 34 * 35 */ 36 37#define ATRQ_CH 0 38#define ATRS_CH 1 39#define ARRQ_CH 2 40#define ARRS_CH 3 41#define ITX_CH 4 --- 1727 unchanged lines hidden (view full) --- 1769 OWRITE(sc, FWOHCI_INTMASKCLR, OHCI_INT_CYC_LOST); 1770 OWRITE(sc, OHCI_LNKCTLCLR, OHCI_CNTL_CYCSRC); 1771 1772 OWRITE(sc, OHCI_ATQCTLCLR, OHCI_CNTL_DMA_RUN); 1773 sc->atrq.xferq.flag &= ~FWXFERQ_RUNNING; 1774 OWRITE(sc, OHCI_ATSCTLCLR, OHCI_CNTL_DMA_RUN); 1775 sc->atrs.xferq.flag &= ~FWXFERQ_RUNNING; 1776 |
1777#if 0 1778 for( i = 0 ; i < fc->nisodma ; i ++ ){ 1779 OWRITE(sc, OHCI_IRCTLCLR(i), OHCI_CNTL_DMA_RUN); 1780 OWRITE(sc, OHCI_ITCTLCLR(i), OHCI_CNTL_DMA_RUN); 1781 } 1782 1783#endif 1784 fw_busreset(fc); 1785 1786 /* XXX need to wait DMA to stop */ | |
1787#ifndef ACK_ALL 1788 OWRITE(sc, FWOHCI_INTSTATCLR, OHCI_INT_PHY_BUS_R); 1789#endif | 1777#ifndef ACK_ALL 1778 OWRITE(sc, FWOHCI_INTSTATCLR, OHCI_INT_PHY_BUS_R); 1779#endif |
1790#if 0 1791 /* pending all pre-bus_reset packets */ 1792 fwohci_txd(sc, &sc->atrq); 1793 fwohci_txd(sc, &sc->atrs); 1794 fwohci_arcv(sc, &sc->arrs, -1); 1795 fwohci_arcv(sc, &sc->arrq, -1); 1796#endif | 1780 fw_busreset(fc); |
1797 | 1781 |
1798 | |
1799 OWRITE(sc, OHCI_AREQHI, 1 << 31); 1800 /* XXX insecure ?? */ 1801 OWRITE(sc, OHCI_PREQHI, 0x7fffffff); 1802 OWRITE(sc, OHCI_PREQLO, 0xffffffff); 1803 OWRITE(sc, OHCI_PREQUPPER, 0x10000); 1804 1805 } 1806 if((stat & OHCI_INT_DMA_IR )){ --- 90 unchanged lines hidden (view full) --- 1897 bcopy((void *)(uintptr_t)(volatile void *)(fc->sid_buf + 1), 1898 buf, plen); 1899#if 1 1900 /* pending all pre-bus_reset packets */ 1901 fwohci_txd(sc, &sc->atrq); 1902 fwohci_txd(sc, &sc->atrs); 1903 fwohci_arcv(sc, &sc->arrs, -1); 1904 fwohci_arcv(sc, &sc->arrq, -1); | 1782 OWRITE(sc, OHCI_AREQHI, 1 << 31); 1783 /* XXX insecure ?? */ 1784 OWRITE(sc, OHCI_PREQHI, 0x7fffffff); 1785 OWRITE(sc, OHCI_PREQLO, 0xffffffff); 1786 OWRITE(sc, OHCI_PREQUPPER, 0x10000); 1787 1788 } 1789 if((stat & OHCI_INT_DMA_IR )){ --- 90 unchanged lines hidden (view full) --- 1880 bcopy((void *)(uintptr_t)(volatile void *)(fc->sid_buf + 1), 1881 buf, plen); 1882#if 1 1883 /* pending all pre-bus_reset packets */ 1884 fwohci_txd(sc, &sc->atrq); 1885 fwohci_txd(sc, &sc->atrs); 1886 fwohci_arcv(sc, &sc->arrs, -1); 1887 fwohci_arcv(sc, &sc->arrq, -1); |
1888 fw_drain_txq(fc); |
|
1905#endif 1906 fw_sidrcv(fc, buf, plen, 0); 1907 } 1908sidout: 1909 if((stat & OHCI_INT_DMA_ATRQ )){ 1910#ifndef ACK_ALL 1911 OWRITE(sc, FWOHCI_INTSTATCLR, OHCI_INT_DMA_ATRQ); 1912#endif --- 646 unchanged lines hidden (view full) --- 2559 if (reg & OHCI_CNTL_DMA_ACTIVE) 2560 return; 2561 device_printf(sc->fc.dev, "IR DMA %d stopped at %x status=%x (%d)\n", 2562 dmach, OREAD(sc, OHCI_DMACMD(off)), reg, i); 2563 dbch->top = db_tr; 2564 fwohci_irx_enable(fc, dmach); 2565} 2566 | 1889#endif 1890 fw_sidrcv(fc, buf, plen, 0); 1891 } 1892sidout: 1893 if((stat & OHCI_INT_DMA_ATRQ )){ 1894#ifndef ACK_ALL 1895 OWRITE(sc, FWOHCI_INTSTATCLR, OHCI_INT_DMA_ATRQ); 1896#endif --- 646 unchanged lines hidden (view full) --- 2543 if (reg & OHCI_CNTL_DMA_ACTIVE) 2544 return; 2545 device_printf(sc->fc.dev, "IR DMA %d stopped at %x status=%x (%d)\n", 2546 dmach, OREAD(sc, OHCI_DMACMD(off)), reg, i); 2547 dbch->top = db_tr; 2548 fwohci_irx_enable(fc, dmach); 2549} 2550 |
2567#define PLEN(x) (((ntohs(x))+0x3) & ~0x3) | 2551#define PLEN(x) roundup2(ntohs(x), sizeof(u_int32_t)) |
2568static int | 2552static int |
2569fwohci_get_plen(struct fwohci_softc *sc, struct fw_pkt *fp, int hlen) | 2553fwohci_get_plen(struct fwohci_softc *sc, struct fwohci_dbch *dbch, struct fw_pkt *fp, int hlen) |
2570{ | 2554{ |
2571 int i; | 2555 int i, r; |
2572 2573 for( i = 4; i < hlen ; i+=4){ 2574 fp->mode.ld[i/4] = htonl(fp->mode.ld[i/4]); 2575 } 2576 2577 switch(fp->mode.common.tcode){ 2578 case FWTCODE_RREQQ: | 2556 2557 for( i = 4; i < hlen ; i+=4){ 2558 fp->mode.ld[i/4] = htonl(fp->mode.ld[i/4]); 2559 } 2560 2561 switch(fp->mode.common.tcode){ 2562 case FWTCODE_RREQQ: |
2579 return sizeof(fp->mode.rreqq) + sizeof(u_int32_t); | 2563 r = sizeof(fp->mode.rreqq) + sizeof(u_int32_t); 2564 break; |
2580 case FWTCODE_WRES: | 2565 case FWTCODE_WRES: |
2581 return sizeof(fp->mode.wres) + sizeof(u_int32_t); | 2566 r = sizeof(fp->mode.wres) + sizeof(u_int32_t); 2567 break; |
2582 case FWTCODE_WREQQ: | 2568 case FWTCODE_WREQQ: |
2583 return sizeof(fp->mode.wreqq) + sizeof(u_int32_t); | 2569 r = sizeof(fp->mode.wreqq) + sizeof(u_int32_t); 2570 break; |
2584 case FWTCODE_RREQB: | 2571 case FWTCODE_RREQB: |
2585 return sizeof(fp->mode.rreqb) + sizeof(u_int32_t); | 2572 r = sizeof(fp->mode.rreqb) + sizeof(u_int32_t); 2573 break; |
2586 case FWTCODE_RRESQ: | 2574 case FWTCODE_RRESQ: |
2587 return sizeof(fp->mode.rresq) + sizeof(u_int32_t); | 2575 r = sizeof(fp->mode.rresq) + sizeof(u_int32_t); 2576 break; |
2588 case FWTCODE_WREQB: | 2577 case FWTCODE_WREQB: |
2589 return sizeof(struct fw_asyhdr) + PLEN(fp->mode.wreqb.len) | 2578 r = sizeof(struct fw_asyhdr) + PLEN(fp->mode.wreqb.len) |
2590 + sizeof(u_int32_t); | 2579 + sizeof(u_int32_t); |
2580 break; |
|
2591 case FWTCODE_LREQ: | 2581 case FWTCODE_LREQ: |
2592 return sizeof(struct fw_asyhdr) + PLEN(fp->mode.lreq.len) | 2582 r = sizeof(struct fw_asyhdr) + PLEN(fp->mode.lreq.len) |
2593 + sizeof(u_int32_t); | 2583 + sizeof(u_int32_t); |
2584 break; |
|
2594 case FWTCODE_RRESB: | 2585 case FWTCODE_RRESB: |
2595 return sizeof(struct fw_asyhdr) + PLEN(fp->mode.rresb.len) | 2586 r = sizeof(struct fw_asyhdr) + PLEN(fp->mode.rresb.len) |
2596 + sizeof(u_int32_t); | 2587 + sizeof(u_int32_t); |
2588 break; |
|
2597 case FWTCODE_LRES: | 2589 case FWTCODE_LRES: |
2598 return sizeof(struct fw_asyhdr) + PLEN(fp->mode.lres.len) | 2590 r = sizeof(struct fw_asyhdr) + PLEN(fp->mode.lres.len) |
2599 + sizeof(u_int32_t); | 2591 + sizeof(u_int32_t); |
2592 break; |
|
2600 case FWOHCITCODE_PHY: | 2593 case FWOHCITCODE_PHY: |
2601 return 16; | 2594 r = 16; 2595 break; 2596 default: 2597 device_printf(sc->fc.dev, "Unknown tcode %d\n", 2598 fp->mode.common.tcode); 2599 r = 0; |
2602 } | 2600 } |
2603 device_printf(sc->fc.dev, "Unknown tcode %d\n", fp->mode.common.tcode); 2604 return 0; | 2601 if (r > dbch->xferq.psize) { 2602 device_printf(sc->fc.dev, "Invalid packet length %d\n", r); 2603 /* panic ? */ 2604 } 2605 return r; |
2605} 2606 2607static void 2608fwohci_arcv(struct fwohci_softc *sc, struct fwohci_dbch *dbch, int count) 2609{ 2610 struct fwohcidb_tr *db_tr; 2611 int z = 1; 2612 struct fw_pkt *fp; --- 37 unchanged lines hidden (view full) --- 2650 ld += rlen; 2651 len -= rlen; 2652 dbch->frag.len += rlen; 2653#if 0 2654 printf("(1)frag.plen=%d frag.len=%d rlen=%d len=%d\n", dbch->frag.plen, dbch->frag.len, rlen, len); 2655#endif 2656 fp=(struct fw_pkt *)dbch->frag.buf; 2657 dbch->frag.plen | 2606} 2607 2608static void 2609fwohci_arcv(struct fwohci_softc *sc, struct fwohci_dbch *dbch, int count) 2610{ 2611 struct fwohcidb_tr *db_tr; 2612 int z = 1; 2613 struct fw_pkt *fp; --- 37 unchanged lines hidden (view full) --- 2651 ld += rlen; 2652 len -= rlen; 2653 dbch->frag.len += rlen; 2654#if 0 2655 printf("(1)frag.plen=%d frag.len=%d rlen=%d len=%d\n", dbch->frag.plen, dbch->frag.len, rlen, len); 2656#endif 2657 fp=(struct fw_pkt *)dbch->frag.buf; 2658 dbch->frag.plen |
2658 = fwohci_get_plen(sc, fp, hlen); | 2659 = fwohci_get_plen(sc, 2660 dbch, fp, hlen); |
2659 if (dbch->frag.plen == 0) 2660 goto out; 2661 } 2662 rlen = dbch->frag.plen - dbch->frag.len; 2663#if 0 2664 printf("(2)frag.plen=%d frag.len=%d rlen=%d len=%d\n", dbch->frag.plen, dbch->frag.len, rlen, len); 2665#endif 2666 bcopy(ld, dbch->frag.buf + dbch->frag.len, --- 23 unchanged lines hidden (view full) --- 2690 case FWTCODE_LRES: 2691 hlen = 16; 2692 break; 2693 default: 2694 device_printf(sc->fc.dev, "Unknown tcode %d\n", fp->mode.common.tcode); 2695 goto out; 2696 } 2697 if (len >= hlen) { | 2661 if (dbch->frag.plen == 0) 2662 goto out; 2663 } 2664 rlen = dbch->frag.plen - dbch->frag.len; 2665#if 0 2666 printf("(2)frag.plen=%d frag.len=%d rlen=%d len=%d\n", dbch->frag.plen, dbch->frag.len, rlen, len); 2667#endif 2668 bcopy(ld, dbch->frag.buf + dbch->frag.len, --- 23 unchanged lines hidden (view full) --- 2692 case FWTCODE_LRES: 2693 hlen = 16; 2694 break; 2695 default: 2696 device_printf(sc->fc.dev, "Unknown tcode %d\n", fp->mode.common.tcode); 2697 goto out; 2698 } 2699 if (len >= hlen) { |
2698 plen = fwohci_get_plen(sc, fp, hlen); | 2700 plen = fwohci_get_plen(sc, 2701 dbch, fp, hlen); |
2699 if (plen == 0) 2700 goto out; 2701 plen = (plen + 3) & ~3; 2702 len -= plen; 2703 } else { 2704 plen = -hlen; 2705 len -= hlen; 2706 } 2707 if(resCount > 0 || len > 0){ | 2702 if (plen == 0) 2703 goto out; 2704 plen = (plen + 3) & ~3; 2705 len -= plen; 2706 } else { 2707 plen = -hlen; 2708 len -= hlen; 2709 } 2710 if(resCount > 0 || len > 0){ |
2708 buf = malloc( dbch->xferq.psize, 2709 M_FW, M_NOWAIT); | 2711 buf = malloc(plen, M_FW, M_NOWAIT); |
2710 if(buf == NULL){ 2711 printf("cannot malloc!\n"); 2712 free(db_tr->buf, M_FW); 2713 goto out; 2714 } 2715 bcopy(ld, buf, plen); 2716 poff = 0; 2717 dbch->frag.buf = NULL; --- 80 unchanged lines hidden --- | 2712 if(buf == NULL){ 2713 printf("cannot malloc!\n"); 2714 free(db_tr->buf, M_FW); 2715 goto out; 2716 } 2717 bcopy(ld, buf, plen); 2718 poff = 0; 2719 dbch->frag.buf = NULL; --- 80 unchanged lines hidden --- |