aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ieee1394/sbp2.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ieee1394/sbp2.c')
-rw-r--r--drivers/ieee1394/sbp2.c218
1 files changed, 91 insertions, 127 deletions
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
index 1d6ad3435537..c52f6e6e8af2 100644
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
@@ -526,26 +526,41 @@ static void sbp2util_write_doorbell(struct work_struct *work)
526 526
527static int sbp2util_create_command_orb_pool(struct sbp2_lu *lu) 527static int sbp2util_create_command_orb_pool(struct sbp2_lu *lu)
528{ 528{
529 struct sbp2_fwhost_info *hi = lu->hi;
530 struct sbp2_command_info *cmd; 529 struct sbp2_command_info *cmd;
530 struct device *dmadev = lu->hi->host->device.parent;
531 int i, orbs = sbp2_serialize_io ? 2 : SBP2_MAX_CMDS; 531 int i, orbs = sbp2_serialize_io ? 2 : SBP2_MAX_CMDS;
532 532
533 for (i = 0; i < orbs; i++) { 533 for (i = 0; i < orbs; i++) {
534 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 534 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
535 if (!cmd) 535 if (!cmd)
536 return -ENOMEM; 536 goto failed_alloc;
537 cmd->command_orb_dma = dma_map_single(hi->host->device.parent, 537
538 &cmd->command_orb, 538 cmd->command_orb_dma =
539 sizeof(struct sbp2_command_orb), 539 dma_map_single(dmadev, &cmd->command_orb,
540 DMA_TO_DEVICE); 540 sizeof(struct sbp2_command_orb),
541 cmd->sge_dma = dma_map_single(hi->host->device.parent, 541 DMA_TO_DEVICE);
542 &cmd->scatter_gather_element, 542 if (dma_mapping_error(dmadev, cmd->command_orb_dma))
543 sizeof(cmd->scatter_gather_element), 543 goto failed_orb;
544 DMA_TO_DEVICE); 544
545 cmd->sge_dma =
546 dma_map_single(dmadev, &cmd->scatter_gather_element,
547 sizeof(cmd->scatter_gather_element),
548 DMA_TO_DEVICE);
549 if (dma_mapping_error(dmadev, cmd->sge_dma))
550 goto failed_sge;
551
545 INIT_LIST_HEAD(&cmd->list); 552 INIT_LIST_HEAD(&cmd->list);
546 list_add_tail(&cmd->list, &lu->cmd_orb_completed); 553 list_add_tail(&cmd->list, &lu->cmd_orb_completed);
547 } 554 }
548 return 0; 555 return 0;
556
557failed_sge:
558 dma_unmap_single(dmadev, cmd->command_orb_dma,
559 sizeof(struct sbp2_command_orb), DMA_TO_DEVICE);
560failed_orb:
561 kfree(cmd);
562failed_alloc:
563 return -ENOMEM;
549} 564}
550 565
551static void sbp2util_remove_command_orb_pool(struct sbp2_lu *lu, 566static void sbp2util_remove_command_orb_pool(struct sbp2_lu *lu,
@@ -641,24 +656,11 @@ static struct sbp2_command_info *sbp2util_allocate_command_orb(
641static void sbp2util_mark_command_completed(struct sbp2_lu *lu, 656static void sbp2util_mark_command_completed(struct sbp2_lu *lu,
642 struct sbp2_command_info *cmd) 657 struct sbp2_command_info *cmd)
643{ 658{
644 struct hpsb_host *host = lu->ud->ne->host; 659 if (scsi_sg_count(cmd->Current_SCpnt))
645 660 dma_unmap_sg(lu->ud->ne->host->device.parent,
646 if (cmd->cmd_dma) { 661 scsi_sglist(cmd->Current_SCpnt),
647 if (cmd->dma_type == CMD_DMA_SINGLE) 662 scsi_sg_count(cmd->Current_SCpnt),
648 dma_unmap_single(host->device.parent, cmd->cmd_dma, 663 cmd->Current_SCpnt->sc_data_direction);
649 cmd->dma_size, cmd->dma_dir);
650 else if (cmd->dma_type == CMD_DMA_PAGE)
651 dma_unmap_page(host->device.parent, cmd->cmd_dma,
652 cmd->dma_size, cmd->dma_dir);
653 /* XXX: Check for CMD_DMA_NONE bug */
654 cmd->dma_type = CMD_DMA_NONE;
655 cmd->cmd_dma = 0;
656 }
657 if (cmd->sge_buffer) {
658 dma_unmap_sg(host->device.parent, cmd->sge_buffer,
659 cmd->dma_size, cmd->dma_dir);
660 cmd->sge_buffer = NULL;
661 }
662 list_move_tail(&cmd->list, &lu->cmd_orb_completed); 664 list_move_tail(&cmd->list, &lu->cmd_orb_completed);
663} 665}
664 666
@@ -823,6 +825,10 @@ static struct sbp2_lu *sbp2_alloc_device(struct unit_directory *ud)
823#endif 825#endif
824 } 826 }
825 827
828 if (dma_get_max_seg_size(hi->host->device.parent) > SBP2_MAX_SEG_SIZE)
829 BUG_ON(dma_set_max_seg_size(hi->host->device.parent,
830 SBP2_MAX_SEG_SIZE));
831
826 /* Prevent unloading of the 1394 host */ 832 /* Prevent unloading of the 1394 host */
827 if (!try_module_get(hi->host->driver->owner)) { 833 if (!try_module_get(hi->host->driver->owner)) {
828 SBP2_ERR("failed to get a reference on 1394 host driver"); 834 SBP2_ERR("failed to get a reference on 1394 host driver");
@@ -1494,84 +1500,65 @@ static int sbp2_agent_reset(struct sbp2_lu *lu, int wait)
1494 return 0; 1500 return 0;
1495} 1501}
1496 1502
1497static void sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb, 1503static int sbp2_prep_command_orb_sg(struct sbp2_command_orb *orb,
1498 struct sbp2_fwhost_info *hi, 1504 struct sbp2_fwhost_info *hi,
1499 struct sbp2_command_info *cmd, 1505 struct sbp2_command_info *cmd,
1500 unsigned int scsi_use_sg, 1506 unsigned int sg_count,
1501 struct scatterlist *sg, 1507 struct scatterlist *sg,
1502 u32 orb_direction, 1508 u32 orb_direction,
1503 enum dma_data_direction dma_dir) 1509 enum dma_data_direction dma_dir)
1504{ 1510{
1505 cmd->dma_dir = dma_dir; 1511 struct device *dmadev = hi->host->device.parent;
1512 struct sbp2_unrestricted_page_table *pt;
1513 int i, n;
1514
1515 n = dma_map_sg(dmadev, sg, sg_count, dma_dir);
1516 if (n == 0)
1517 return -ENOMEM;
1518
1506 orb->data_descriptor_hi = ORB_SET_NODE_ID(hi->host->node_id); 1519 orb->data_descriptor_hi = ORB_SET_NODE_ID(hi->host->node_id);
1507 orb->misc |= ORB_SET_DIRECTION(orb_direction); 1520 orb->misc |= ORB_SET_DIRECTION(orb_direction);
1508 1521
1509 /* special case if only one element (and less than 64KB in size) */ 1522 /* special case if only one element (and less than 64KB in size) */
1510 if (scsi_use_sg == 1 && sg->length <= SBP2_MAX_SG_ELEMENT_LENGTH) { 1523 if (n == 1) {
1511 1524 orb->misc |= ORB_SET_DATA_SIZE(sg_dma_len(sg));
1512 cmd->dma_size = sg->length; 1525 orb->data_descriptor_lo = sg_dma_address(sg);
1513 cmd->dma_type = CMD_DMA_PAGE;
1514 cmd->cmd_dma = dma_map_page(hi->host->device.parent,
1515 sg_page(sg), sg->offset,
1516 cmd->dma_size, cmd->dma_dir);
1517
1518 orb->data_descriptor_lo = cmd->cmd_dma;
1519 orb->misc |= ORB_SET_DATA_SIZE(cmd->dma_size);
1520
1521 } else { 1526 } else {
1522 struct sbp2_unrestricted_page_table *sg_element = 1527 pt = &cmd->scatter_gather_element[0];
1523 &cmd->scatter_gather_element[0];
1524 u32 sg_count, sg_len;
1525 dma_addr_t sg_addr;
1526 int i, count = dma_map_sg(hi->host->device.parent, sg,
1527 scsi_use_sg, dma_dir);
1528
1529 cmd->dma_size = scsi_use_sg;
1530 cmd->sge_buffer = sg;
1531
1532 /* use page tables (s/g) */
1533 orb->misc |= ORB_SET_PAGE_TABLE_PRESENT(0x1);
1534 orb->data_descriptor_lo = cmd->sge_dma;
1535 1528
1536 /* loop through and fill out our SBP-2 page tables 1529 dma_sync_single_for_cpu(dmadev, cmd->sge_dma,
1537 * (and split up anything too large) */ 1530 sizeof(cmd->scatter_gather_element),
1538 for (i = 0, sg_count = 0; i < count; i++, sg = sg_next(sg)) { 1531 DMA_TO_DEVICE);
1539 sg_len = sg_dma_len(sg); 1532
1540 sg_addr = sg_dma_address(sg); 1533 for_each_sg(sg, sg, n, i) {
1541 while (sg_len) { 1534 pt[i].high = cpu_to_be32(sg_dma_len(sg) << 16);
1542 sg_element[sg_count].segment_base_lo = sg_addr; 1535 pt[i].low = cpu_to_be32(sg_dma_address(sg));
1543 if (sg_len > SBP2_MAX_SG_ELEMENT_LENGTH) {
1544 sg_element[sg_count].length_segment_base_hi =
1545 PAGE_TABLE_SET_SEGMENT_LENGTH(SBP2_MAX_SG_ELEMENT_LENGTH);
1546 sg_addr += SBP2_MAX_SG_ELEMENT_LENGTH;
1547 sg_len -= SBP2_MAX_SG_ELEMENT_LENGTH;
1548 } else {
1549 sg_element[sg_count].length_segment_base_hi =
1550 PAGE_TABLE_SET_SEGMENT_LENGTH(sg_len);
1551 sg_len = 0;
1552 }
1553 sg_count++;
1554 }
1555 } 1536 }
1556 1537
1557 orb->misc |= ORB_SET_DATA_SIZE(sg_count); 1538 orb->misc |= ORB_SET_PAGE_TABLE_PRESENT(0x1) |
1539 ORB_SET_DATA_SIZE(n);
1540 orb->data_descriptor_lo = cmd->sge_dma;
1558 1541
1559 sbp2util_cpu_to_be32_buffer(sg_element, 1542 dma_sync_single_for_device(dmadev, cmd->sge_dma,
1560 (sizeof(struct sbp2_unrestricted_page_table)) * 1543 sizeof(cmd->scatter_gather_element),
1561 sg_count); 1544 DMA_TO_DEVICE);
1562 } 1545 }
1546 return 0;
1563} 1547}
1564 1548
1565static void sbp2_create_command_orb(struct sbp2_lu *lu, 1549static int sbp2_create_command_orb(struct sbp2_lu *lu,
1566 struct sbp2_command_info *cmd, 1550 struct sbp2_command_info *cmd,
1567 struct scsi_cmnd *SCpnt) 1551 struct scsi_cmnd *SCpnt)
1568{ 1552{
1569 struct sbp2_fwhost_info *hi = lu->hi; 1553 struct device *dmadev = lu->hi->host->device.parent;
1570 struct sbp2_command_orb *orb = &cmd->command_orb; 1554 struct sbp2_command_orb *orb = &cmd->command_orb;
1571 u32 orb_direction;
1572 unsigned int scsi_request_bufflen = scsi_bufflen(SCpnt); 1555 unsigned int scsi_request_bufflen = scsi_bufflen(SCpnt);
1573 enum dma_data_direction dma_dir = SCpnt->sc_data_direction; 1556 enum dma_data_direction dma_dir = SCpnt->sc_data_direction;
1557 u32 orb_direction;
1558 int ret;
1574 1559
1560 dma_sync_single_for_cpu(dmadev, cmd->command_orb_dma,
1561 sizeof(struct sbp2_command_orb), DMA_TO_DEVICE);
1575 /* 1562 /*
1576 * Set-up our command ORB. 1563 * Set-up our command ORB.
1577 * 1564 *
@@ -1602,15 +1589,21 @@ static void sbp2_create_command_orb(struct sbp2_lu *lu,
1602 orb->data_descriptor_hi = 0x0; 1589 orb->data_descriptor_hi = 0x0;
1603 orb->data_descriptor_lo = 0x0; 1590 orb->data_descriptor_lo = 0x0;
1604 orb->misc |= ORB_SET_DIRECTION(1); 1591 orb->misc |= ORB_SET_DIRECTION(1);
1605 } else 1592 ret = 0;
1606 sbp2_prep_command_orb_sg(orb, hi, cmd, scsi_sg_count(SCpnt), 1593 } else {
1607 scsi_sglist(SCpnt), 1594 ret = sbp2_prep_command_orb_sg(orb, lu->hi, cmd,
1608 orb_direction, dma_dir); 1595 scsi_sg_count(SCpnt),
1609 1596 scsi_sglist(SCpnt),
1597 orb_direction, dma_dir);
1598 }
1610 sbp2util_cpu_to_be32_buffer(orb, sizeof(*orb)); 1599 sbp2util_cpu_to_be32_buffer(orb, sizeof(*orb));
1611 1600
1612 memset(orb->cdb, 0, sizeof(orb->cdb)); 1601 memset(orb->cdb, 0, sizeof(orb->cdb));
1613 memcpy(orb->cdb, SCpnt->cmnd, SCpnt->cmd_len); 1602 memcpy(orb->cdb, SCpnt->cmnd, SCpnt->cmd_len);
1603
1604 dma_sync_single_for_device(dmadev, cmd->command_orb_dma,
1605 sizeof(struct sbp2_command_orb), DMA_TO_DEVICE);
1606 return ret;
1614} 1607}
1615 1608
1616static void sbp2_link_orb_command(struct sbp2_lu *lu, 1609static void sbp2_link_orb_command(struct sbp2_lu *lu,
@@ -1624,14 +1617,6 @@ static void sbp2_link_orb_command(struct sbp2_lu *lu,
1624 size_t length; 1617 size_t length;
1625 unsigned long flags; 1618 unsigned long flags;
1626 1619
1627 dma_sync_single_for_device(hi->host->device.parent,
1628 cmd->command_orb_dma,
1629 sizeof(struct sbp2_command_orb),
1630 DMA_TO_DEVICE);
1631 dma_sync_single_for_device(hi->host->device.parent, cmd->sge_dma,
1632 sizeof(cmd->scatter_gather_element),
1633 DMA_TO_DEVICE);
1634
1635 /* check to see if there are any previous orbs to use */ 1620 /* check to see if there are any previous orbs to use */
1636 spin_lock_irqsave(&lu->cmd_orb_lock, flags); 1621 spin_lock_irqsave(&lu->cmd_orb_lock, flags);
1637 last_orb = lu->last_orb; 1622 last_orb = lu->last_orb;
@@ -1699,9 +1684,10 @@ static int sbp2_send_command(struct sbp2_lu *lu, struct scsi_cmnd *SCpnt,
1699 if (!cmd) 1684 if (!cmd)
1700 return -EIO; 1685 return -EIO;
1701 1686
1702 sbp2_create_command_orb(lu, cmd, SCpnt); 1687 if (sbp2_create_command_orb(lu, cmd, SCpnt))
1703 sbp2_link_orb_command(lu, cmd); 1688 return -ENOMEM;
1704 1689
1690 sbp2_link_orb_command(lu, cmd);
1705 return 0; 1691 return 0;
1706} 1692}
1707 1693
@@ -1789,13 +1775,6 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid,
1789 else 1775 else
1790 cmd = sbp2util_find_command_for_orb(lu, sb->ORB_offset_lo); 1776 cmd = sbp2util_find_command_for_orb(lu, sb->ORB_offset_lo);
1791 if (cmd) { 1777 if (cmd) {
1792 dma_sync_single_for_cpu(hi->host->device.parent,
1793 cmd->command_orb_dma,
1794 sizeof(struct sbp2_command_orb),
1795 DMA_TO_DEVICE);
1796 dma_sync_single_for_cpu(hi->host->device.parent, cmd->sge_dma,
1797 sizeof(cmd->scatter_gather_element),
1798 DMA_TO_DEVICE);
1799 /* Grab SCSI command pointers and check status. */ 1778 /* Grab SCSI command pointers and check status. */
1800 /* 1779 /*
1801 * FIXME: If the src field in the status is 1, the ORB DMA must 1780 * FIXME: If the src field in the status is 1, the ORB DMA must
@@ -1912,7 +1891,6 @@ done:
1912 1891
1913static void sbp2scsi_complete_all_commands(struct sbp2_lu *lu, u32 status) 1892static void sbp2scsi_complete_all_commands(struct sbp2_lu *lu, u32 status)
1914{ 1893{
1915 struct sbp2_fwhost_info *hi = lu->hi;
1916 struct list_head *lh; 1894 struct list_head *lh;
1917 struct sbp2_command_info *cmd; 1895 struct sbp2_command_info *cmd;
1918 unsigned long flags; 1896 unsigned long flags;
@@ -1921,13 +1899,6 @@ static void sbp2scsi_complete_all_commands(struct sbp2_lu *lu, u32 status)
1921 while (!list_empty(&lu->cmd_orb_inuse)) { 1899 while (!list_empty(&lu->cmd_orb_inuse)) {
1922 lh = lu->cmd_orb_inuse.next; 1900 lh = lu->cmd_orb_inuse.next;
1923 cmd = list_entry(lh, struct sbp2_command_info, list); 1901 cmd = list_entry(lh, struct sbp2_command_info, list);
1924 dma_sync_single_for_cpu(hi->host->device.parent,
1925 cmd->command_orb_dma,
1926 sizeof(struct sbp2_command_orb),
1927 DMA_TO_DEVICE);
1928 dma_sync_single_for_cpu(hi->host->device.parent, cmd->sge_dma,
1929 sizeof(cmd->scatter_gather_element),
1930 DMA_TO_DEVICE);
1931 sbp2util_mark_command_completed(lu, cmd); 1902 sbp2util_mark_command_completed(lu, cmd);
1932 if (cmd->Current_SCpnt) { 1903 if (cmd->Current_SCpnt) {
1933 cmd->Current_SCpnt->result = status << 16; 1904 cmd->Current_SCpnt->result = status << 16;
@@ -2033,6 +2004,8 @@ static int sbp2scsi_slave_configure(struct scsi_device *sdev)
2033 sdev->start_stop_pwr_cond = 1; 2004 sdev->start_stop_pwr_cond = 1;
2034 if (lu->workarounds & SBP2_WORKAROUND_128K_MAX_TRANS) 2005 if (lu->workarounds & SBP2_WORKAROUND_128K_MAX_TRANS)
2035 blk_queue_max_sectors(sdev->request_queue, 128 * 1024 / 512); 2006 blk_queue_max_sectors(sdev->request_queue, 128 * 1024 / 512);
2007
2008 blk_queue_max_segment_size(sdev->request_queue, SBP2_MAX_SEG_SIZE);
2036 return 0; 2009 return 0;
2037} 2010}
2038 2011
@@ -2049,7 +2022,6 @@ static void sbp2scsi_slave_destroy(struct scsi_device *sdev)
2049static int sbp2scsi_abort(struct scsi_cmnd *SCpnt) 2022static int sbp2scsi_abort(struct scsi_cmnd *SCpnt)
2050{ 2023{
2051 struct sbp2_lu *lu = (struct sbp2_lu *)SCpnt->device->host->hostdata[0]; 2024 struct sbp2_lu *lu = (struct sbp2_lu *)SCpnt->device->host->hostdata[0];
2052 struct sbp2_fwhost_info *hi = lu->hi;
2053 struct sbp2_command_info *cmd; 2025 struct sbp2_command_info *cmd;
2054 unsigned long flags; 2026 unsigned long flags;
2055 2027
@@ -2063,14 +2035,6 @@ static int sbp2scsi_abort(struct scsi_cmnd *SCpnt)
2063 spin_lock_irqsave(&lu->cmd_orb_lock, flags); 2035 spin_lock_irqsave(&lu->cmd_orb_lock, flags);
2064 cmd = sbp2util_find_command_for_SCpnt(lu, SCpnt); 2036 cmd = sbp2util_find_command_for_SCpnt(lu, SCpnt);
2065 if (cmd) { 2037 if (cmd) {
2066 dma_sync_single_for_cpu(hi->host->device.parent,
2067 cmd->command_orb_dma,
2068 sizeof(struct sbp2_command_orb),
2069 DMA_TO_DEVICE);
2070 dma_sync_single_for_cpu(hi->host->device.parent,
2071 cmd->sge_dma,
2072 sizeof(cmd->scatter_gather_element),
2073 DMA_TO_DEVICE);
2074 sbp2util_mark_command_completed(lu, cmd); 2038 sbp2util_mark_command_completed(lu, cmd);
2075 if (cmd->Current_SCpnt) { 2039 if (cmd->Current_SCpnt) {
2076 cmd->Current_SCpnt->result = DID_ABORT << 16; 2040 cmd->Current_SCpnt->result = DID_ABORT << 16;