firewire: sbp2: fix DMA mapping leak on the failure path

Reported-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
who also provided a first version of the fix.

Signed-off-by: Stefan Richter <stefanr@s5r6.in-berlin.de>

+17 -10
+17 -10
drivers/firewire/fw-sbp2.c
··· 1284 1284 .id_table = sbp2_id_table, 1285 1285 }; 1286 1286 1287 + static void sbp2_unmap_scatterlist(struct device *card_device, 1288 + struct sbp2_command_orb *orb) 1289 + { 1290 + if (scsi_sg_count(orb->cmd)) 1291 + dma_unmap_sg(card_device, scsi_sglist(orb->cmd), 1292 + scsi_sg_count(orb->cmd), 1293 + orb->cmd->sc_data_direction); 1294 + 1295 + if (orb->request.misc & cpu_to_be32(COMMAND_ORB_PAGE_TABLE_PRESENT)) 1296 + dma_unmap_single(card_device, orb->page_table_bus, 1297 + sizeof(orb->page_table), DMA_TO_DEVICE); 1298 + } 1299 + 1287 1300 static unsigned int 1288 1301 sbp2_status_to_sense_data(u8 *sbp2_status, u8 *sense_data) 1289 1302 { ··· 1376 1363 1377 1364 dma_unmap_single(device->card->device, orb->base.request_bus, 1378 1365 sizeof(orb->request), DMA_TO_DEVICE); 1379 - 1380 - if (scsi_sg_count(orb->cmd) > 0) 1381 - dma_unmap_sg(device->card->device, scsi_sglist(orb->cmd), 1382 - scsi_sg_count(orb->cmd), 1383 - orb->cmd->sc_data_direction); 1384 - 1385 - if (orb->page_table_bus != 0) 1386 - dma_unmap_single(device->card->device, orb->page_table_bus, 1387 - sizeof(orb->page_table), DMA_TO_DEVICE); 1366 + sbp2_unmap_scatterlist(device->card->device, orb); 1388 1367 1389 1368 orb->cmd->result = result; 1390 1369 orb->done(orb->cmd); ··· 1498 1493 orb->base.request_bus = 1499 1494 dma_map_single(device->card->device, &orb->request, 1500 1495 sizeof(orb->request), DMA_TO_DEVICE); 1501 - if (dma_mapping_error(device->card->device, orb->base.request_bus)) 1496 + if (dma_mapping_error(device->card->device, orb->base.request_bus)) { 1497 + sbp2_unmap_scatterlist(device->card->device, orb); 1502 1498 goto out; 1499 + } 1503 1500 1504 1501 sbp2_send_orb(&orb->base, lu, lu->tgt->node_id, generation, 1505 1502 lu->command_block_agent_address + SBP2_ORB_POINTER);