summaryrefslogtreecommitdiffstats
path: root/sys/dev/firewire/firewire.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/firewire/firewire.c')
-rw-r--r--sys/dev/firewire/firewire.c85
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);
}
OpenPOWER on IntegriCloud