diff options
Diffstat (limited to 'sys/dev/firewire/firewire.c')
-rw-r--r-- | sys/dev/firewire/firewire.c | 85 |
1 files changed, 49 insertions, 36 deletions
diff --git a/sys/dev/firewire/firewire.c b/sys/dev/firewire/firewire.c index ae0d5d3..8137df6 100644 --- a/sys/dev/firewire/firewire.c +++ b/sys/dev/firewire/firewire.c @@ -430,6 +430,31 @@ firewire_attach(device_t dev) fwdev_makedev(sc); + fc->crom_src_buf = (struct crom_src_buf *)malloc( + sizeof(struct crom_src_buf), + M_FW, M_NOWAIT | M_ZERO); + if (fc->crom_src_buf == NULL) { + device_printf(fc->dev, "%s: Malloc Failure crom src buff\n", __func__); + return ENOMEM; + } + fc->topology_map = (struct fw_topology_map *)malloc( + sizeof(struct fw_topology_map), + M_FW, M_NOWAIT | M_ZERO); + if (fc->topology_map == NULL) { + device_printf(fc->dev, "%s: Malloc Failure topology map\n", __func__); + free(fc->crom_src_buf, M_FW); + return ENOMEM; + } + fc->speed_map = (struct fw_speed_map *)malloc( + sizeof(struct fw_speed_map), + M_FW, M_NOWAIT | M_ZERO); + if (fc->speed_map == NULL) { + device_printf(fc->dev, "%s: Malloc Failure speed map\n", __func__); + free(fc->crom_src_buf, M_FW); + free(fc->topology_map, M_FW); + return ENOMEM; + } + mtx_init(&fc->wait_lock, "fwwait", NULL, MTX_DEF); mtx_init(&fc->tlabel_lock, "fwtlabel", NULL, MTX_DEF); CALLOUT_INIT(&fc->timeout_callout); @@ -451,7 +476,9 @@ firewire_attach(device_t dev) bus_generic_attach(dev); /* bus_reset */ + FW_GLOCK(fc); fw_busreset(fc, FWBUSNOTREADY); + FW_GUNLOCK(fc); fc->ibr(fc); return 0; @@ -642,11 +669,6 @@ 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)); @@ -663,7 +685,7 @@ fw_init_crom(struct firewire_comm *fc) src->businfo.cyc_clk_acc = 100; src->businfo.max_rec = fc->maxrec; src->businfo.max_rom = MAXROM_4; - src->businfo.generation = 1; + src->businfo.generation = 0; src->businfo.link_spd = fc->speed; src->businfo.eui64.hi = fc->eui.hi; @@ -682,9 +704,6 @@ fw_reset_crom(struct firewire_comm *fc) 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; @@ -715,18 +734,18 @@ fw_busreset(struct firewire_comm *fc, uint32_t new_status) struct firewire_dev_comm *fdc; struct crom_src *src; device_t *devlistp; - void *newrom; int i, devcnt; - switch(fc->status){ - case FWBUSMGRELECT: + FW_GLOCK_ASSERT(fc); + if (fc->status == FWBUSMGRELECT) callout_stop(&fc->bmr_callout); - break; - default: - break; - } + fc->status = new_status; fw_reset_csr(fc); + + if (fc->status == FWBUSNOTREADY) + fw_init_crom(fc); + fw_reset_crom(fc); if (device_get_children(fc->bdev, &devlistp, &devcnt) == 0) { @@ -739,19 +758,19 @@ fw_busreset(struct firewire_comm *fc, uint32_t new_status) free(devlistp, M_TEMP); } - newrom = malloc(CROMSIZE, M_FW, M_NOWAIT | M_ZERO); src = &fc->crom_src_buf->src; - crom_load(src, (uint32_t *)newrom, CROMSIZE); - if (bcmp(newrom, fc->config_rom, CROMSIZE) != 0) { - /* bump generation and reload */ - src->businfo.generation ++; - /* generation must be between 0x2 and 0xF */ - if (src->businfo.generation < 2) - src->businfo.generation ++; - crom_load(src, (uint32_t *)newrom, CROMSIZE); - bcopy(newrom, (void *)fc->config_rom, CROMSIZE); - } - free(newrom, M_FW); + /* + * If the old config rom needs to be overwritten, + * bump the businfo.generation indicator to + * indicate that we need to be reprobed + */ + if (bcmp(src, fc->config_rom, CROMSIZE) != 0) { + /* generation is a 2 bit field */ + /* valid values are only from 0 - 3 */ + src->businfo.generation = 1; + bcopy(src, (void *)fc->config_rom, CROMSIZE); + } else + src->businfo.generation = 0; } /* Call once after reboot */ @@ -807,13 +826,7 @@ void fw_init(struct firewire_comm *fc) fc->ir[i]->maxq = FWMAXQUEUE; fc->it[i]->maxq = FWMAXQUEUE; } -/* Initialize csr registers */ - fc->topology_map = (struct fw_topology_map *)malloc( - sizeof(struct fw_topology_map), - M_FW, M_NOWAIT | M_ZERO); - fc->speed_map = (struct fw_speed_map *)malloc( - sizeof(struct fw_speed_map), - M_FW, M_NOWAIT | M_ZERO); + CSRARC(fc, TOPO_MAP) = 0x3f1 << 16; CSRARC(fc, TOPO_MAP + 4) = 1; CSRARC(fc, SPED_MAP) = 0x3f1 << 16; @@ -1559,7 +1572,7 @@ fw_explore_node(struct fw_device *dfwdev) /* unchanged ? */ if (bcmp(&csr[0], &fwdev->csrrom[0], sizeof(uint32_t) * 5) == 0) { if (firewire_debug) - printf("node%d: crom unchanged\n", node); + device_printf(fc->dev, "node%d: crom unchanged\n", node); return (0); } |