aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ieee1394
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ieee1394')
-rw-r--r--drivers/ieee1394/sbp2.c64
-rw-r--r--drivers/ieee1394/sbp2.h64
2 files changed, 59 insertions, 69 deletions
diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
index 8963dd484eb9..0672224fa109 100644
--- a/drivers/ieee1394/sbp2.c
+++ b/drivers/ieee1394/sbp2.c
@@ -748,11 +748,6 @@ static struct scsi_id_instance_data *sbp2_alloc_device(struct unit_directory *ud
748 hi->host = ud->ne->host; 748 hi->host = ud->ne->host;
749 INIT_LIST_HEAD(&hi->scsi_ids); 749 INIT_LIST_HEAD(&hi->scsi_ids);
750 750
751 /* Register our sbp2 status address space... */
752 hpsb_register_addrspace(&sbp2_highlevel, ud->ne->host, &sbp2_ops,
753 SBP2_STATUS_FIFO_ADDRESS,
754 SBP2_STATUS_FIFO_ADDRESS +
755 SBP2_STATUS_FIFO_ENTRY_TO_OFFSET(SBP2_MAX_UDS_PER_NODE+1));
756#ifdef CONFIG_IEEE1394_SBP2_PHYS_DMA 751#ifdef CONFIG_IEEE1394_SBP2_PHYS_DMA
757 /* Handle data movement if physical dma is not 752 /* Handle data movement if physical dma is not
758 * enabled/supportedon host controller */ 753 * enabled/supportedon host controller */
@@ -765,6 +760,18 @@ static struct scsi_id_instance_data *sbp2_alloc_device(struct unit_directory *ud
765 760
766 list_add_tail(&scsi_id->scsi_list, &hi->scsi_ids); 761 list_add_tail(&scsi_id->scsi_list, &hi->scsi_ids);
767 762
763 /* Register the status FIFO address range. We could use the same FIFO
764 * for targets at different nodes. However we need different FIFOs per
765 * target in order to support multi-unit devices. */
766 scsi_id->status_fifo_addr = hpsb_allocate_and_register_addrspace(
767 &sbp2_highlevel, ud->ne->host, &sbp2_ops,
768 sizeof(struct sbp2_status_block), sizeof(quadlet_t),
769 ~0ULL, ~0ULL);
770 if (!scsi_id->status_fifo_addr) {
771 SBP2_ERR("failed to allocate status FIFO address range");
772 goto failed_alloc;
773 }
774
768 /* Register our host with the SCSI stack. */ 775 /* Register our host with the SCSI stack. */
769 scsi_host = scsi_host_alloc(&scsi_driver_template, 776 scsi_host = scsi_host_alloc(&scsi_driver_template,
770 sizeof(unsigned long)); 777 sizeof(unsigned long));
@@ -1003,6 +1010,10 @@ static void sbp2_remove_device(struct scsi_id_instance_data *scsi_id)
1003 SBP2_DMA_FREE("single query logins data"); 1010 SBP2_DMA_FREE("single query logins data");
1004 } 1011 }
1005 1012
1013 if (scsi_id->status_fifo_addr)
1014 hpsb_unregister_addrspace(&sbp2_highlevel, hi->host,
1015 scsi_id->status_fifo_addr);
1016
1006 scsi_id->ud->device.driver_data = NULL; 1017 scsi_id->ud->device.driver_data = NULL;
1007 1018
1008 SBP2_DEBUG("SBP-2 device removed, SCSI ID = %d", scsi_id->ud->id); 1019 SBP2_DEBUG("SBP-2 device removed, SCSI ID = %d", scsi_id->ud->id);
@@ -1081,11 +1092,10 @@ static int sbp2_query_logins(struct scsi_id_instance_data *scsi_id)
1081 ORB_SET_QUERY_LOGINS_RESP_LENGTH(sizeof(struct sbp2_query_logins_response)); 1092 ORB_SET_QUERY_LOGINS_RESP_LENGTH(sizeof(struct sbp2_query_logins_response));
1082 SBP2_DEBUG("sbp2_query_logins: reserved_resp_length initialized"); 1093 SBP2_DEBUG("sbp2_query_logins: reserved_resp_length initialized");
1083 1094
1084 scsi_id->query_logins_orb->status_FIFO_lo = SBP2_STATUS_FIFO_ADDRESS_LO + 1095 scsi_id->query_logins_orb->status_fifo_hi =
1085 SBP2_STATUS_FIFO_ENTRY_TO_OFFSET(scsi_id->ud->id); 1096 ORB_SET_STATUS_FIFO_HI(scsi_id->status_fifo_addr, hi->host->node_id);
1086 scsi_id->query_logins_orb->status_FIFO_hi = (ORB_SET_NODE_ID(hi->host->node_id) | 1097 scsi_id->query_logins_orb->status_fifo_lo =
1087 SBP2_STATUS_FIFO_ADDRESS_HI); 1098 ORB_SET_STATUS_FIFO_LO(scsi_id->status_fifo_addr);
1088 SBP2_DEBUG("sbp2_query_logins: status FIFO initialized");
1089 1099
1090 sbp2util_cpu_to_be32_buffer(scsi_id->query_logins_orb, sizeof(struct sbp2_query_logins_orb)); 1100 sbp2util_cpu_to_be32_buffer(scsi_id->query_logins_orb, sizeof(struct sbp2_query_logins_orb));
1091 1101
@@ -1190,11 +1200,10 @@ static int sbp2_login_device(struct scsi_id_instance_data *scsi_id)
1190 ORB_SET_LOGIN_RESP_LENGTH(sizeof(struct sbp2_login_response)); 1200 ORB_SET_LOGIN_RESP_LENGTH(sizeof(struct sbp2_login_response));
1191 SBP2_DEBUG("sbp2_login_device: passwd_resp_lengths initialized"); 1201 SBP2_DEBUG("sbp2_login_device: passwd_resp_lengths initialized");
1192 1202
1193 scsi_id->login_orb->status_FIFO_lo = SBP2_STATUS_FIFO_ADDRESS_LO + 1203 scsi_id->login_orb->status_fifo_hi =
1194 SBP2_STATUS_FIFO_ENTRY_TO_OFFSET(scsi_id->ud->id); 1204 ORB_SET_STATUS_FIFO_HI(scsi_id->status_fifo_addr, hi->host->node_id);
1195 scsi_id->login_orb->status_FIFO_hi = (ORB_SET_NODE_ID(hi->host->node_id) | 1205 scsi_id->login_orb->status_fifo_lo =
1196 SBP2_STATUS_FIFO_ADDRESS_HI); 1206 ORB_SET_STATUS_FIFO_LO(scsi_id->status_fifo_addr);
1197 SBP2_DEBUG("sbp2_login_device: status FIFO initialized");
1198 1207
1199 /* 1208 /*
1200 * Byte swap ORB if necessary 1209 * Byte swap ORB if necessary
@@ -1307,10 +1316,10 @@ static int sbp2_logout_device(struct scsi_id_instance_data *scsi_id)
1307 scsi_id->logout_orb->login_ID_misc |= ORB_SET_NOTIFY(1); 1316 scsi_id->logout_orb->login_ID_misc |= ORB_SET_NOTIFY(1);
1308 1317
1309 scsi_id->logout_orb->reserved5 = 0x0; 1318 scsi_id->logout_orb->reserved5 = 0x0;
1310 scsi_id->logout_orb->status_FIFO_lo = SBP2_STATUS_FIFO_ADDRESS_LO + 1319 scsi_id->logout_orb->status_fifo_hi =
1311 SBP2_STATUS_FIFO_ENTRY_TO_OFFSET(scsi_id->ud->id); 1320 ORB_SET_STATUS_FIFO_HI(scsi_id->status_fifo_addr, hi->host->node_id);
1312 scsi_id->logout_orb->status_FIFO_hi = (ORB_SET_NODE_ID(hi->host->node_id) | 1321 scsi_id->logout_orb->status_fifo_lo =
1313 SBP2_STATUS_FIFO_ADDRESS_HI); 1322 ORB_SET_STATUS_FIFO_LO(scsi_id->status_fifo_addr);
1314 1323
1315 /* 1324 /*
1316 * Byte swap ORB if necessary 1325 * Byte swap ORB if necessary
@@ -1372,10 +1381,10 @@ static int sbp2_reconnect_device(struct scsi_id_instance_data *scsi_id)
1372 scsi_id->reconnect_orb->login_ID_misc |= ORB_SET_NOTIFY(1); 1381 scsi_id->reconnect_orb->login_ID_misc |= ORB_SET_NOTIFY(1);
1373 1382
1374 scsi_id->reconnect_orb->reserved5 = 0x0; 1383 scsi_id->reconnect_orb->reserved5 = 0x0;
1375 scsi_id->reconnect_orb->status_FIFO_lo = SBP2_STATUS_FIFO_ADDRESS_LO + 1384 scsi_id->reconnect_orb->status_fifo_hi =
1376 SBP2_STATUS_FIFO_ENTRY_TO_OFFSET(scsi_id->ud->id); 1385 ORB_SET_STATUS_FIFO_HI(scsi_id->status_fifo_addr, hi->host->node_id);
1377 scsi_id->reconnect_orb->status_FIFO_hi = 1386 scsi_id->reconnect_orb->status_fifo_lo =
1378 (ORB_SET_NODE_ID(hi->host->node_id) | SBP2_STATUS_FIFO_ADDRESS_HI); 1387 ORB_SET_STATUS_FIFO_LO(scsi_id->status_fifo_addr);
1379 1388
1380 /* 1389 /*
1381 * Byte swap ORB if necessary 1390 * Byte swap ORB if necessary
@@ -2112,7 +2121,6 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest
2112{ 2121{
2113 struct sbp2scsi_host_info *hi; 2122 struct sbp2scsi_host_info *hi;
2114 struct scsi_id_instance_data *scsi_id = NULL, *scsi_id_tmp; 2123 struct scsi_id_instance_data *scsi_id = NULL, *scsi_id_tmp;
2115 u32 id;
2116 struct scsi_cmnd *SCpnt = NULL; 2124 struct scsi_cmnd *SCpnt = NULL;
2117 u32 scsi_status = SBP2_SCSI_STATUS_GOOD; 2125 u32 scsi_status = SBP2_SCSI_STATUS_GOOD;
2118 struct sbp2_command_info *command; 2126 struct sbp2_command_info *command;
@@ -2135,12 +2143,12 @@ static int sbp2_handle_status_write(struct hpsb_host *host, int nodeid, int dest
2135 } 2143 }
2136 2144
2137 /* 2145 /*
2138 * Find our scsi_id structure by looking at the status fifo address written to by 2146 * Find our scsi_id structure by looking at the status fifo address
2139 * the sbp2 device. 2147 * written to by the sbp2 device.
2140 */ 2148 */
2141 id = SBP2_STATUS_FIFO_OFFSET_TO_ENTRY((u32)(addr - SBP2_STATUS_FIFO_ADDRESS));
2142 list_for_each_entry(scsi_id_tmp, &hi->scsi_ids, scsi_list) { 2149 list_for_each_entry(scsi_id_tmp, &hi->scsi_ids, scsi_list) {
2143 if (scsi_id_tmp->ne->nodeid == nodeid && scsi_id_tmp->ud->id == id) { 2150 if (scsi_id_tmp->ne->nodeid == nodeid &&
2151 scsi_id_tmp->status_fifo_addr == addr) {
2144 scsi_id = scsi_id_tmp; 2152 scsi_id = scsi_id_tmp;
2145 break; 2153 break;
2146 } 2154 }
diff --git a/drivers/ieee1394/sbp2.h b/drivers/ieee1394/sbp2.h
index 900ea1d25e71..e2d357a9ea3a 100644
--- a/drivers/ieee1394/sbp2.h
+++ b/drivers/ieee1394/sbp2.h
@@ -33,15 +33,17 @@
33#define ORB_DIRECTION_NO_DATA_TRANSFER 0x2 33#define ORB_DIRECTION_NO_DATA_TRANSFER 0x2
34 34
35#define ORB_SET_NULL_PTR(value) ((value & 0x1) << 31) 35#define ORB_SET_NULL_PTR(value) ((value & 0x1) << 31)
36#define ORB_SET_NOTIFY(value) ((value & 0x1) << 31) 36#define ORB_SET_NOTIFY(value) ((value & 0x1) << 31)
37#define ORB_SET_RQ_FMT(value) ((value & 0x3) << 29) /* unused ? */ 37#define ORB_SET_RQ_FMT(value) ((value & 0x3) << 29) /* unused ? */
38#define ORB_SET_NODE_ID(value) ((value & 0xffff) << 16) 38#define ORB_SET_NODE_ID(value) ((value & 0xffff) << 16)
39#define ORB_SET_DATA_SIZE(value) (value & 0xffff) 39#define ORB_SET_STATUS_FIFO_HI(value, id) (value >> 32 | ORB_SET_NODE_ID(id))
40#define ORB_SET_PAGE_SIZE(value) ((value & 0x7) << 16) 40#define ORB_SET_STATUS_FIFO_LO(value) (value & 0xffffffff)
41#define ORB_SET_PAGE_TABLE_PRESENT(value) ((value & 0x1) << 19) 41#define ORB_SET_DATA_SIZE(value) (value & 0xffff)
42#define ORB_SET_MAX_PAYLOAD(value) ((value & 0xf) << 20) 42#define ORB_SET_PAGE_SIZE(value) ((value & 0x7) << 16)
43#define ORB_SET_SPEED(value) ((value & 0x7) << 24) 43#define ORB_SET_PAGE_TABLE_PRESENT(value) ((value & 0x1) << 19)
44#define ORB_SET_DIRECTION(value) ((value & 0x1) << 27) 44#define ORB_SET_MAX_PAYLOAD(value) ((value & 0xf) << 20)
45#define ORB_SET_SPEED(value) ((value & 0x7) << 24)
46#define ORB_SET_DIRECTION(value) ((value & 0x1) << 27)
45 47
46struct sbp2_command_orb { 48struct sbp2_command_orb {
47 volatile u32 next_ORB_hi; 49 volatile u32 next_ORB_hi;
@@ -76,8 +78,8 @@ struct sbp2_login_orb {
76 u32 login_response_lo; 78 u32 login_response_lo;
77 u32 lun_misc; 79 u32 lun_misc;
78 u32 passwd_resp_lengths; 80 u32 passwd_resp_lengths;
79 u32 status_FIFO_hi; 81 u32 status_fifo_hi;
80 u32 status_FIFO_lo; 82 u32 status_fifo_lo;
81}; 83};
82 84
83#define RESPONSE_GET_LOGIN_ID(value) (value & 0xffff) 85#define RESPONSE_GET_LOGIN_ID(value) (value & 0xffff)
@@ -102,8 +104,8 @@ struct sbp2_query_logins_orb {
102 u32 query_response_lo; 104 u32 query_response_lo;
103 u32 lun_misc; 105 u32 lun_misc;
104 u32 reserved_resp_length; 106 u32 reserved_resp_length;
105 u32 status_FIFO_hi; 107 u32 status_fifo_hi;
106 u32 status_FIFO_lo; 108 u32 status_fifo_lo;
107}; 109};
108 110
109#define RESPONSE_GET_MAX_LOGINS(value) (value & 0xffff) 111#define RESPONSE_GET_MAX_LOGINS(value) (value & 0xffff)
@@ -123,8 +125,8 @@ struct sbp2_reconnect_orb {
123 u32 reserved4; 125 u32 reserved4;
124 u32 login_ID_misc; 126 u32 login_ID_misc;
125 u32 reserved5; 127 u32 reserved5;
126 u32 status_FIFO_hi; 128 u32 status_fifo_hi;
127 u32 status_FIFO_lo; 129 u32 status_fifo_lo;
128}; 130};
129 131
130struct sbp2_logout_orb { 132struct sbp2_logout_orb {
@@ -134,8 +136,8 @@ struct sbp2_logout_orb {
134 u32 reserved4; 136 u32 reserved4;
135 u32 login_ID_misc; 137 u32 login_ID_misc;
136 u32 reserved5; 138 u32 reserved5;
137 u32 status_FIFO_hi; 139 u32 status_fifo_hi;
138 u32 status_FIFO_lo; 140 u32 status_fifo_lo;
139}; 141};
140 142
141#define PAGE_TABLE_SET_SEGMENT_BASE_HI(value) (value & 0xffff) 143#define PAGE_TABLE_SET_SEGMENT_BASE_HI(value) (value & 0xffff)
@@ -195,30 +197,6 @@ struct sbp2_status_block {
195 * Miscellaneous SBP2 related config rom defines 197 * Miscellaneous SBP2 related config rom defines
196 */ 198 */
197 199
198/* The status fifo address definition below is used as a base for each
199 * node, which a chunk seperately assigned to each unit directory in the
200 * node. For example, 0xfffe00000000ULL is used for the first sbp2 device
201 * detected on node 0, 0xfffe00000020ULL for the next sbp2 device on node
202 * 0, and so on.
203 *
204 * Note: We could use a single status fifo address for all sbp2 devices,
205 * and figure out which sbp2 device the status belongs to by looking at
206 * the source node id of the status write... but, using separate addresses
207 * for each sbp2 unit directory allows for better code and the ability to
208 * support multiple luns within a single 1394 node.
209 *
210 * Also note that we choose the address range below as it is a region
211 * specified for write posting, where the ohci controller will
212 * automatically send an ack_complete when the status is written by the
213 * sbp2 device... saving a split transaction. =)
214 */
215#define SBP2_STATUS_FIFO_ADDRESS 0xfffe00000000ULL
216#define SBP2_STATUS_FIFO_ADDRESS_HI 0xfffe
217#define SBP2_STATUS_FIFO_ADDRESS_LO 0x0
218
219#define SBP2_STATUS_FIFO_ENTRY_TO_OFFSET(entry) ((entry) << 5)
220#define SBP2_STATUS_FIFO_OFFSET_TO_ENTRY(offset) ((offset) >> 5)
221
222#define SBP2_UNIT_DIRECTORY_OFFSET_KEY 0xd1 200#define SBP2_UNIT_DIRECTORY_OFFSET_KEY 0xd1
223#define SBP2_CSR_OFFSET_KEY 0x54 201#define SBP2_CSR_OFFSET_KEY 0x54
224#define SBP2_UNIT_SPEC_ID_KEY 0x12 202#define SBP2_UNIT_SPEC_ID_KEY 0x12
@@ -258,7 +236,6 @@ struct sbp2_status_block {
258 */ 236 */
259 237
260#define SBP2_MAX_SG_ELEMENT_LENGTH 0xf000 238#define SBP2_MAX_SG_ELEMENT_LENGTH 0xf000
261#define SBP2_MAX_UDS_PER_NODE 16 /* Maximum scsi devices per node */
262#define SBP2_MAX_SECTORS 255 /* Max sectors supported */ 239#define SBP2_MAX_SECTORS 255 /* Max sectors supported */
263#define SBP2_MAX_CMDS 8 /* This should be safe */ 240#define SBP2_MAX_CMDS 8 /* This should be safe */
264 241
@@ -338,6 +315,11 @@ struct scsi_id_instance_data {
338 u32 sbp2_firmware_revision; 315 u32 sbp2_firmware_revision;
339 316
340 /* 317 /*
318 * Address for the device to write status blocks to
319 */
320 u64 status_fifo_addr;
321
322 /*
341 * Variable used for logins, reconnects, logouts, query logins 323 * Variable used for logins, reconnects, logouts, query logins
342 */ 324 */
343 atomic_t sbp2_login_complete; 325 atomic_t sbp2_login_complete;