summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/firewire/firewire.c116
-rw-r--r--sys/dev/firewire/firewirereg.h3
-rw-r--r--sys/dev/firewire/fwohci.c9
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 <dev/firewire/iec13213.h>
#include <dev/firewire/iec68113.h>
+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 )){