diff options
| -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); |
