aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firewire/ohci.c
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2011-04-11 03:57:54 -0400
committerStefan Richter <stefanr@s5r6.in-berlin.de>2011-04-19 14:00:11 -0400
commitda28947e7e3602669e27d5e9ce787436ed662fa4 (patch)
tree33b3cfb25fddbe12b4f19f02ce3253872eed2436 /drivers/firewire/ohci.c
parentecf8328e59447b83a1f79628487e0e9f8801db84 (diff)
firewire: ohci: avoid separate DMA mapping for small AT payloads
For AT packet payloads of up to eight bytes, we have enough unused space in the DMA descriptors list so that we can put a copy of the payload there and thus avoid having to create a separate streaming DMA mapping for the payload buffer. In a CPU-bound microbenchmark that just sends 8-byte packets, bandwidth was measured to increase by 5.7 %, from 1009 KB/s to 1067 KB/s. In practice, the only performance-sensitive usage of small asynchronous packets is the SBP-2 driver's write to the ORB_POINTER register during SCSI command submission. Signed-off-by: Clemens Ladisch <clemens@ladisch.de> Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>
Diffstat (limited to 'drivers/firewire/ohci.c')
-rw-r--r--drivers/firewire/ohci.c25
1 files changed, 17 insertions, 8 deletions
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c
index dfb3cb774a79..435ed800d03f 100644
--- a/drivers/firewire/ohci.c
+++ b/drivers/firewire/ohci.c
@@ -1218,6 +1218,7 @@ static void context_stop(struct context *ctx)
1218} 1218}
1219 1219
1220struct driver_data { 1220struct driver_data {
1221 u8 inline_data[8];
1221 struct fw_packet *packet; 1222 struct fw_packet *packet;
1222}; 1223};
1223 1224
@@ -1301,20 +1302,28 @@ static int at_context_queue_packet(struct context *ctx,
1301 return -1; 1302 return -1;
1302 } 1303 }
1303 1304
1305 BUILD_BUG_ON(sizeof(struct driver_data) > sizeof(struct descriptor));
1304 driver_data = (struct driver_data *) &d[3]; 1306 driver_data = (struct driver_data *) &d[3];
1305 driver_data->packet = packet; 1307 driver_data->packet = packet;
1306 packet->driver_data = driver_data; 1308 packet->driver_data = driver_data;
1307 1309
1308 if (packet->payload_length > 0) { 1310 if (packet->payload_length > 0) {
1309 payload_bus = 1311 if (packet->payload_length > sizeof(driver_data->inline_data)) {
1310 dma_map_single(ohci->card.device, packet->payload, 1312 payload_bus = dma_map_single(ohci->card.device,
1311 packet->payload_length, DMA_TO_DEVICE); 1313 packet->payload,
1312 if (dma_mapping_error(ohci->card.device, payload_bus)) { 1314 packet->payload_length,
1313 packet->ack = RCODE_SEND_ERROR; 1315 DMA_TO_DEVICE);
1314 return -1; 1316 if (dma_mapping_error(ohci->card.device, payload_bus)) {
1317 packet->ack = RCODE_SEND_ERROR;
1318 return -1;
1319 }
1320 packet->payload_bus = payload_bus;
1321 packet->payload_mapped = true;
1322 } else {
1323 memcpy(driver_data->inline_data, packet->payload,
1324 packet->payload_length);
1325 payload_bus = d_bus + 3 * sizeof(*d);
1315 } 1326 }
1316 packet->payload_bus = payload_bus;
1317 packet->payload_mapped = true;
1318 1327
1319 d[2].req_count = cpu_to_le16(packet->payload_length); 1328 d[2].req_count = cpu_to_le16(packet->payload_length);
1320 d[2].data_address = cpu_to_le32(payload_bus); 1329 d[2].data_address = cpu_to_le32(payload_bus);