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.c51
1 files changed, 22 insertions, 29 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
423static 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 */
426static int sbp2util_down_timeout(atomic_t *done, int timeout) 429static 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 */
438static void sbp2_free_packet(struct hpsb_packet *packet) 440static 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) {