diff options
Diffstat (limited to 'drivers/ieee1394/sbp2.c')
-rw-r--r-- | drivers/ieee1394/sbp2.c | 80 |
1 files changed, 30 insertions, 50 deletions
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c index 11595df8b75e..c6776909747a 100644 --- a/drivers/ieee1394/sbp2.c +++ b/drivers/ieee1394/sbp2.c @@ -1182,7 +1182,6 @@ static int sbp2_query_logins(struct scsi_id_instance_data *scsi_id) "sbp2 query logins orb", scsi_id->query_logins_orb_dma); memset(scsi_id->query_logins_response, 0, sizeof(struct sbp2_query_logins_response)); - memset(&scsi_id->status_block, 0, sizeof(struct sbp2_status_block)); data[0] = ORB_SET_NODE_ID(hi->host->node_id); data[1] = scsi_id->query_logins_orb_dma; @@ -1278,7 +1277,6 @@ static int sbp2_login_device(struct scsi_id_instance_data *scsi_id) "sbp2 login orb", scsi_id->login_orb_dma); memset(scsi_id->login_response, 0, sizeof(struct sbp2_login_response)); - memset(&scsi_id->status_block, 0, sizeof(struct sbp2_status_block)); data[0] = ORB_SET_NODE_ID(hi->host->node_id); data[1] = scsi_id->login_orb_dma; @@ -1445,14 +1443,6 @@ static int sbp2_reconnect_device(struct scsi_id_instance_data *scsi_id) sbp2util_packet_dump(scsi_id->reconnect_orb, sizeof(struct sbp2_reconnect_orb), "sbp2 reconnect orb", scsi_id->reconnect_orb_dma); - /* - * Initialize status fifo - */ - memset(&scsi_id->status_block, 0, sizeof(struct sbp2_status_block)); - - /* - * Ok, let's write to the target's management agent register - */ data[0] = ORB_SET_NODE_ID(hi->host->node_id); data[1] = scsi_id->reconnect_orb_dma; sbp2util_cpu_to_be32_buffer(data, 8); @@ -2069,11 +2059,6 @@ static int sbp2_send_command(struct scsi_id_instance_data *scsi_id, "sbp2 command orb", command->command_orb_dma); /* - * Initialize status fifo - */ - memset(&scsi_id->status_block, 0, sizeof(struct sbp2_status_block)); - - /* * Link up the orb, and ring the doorbell if needed */ sbp2_link_orb_command(scsi_id, command); @@ -2114,12 +2099,14 @@ static unsigned int sbp2_status_to_sense_data(unchar *sbp2_status, unchar *sense /* * This function deals with status writes from the SBP-2 device */ -static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int destid, - quadlet_t *data, u64 addr, size_t length, u16 fl) +static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, + int destid, quadlet_t *data, u64 addr, + size_t length, u16 fl) { struct sbp2scsi_host_info *hi; struct scsi_id_instance_data *scsi_id = NULL, *scsi_id_tmp; struct scsi_cmnd *SCpnt = NULL; + struct sbp2_status_block *sb; u32 scsi_status = SBP2_SCSI_STATUS_GOOD; struct sbp2_command_info *command; unsigned long flags; @@ -2158,19 +2145,21 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest } /* - * Put response into scsi_id status fifo... + * Put response into scsi_id status fifo buffer. The first two bytes + * come in big endian bit order. Often the target writes only a + * truncated status block, minimally the first two quadlets. The rest + * is implied to be zeros. */ - memcpy(&scsi_id->status_block, data, length); + sb = &scsi_id->status_block; + memset(sb->command_set_dependent, 0, sizeof(sb->command_set_dependent)); + memcpy(sb, data, length); + sbp2util_be32_to_cpu_buffer(sb, 8); /* - * Byte swap first two quadlets (8 bytes) of status for processing + * Handle command ORB status here if necessary. First, need to match + * status with command. */ - sbp2util_be32_to_cpu_buffer(&scsi_id->status_block, 8); - - /* - * Handle command ORB status here if necessary. First, need to match status with command. - */ - command = sbp2util_find_command_for_orb(scsi_id, scsi_id->status_block.ORB_offset_lo); + command = sbp2util_find_command_for_orb(scsi_id, sb->ORB_offset_lo); if (command) { SBP2_DEBUG("Found status for command ORB"); @@ -2185,7 +2174,8 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest outstanding_orb_decr; /* - * Matched status with command, now grab scsi command pointers and check status + * Matched status with command, now grab scsi command pointers + * and check status. */ SCpnt = command->Current_SCpnt; spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags); @@ -2193,28 +2183,22 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags); if (SCpnt) { - /* - * See if the target stored any scsi status information + * See if the target stored any scsi status information. */ - if (STATUS_GET_LENGTH(scsi_id->status_block.ORB_offset_hi_misc) > 1) { - /* - * Translate SBP-2 status to SCSI sense data - */ + if (STATUS_GET_LENGTH(sb->ORB_offset_hi_misc) > 1) { SBP2_DEBUG("CHECK CONDITION"); - scsi_status = sbp2_status_to_sense_data((unchar *)&scsi_id->status_block, SCpnt->sense_buffer); + scsi_status = sbp2_status_to_sense_data( + (unchar *)sb, SCpnt->sense_buffer); } /* - * Check to see if the dead bit is set. If so, we'll have to initiate - * a fetch agent reset. + * Check to see if the dead bit is set. If so, we'll + * have to initiate a fetch agent reset. */ - if (STATUS_GET_DEAD_BIT(scsi_id->status_block.ORB_offset_hi_misc)) { - - /* - * Initiate a fetch agent reset. - */ - SBP2_DEBUG("Dead bit set - initiating fetch agent reset"); + if (STATUS_GET_DEAD_BIT(sb->ORB_offset_hi_misc)) { + SBP2_DEBUG("Dead bit set - " + "initiating fetch agent reset"); sbp2_agent_reset(scsi_id, 0); } @@ -2235,21 +2219,17 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags); } else { - /* * It's probably a login/logout/reconnect status. */ - if ((scsi_id->login_orb_dma == scsi_id->status_block.ORB_offset_lo) || - (scsi_id->query_logins_orb_dma == scsi_id->status_block.ORB_offset_lo) || - (scsi_id->reconnect_orb_dma == scsi_id->status_block.ORB_offset_lo) || - (scsi_id->logout_orb_dma == scsi_id->status_block.ORB_offset_lo)) { + if ((sb->ORB_offset_lo == scsi_id->reconnect_orb_dma) || + (sb->ORB_offset_lo == scsi_id->login_orb_dma) || + (sb->ORB_offset_lo == scsi_id->query_logins_orb_dma) || + (sb->ORB_offset_lo == scsi_id->logout_orb_dma)) atomic_set(&scsi_id->sbp2_login_complete, 1); - } } if (SCpnt) { - - /* Complete the SCSI command. */ SBP2_DEBUG("Completing SCSI command"); sbp2scsi_complete_command(scsi_id, scsi_status, SCpnt, command->Current_done); |