diff options
Diffstat (limited to 'drivers/firewire/fw-sbp2.c')
-rw-r--r-- | drivers/firewire/fw-sbp2.c | 94 |
1 files changed, 43 insertions, 51 deletions
diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index ea62e825a3b6..302160202644 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c | |||
@@ -224,8 +224,8 @@ struct sbp2_status { | |||
224 | }; | 224 | }; |
225 | 225 | ||
226 | struct sbp2_pointer { | 226 | struct sbp2_pointer { |
227 | u32 high; | 227 | __be32 high; |
228 | u32 low; | 228 | __be32 low; |
229 | }; | 229 | }; |
230 | 230 | ||
231 | struct sbp2_orb { | 231 | struct sbp2_orb { |
@@ -253,8 +253,8 @@ struct sbp2_management_orb { | |||
253 | struct { | 253 | struct { |
254 | struct sbp2_pointer password; | 254 | struct sbp2_pointer password; |
255 | struct sbp2_pointer response; | 255 | struct sbp2_pointer response; |
256 | u32 misc; | 256 | __be32 misc; |
257 | u32 length; | 257 | __be32 length; |
258 | struct sbp2_pointer status_fifo; | 258 | struct sbp2_pointer status_fifo; |
259 | } request; | 259 | } request; |
260 | __be32 response[4]; | 260 | __be32 response[4]; |
@@ -263,13 +263,10 @@ struct sbp2_management_orb { | |||
263 | struct sbp2_status status; | 263 | struct sbp2_status status; |
264 | }; | 264 | }; |
265 | 265 | ||
266 | #define LOGIN_RESPONSE_GET_LOGIN_ID(v) ((v).misc & 0xffff) | ||
267 | #define LOGIN_RESPONSE_GET_LENGTH(v) (((v).misc >> 16) & 0xffff) | ||
268 | |||
269 | struct sbp2_login_response { | 266 | struct sbp2_login_response { |
270 | u32 misc; | 267 | __be32 misc; |
271 | struct sbp2_pointer command_block_agent; | 268 | struct sbp2_pointer command_block_agent; |
272 | u32 reconnect_hold; | 269 | __be32 reconnect_hold; |
273 | }; | 270 | }; |
274 | #define COMMAND_ORB_DATA_SIZE(v) ((v)) | 271 | #define COMMAND_ORB_DATA_SIZE(v) ((v)) |
275 | #define COMMAND_ORB_PAGE_SIZE(v) ((v) << 16) | 272 | #define COMMAND_ORB_PAGE_SIZE(v) ((v) << 16) |
@@ -285,7 +282,7 @@ struct sbp2_command_orb { | |||
285 | struct { | 282 | struct { |
286 | struct sbp2_pointer next; | 283 | struct sbp2_pointer next; |
287 | struct sbp2_pointer data_descriptor; | 284 | struct sbp2_pointer data_descriptor; |
288 | u32 misc; | 285 | __be32 misc; |
289 | u8 command_block[12]; | 286 | u8 command_block[12]; |
290 | } request; | 287 | } request; |
291 | struct scsi_cmnd *cmd; | 288 | struct scsi_cmnd *cmd; |
@@ -459,8 +456,7 @@ sbp2_send_orb(struct sbp2_orb *orb, struct sbp2_logical_unit *lu, | |||
459 | unsigned long flags; | 456 | unsigned long flags; |
460 | 457 | ||
461 | orb->pointer.high = 0; | 458 | orb->pointer.high = 0; |
462 | orb->pointer.low = orb->request_bus; | 459 | orb->pointer.low = cpu_to_be32(orb->request_bus); |
463 | fw_memcpy_to_be32(&orb->pointer, &orb->pointer, sizeof(orb->pointer)); | ||
464 | 460 | ||
465 | spin_lock_irqsave(&device->card->lock, flags); | 461 | spin_lock_irqsave(&device->card->lock, flags); |
466 | list_add_tail(&orb->link, &lu->orb_list); | 462 | list_add_tail(&orb->link, &lu->orb_list); |
@@ -536,31 +532,31 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id, | |||
536 | if (dma_mapping_error(orb->response_bus)) | 532 | if (dma_mapping_error(orb->response_bus)) |
537 | goto fail_mapping_response; | 533 | goto fail_mapping_response; |
538 | 534 | ||
539 | orb->request.response.high = 0; | 535 | orb->request.response.high = 0; |
540 | orb->request.response.low = orb->response_bus; | 536 | orb->request.response.low = cpu_to_be32(orb->response_bus); |
541 | 537 | ||
542 | orb->request.misc = | 538 | orb->request.misc = cpu_to_be32( |
543 | MANAGEMENT_ORB_NOTIFY | | 539 | MANAGEMENT_ORB_NOTIFY | |
544 | MANAGEMENT_ORB_FUNCTION(function) | | 540 | MANAGEMENT_ORB_FUNCTION(function) | |
545 | MANAGEMENT_ORB_LUN(lun_or_login_id); | 541 | MANAGEMENT_ORB_LUN(lun_or_login_id)); |
546 | orb->request.length = | 542 | orb->request.length = cpu_to_be32( |
547 | MANAGEMENT_ORB_RESPONSE_LENGTH(sizeof(orb->response)); | 543 | MANAGEMENT_ORB_RESPONSE_LENGTH(sizeof(orb->response))); |
548 | 544 | ||
549 | orb->request.status_fifo.high = lu->address_handler.offset >> 32; | 545 | orb->request.status_fifo.high = |
550 | orb->request.status_fifo.low = lu->address_handler.offset; | 546 | cpu_to_be32(lu->address_handler.offset >> 32); |
547 | orb->request.status_fifo.low = | ||
548 | cpu_to_be32(lu->address_handler.offset); | ||
551 | 549 | ||
552 | if (function == SBP2_LOGIN_REQUEST) { | 550 | if (function == SBP2_LOGIN_REQUEST) { |
553 | /* Ask for 2^2 == 4 seconds reconnect grace period */ | 551 | /* Ask for 2^2 == 4 seconds reconnect grace period */ |
554 | orb->request.misc |= | 552 | orb->request.misc |= cpu_to_be32( |
555 | MANAGEMENT_ORB_RECONNECT(2) | | 553 | MANAGEMENT_ORB_RECONNECT(2) | |
556 | MANAGEMENT_ORB_EXCLUSIVE(sbp2_param_exclusive_login); | 554 | MANAGEMENT_ORB_EXCLUSIVE(sbp2_param_exclusive_login)); |
557 | timeout = lu->tgt->mgt_orb_timeout; | 555 | timeout = lu->tgt->mgt_orb_timeout; |
558 | } else { | 556 | } else { |
559 | timeout = SBP2_ORB_TIMEOUT; | 557 | timeout = SBP2_ORB_TIMEOUT; |
560 | } | 558 | } |
561 | 559 | ||
562 | fw_memcpy_to_be32(&orb->request, &orb->request, sizeof(orb->request)); | ||
563 | |||
564 | init_completion(&orb->done); | 560 | init_completion(&orb->done); |
565 | orb->base.callback = complete_management_orb; | 561 | orb->base.callback = complete_management_orb; |
566 | 562 | ||
@@ -605,8 +601,7 @@ sbp2_send_management_orb(struct sbp2_logical_unit *lu, int node_id, | |||
605 | sizeof(orb->response), DMA_FROM_DEVICE); | 601 | sizeof(orb->response), DMA_FROM_DEVICE); |
606 | fail_mapping_response: | 602 | fail_mapping_response: |
607 | if (response) | 603 | if (response) |
608 | fw_memcpy_from_be32(response, | 604 | memcpy(response, orb->response, sizeof(orb->response)); |
609 | orb->response, sizeof(orb->response)); | ||
610 | kref_put(&orb->base.kref, free_orb); | 605 | kref_put(&orb->base.kref, free_orb); |
611 | 606 | ||
612 | return retval; | 607 | return retval; |
@@ -885,11 +880,10 @@ static void sbp2_login(struct work_struct *work) | |||
885 | tgt->address_high = local_node_id << 16; | 880 | tgt->address_high = local_node_id << 16; |
886 | sbp2_set_generation(lu, generation); | 881 | sbp2_set_generation(lu, generation); |
887 | 882 | ||
888 | /* Get command block agent offset and login id. */ | ||
889 | lu->command_block_agent_address = | 883 | lu->command_block_agent_address = |
890 | ((u64) (response.command_block_agent.high & 0xffff) << 32) | | 884 | ((u64)(be32_to_cpu(response.command_block_agent.high) & 0xffff) |
891 | response.command_block_agent.low; | 885 | << 32) | be32_to_cpu(response.command_block_agent.low); |
892 | lu->login_id = LOGIN_RESPONSE_GET_LOGIN_ID(response); | 886 | lu->login_id = be32_to_cpu(response.misc) & 0xffff; |
893 | 887 | ||
894 | fw_notify("%s: logged in to LUN %04x (%d retries)\n", | 888 | fw_notify("%s: logged in to LUN %04x (%d retries)\n", |
895 | tgt->bus_id, lu->lun, lu->retries); | 889 | tgt->bus_id, lu->lun, lu->retries); |
@@ -1366,9 +1360,12 @@ sbp2_map_scatterlist(struct sbp2_command_orb *orb, struct fw_device *device, | |||
1366 | * tables. | 1360 | * tables. |
1367 | */ | 1361 | */ |
1368 | if (count == 1 && sg_dma_len(sg) < SBP2_MAX_SG_ELEMENT_LENGTH) { | 1362 | if (count == 1 && sg_dma_len(sg) < SBP2_MAX_SG_ELEMENT_LENGTH) { |
1369 | orb->request.data_descriptor.high = lu->tgt->address_high; | 1363 | orb->request.data_descriptor.high = |
1370 | orb->request.data_descriptor.low = sg_dma_address(sg); | 1364 | cpu_to_be32(lu->tgt->address_high); |
1371 | orb->request.misc |= COMMAND_ORB_DATA_SIZE(sg_dma_len(sg)); | 1365 | orb->request.data_descriptor.low = |
1366 | cpu_to_be32(sg_dma_address(sg)); | ||
1367 | orb->request.misc |= | ||
1368 | cpu_to_be32(COMMAND_ORB_DATA_SIZE(sg_dma_len(sg))); | ||
1372 | return 0; | 1369 | return 0; |
1373 | } | 1370 | } |
1374 | 1371 | ||
@@ -1389,16 +1386,14 @@ sbp2_map_scatterlist(struct sbp2_command_orb *orb, struct fw_device *device, | |||
1389 | goto fail_page_table; | 1386 | goto fail_page_table; |
1390 | } | 1387 | } |
1391 | l = min(sg_len, SBP2_MAX_SG_ELEMENT_LENGTH); | 1388 | l = min(sg_len, SBP2_MAX_SG_ELEMENT_LENGTH); |
1392 | orb->page_table[j].low = sg_addr; | 1389 | orb->page_table[j].low = cpu_to_be32(sg_addr); |
1393 | orb->page_table[j].high = (l << 16); | 1390 | orb->page_table[j].high = cpu_to_be32(l << 16); |
1394 | sg_addr += l; | 1391 | sg_addr += l; |
1395 | sg_len -= l; | 1392 | sg_len -= l; |
1396 | j++; | 1393 | j++; |
1397 | } | 1394 | } |
1398 | } | 1395 | } |
1399 | 1396 | ||
1400 | fw_memcpy_to_be32(orb->page_table, orb->page_table, | ||
1401 | sizeof(orb->page_table[0]) * j); | ||
1402 | orb->page_table_bus = | 1397 | orb->page_table_bus = |
1403 | dma_map_single(device->card->device, orb->page_table, | 1398 | dma_map_single(device->card->device, orb->page_table, |
1404 | sizeof(orb->page_table), DMA_TO_DEVICE); | 1399 | sizeof(orb->page_table), DMA_TO_DEVICE); |
@@ -1412,11 +1407,10 @@ sbp2_map_scatterlist(struct sbp2_command_orb *orb, struct fw_device *device, | |||
1412 | * initiator (i.e. us), but data_descriptor can refer to data | 1407 | * initiator (i.e. us), but data_descriptor can refer to data |
1413 | * on other nodes so we need to put our ID in descriptor.high. | 1408 | * on other nodes so we need to put our ID in descriptor.high. |
1414 | */ | 1409 | */ |
1415 | orb->request.data_descriptor.high = lu->tgt->address_high; | 1410 | orb->request.data_descriptor.high = cpu_to_be32(lu->tgt->address_high); |
1416 | orb->request.data_descriptor.low = orb->page_table_bus; | 1411 | orb->request.data_descriptor.low = cpu_to_be32(orb->page_table_bus); |
1417 | orb->request.misc |= | 1412 | orb->request.misc |= cpu_to_be32(COMMAND_ORB_PAGE_TABLE_PRESENT | |
1418 | COMMAND_ORB_PAGE_TABLE_PRESENT | | 1413 | COMMAND_ORB_DATA_SIZE(j)); |
1419 | COMMAND_ORB_DATA_SIZE(j); | ||
1420 | 1414 | ||
1421 | return 0; | 1415 | return 0; |
1422 | 1416 | ||
@@ -1462,7 +1456,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done) | |||
1462 | orb->done = done; | 1456 | orb->done = done; |
1463 | orb->cmd = cmd; | 1457 | orb->cmd = cmd; |
1464 | 1458 | ||
1465 | orb->request.next.high = SBP2_ORB_NULL; | 1459 | orb->request.next.high = cpu_to_be32(SBP2_ORB_NULL); |
1466 | orb->request.next.low = 0x0; | 1460 | orb->request.next.low = 0x0; |
1467 | /* | 1461 | /* |
1468 | * At speed 100 we can do 512 bytes per packet, at speed 200, | 1462 | * At speed 100 we can do 512 bytes per packet, at speed 200, |
@@ -1472,23 +1466,21 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done) | |||
1472 | */ | 1466 | */ |
1473 | max_payload = min(device->max_speed + 7, | 1467 | max_payload = min(device->max_speed + 7, |
1474 | device->card->max_receive - 1); | 1468 | device->card->max_receive - 1); |
1475 | orb->request.misc = | 1469 | orb->request.misc = cpu_to_be32( |
1476 | COMMAND_ORB_MAX_PAYLOAD(max_payload) | | 1470 | COMMAND_ORB_MAX_PAYLOAD(max_payload) | |
1477 | COMMAND_ORB_SPEED(device->max_speed) | | 1471 | COMMAND_ORB_SPEED(device->max_speed) | |
1478 | COMMAND_ORB_NOTIFY; | 1472 | COMMAND_ORB_NOTIFY); |
1479 | 1473 | ||
1480 | if (cmd->sc_data_direction == DMA_FROM_DEVICE) | 1474 | if (cmd->sc_data_direction == DMA_FROM_DEVICE) |
1481 | orb->request.misc |= | 1475 | orb->request.misc |= cpu_to_be32( |
1482 | COMMAND_ORB_DIRECTION(SBP2_DIRECTION_FROM_MEDIA); | 1476 | COMMAND_ORB_DIRECTION(SBP2_DIRECTION_FROM_MEDIA)); |
1483 | else if (cmd->sc_data_direction == DMA_TO_DEVICE) | 1477 | else if (cmd->sc_data_direction == DMA_TO_DEVICE) |
1484 | orb->request.misc |= | 1478 | orb->request.misc |= cpu_to_be32( |
1485 | COMMAND_ORB_DIRECTION(SBP2_DIRECTION_TO_MEDIA); | 1479 | COMMAND_ORB_DIRECTION(SBP2_DIRECTION_TO_MEDIA)); |
1486 | 1480 | ||
1487 | if (scsi_sg_count(cmd) && sbp2_map_scatterlist(orb, device, lu) < 0) | 1481 | if (scsi_sg_count(cmd) && sbp2_map_scatterlist(orb, device, lu) < 0) |
1488 | goto out; | 1482 | goto out; |
1489 | 1483 | ||
1490 | fw_memcpy_to_be32(&orb->request, &orb->request, sizeof(orb->request)); | ||
1491 | |||
1492 | memset(orb->request.command_block, | 1484 | memset(orb->request.command_block, |
1493 | 0, sizeof(orb->request.command_block)); | 1485 | 0, sizeof(orb->request.command_block)); |
1494 | memcpy(orb->request.command_block, cmd->cmnd, COMMAND_SIZE(*cmd->cmnd)); | 1486 | memcpy(orb->request.command_block, cmd->cmnd, COMMAND_SIZE(*cmd->cmnd)); |