Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 37277
b: refs/heads/master
c: cc07818
h: refs/heads/master
i:
  37275: e07b233
v: v3
  • Loading branch information
Stefan Richter committed Sep 17, 2006
1 parent 7d3bcfc commit 7fc484f
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 56 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9154df538fa044ac2b729ae5c6c47cae09e6977f
refs/heads/master: cc078189125db84a85a3bbb82df788b84fc68aa1
101 changes: 48 additions & 53 deletions trunk/drivers/ieee1394/sbp2.c
Original file line number Diff line number Diff line change
Expand Up @@ -1705,6 +1705,7 @@ static int sbp2_agent_reset(struct scsi_id_instance_data *scsi_id, int wait)
quadlet_t data;
u64 addr;
int retval;
unsigned long flags;

SBP2_DEBUG_ENTER();

Expand All @@ -1724,7 +1725,9 @@ static int sbp2_agent_reset(struct scsi_id_instance_data *scsi_id, int wait)
/*
* Need to make sure orb pointer is written on next command
*/
spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags);
scsi_id->last_orb = NULL;
spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags);

return 0;
}
Expand Down Expand Up @@ -1966,8 +1969,12 @@ static int sbp2_link_orb_command(struct scsi_id_instance_data *scsi_id,
{
struct sbp2scsi_host_info *hi = scsi_id->hi;
struct sbp2_command_orb *command_orb = &command->command_orb;
struct node_entry *ne = scsi_id->ne;
u64 addr;
struct sbp2_command_orb *last_orb;
dma_addr_t last_orb_dma;
u64 addr = scsi_id->sbp2_command_block_agent_addr;
quadlet_t data[2];
size_t length;
unsigned long flags;

outstanding_orb_incr;
SBP2_ORB_DEBUG("sending command orb %p, total orbs = %x",
Expand All @@ -1982,64 +1989,50 @@ static int sbp2_link_orb_command(struct scsi_id_instance_data *scsi_id,
/*
* Check to see if there are any previous orbs to use
*/
if (scsi_id->last_orb == NULL) {
quadlet_t data[2];

spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags);
last_orb = scsi_id->last_orb;
last_orb_dma = scsi_id->last_orb_dma;
if (!last_orb) {
/*
* Ok, let's write to the target's management agent register
* last_orb == NULL means: We know that the target's fetch agent
* is not active right now.
*/
addr = scsi_id->sbp2_command_block_agent_addr + SBP2_ORB_POINTER_OFFSET;
addr += SBP2_ORB_POINTER_OFFSET;
data[0] = ORB_SET_NODE_ID(hi->host->node_id);
data[1] = command->command_orb_dma;
sbp2util_cpu_to_be32_buffer(data, 8);

SBP2_ORB_DEBUG("write command agent, command orb %p", command_orb);

if (sbp2util_node_write_no_wait(ne, addr, data, 8) < 0) {
SBP2_ERR("sbp2util_node_write_no_wait failed.\n");
return -EIO;
}

SBP2_ORB_DEBUG("write command agent complete");

scsi_id->last_orb = command_orb;
scsi_id->last_orb_dma = command->command_orb_dma;

length = 8;
} else {
quadlet_t data;

/*
* We have an orb already sent (maybe or maybe not
* processed) that we can append this orb to. So do so,
* and ring the doorbell. Have to be very careful
* modifying these next orb pointers, as they are accessed
* both by the sbp2 device and us.
* last_orb != NULL means: We know that the target's fetch agent
* is (very probably) not dead or in reset state right now.
* We have an ORB already sent that we can append a new one to.
* The target's fetch agent may or may not have read this
* previous ORB yet.
*/
scsi_id->last_orb->next_ORB_lo =
cpu_to_be32(command->command_orb_dma);
pci_dma_sync_single_for_cpu(hi->host->pdev, last_orb_dma,
sizeof(struct sbp2_command_orb),
PCI_DMA_BIDIRECTIONAL);
last_orb->next_ORB_lo = cpu_to_be32(command->command_orb_dma);
wmb();
/* Tells hardware that this pointer is valid */
scsi_id->last_orb->next_ORB_hi = 0x0;
pci_dma_sync_single_for_device(hi->host->pdev,
scsi_id->last_orb_dma,
last_orb->next_ORB_hi = 0;
pci_dma_sync_single_for_device(hi->host->pdev, last_orb_dma,
sizeof(struct sbp2_command_orb),
PCI_DMA_BIDIRECTIONAL);
addr += SBP2_DOORBELL_OFFSET;
data[0] = 0;
length = 4;
}
scsi_id->last_orb = command_orb;
scsi_id->last_orb_dma = command->command_orb_dma;
spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags);

/*
* Ring the doorbell
*/
data = cpu_to_be32(command->command_orb_dma);
addr = scsi_id->sbp2_command_block_agent_addr + SBP2_DOORBELL_OFFSET;

SBP2_ORB_DEBUG("ring doorbell, command orb %p", command_orb);

if (sbp2util_node_write_no_wait(ne, addr, &data, 4) < 0) {
SBP2_ERR("sbp2util_node_write_no_wait failed");
return -EIO;
}

scsi_id->last_orb = command_orb;
scsi_id->last_orb_dma = command->command_orb_dma;

SBP2_ORB_DEBUG("write to %s register, command orb %p",
last_orb ? "DOORBELL" : "ORB_POINTER", command_orb);
if (sbp2util_node_write_no_wait(scsi_id->ne, addr, data, length) < 0) {
SBP2_ERR("sbp2util_node_write_no_wait failed.\n");
return -EIO;
}
return 0;
}
Expand Down Expand Up @@ -2231,14 +2224,16 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest
}

/*
* Check here to see if there are no commands in-use. If there are none, we can
* null out last orb so that next time around we write directly to the orb pointer...
* Quick start saves one 1394 bus transaction.
* Check here to see if there are no commands in-use. If there
* are none, we know that the fetch agent left the active state
* _and_ that we did not reactivate it yet. Therefore clear
* last_orb so that next time we write directly to the
* ORB_POINTER register. That way the fetch agent does not need
* to refetch the next_ORB.
*/
spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags);
if (list_empty(&scsi_id->sbp2_command_orb_inuse)) {
if (list_empty(&scsi_id->sbp2_command_orb_inuse))
scsi_id->last_orb = NULL;
}
spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags);

} else {
Expand Down
4 changes: 2 additions & 2 deletions trunk/drivers/ieee1394/sbp2.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,8 @@
#define ORB_SET_DIRECTION(value) ((value & 0x1) << 27)

struct sbp2_command_orb {
volatile u32 next_ORB_hi;
volatile u32 next_ORB_lo;
u32 next_ORB_hi;
u32 next_ORB_lo;
u32 data_descriptor_hi;
u32 data_descriptor_lo;
u32 misc;
Expand Down

0 comments on commit 7fc484f

Please sign in to comment.