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.c80
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)
1182 "sbp2 query logins orb", scsi_id->query_logins_orb_dma); 1182 "sbp2 query logins orb", scsi_id->query_logins_orb_dma);
1183 1183
1184 memset(scsi_id->query_logins_response, 0, sizeof(struct sbp2_query_logins_response)); 1184 memset(scsi_id->query_logins_response, 0, sizeof(struct sbp2_query_logins_response));
1185 memset(&scsi_id->status_block, 0, sizeof(struct sbp2_status_block));
1186 1185
1187 data[0] = ORB_SET_NODE_ID(hi->host->node_id); 1186 data[0] = ORB_SET_NODE_ID(hi->host->node_id);
1188 data[1] = scsi_id->query_logins_orb_dma; 1187 data[1] = scsi_id->query_logins_orb_dma;
@@ -1278,7 +1277,6 @@ static int sbp2_login_device(struct scsi_id_instance_data *scsi_id)
1278 "sbp2 login orb", scsi_id->login_orb_dma); 1277 "sbp2 login orb", scsi_id->login_orb_dma);
1279 1278
1280 memset(scsi_id->login_response, 0, sizeof(struct sbp2_login_response)); 1279 memset(scsi_id->login_response, 0, sizeof(struct sbp2_login_response));
1281 memset(&scsi_id->status_block, 0, sizeof(struct sbp2_status_block));
1282 1280
1283 data[0] = ORB_SET_NODE_ID(hi->host->node_id); 1281 data[0] = ORB_SET_NODE_ID(hi->host->node_id);
1284 data[1] = scsi_id->login_orb_dma; 1282 data[1] = scsi_id->login_orb_dma;
@@ -1445,14 +1443,6 @@ static int sbp2_reconnect_device(struct scsi_id_instance_data *scsi_id)
1445 sbp2util_packet_dump(scsi_id->reconnect_orb, sizeof(struct sbp2_reconnect_orb), 1443 sbp2util_packet_dump(scsi_id->reconnect_orb, sizeof(struct sbp2_reconnect_orb),
1446 "sbp2 reconnect orb", scsi_id->reconnect_orb_dma); 1444 "sbp2 reconnect orb", scsi_id->reconnect_orb_dma);
1447 1445
1448 /*
1449 * Initialize status fifo
1450 */
1451 memset(&scsi_id->status_block, 0, sizeof(struct sbp2_status_block));
1452
1453 /*
1454 * Ok, let's write to the target's management agent register
1455 */
1456 data[0] = ORB_SET_NODE_ID(hi->host->node_id); 1446 data[0] = ORB_SET_NODE_ID(hi->host->node_id);
1457 data[1] = scsi_id->reconnect_orb_dma; 1447 data[1] = scsi_id->reconnect_orb_dma;
1458 sbp2util_cpu_to_be32_buffer(data, 8); 1448 sbp2util_cpu_to_be32_buffer(data, 8);
@@ -2069,11 +2059,6 @@ static int sbp2_send_command(struct scsi_id_instance_data *scsi_id,
2069 "sbp2 command orb", command->command_orb_dma); 2059 "sbp2 command orb", command->command_orb_dma);
2070 2060
2071 /* 2061 /*
2072 * Initialize status fifo
2073 */
2074 memset(&scsi_id->status_block, 0, sizeof(struct sbp2_status_block));
2075
2076 /*
2077 * Link up the orb, and ring the doorbell if needed 2062 * Link up the orb, and ring the doorbell if needed
2078 */ 2063 */
2079 sbp2_link_orb_command(scsi_id, command); 2064 sbp2_link_orb_command(scsi_id, command);
@@ -2114,12 +2099,14 @@ static unsigned int sbp2_status_to_sense_data(unchar *sbp2_status, unchar *sense
2114/* 2099/*
2115 * This function deals with status writes from the SBP-2 device 2100 * This function deals with status writes from the SBP-2 device
2116 */ 2101 */
2117static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int destid, 2102static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid,
2118 quadlet_t *data, u64 addr, size_t length, u16 fl) 2103 int destid, quadlet_t *data, u64 addr,
2104 size_t length, u16 fl)
2119{ 2105{
2120 struct sbp2scsi_host_info *hi; 2106 struct sbp2scsi_host_info *hi;
2121 struct scsi_id_instance_data *scsi_id = NULL, *scsi_id_tmp; 2107 struct scsi_id_instance_data *scsi_id = NULL, *scsi_id_tmp;
2122 struct scsi_cmnd *SCpnt = NULL; 2108 struct scsi_cmnd *SCpnt = NULL;
2109 struct sbp2_status_block *sb;
2123 u32 scsi_status = SBP2_SCSI_STATUS_GOOD; 2110 u32 scsi_status = SBP2_SCSI_STATUS_GOOD;
2124 struct sbp2_command_info *command; 2111 struct sbp2_command_info *command;
2125 unsigned long flags; 2112 unsigned long flags;
@@ -2158,19 +2145,21 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest
2158 } 2145 }
2159 2146
2160 /* 2147 /*
2161 * Put response into scsi_id status fifo... 2148 * Put response into scsi_id status fifo buffer. The first two bytes
2149 * come in big endian bit order. Often the target writes only a
2150 * truncated status block, minimally the first two quadlets. The rest
2151 * is implied to be zeros.
2162 */ 2152 */
2163 memcpy(&scsi_id->status_block, data, length); 2153 sb = &scsi_id->status_block;
2154 memset(sb->command_set_dependent, 0, sizeof(sb->command_set_dependent));
2155 memcpy(sb, data, length);
2156 sbp2util_be32_to_cpu_buffer(sb, 8);
2164 2157
2165 /* 2158 /*
2166 * Byte swap first two quadlets (8 bytes) of status for processing 2159 * Handle command ORB status here if necessary. First, need to match
2160 * status with command.
2167 */ 2161 */
2168 sbp2util_be32_to_cpu_buffer(&scsi_id->status_block, 8); 2162 command = sbp2util_find_command_for_orb(scsi_id, sb->ORB_offset_lo);
2169
2170 /*
2171 * Handle command ORB status here if necessary. First, need to match status with command.
2172 */
2173 command = sbp2util_find_command_for_orb(scsi_id, scsi_id->status_block.ORB_offset_lo);
2174 if (command) { 2163 if (command) {
2175 2164
2176 SBP2_DEBUG("Found status for command ORB"); 2165 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
2185 outstanding_orb_decr; 2174 outstanding_orb_decr;
2186 2175
2187 /* 2176 /*
2188 * Matched status with command, now grab scsi command pointers and check status 2177 * Matched status with command, now grab scsi command pointers
2178 * and check status.
2189 */ 2179 */
2190 SCpnt = command->Current_SCpnt; 2180 SCpnt = command->Current_SCpnt;
2191 spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags); 2181 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
2193 spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags); 2183 spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags);
2194 2184
2195 if (SCpnt) { 2185 if (SCpnt) {
2196
2197 /* 2186 /*
2198 * See if the target stored any scsi status information 2187 * See if the target stored any scsi status information.
2199 */ 2188 */
2200 if (STATUS_GET_LENGTH(scsi_id->status_block.ORB_offset_hi_misc) > 1) { 2189 if (STATUS_GET_LENGTH(sb->ORB_offset_hi_misc) > 1) {
2201 /*
2202 * Translate SBP-2 status to SCSI sense data
2203 */
2204 SBP2_DEBUG("CHECK CONDITION"); 2190 SBP2_DEBUG("CHECK CONDITION");
2205 scsi_status = sbp2_status_to_sense_data((unchar *)&scsi_id->status_block, SCpnt->sense_buffer); 2191 scsi_status = sbp2_status_to_sense_data(
2192 (unchar *)sb, SCpnt->sense_buffer);
2206 } 2193 }
2207 2194
2208 /* 2195 /*
2209 * Check to see if the dead bit is set. If so, we'll have to initiate 2196 * Check to see if the dead bit is set. If so, we'll
2210 * a fetch agent reset. 2197 * have to initiate a fetch agent reset.
2211 */ 2198 */
2212 if (STATUS_GET_DEAD_BIT(scsi_id->status_block.ORB_offset_hi_misc)) { 2199 if (STATUS_GET_DEAD_BIT(sb->ORB_offset_hi_misc)) {
2213 2200 SBP2_DEBUG("Dead bit set - "
2214 /* 2201 "initiating fetch agent reset");
2215 * Initiate a fetch agent reset.
2216 */
2217 SBP2_DEBUG("Dead bit set - initiating fetch agent reset");
2218 sbp2_agent_reset(scsi_id, 0); 2202 sbp2_agent_reset(scsi_id, 0);
2219 } 2203 }
2220 2204
@@ -2235,21 +2219,17 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest
2235 spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags); 2219 spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags);
2236 2220
2237 } else { 2221 } else {
2238
2239 /* 2222 /*
2240 * It's probably a login/logout/reconnect status. 2223 * It's probably a login/logout/reconnect status.
2241 */ 2224 */
2242 if ((scsi_id->login_orb_dma == scsi_id->status_block.ORB_offset_lo) || 2225 if ((sb->ORB_offset_lo == scsi_id->reconnect_orb_dma) ||
2243 (scsi_id->query_logins_orb_dma == scsi_id->status_block.ORB_offset_lo) || 2226 (sb->ORB_offset_lo == scsi_id->login_orb_dma) ||
2244 (scsi_id->reconnect_orb_dma == scsi_id->status_block.ORB_offset_lo) || 2227 (sb->ORB_offset_lo == scsi_id->query_logins_orb_dma) ||
2245 (scsi_id->logout_orb_dma == scsi_id->status_block.ORB_offset_lo)) { 2228 (sb->ORB_offset_lo == scsi_id->logout_orb_dma))
2246 atomic_set(&scsi_id->sbp2_login_complete, 1); 2229 atomic_set(&scsi_id->sbp2_login_complete, 1);
2247 }
2248 } 2230 }
2249 2231
2250 if (SCpnt) { 2232 if (SCpnt) {
2251
2252 /* Complete the SCSI command. */
2253 SBP2_DEBUG("Completing SCSI command"); 2233 SBP2_DEBUG("Completing SCSI command");
2254 sbp2scsi_complete_command(scsi_id, scsi_status, SCpnt, 2234 sbp2scsi_complete_command(scsi_id, scsi_status, SCpnt,
2255 command->Current_done); 2235 command->Current_done);