diff options
| -rw-r--r-- | drivers/ieee1394/sbp2.c | 70 | ||||
| -rw-r--r-- | drivers/ieee1394/sbp2.h | 14 |
2 files changed, 38 insertions, 46 deletions
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c index c6776909747a..07030be0ef2a 100644 --- a/drivers/ieee1394/sbp2.c +++ b/drivers/ieee1394/sbp2.c | |||
| @@ -1201,11 +1201,8 @@ static int sbp2_query_logins(struct scsi_id_instance_data *scsi_id) | |||
| 1201 | return -EIO; | 1201 | return -EIO; |
| 1202 | } | 1202 | } |
| 1203 | 1203 | ||
| 1204 | if (STATUS_GET_RESP(scsi_id->status_block.ORB_offset_hi_misc) || | 1204 | if (STATUS_TEST_RDS(scsi_id->status_block.ORB_offset_hi_misc)) { |
| 1205 | STATUS_GET_DEAD_BIT(scsi_id->status_block.ORB_offset_hi_misc) || | 1205 | SBP2_INFO("Error querying logins to SBP-2 device - failed"); |
| 1206 | STATUS_GET_SBP_STATUS(scsi_id->status_block.ORB_offset_hi_misc)) { | ||
| 1207 | |||
| 1208 | SBP2_INFO("Error querying logins to SBP-2 device - timed out"); | ||
| 1209 | return -EIO; | 1206 | return -EIO; |
| 1210 | } | 1207 | } |
| 1211 | 1208 | ||
| @@ -1298,18 +1295,12 @@ static int sbp2_login_device(struct scsi_id_instance_data *scsi_id) | |||
| 1298 | * Sanity. Make sure status returned matches login orb. | 1295 | * Sanity. Make sure status returned matches login orb. |
| 1299 | */ | 1296 | */ |
| 1300 | if (scsi_id->status_block.ORB_offset_lo != scsi_id->login_orb_dma) { | 1297 | if (scsi_id->status_block.ORB_offset_lo != scsi_id->login_orb_dma) { |
| 1301 | SBP2_ERR("Error logging into SBP-2 device - login timed-out"); | 1298 | SBP2_ERR("Error logging into SBP-2 device - timed out"); |
| 1302 | return -EIO; | 1299 | return -EIO; |
| 1303 | } | 1300 | } |
| 1304 | 1301 | ||
| 1305 | /* | 1302 | if (STATUS_TEST_RDS(scsi_id->status_block.ORB_offset_hi_misc)) { |
| 1306 | * Check status | 1303 | SBP2_ERR("Error logging into SBP-2 device - failed"); |
| 1307 | */ | ||
| 1308 | if (STATUS_GET_RESP(scsi_id->status_block.ORB_offset_hi_misc) || | ||
| 1309 | STATUS_GET_DEAD_BIT(scsi_id->status_block.ORB_offset_hi_misc) || | ||
| 1310 | STATUS_GET_SBP_STATUS(scsi_id->status_block.ORB_offset_hi_misc)) { | ||
| 1311 | |||
| 1312 | SBP2_ERR("Error logging into SBP-2 device - login failed"); | ||
| 1313 | return -EIO; | 1304 | return -EIO; |
| 1314 | } | 1305 | } |
| 1315 | 1306 | ||
| @@ -1333,9 +1324,7 @@ static int sbp2_login_device(struct scsi_id_instance_data *scsi_id) | |||
| 1333 | scsi_id->sbp2_command_block_agent_addr &= 0x0000ffffffffffffULL; | 1324 | scsi_id->sbp2_command_block_agent_addr &= 0x0000ffffffffffffULL; |
| 1334 | 1325 | ||
| 1335 | SBP2_INFO("Logged into SBP-2 device"); | 1326 | SBP2_INFO("Logged into SBP-2 device"); |
| 1336 | |||
| 1337 | return 0; | 1327 | return 0; |
| 1338 | |||
| 1339 | } | 1328 | } |
| 1340 | 1329 | ||
| 1341 | /* | 1330 | /* |
| @@ -1466,25 +1455,17 @@ static int sbp2_reconnect_device(struct scsi_id_instance_data *scsi_id) | |||
| 1466 | * Sanity. Make sure status returned matches reconnect orb. | 1455 | * Sanity. Make sure status returned matches reconnect orb. |
| 1467 | */ | 1456 | */ |
| 1468 | if (scsi_id->status_block.ORB_offset_lo != scsi_id->reconnect_orb_dma) { | 1457 | if (scsi_id->status_block.ORB_offset_lo != scsi_id->reconnect_orb_dma) { |
| 1469 | SBP2_ERR("Error reconnecting to SBP-2 device - reconnect timed-out"); | 1458 | SBP2_ERR("Error reconnecting to SBP-2 device - timed out"); |
| 1470 | return -EIO; | 1459 | return -EIO; |
| 1471 | } | 1460 | } |
| 1472 | 1461 | ||
| 1473 | /* | 1462 | if (STATUS_TEST_RDS(scsi_id->status_block.ORB_offset_hi_misc)) { |
| 1474 | * Check status | 1463 | SBP2_ERR("Error reconnecting to SBP-2 device - failed"); |
| 1475 | */ | ||
| 1476 | if (STATUS_GET_RESP(scsi_id->status_block.ORB_offset_hi_misc) || | ||
| 1477 | STATUS_GET_DEAD_BIT(scsi_id->status_block.ORB_offset_hi_misc) || | ||
| 1478 | STATUS_GET_SBP_STATUS(scsi_id->status_block.ORB_offset_hi_misc)) { | ||
| 1479 | |||
| 1480 | SBP2_ERR("Error reconnecting to SBP-2 device - reconnect failed"); | ||
| 1481 | return -EIO; | 1464 | return -EIO; |
| 1482 | } | 1465 | } |
| 1483 | 1466 | ||
| 1484 | HPSB_DEBUG("Reconnected to SBP-2 device"); | 1467 | HPSB_DEBUG("Reconnected to SBP-2 device"); |
| 1485 | |||
| 1486 | return 0; | 1468 | return 0; |
| 1487 | |||
| 1488 | } | 1469 | } |
| 1489 | 1470 | ||
| 1490 | /* | 1471 | /* |
| @@ -2115,18 +2096,19 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, | |||
| 2115 | 2096 | ||
| 2116 | sbp2util_packet_dump(data, length, "sbp2 status write by device", (u32)addr); | 2097 | sbp2util_packet_dump(data, length, "sbp2 status write by device", (u32)addr); |
| 2117 | 2098 | ||
| 2118 | if (!host) { | 2099 | if (unlikely(length < 8 || length > sizeof(struct sbp2_status_block))) { |
| 2100 | SBP2_ERR("Wrong size of status block"); | ||
| 2101 | return RCODE_ADDRESS_ERROR; | ||
| 2102 | } | ||
| 2103 | if (unlikely(!host)) { | ||
| 2119 | SBP2_ERR("host is NULL - this is bad!"); | 2104 | SBP2_ERR("host is NULL - this is bad!"); |
| 2120 | return RCODE_ADDRESS_ERROR; | 2105 | return RCODE_ADDRESS_ERROR; |
| 2121 | } | 2106 | } |
| 2122 | |||
| 2123 | hi = hpsb_get_hostinfo(&sbp2_highlevel, host); | 2107 | hi = hpsb_get_hostinfo(&sbp2_highlevel, host); |
| 2124 | 2108 | if (unlikely(!hi)) { | |
| 2125 | if (!hi) { | ||
| 2126 | SBP2_ERR("host info is NULL - this is bad!"); | 2109 | SBP2_ERR("host info is NULL - this is bad!"); |
| 2127 | return RCODE_ADDRESS_ERROR; | 2110 | return RCODE_ADDRESS_ERROR; |
| 2128 | } | 2111 | } |
| 2129 | |||
| 2130 | /* | 2112 | /* |
| 2131 | * Find our scsi_id structure by looking at the status fifo address | 2113 | * Find our scsi_id structure by looking at the status fifo address |
| 2132 | * written to by the sbp2 device. | 2114 | * written to by the sbp2 device. |
| @@ -2138,8 +2120,7 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, | |||
| 2138 | break; | 2120 | break; |
| 2139 | } | 2121 | } |
| 2140 | } | 2122 | } |
| 2141 | 2123 | if (unlikely(!scsi_id)) { | |
| 2142 | if (!scsi_id) { | ||
| 2143 | SBP2_ERR("scsi_id is NULL - device is gone?"); | 2124 | SBP2_ERR("scsi_id is NULL - device is gone?"); |
| 2144 | return RCODE_ADDRESS_ERROR; | 2125 | return RCODE_ADDRESS_ERROR; |
| 2145 | } | 2126 | } |
| @@ -2156,12 +2137,14 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, | |||
| 2156 | sbp2util_be32_to_cpu_buffer(sb, 8); | 2137 | sbp2util_be32_to_cpu_buffer(sb, 8); |
| 2157 | 2138 | ||
| 2158 | /* | 2139 | /* |
| 2159 | * Handle command ORB status here if necessary. First, need to match | 2140 | * Ignore unsolicited status. Handle command ORB status. |
| 2160 | * status with command. | ||
| 2161 | */ | 2141 | */ |
| 2162 | command = sbp2util_find_command_for_orb(scsi_id, sb->ORB_offset_lo); | 2142 | if (unlikely(STATUS_GET_SRC(sb->ORB_offset_hi_misc) == 2)) |
| 2143 | command = NULL; | ||
| 2144 | else | ||
| 2145 | command = sbp2util_find_command_for_orb(scsi_id, | ||
| 2146 | sb->ORB_offset_lo); | ||
| 2163 | if (command) { | 2147 | if (command) { |
| 2164 | |||
| 2165 | SBP2_DEBUG("Found status for command ORB"); | 2148 | SBP2_DEBUG("Found status for command ORB"); |
| 2166 | pci_dma_sync_single_for_cpu(hi->host->pdev, command->command_orb_dma, | 2149 | pci_dma_sync_single_for_cpu(hi->host->pdev, command->command_orb_dma, |
| 2167 | sizeof(struct sbp2_command_orb), | 2150 | sizeof(struct sbp2_command_orb), |
| @@ -2177,16 +2160,23 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, | |||
| 2177 | * Matched status with command, now grab scsi command pointers | 2160 | * Matched status with command, now grab scsi command pointers |
| 2178 | * and check status. | 2161 | * and check status. |
| 2179 | */ | 2162 | */ |
| 2163 | /* | ||
| 2164 | * FIXME: If the src field in the status is 1, the ORB DMA must | ||
| 2165 | * not be reused until status for a subsequent ORB is received. | ||
| 2166 | */ | ||
| 2180 | SCpnt = command->Current_SCpnt; | 2167 | SCpnt = command->Current_SCpnt; |
| 2181 | spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags); | 2168 | spin_lock_irqsave(&scsi_id->sbp2_command_orb_lock, flags); |
| 2182 | sbp2util_mark_command_completed(scsi_id, command); | 2169 | sbp2util_mark_command_completed(scsi_id, command); |
| 2183 | spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags); | 2170 | spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags); |
| 2184 | 2171 | ||
| 2185 | if (SCpnt) { | 2172 | if (SCpnt) { |
| 2173 | if (STATUS_TEST_RS(sb->ORB_offset_hi_misc)) | ||
| 2174 | scsi_status = | ||
| 2175 | SBP2_SCSI_STATUS_COMMAND_TERMINATED; | ||
| 2186 | /* | 2176 | /* |
| 2187 | * See if the target stored any scsi status information. | 2177 | * See if the target stored any scsi status information. |
| 2188 | */ | 2178 | */ |
| 2189 | if (STATUS_GET_LENGTH(sb->ORB_offset_hi_misc) > 1) { | 2179 | if (STATUS_GET_LEN(sb->ORB_offset_hi_misc) > 1) { |
| 2190 | SBP2_DEBUG("CHECK CONDITION"); | 2180 | SBP2_DEBUG("CHECK CONDITION"); |
| 2191 | scsi_status = sbp2_status_to_sense_data( | 2181 | scsi_status = sbp2_status_to_sense_data( |
| 2192 | (unchar *)sb, SCpnt->sense_buffer); | 2182 | (unchar *)sb, SCpnt->sense_buffer); |
| @@ -2196,7 +2186,7 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, | |||
| 2196 | * Check to see if the dead bit is set. If so, we'll | 2186 | * Check to see if the dead bit is set. If so, we'll |
| 2197 | * have to initiate a fetch agent reset. | 2187 | * have to initiate a fetch agent reset. |
| 2198 | */ | 2188 | */ |
| 2199 | if (STATUS_GET_DEAD_BIT(sb->ORB_offset_hi_misc)) { | 2189 | if (STATUS_TEST_D(sb->ORB_offset_hi_misc)) { |
| 2200 | SBP2_DEBUG("Dead bit set - " | 2190 | SBP2_DEBUG("Dead bit set - " |
| 2201 | "initiating fetch agent reset"); | 2191 | "initiating fetch agent reset"); |
| 2202 | sbp2_agent_reset(scsi_id, 0); | 2192 | sbp2_agent_reset(scsi_id, 0); |
diff --git a/drivers/ieee1394/sbp2.h b/drivers/ieee1394/sbp2.h index b17016b7cfcf..34e3d37fc79f 100644 --- a/drivers/ieee1394/sbp2.h +++ b/drivers/ieee1394/sbp2.h | |||
| @@ -180,12 +180,14 @@ struct sbp2_unrestricted_page_table { | |||
| 180 | 180 | ||
| 181 | #define SBP2_SCSI_STATUS_SELECTION_TIMEOUT 0xff | 181 | #define SBP2_SCSI_STATUS_SELECTION_TIMEOUT 0xff |
| 182 | 182 | ||
| 183 | #define STATUS_GET_ORB_OFFSET_HI(value) (value & 0xffff) | 183 | #define STATUS_GET_SRC(value) (((value) >> 30) & 0x3) |
| 184 | #define STATUS_GET_SBP_STATUS(value) ((value >> 16) & 0xff) | 184 | #define STATUS_GET_LEN(value) (((value) >> 24) & 0x7) |
| 185 | #define STATUS_GET_LENGTH(value) ((value >> 24) & 0x7) | 185 | #define STATUS_GET_ORB_OFFSET_HI(value) ((value) & 0x0000ffff) |
| 186 | #define STATUS_GET_DEAD_BIT(value) ((value >> 27) & 0x1) | 186 | #define STATUS_TEST_D(value) ((value) & 0x08000000) |
| 187 | #define STATUS_GET_RESP(value) ((value >> 28) & 0x3) | 187 | /* test 'resp' | 'sbp2_status' */ |
| 188 | #define STATUS_GET_SRC(value) ((value >> 30) & 0x3) | 188 | #define STATUS_TEST_RS(value) ((value) & 0x30ff0000) |
| 189 | /* test 'resp' | 'dead' | 'sbp2_status' */ | ||
| 190 | #define STATUS_TEST_RDS(value) ((value) & 0x38ff0000) | ||
| 189 | 191 | ||
| 190 | struct sbp2_status_block { | 192 | struct sbp2_status_block { |
| 191 | u32 ORB_offset_hi_misc; | 193 | u32 ORB_offset_hi_misc; |
