diff options
Diffstat (limited to 'drivers/ieee1394')
-rw-r--r-- | drivers/ieee1394/sbp2.c | 64 | ||||
-rw-r--r-- | drivers/ieee1394/sbp2.h | 64 |
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 | ||
46 | struct sbp2_command_orb { | 48 | struct 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 | ||
130 | struct sbp2_logout_orb { | 132 | struct 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; |