aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire/ohci.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/firewire/ohci.c')
-rw-r--r--drivers/firewire/ohci.c64
1 files changed, 42 insertions, 22 deletions
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index 23d1468ad253..438e6c831170 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -1006,13 +1006,12 @@ static void ar_context_run(struct ar_context *ctx)
1006 1006
1007static struct descriptor *find_branch_descriptor(struct descriptor *d, int z) 1007static struct descriptor *find_branch_descriptor(struct descriptor *d, int z)
1008{ 1008{
1009 int b, key; 1009 __le16 branch;
1010 1010
1011 b = (le16_to_cpu(d->control) & DESCRIPTOR_BRANCH_ALWAYS) >> 2; 1011 branch = d->control & cpu_to_le16(DESCRIPTOR_BRANCH_ALWAYS);
1012 key = (le16_to_cpu(d->control) & DESCRIPTOR_KEY_IMMEDIATE) >> 8;
1013 1012
1014 /* figure out which descriptor the branch address goes in */ 1013 /* figure out which descriptor the branch address goes in */
1015 if (z == 2 && (b == 3 || key == 2)) 1014 if (z == 2 && branch == cpu_to_le16(DESCRIPTOR_BRANCH_ALWAYS))
1016 return d; 1015 return d;
1017 else 1016 else
1018 return d + z - 1; 1017 return d + z - 1;
@@ -1193,9 +1192,6 @@ static void context_append(struct context *ctx,
1193 wmb(); /* finish init of new descriptors before branch_address update */ 1192 wmb(); /* finish init of new descriptors before branch_address update */
1194 ctx->prev->branch_address = cpu_to_le32(d_bus | z); 1193 ctx->prev->branch_address = cpu_to_le32(d_bus | z);
1195 ctx->prev = find_branch_descriptor(d, z); 1194 ctx->prev = find_branch_descriptor(d, z);
1196
1197 reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_WAKE);
1198 flush_writes(ctx->ohci);
1199} 1195}
1200 1196
1201static void context_stop(struct context *ctx) 1197static void context_stop(struct context *ctx)
@@ -1218,6 +1214,7 @@ static void context_stop(struct context *ctx)
1218} 1214}
1219 1215
1220struct driver_data { 1216struct driver_data {
1217 u8 inline_data[8];
1221 struct fw_packet *packet; 1218 struct fw_packet *packet;
1222}; 1219};
1223 1220
@@ -1301,20 +1298,28 @@ static int at_context_queue_packet(struct context *ctx,
1301 return -1; 1298 return -1;
1302 } 1299 }
1303 1300
1301 BUILD_BUG_ON(sizeof(struct driver_data) > sizeof(struct descriptor));
1304 driver_data = (struct driver_data *) &d[3]; 1302 driver_data = (struct driver_data *) &d[3];
1305 driver_data->packet = packet; 1303 driver_data->packet = packet;
1306 packet->driver_data = driver_data; 1304 packet->driver_data = driver_data;
1307 1305
1308 if (packet->payload_length > 0) { 1306 if (packet->payload_length > 0) {
1309 payload_bus = 1307 if (packet->payload_length > sizeof(driver_data->inline_data)) {
1310 dma_map_single(ohci->card.device, packet->payload, 1308 payload_bus = dma_map_single(ohci->card.device,
1311 packet->payload_length, DMA_TO_DEVICE); 1309 packet->payload,
1312 if (dma_mapping_error(ohci->card.device, payload_bus)) { 1310 packet->payload_length,
1313 packet->ack = RCODE_SEND_ERROR; 1311 DMA_TO_DEVICE);
1314 return -1; 1312 if (dma_mapping_error(ohci->card.device, payload_bus)) {
1313 packet->ack = RCODE_SEND_ERROR;
1314 return -1;
1315 }
1316 packet->payload_bus = payload_bus;
1317 packet->payload_mapped = true;
1318 } else {
1319 memcpy(driver_data->inline_data, packet->payload,
1320 packet->payload_length);
1321 payload_bus = d_bus + 3 * sizeof(*d);
1315 } 1322 }
1316 packet->payload_bus = payload_bus;
1317 packet->payload_mapped = true;
1318 1323
1319 d[2].req_count = cpu_to_le16(packet->payload_length); 1324 d[2].req_count = cpu_to_le16(packet->payload_length);
1320 d[2].data_address = cpu_to_le32(payload_bus); 1325 d[2].data_address = cpu_to_le32(payload_bus);
@@ -1340,8 +1345,12 @@ static int at_context_queue_packet(struct context *ctx,
1340 1345
1341 context_append(ctx, d, z, 4 - z); 1346 context_append(ctx, d, z, 4 - z);
1342 1347
1343 if (!ctx->running) 1348 if (ctx->running) {
1349 reg_write(ohci, CONTROL_SET(ctx->regs), CONTEXT_WAKE);
1350 flush_writes(ohci);
1351 } else {
1344 context_run(ctx, 0); 1352 context_run(ctx, 0);
1353 }
1345 1354
1346 return 0; 1355 return 0;
1347} 1356}
@@ -2066,8 +2075,6 @@ static int ohci_enable(struct fw_card *card,
2066 2075
2067 reg_write(ohci, OHCI1394_SelfIDBuffer, ohci->self_id_bus); 2076 reg_write(ohci, OHCI1394_SelfIDBuffer, ohci->self_id_bus);
2068 reg_write(ohci, OHCI1394_LinkControlSet, 2077 reg_write(ohci, OHCI1394_LinkControlSet,
2069 OHCI1394_LinkControl_rcvSelfID |
2070 OHCI1394_LinkControl_rcvPhyPkt |
2071 OHCI1394_LinkControl_cycleTimerEnable | 2078 OHCI1394_LinkControl_cycleTimerEnable |
2072 OHCI1394_LinkControl_cycleMaster); 2079 OHCI1394_LinkControl_cycleMaster);
2073 2080
@@ -2094,9 +2101,6 @@ static int ohci_enable(struct fw_card *card,
2094 reg_write(ohci, OHCI1394_FairnessControl, 0); 2101 reg_write(ohci, OHCI1394_FairnessControl, 0);
2095 card->priority_budget_implemented = ohci->pri_req_max != 0; 2102 card->priority_budget_implemented = ohci->pri_req_max != 0;
2096 2103
2097 ar_context_run(&ohci->ar_request_ctx);
2098 ar_context_run(&ohci->ar_response_ctx);
2099
2100 reg_write(ohci, OHCI1394_PhyUpperBound, 0x00010000); 2104 reg_write(ohci, OHCI1394_PhyUpperBound, 0x00010000);
2101 reg_write(ohci, OHCI1394_IntEventClear, ~0); 2105 reg_write(ohci, OHCI1394_IntEventClear, ~0);
2102 reg_write(ohci, OHCI1394_IntMaskClear, ~0); 2106 reg_write(ohci, OHCI1394_IntMaskClear, ~0);
@@ -2186,7 +2190,13 @@ static int ohci_enable(struct fw_card *card,
2186 reg_write(ohci, OHCI1394_HCControlSet, 2190 reg_write(ohci, OHCI1394_HCControlSet,
2187 OHCI1394_HCControl_linkEnable | 2191 OHCI1394_HCControl_linkEnable |
2188 OHCI1394_HCControl_BIBimageValid); 2192 OHCI1394_HCControl_BIBimageValid);
2189 flush_writes(ohci); 2193
2194 reg_write(ohci, OHCI1394_LinkControlSet,
2195 OHCI1394_LinkControl_rcvSelfID |
2196 OHCI1394_LinkControl_rcvPhyPkt);
2197
2198 ar_context_run(&ohci->ar_request_ctx);
2199 ar_context_run(&ohci->ar_response_ctx); /* also flushes writes */
2190 2200
2191 /* We are ready to go, reset bus to finish initialization. */ 2201 /* We are ready to go, reset bus to finish initialization. */
2192 fw_schedule_bus_reset(&ohci->card, false, true); 2202 fw_schedule_bus_reset(&ohci->card, false, true);
@@ -3112,6 +3122,15 @@ static int ohci_queue_iso(struct fw_iso_context *base,
3112 return ret; 3122 return ret;
3113} 3123}
3114 3124
3125static void ohci_flush_queue_iso(struct fw_iso_context *base)
3126{
3127 struct context *ctx =
3128 &container_of(base, struct iso_context, base)->context;
3129
3130 reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_WAKE);
3131 flush_writes(ctx->ohci);
3132}
3133
3115static const struct fw_card_driver ohci_driver = { 3134static const struct fw_card_driver ohci_driver = {
3116 .enable = ohci_enable, 3135 .enable = ohci_enable,
3117 .read_phy_reg = ohci_read_phy_reg, 3136 .read_phy_reg = ohci_read_phy_reg,
@@ -3128,6 +3147,7 @@ static const struct fw_card_driver ohci_driver = {
3128 .free_iso_context = ohci_free_iso_context, 3147 .free_iso_context = ohci_free_iso_context,
3129 .set_iso_channels = ohci_set_iso_channels, 3148 .set_iso_channels = ohci_set_iso_channels,
3130 .queue_iso = ohci_queue_iso, 3149 .queue_iso = ohci_queue_iso,
3150 .flush_queue_iso = ohci_flush_queue_iso,
3131 .start_iso = ohci_start_iso, 3151 .start_iso = ohci_start_iso,
3132 .stop_iso = ohci_stop_iso, 3152 .stop_iso = ohci_stop_iso,
3133}; 3153};