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) | |||
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 | */ |
2117 | static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int destid, | 2102 | static 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); |