diff options
-rw-r--r-- | drivers/ieee1394/sbp2.c | 51 | ||||
-rw-r--r-- | drivers/ieee1394/sbp2.h | 4 |
2 files changed, 24 insertions, 31 deletions
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c index 07030be0ef2a..6adbe1c796c2 100644 --- a/drivers/ieee1394/sbp2.c +++ b/drivers/ieee1394/sbp2.c | |||
@@ -55,12 +55,12 @@ | |||
55 | #include <linux/smp_lock.h> | 55 | #include <linux/smp_lock.h> |
56 | #include <linux/init.h> | 56 | #include <linux/init.h> |
57 | #include <linux/pci.h> | 57 | #include <linux/pci.h> |
58 | #include <linux/wait.h> | ||
58 | 59 | ||
59 | #include <asm/current.h> | 60 | #include <asm/current.h> |
60 | #include <asm/uaccess.h> | 61 | #include <asm/uaccess.h> |
61 | #include <asm/io.h> | 62 | #include <asm/io.h> |
62 | #include <asm/byteorder.h> | 63 | #include <asm/byteorder.h> |
63 | #include <asm/atomic.h> | ||
64 | #include <asm/system.h> | 64 | #include <asm/system.h> |
65 | #include <asm/scatterlist.h> | 65 | #include <asm/scatterlist.h> |
66 | 66 | ||
@@ -420,21 +420,23 @@ static void sbp2util_packet_dump(void *buffer, int length, char *dump_name, | |||
420 | #define sbp2util_packet_dump(w,x,y,z) | 420 | #define sbp2util_packet_dump(w,x,y,z) |
421 | #endif | 421 | #endif |
422 | 422 | ||
423 | static DECLARE_WAIT_QUEUE_HEAD(access_wq); | ||
424 | |||
423 | /* | 425 | /* |
424 | * Goofy routine that basically does a down_timeout function. | 426 | * Waits for completion of an SBP-2 access request. |
427 | * Returns nonzero if timed out or prematurely interrupted. | ||
425 | */ | 428 | */ |
426 | static int sbp2util_down_timeout(atomic_t *done, int timeout) | 429 | static int sbp2util_access_timeout(struct scsi_id_instance_data *scsi_id, |
430 | int timeout) | ||
427 | { | 431 | { |
428 | int i; | 432 | long leftover = wait_event_interruptible_timeout( |
433 | access_wq, scsi_id->access_complete, timeout); | ||
429 | 434 | ||
430 | for (i = timeout; (i > 0 && atomic_read(done) == 0); i-= HZ/10) { | 435 | scsi_id->access_complete = 0; |
431 | if (msleep_interruptible(100)) /* 100ms */ | 436 | return leftover <= 0; |
432 | return 1; | ||
433 | } | ||
434 | return (i > 0) ? 0 : 1; | ||
435 | } | 437 | } |
436 | 438 | ||
437 | /* Free's an allocated packet */ | 439 | /* Frees an allocated packet */ |
438 | static void sbp2_free_packet(struct hpsb_packet *packet) | 440 | static void sbp2_free_packet(struct hpsb_packet *packet) |
439 | { | 441 | { |
440 | hpsb_free_tlabel(packet); | 442 | hpsb_free_tlabel(packet); |
@@ -794,7 +796,6 @@ static struct scsi_id_instance_data *sbp2_alloc_device(struct unit_directory *ud | |||
794 | scsi_id->speed_code = IEEE1394_SPEED_100; | 796 | scsi_id->speed_code = IEEE1394_SPEED_100; |
795 | scsi_id->max_payload_size = sbp2_speedto_max_payload[IEEE1394_SPEED_100]; | 797 | scsi_id->max_payload_size = sbp2_speedto_max_payload[IEEE1394_SPEED_100]; |
796 | scsi_id->status_fifo_addr = CSR1212_INVALID_ADDR_SPACE; | 798 | scsi_id->status_fifo_addr = CSR1212_INVALID_ADDR_SPACE; |
797 | atomic_set(&scsi_id->sbp2_login_complete, 0); | ||
798 | INIT_LIST_HEAD(&scsi_id->sbp2_command_orb_inuse); | 799 | INIT_LIST_HEAD(&scsi_id->sbp2_command_orb_inuse); |
799 | INIT_LIST_HEAD(&scsi_id->sbp2_command_orb_completed); | 800 | INIT_LIST_HEAD(&scsi_id->sbp2_command_orb_completed); |
800 | INIT_LIST_HEAD(&scsi_id->scsi_list); | 801 | INIT_LIST_HEAD(&scsi_id->scsi_list); |
@@ -1187,11 +1188,9 @@ static int sbp2_query_logins(struct scsi_id_instance_data *scsi_id) | |||
1187 | data[1] = scsi_id->query_logins_orb_dma; | 1188 | data[1] = scsi_id->query_logins_orb_dma; |
1188 | sbp2util_cpu_to_be32_buffer(data, 8); | 1189 | sbp2util_cpu_to_be32_buffer(data, 8); |
1189 | 1190 | ||
1190 | atomic_set(&scsi_id->sbp2_login_complete, 0); | ||
1191 | |||
1192 | hpsb_node_write(scsi_id->ne, scsi_id->sbp2_management_agent_addr, data, 8); | 1191 | hpsb_node_write(scsi_id->ne, scsi_id->sbp2_management_agent_addr, data, 8); |
1193 | 1192 | ||
1194 | if (sbp2util_down_timeout(&scsi_id->sbp2_login_complete, 2*HZ)) { | 1193 | if (sbp2util_access_timeout(scsi_id, 2*HZ)) { |
1195 | SBP2_INFO("Error querying logins to SBP-2 device - timed out"); | 1194 | SBP2_INFO("Error querying logins to SBP-2 device - timed out"); |
1196 | return -EIO; | 1195 | return -EIO; |
1197 | } | 1196 | } |
@@ -1279,15 +1278,13 @@ static int sbp2_login_device(struct scsi_id_instance_data *scsi_id) | |||
1279 | data[1] = scsi_id->login_orb_dma; | 1278 | data[1] = scsi_id->login_orb_dma; |
1280 | sbp2util_cpu_to_be32_buffer(data, 8); | 1279 | sbp2util_cpu_to_be32_buffer(data, 8); |
1281 | 1280 | ||
1282 | atomic_set(&scsi_id->sbp2_login_complete, 0); | ||
1283 | |||
1284 | hpsb_node_write(scsi_id->ne, scsi_id->sbp2_management_agent_addr, data, 8); | 1281 | hpsb_node_write(scsi_id->ne, scsi_id->sbp2_management_agent_addr, data, 8); |
1285 | 1282 | ||
1286 | /* | 1283 | /* |
1287 | * Wait for login status (up to 20 seconds)... | 1284 | * Wait for login status (up to 20 seconds)... |
1288 | */ | 1285 | */ |
1289 | if (sbp2util_down_timeout(&scsi_id->sbp2_login_complete, 20*HZ)) { | 1286 | if (sbp2util_access_timeout(scsi_id, 20*HZ)) { |
1290 | SBP2_ERR("Error logging into SBP-2 device - login timed-out"); | 1287 | SBP2_ERR("Error logging into SBP-2 device - timed out"); |
1291 | return -EIO; | 1288 | return -EIO; |
1292 | } | 1289 | } |
1293 | 1290 | ||
@@ -1374,21 +1371,17 @@ static int sbp2_logout_device(struct scsi_id_instance_data *scsi_id) | |||
1374 | data[1] = scsi_id->logout_orb_dma; | 1371 | data[1] = scsi_id->logout_orb_dma; |
1375 | sbp2util_cpu_to_be32_buffer(data, 8); | 1372 | sbp2util_cpu_to_be32_buffer(data, 8); |
1376 | 1373 | ||
1377 | atomic_set(&scsi_id->sbp2_login_complete, 0); | ||
1378 | |||
1379 | error = hpsb_node_write(scsi_id->ne, | 1374 | error = hpsb_node_write(scsi_id->ne, |
1380 | scsi_id->sbp2_management_agent_addr, data, 8); | 1375 | scsi_id->sbp2_management_agent_addr, data, 8); |
1381 | if (error) | 1376 | if (error) |
1382 | return error; | 1377 | return error; |
1383 | 1378 | ||
1384 | /* Wait for device to logout...1 second. */ | 1379 | /* Wait for device to logout...1 second. */ |
1385 | if (sbp2util_down_timeout(&scsi_id->sbp2_login_complete, HZ)) | 1380 | if (sbp2util_access_timeout(scsi_id, HZ)) |
1386 | return -EIO; | 1381 | return -EIO; |
1387 | 1382 | ||
1388 | SBP2_INFO("Logged out of SBP-2 device"); | 1383 | SBP2_INFO("Logged out of SBP-2 device"); |
1389 | |||
1390 | return 0; | 1384 | return 0; |
1391 | |||
1392 | } | 1385 | } |
1393 | 1386 | ||
1394 | /* | 1387 | /* |
@@ -1436,8 +1429,6 @@ static int sbp2_reconnect_device(struct scsi_id_instance_data *scsi_id) | |||
1436 | data[1] = scsi_id->reconnect_orb_dma; | 1429 | data[1] = scsi_id->reconnect_orb_dma; |
1437 | sbp2util_cpu_to_be32_buffer(data, 8); | 1430 | sbp2util_cpu_to_be32_buffer(data, 8); |
1438 | 1431 | ||
1439 | atomic_set(&scsi_id->sbp2_login_complete, 0); | ||
1440 | |||
1441 | error = hpsb_node_write(scsi_id->ne, | 1432 | error = hpsb_node_write(scsi_id->ne, |
1442 | scsi_id->sbp2_management_agent_addr, data, 8); | 1433 | scsi_id->sbp2_management_agent_addr, data, 8); |
1443 | if (error) | 1434 | if (error) |
@@ -1446,8 +1437,8 @@ static int sbp2_reconnect_device(struct scsi_id_instance_data *scsi_id) | |||
1446 | /* | 1437 | /* |
1447 | * Wait for reconnect status (up to 1 second)... | 1438 | * Wait for reconnect status (up to 1 second)... |
1448 | */ | 1439 | */ |
1449 | if (sbp2util_down_timeout(&scsi_id->sbp2_login_complete, HZ)) { | 1440 | if (sbp2util_access_timeout(scsi_id, HZ)) { |
1450 | SBP2_ERR("Error reconnecting to SBP-2 device - reconnect timed-out"); | 1441 | SBP2_ERR("Error reconnecting to SBP-2 device - timed out"); |
1451 | return -EIO; | 1442 | return -EIO; |
1452 | } | 1443 | } |
1453 | 1444 | ||
@@ -2215,8 +2206,10 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, | |||
2215 | if ((sb->ORB_offset_lo == scsi_id->reconnect_orb_dma) || | 2206 | if ((sb->ORB_offset_lo == scsi_id->reconnect_orb_dma) || |
2216 | (sb->ORB_offset_lo == scsi_id->login_orb_dma) || | 2207 | (sb->ORB_offset_lo == scsi_id->login_orb_dma) || |
2217 | (sb->ORB_offset_lo == scsi_id->query_logins_orb_dma) || | 2208 | (sb->ORB_offset_lo == scsi_id->query_logins_orb_dma) || |
2218 | (sb->ORB_offset_lo == scsi_id->logout_orb_dma)) | 2209 | (sb->ORB_offset_lo == scsi_id->logout_orb_dma)) { |
2219 | atomic_set(&scsi_id->sbp2_login_complete, 1); | 2210 | scsi_id->access_complete = 1; |
2211 | wake_up_interruptible(&access_wq); | ||
2212 | } | ||
2220 | } | 2213 | } |
2221 | 2214 | ||
2222 | if (SCpnt) { | 2215 | if (SCpnt) { |
diff --git a/drivers/ieee1394/sbp2.h b/drivers/ieee1394/sbp2.h index 34e3d37fc79f..89098fe565e9 100644 --- a/drivers/ieee1394/sbp2.h +++ b/drivers/ieee1394/sbp2.h | |||
@@ -320,9 +320,9 @@ struct scsi_id_instance_data { | |||
320 | u64 status_fifo_addr; | 320 | u64 status_fifo_addr; |
321 | 321 | ||
322 | /* | 322 | /* |
323 | * Variable used for logins, reconnects, logouts, query logins | 323 | * Waitqueue flag for logins, reconnects, logouts, query logins |
324 | */ | 324 | */ |
325 | atomic_t sbp2_login_complete; | 325 | int access_complete:1; |
326 | 326 | ||
327 | /* | 327 | /* |
328 | * Pool of command orbs, so we can have more than overlapped command per id | 328 | * Pool of command orbs, so we can have more than overlapped command per id |