From 0bc666e09b514a36f6e8eaa2a8a0c55db59d6c5f Mon Sep 17 00:00:00 2001 From: Hidetoshi Shimokawa Date: Sun, 15 Jun 2003 04:09:26 +0000 Subject: [PATCH] - Enable support for building Configuration ROM. - Improve probe message for S800 chips. --- sys/dev/firewire/firewire.c | 116 ++++++++++++++++++++++++++++----- sys/dev/firewire/firewirereg.h | 3 + sys/dev/firewire/fwohci.c | 9 ++- 3 files changed, 109 insertions(+), 19 deletions(-) diff --git a/sys/dev/firewire/firewire.c b/sys/dev/firewire/firewire.c index 4d6c99ec4cf7..3b100c2be154 100644 --- a/sys/dev/firewire/firewire.c +++ b/sys/dev/firewire/firewire.c @@ -59,6 +59,13 @@ #include #include +struct crom_src_buf { + struct crom_src src; + struct crom_chunk root; + struct crom_chunk vendor; + struct crom_chunk hw; +}; + int firewire_debug=0, try_bmr=1; SYSCTL_INT(_debug, OID_AUTO, firewire_debug, CTLFLAG_RW, &firewire_debug, 0, "FireWire driver debug flag"); @@ -467,6 +474,7 @@ firewire_detach( device_t dev ) } free(sc->fc->topology_map, M_FW); free(sc->fc->speed_map, M_FW); + free(sc->fc->crom_src_buf, M_FW); return(0); } #if 0 @@ -502,25 +510,11 @@ fw_drain_txq(struct firewire_comm *fc) fw_xferq_drain(fc->it[i]); } -/* - * Called after bus reset. - */ -void -fw_busreset(struct firewire_comm *fc) +static void +fw_reset_csr(struct firewire_comm *fc) { - struct firewire_dev_comm *fdc; - device_t *devlistp; - int devcnt; int i; - switch(fc->status){ - case FWBUSMGRELECT: - callout_stop(&fc->bmr_callout); - break; - default: - break; - } - fc->status = FWBUSRESET; CSRARC(fc, STATE_CLEAR) = 1 << 23 | 0 << 17 | 1 << 16 | 1 << 15 | 1 << 14 ; CSRARC(fc, STATE_SET) = CSRARC(fc, STATE_CLEAR); @@ -559,6 +553,93 @@ fw_busreset(struct firewire_comm *fc) CSRARC(fc, STATE_CLEAR) &= ~(1 << 23 | 1 << 15 | 1 << 14 ); CSRARC(fc, STATE_SET) = CSRARC(fc, STATE_CLEAR); +} + +static void +fw_init_crom(struct firewire_comm *fc) +{ + struct crom_src *src; + + fc->crom_src_buf = (struct crom_src_buf *) + malloc(sizeof(struct crom_src_buf), M_FW, M_WAITOK | M_ZERO); + if (fc->crom_src_buf == NULL) + return; + + src = &fc->crom_src_buf->src; + bzero(src, sizeof(struct crom_src)); + + /* BUS info sample */ + src->hdr.info_len = 4; + + src->businfo.bus_name = CSR_BUS_NAME_IEEE1394; + + src->businfo.irmc = 1; + src->businfo.cmc = 1; + src->businfo.isc = 1; + src->businfo.bmc = 1; + src->businfo.pmc = 0; + src->businfo.cyc_clk_acc = 100; + src->businfo.max_rec = fc->maxrec; + src->businfo.max_rom = MAXROM_4; + src->businfo.generation = 0; + src->businfo.link_spd = fc->speed; + + src->businfo.eui64.hi = fc->eui.hi; + src->businfo.eui64.lo = fc->eui.lo; + + STAILQ_INIT(&src->chunk_list); + + fc->crom_src = src; + fc->crom_root = &fc->crom_src_buf->root; +} + +static void +fw_reset_crom(struct firewire_comm *fc) +{ + struct crom_src_buf *buf; + struct crom_src *src; + struct crom_chunk *root; + + if (fc->crom_src_buf == NULL) + fw_init_crom(fc); + + buf = fc->crom_src_buf; + src = fc->crom_src; + root = fc->crom_root; + + src->businfo.generation ++; + STAILQ_INIT(&src->chunk_list); + + bzero(root, sizeof(struct crom_chunk)); + crom_add_chunk(src, NULL, root, 0); + crom_add_entry(root, CSRKEY_NCAP, 0x0083c0); /* XXX */ + /* private company_id */ + crom_add_entry(root, CSRKEY_VENDOR, CSRVAL_VENDOR_PRIVATE); + crom_add_simple_text(src, root, &buf->vendor, "FreeBSD Project"); + crom_add_entry(root, CSRKEY_HW, __FreeBSD_version); + crom_add_simple_text(src, root, &buf->hw, hostname); +} + +/* + * Called after bus reset. + */ +void +fw_busreset(struct firewire_comm *fc) +{ + struct firewire_dev_comm *fdc; + device_t *devlistp; + int i, devcnt; + + switch(fc->status){ + case FWBUSMGRELECT: + callout_stop(&fc->bmr_callout); + break; + default: + break; + } + fc->status = FWBUSRESET; + fw_reset_csr(fc); + fw_reset_crom(fc); if (device_get_children(fc->bdev, &devlistp, &devcnt) == 0) { for( i = 0 ; i < devcnt ; i++) @@ -569,6 +650,8 @@ fw_busreset(struct firewire_comm *fc) } free(devlistp, M_TEMP); } + + crom_load(&fc->crom_src_buf->src, fc->config_rom, CROMSIZE); } /* Call once after reboot */ @@ -675,6 +758,7 @@ void fw_init(struct firewire_comm *fc) } #endif + fc->crom_src_buf = NULL; #ifdef FW_VMACCESS xfer = fw_xfer_alloc(); diff --git a/sys/dev/firewire/firewirereg.h b/sys/dev/firewire/firewirereg.h index c918e202095a..f16fd32ee3b0 100644 --- a/sys/dev/firewire/firewirereg.h +++ b/sys/dev/firewire/firewirereg.h @@ -143,6 +143,9 @@ struct firewire_comm{ u_int32_t csr_arc[CSRSIZE/4]; #define CROMSIZE 0x400 u_int32_t *config_rom; + struct crom_src_buf *crom_src_buf; + struct crom_src *crom_src; + struct crom_chunk *crom_root; struct fw_topology_map *topology_map; struct fw_speed_map *speed_map; struct callout busprobe_callout; diff --git a/sys/dev/firewire/fwohci.c b/sys/dev/firewire/fwohci.c index ab97e95940e4..d7ca246fe1a0 100644 --- a/sys/dev/firewire/fwohci.c +++ b/sys/dev/firewire/fwohci.c @@ -94,8 +94,8 @@ char fwohcicode[32][0x20]={ "Undef","Undef","Undef","ack tardy", "Undef","ack data_err","ack type_err",""}; -#define MAX_SPEED 2 -extern char linkspeed[MAX_SPEED+1][0x10]; +#define MAX_SPEED 3 +extern char linkspeed[][0x10]; u_int32_t tagbit[4] = { 1 << 28, 1 << 29, 1 << 30, 1 << 31}; static struct tcode_info tinfo[] = { @@ -648,7 +648,8 @@ fwohci_init(struct fwohci_softc *sc, device_t dev) return ENOMEM; } -#if 1 +#if 0 + bzero(&sc->fc.config_rom[0], CROMSIZE); sc->fc.config_rom[1] = 0x31333934; sc->fc.config_rom[2] = 0xf000a002; sc->fc.config_rom[3] = OREAD(sc, OHCI_EUID_HI); @@ -1761,6 +1762,8 @@ fwohci_intr_body(struct fwohci_softc *sc, u_int32_t stat, int count) OWRITE(sc, FWOHCI_INTSTATCLR, OHCI_INT_PHY_BUS_R); #endif fw_busreset(fc); + OWRITE(sc, OHCI_CROMHDR, ntohl(sc->fc.config_rom[0])); + OWRITE(sc, OHCI_BUS_OPT, ntohl(sc->fc.config_rom[2])); } busresetout: if((stat & OHCI_INT_DMA_IR )){