diff options
-rw-r--r-- | drivers/ieee1394/sbp2.c | 101 | ||||
-rw-r--r-- | drivers/ieee1394/sbp2.h | 4 |
2 files changed, 50 insertions, 55 deletions
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c index baa063c9e6e3..e312d5e2a647 100644 --- a/drivers/ieee1394/sbp2.c +++ b/drivers/ieee1394/sbp2.c | |||
@@ -1705,6 +1705,7 @@ static int sbp2_agent_reset(struct scsi_id_instance_data *scsi_id, int wait) | |||
1705 | quadlet_t data; | 1705 | quadlet_t data; |
1706 | u64 addr; | 1706 | u64 addr; |
1707 | int retval; | 1707 | int retval; |
1708 | unsigned long flags; | ||
1708 | 1709 | ||
1709 | SBP2_DEBUG_ENTER(); | 1710 | SBP2_DEBUG_ENTER(); |
1710 | 1711 | ||
@@ -1724,7 +1725,9 @@ static int sbp2_agent_reset(struct scsi_id_instance_data *scsi_id, int wait) | |||
1724 | /* | 1725 | /* |
1725 | * Need to make sure orb pointer is written on next command | 1726 | * Need to make sure orb pointer is written on next command |
1726 | */ | 1727 | */ |
1728 | spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags); | ||
1727 | scsi_id->last_orb = NULL; | 1729 | scsi_id->last_orb = NULL; |
1730 | spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags); | ||
1728 | 1731 | ||
1729 | return 0; | 1732 | return 0; |
1730 | } | 1733 | } |
@@ -1966,8 +1969,12 @@ static int sbp2_link_orb_command(struct scsi_id_instance_data *scsi_id, | |||
1966 | { | 1969 | { |
1967 | struct sbp2scsi_host_info *hi = scsi_id->hi; | 1970 | struct sbp2scsi_host_info *hi = scsi_id->hi; |
1968 | struct sbp2_command_orb *command_orb = &command->command_orb; | 1971 | struct sbp2_command_orb *command_orb = &command->command_orb; |
1969 | struct node_entry *ne = scsi_id->ne; | 1972 | struct sbp2_command_orb *last_orb; |
1970 | u64 addr; | 1973 | dma_addr_t last_orb_dma; |
1974 | u64 addr = scsi_id->sbp2_command_block_agent_addr; | ||
1975 | quadlet_t data[2]; | ||
1976 | size_t length; | ||
1977 | unsigned long flags; | ||
1971 | 1978 | ||
1972 | outstanding_orb_incr; | 1979 | outstanding_orb_incr; |
1973 | SBP2_ORB_DEBUG("sending command orb %p, total orbs = %x", | 1980 | SBP2_ORB_DEBUG("sending command orb %p, total orbs = %x", |
@@ -1982,64 +1989,50 @@ static int sbp2_link_orb_command(struct scsi_id_instance_data *scsi_id, | |||
1982 | /* | 1989 | /* |
1983 | * Check to see if there are any previous orbs to use | 1990 | * Check to see if there are any previous orbs to use |
1984 | */ | 1991 | */ |
1985 | if (scsi_id->last_orb == NULL) { | 1992 | spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags); |
1986 | quadlet_t data[2]; | 1993 | last_orb = scsi_id->last_orb; |
1987 | 1994 | last_orb_dma = scsi_id->last_orb_dma; | |
1995 | if (!last_orb) { | ||
1988 | /* | 1996 | /* |
1989 | * Ok, let's write to the target's management agent register | 1997 | * last_orb == NULL means: We know that the target's fetch agent |
1998 | * is not active right now. | ||
1990 | */ | 1999 | */ |
1991 | addr = scsi_id->sbp2_command_block_agent_addr + SBP2_ORB_POINTER_OFFSET; | 2000 | addr += SBP2_ORB_POINTER_OFFSET; |
1992 | data[0] = ORB_SET_NODE_ID(hi->host->node_id); | 2001 | data[0] = ORB_SET_NODE_ID(hi->host->node_id); |
1993 | data[1] = command->command_orb_dma; | 2002 | data[1] = command->command_orb_dma; |
1994 | sbp2util_cpu_to_be32_buffer(data, 8); | 2003 | sbp2util_cpu_to_be32_buffer(data, 8); |
1995 | 2004 | length = 8; | |
1996 | SBP2_ORB_DEBUG("write command agent, command orb %p", command_orb); | ||
1997 | |||
1998 | if (sbp2util_node_write_no_wait(ne, addr, data, 8) < 0) { | ||
1999 | SBP2_ERR("sbp2util_node_write_no_wait failed.\n"); | ||
2000 | return -EIO; | ||
2001 | } | ||
2002 | |||
2003 | SBP2_ORB_DEBUG("write command agent complete"); | ||
2004 | |||
2005 | scsi_id->last_orb = command_orb; | ||
2006 | scsi_id->last_orb_dma = command->command_orb_dma; | ||
2007 | |||
2008 | } else { | 2005 | } else { |
2009 | quadlet_t data; | ||
2010 | |||
2011 | /* | 2006 | /* |
2012 | * We have an orb already sent (maybe or maybe not | 2007 | * last_orb != NULL means: We know that the target's fetch agent |
2013 | * processed) that we can append this orb to. So do so, | 2008 | * is (very probably) not dead or in reset state right now. |
2014 | * and ring the doorbell. Have to be very careful | 2009 | * We have an ORB already sent that we can append a new one to. |
2015 | * modifying these next orb pointers, as they are accessed | 2010 | * The target's fetch agent may or may not have read this |
2016 | * both by the sbp2 device and us. | 2011 | * previous ORB yet. |
2017 | */ | 2012 | */ |
2018 | scsi_id->last_orb->next_ORB_lo = | 2013 | pci_dma_sync_single_for_cpu(hi->host->pdev, last_orb_dma, |
2019 | cpu_to_be32(command->command_orb_dma); | 2014 | sizeof(struct sbp2_command_orb), |
2015 | PCI_DMA_BIDIRECTIONAL); | ||
2016 | last_orb->next_ORB_lo = cpu_to_be32(command->command_orb_dma); | ||
2017 | wmb(); | ||
2020 | /* Tells hardware that this pointer is valid */ | 2018 | /* Tells hardware that this pointer is valid */ |
2021 | scsi_id->last_orb->next_ORB_hi = 0x0; | 2019 | last_orb->next_ORB_hi = 0; |
2022 | pci_dma_sync_single_for_device(hi->host->pdev, | 2020 | pci_dma_sync_single_for_device(hi->host->pdev, last_orb_dma, |
2023 | scsi_id->last_orb_dma, | ||
2024 | sizeof(struct sbp2_command_orb), | 2021 | sizeof(struct sbp2_command_orb), |
2025 | PCI_DMA_BIDIRECTIONAL); | 2022 | PCI_DMA_BIDIRECTIONAL); |
2023 | addr += SBP2_DOORBELL_OFFSET; | ||
2024 | data[0] = 0; | ||
2025 | length = 4; | ||
2026 | } | ||
2027 | scsi_id->last_orb = command_orb; | ||
2028 | scsi_id->last_orb_dma = command->command_orb_dma; | ||
2029 | spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags); | ||
2026 | 2030 | ||
2027 | /* | 2031 | SBP2_ORB_DEBUG("write to %s register, command orb %p", |
2028 | * Ring the doorbell | 2032 | last_orb ? "DOORBELL" : "ORB_POINTER", command_orb); |
2029 | */ | 2033 | if (sbp2util_node_write_no_wait(scsi_id->ne, addr, data, length) < 0) { |
2030 | data = cpu_to_be32(command->command_orb_dma); | 2034 | SBP2_ERR("sbp2util_node_write_no_wait failed.\n"); |
2031 | addr = scsi_id->sbp2_command_block_agent_addr + SBP2_DOORBELL_OFFSET; | 2035 | return -EIO; |
2032 | |||
2033 | SBP2_ORB_DEBUG("ring doorbell, command orb %p", command_orb); | ||
2034 | |||
2035 | if (sbp2util_node_write_no_wait(ne, addr, &data, 4) < 0) { | ||
2036 | SBP2_ERR("sbp2util_node_write_no_wait failed"); | ||
2037 | return -EIO; | ||
2038 | } | ||
2039 | |||
2040 | scsi_id->last_orb = command_orb; | ||
2041 | scsi_id->last_orb_dma = command->command_orb_dma; | ||
2042 | |||
2043 | } | 2036 | } |
2044 | return 0; | 2037 | return 0; |
2045 | } | 2038 | } |
@@ -2231,14 +2224,16 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest | |||
2231 | } | 2224 | } |
2232 | 2225 | ||
2233 | /* | 2226 | /* |
2234 | * Check here to see if there are no commands in-use. If there are none, we can | 2227 | * Check here to see if there are no commands in-use. If there |
2235 | * null out last orb so that next time around we write directly to the orb pointer... | 2228 | * are none, we know that the fetch agent left the active state |
2236 | * Quick start saves one 1394 bus transaction. | 2229 | * _and_ that we did not reactivate it yet. Therefore clear |
2230 | * last_orb so that next time we write directly to the | ||
2231 | * ORB_POINTER register. That way the fetch agent does not need | ||
2232 | * to refetch the next_ORB. | ||
2237 | */ | 2233 | */ |
2238 | spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags); | 2234 | spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags); |
2239 | if (list_empty(&scsi_id->sbp2_command_orb_inuse)) { | 2235 | if (list_empty(&scsi_id->sbp2_command_orb_inuse)) |
2240 | scsi_id->last_orb = NULL; | 2236 | scsi_id->last_orb = NULL; |
2241 | } | ||
2242 | spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags); | 2237 | spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags); |
2243 | 2238 | ||
2244 | } else { | 2239 | } else { |
diff --git a/drivers/ieee1394/sbp2.h b/drivers/ieee1394/sbp2.h index b22ce1aa8fe4..dd80906e8a92 100644 --- a/drivers/ieee1394/sbp2.h +++ b/drivers/ieee1394/sbp2.h | |||
@@ -46,8 +46,8 @@ | |||
46 | #define ORB_SET_DIRECTION(value) ((value & 0x1) << 27) | 46 | #define ORB_SET_DIRECTION(value) ((value & 0x1) << 27) |
47 | 47 | ||
48 | struct sbp2_command_orb { | 48 | struct sbp2_command_orb { |
49 | volatile u32 next_ORB_hi; | 49 | u32 next_ORB_hi; |
50 | volatile u32 next_ORB_lo; | 50 | u32 next_ORB_lo; |
51 | u32 data_descriptor_hi; | 51 | u32 data_descriptor_hi; |
52 | u32 data_descriptor_lo; | 52 | u32 data_descriptor_lo; |
53 | u32 misc; | 53 | u32 misc; |