diff options
author | Jayamohan Kallickal <jayamohank@serverengines.com> | 2010-07-21 18:59:18 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@suse.de> | 2010-08-06 10:41:51 -0400 |
commit | c7acc5b8f9a0e6cb17d313ebfbc5d392aa837ac7 (patch) | |
tree | 73f61ea13608fdfb3c96c842e0cdb2e0257a9575 /drivers | |
parent | f3506b755f730f199aea3289712f9604ae562319 (diff) |
[SCSI] be2iscsi: Add support for iscsi boot
This patch contains changes for adding support for iscsi_boot.
Have modified to make read of mac address from chip as a function.
The mac_address is being cached after teh first call as it is
not expected to change
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: Jayamohan Kallickal <jayamohank@serverengines.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/scsi/be2iscsi/be_cmds.h | 147 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_iscsi.c | 76 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_iscsi.h | 2 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_main.c | 311 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_main.h | 3 | ||||
-rw-r--r-- | drivers/scsi/be2iscsi/be_mgmt.c | 71 |
6 files changed, 564 insertions, 46 deletions
diff --git a/drivers/scsi/be2iscsi/be_cmds.h b/drivers/scsi/be2iscsi/be_cmds.h index 40641d0845f4..5218de4ab35a 100644 --- a/drivers/scsi/be2iscsi/be_cmds.h +++ b/drivers/scsi/be2iscsi/be_cmds.h | |||
@@ -162,6 +162,13 @@ struct be_mcc_mailbox { | |||
162 | #define OPCODE_COMMON_ISCSI_CFG_POST_SGL_PAGES 2 | 162 | #define OPCODE_COMMON_ISCSI_CFG_POST_SGL_PAGES 2 |
163 | #define OPCODE_COMMON_ISCSI_CFG_REMOVE_SGL_PAGES 3 | 163 | #define OPCODE_COMMON_ISCSI_CFG_REMOVE_SGL_PAGES 3 |
164 | #define OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG 7 | 164 | #define OPCODE_COMMON_ISCSI_NTWK_GET_NIC_CONFIG 7 |
165 | #define OPCODE_COMMON_ISCSI_NTWK_SET_VLAN 14 | ||
166 | #define OPCODE_COMMON_ISCSI_NTWK_CONFIGURE_STATELESS_IP_ADDR 17 | ||
167 | #define OPCODE_COMMON_ISCSI_NTWK_MODIFY_IP_ADDR 21 | ||
168 | #define OPCODE_COMMON_ISCSI_NTWK_GET_DEFAULT_GATEWAY 22 | ||
169 | #define OPCODE_COMMON_ISCSI_NTWK_MODIFY_DEFAULT_GATEWAY 23 | ||
170 | #define OPCODE_COMMON_ISCSI_NTWK_GET_ALL_IF_ID 24 | ||
171 | #define OPCODE_COMMON_ISCSI_NTWK_GET_IF_INFO 25 | ||
165 | #define OPCODE_COMMON_ISCSI_SET_FRAGNUM_BITS_FOR_SGL_CRA 61 | 172 | #define OPCODE_COMMON_ISCSI_SET_FRAGNUM_BITS_FOR_SGL_CRA 61 |
166 | #define OPCODE_COMMON_ISCSI_DEFQ_CREATE 64 | 173 | #define OPCODE_COMMON_ISCSI_DEFQ_CREATE 64 |
167 | #define OPCODE_COMMON_ISCSI_DEFQ_DESTROY 65 | 174 | #define OPCODE_COMMON_ISCSI_DEFQ_DESTROY 65 |
@@ -237,11 +244,109 @@ struct be_cmd_resp_eq_create { | |||
237 | u16 rsvd0; /* sword */ | 244 | u16 rsvd0; /* sword */ |
238 | } __packed; | 245 | } __packed; |
239 | 246 | ||
247 | struct mgmt_chap_format { | ||
248 | u32 flags; | ||
249 | u8 intr_chap_name[256]; | ||
250 | u8 intr_secret[16]; | ||
251 | u8 target_chap_name[256]; | ||
252 | u8 target_secret[16]; | ||
253 | u16 intr_chap_name_length; | ||
254 | u16 intr_secret_length; | ||
255 | u16 target_chap_name_length; | ||
256 | u16 target_secret_length; | ||
257 | } __packed; | ||
258 | |||
259 | struct mgmt_auth_method_format { | ||
260 | u8 auth_method_type; | ||
261 | u8 padding[3]; | ||
262 | struct mgmt_chap_format chap; | ||
263 | } __packed; | ||
264 | |||
265 | struct mgmt_conn_login_options { | ||
266 | u8 flags; | ||
267 | u8 header_digest; | ||
268 | u8 data_digest; | ||
269 | u8 rsvd0; | ||
270 | u32 max_recv_datasegment_len_ini; | ||
271 | u32 max_recv_datasegment_len_tgt; | ||
272 | u32 tcp_mss; | ||
273 | u32 tcp_window_size; | ||
274 | struct mgmt_auth_method_format auth_data; | ||
275 | } __packed; | ||
276 | |||
277 | struct ip_address_format { | ||
278 | u16 size_of_structure; | ||
279 | u8 reserved; | ||
280 | u8 ip_type; | ||
281 | u8 ip_address[16]; | ||
282 | u32 rsvd0; | ||
283 | } __packed; | ||
284 | |||
285 | struct mgmt_conn_info { | ||
286 | u32 connection_handle; | ||
287 | u32 connection_status; | ||
288 | u16 src_port; | ||
289 | u16 dest_port; | ||
290 | u16 dest_port_redirected; | ||
291 | u16 cid; | ||
292 | u32 estimated_throughput; | ||
293 | struct ip_address_format src_ipaddr; | ||
294 | struct ip_address_format dest_ipaddr; | ||
295 | struct ip_address_format dest_ipaddr_redirected; | ||
296 | struct mgmt_conn_login_options negotiated_login_options; | ||
297 | } __packed; | ||
298 | |||
299 | struct mgmt_session_login_options { | ||
300 | u8 flags; | ||
301 | u8 error_recovery_level; | ||
302 | u16 rsvd0; | ||
303 | u32 first_burst_length; | ||
304 | u32 max_burst_length; | ||
305 | u16 max_connections; | ||
306 | u16 max_outstanding_r2t; | ||
307 | u16 default_time2wait; | ||
308 | u16 default_time2retain; | ||
309 | } __packed; | ||
310 | |||
311 | struct mgmt_session_info { | ||
312 | u32 session_handle; | ||
313 | u32 status; | ||
314 | u8 isid[6]; | ||
315 | u16 tsih; | ||
316 | u32 session_flags; | ||
317 | u16 conn_count; | ||
318 | u16 pad; | ||
319 | u8 target_name[224]; | ||
320 | u8 initiator_iscsiname[224]; | ||
321 | struct mgmt_session_login_options negotiated_login_options; | ||
322 | struct mgmt_conn_info conn_list[1]; | ||
323 | } __packed; | ||
324 | |||
325 | struct be_cmd_req_get_session { | ||
326 | struct be_cmd_req_hdr hdr; | ||
327 | u32 session_handle; | ||
328 | } __packed; | ||
329 | |||
330 | struct be_cmd_resp_get_session { | ||
331 | struct be_cmd_resp_hdr hdr; | ||
332 | struct mgmt_session_info session_info; | ||
333 | } __packed; | ||
334 | |||
240 | struct mac_addr { | 335 | struct mac_addr { |
241 | u16 size_of_struct; | 336 | u16 size_of_struct; |
242 | u8 addr[ETH_ALEN]; | 337 | u8 addr[ETH_ALEN]; |
243 | } __packed; | 338 | } __packed; |
244 | 339 | ||
340 | struct be_cmd_req_get_boot_target { | ||
341 | struct be_cmd_req_hdr hdr; | ||
342 | } __packed; | ||
343 | |||
344 | struct be_cmd_resp_get_boot_target { | ||
345 | struct be_cmd_resp_hdr hdr; | ||
346 | u32 boot_session_count; | ||
347 | int boot_session_handle; | ||
348 | }; | ||
349 | |||
245 | struct be_cmd_req_mac_query { | 350 | struct be_cmd_req_mac_query { |
246 | struct be_cmd_req_hdr hdr; | 351 | struct be_cmd_req_hdr hdr; |
247 | u8 type; | 352 | u8 type; |
@@ -426,6 +531,11 @@ int be_poll_mcc(struct be_ctrl_info *ctrl); | |||
426 | int mgmt_check_supported_fw(struct be_ctrl_info *ctrl, | 531 | int mgmt_check_supported_fw(struct be_ctrl_info *ctrl, |
427 | struct beiscsi_hba *phba); | 532 | struct beiscsi_hba *phba); |
428 | unsigned int be_cmd_get_mac_addr(struct beiscsi_hba *phba); | 533 | unsigned int be_cmd_get_mac_addr(struct beiscsi_hba *phba); |
534 | unsigned int beiscsi_get_boot_target(struct beiscsi_hba *phba); | ||
535 | unsigned int beiscsi_get_session_info(struct beiscsi_hba *phba, | ||
536 | u32 boot_session_handle, | ||
537 | struct be_dma_mem *nonemb_cmd); | ||
538 | |||
429 | void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag); | 539 | void free_mcc_tag(struct be_ctrl_info *ctrl, unsigned int tag); |
430 | /*ISCSI Functuions */ | 540 | /*ISCSI Functuions */ |
431 | int be_cmd_fw_initialize(struct be_ctrl_info *ctrl); | 541 | int be_cmd_fw_initialize(struct be_ctrl_info *ctrl); |
@@ -601,14 +711,6 @@ struct be_eq_delay_params_in { | |||
601 | struct eq_delay delay[8]; | 711 | struct eq_delay delay[8]; |
602 | } __packed; | 712 | } __packed; |
603 | 713 | ||
604 | struct ip_address_format { | ||
605 | u16 size_of_structure; | ||
606 | u8 reserved; | ||
607 | u8 ip_type; | ||
608 | u8 ip_address[16]; | ||
609 | u32 rsvd0; | ||
610 | } __packed; | ||
611 | |||
612 | struct tcp_connect_and_offload_in { | 714 | struct tcp_connect_and_offload_in { |
613 | struct be_cmd_req_hdr hdr; | 715 | struct be_cmd_req_hdr hdr; |
614 | struct ip_address_format ip_address; | 716 | struct ip_address_format ip_address; |
@@ -688,18 +790,29 @@ struct be_fw_cfg { | |||
688 | u32 function_caps; | 790 | u32 function_caps; |
689 | } __packed; | 791 | } __packed; |
690 | 792 | ||
691 | #define CMD_ISCSI_COMMAND_INVALIDATE 1 | 793 | struct be_all_if_id { |
692 | #define ISCSI_OPCODE_SCSI_DATA_OUT 5 | 794 | struct be_cmd_req_hdr hdr; |
795 | u32 if_count; | ||
796 | u32 if_hndl_list[1]; | ||
797 | } __packed; | ||
798 | |||
799 | #define ISCSI_OPCODE_SCSI_DATA_OUT 5 | ||
800 | #define OPCODE_COMMON_MODIFY_EQ_DELAY 41 | ||
801 | #define OPCODE_COMMON_ISCSI_CLEANUP 59 | ||
802 | #define OPCODE_COMMON_TCP_UPLOAD 56 | ||
693 | #define OPCODE_COMMON_ISCSI_TCP_CONNECT_AND_OFFLOAD 70 | 803 | #define OPCODE_COMMON_ISCSI_TCP_CONNECT_AND_OFFLOAD 70 |
694 | #define OPCODE_ISCSI_INI_DRIVER_OFFLOAD_SESSION 41 | ||
695 | #define OPCODE_COMMON_MODIFY_EQ_DELAY 41 | ||
696 | #define OPCODE_COMMON_ISCSI_CLEANUP 59 | ||
697 | #define OPCODE_COMMON_TCP_UPLOAD 56 | ||
698 | #define OPCODE_COMMON_ISCSI_ERROR_RECOVERY_INVALIDATE_COMMANDS 1 | 804 | #define OPCODE_COMMON_ISCSI_ERROR_RECOVERY_INVALIDATE_COMMANDS 1 |
699 | /* --- CMD_ISCSI_INVALIDATE_CONNECTION_TYPE --- */ | 805 | #define OPCODE_ISCSI_INI_CFG_GET_HBA_NAME 6 |
700 | #define CMD_ISCSI_CONNECTION_INVALIDATE 0x8001 | 806 | #define OPCODE_ISCSI_INI_CFG_SET_HBA_NAME 7 |
701 | #define CMD_ISCSI_CONNECTION_ISSUE_TCP_RST 0x8002 | 807 | #define OPCODE_ISCSI_INI_SESSION_GET_A_SESSION 14 |
808 | #define OPCODE_ISCSI_INI_DRIVER_OFFLOAD_SESSION 41 | ||
702 | #define OPCODE_ISCSI_INI_DRIVER_INVALIDATE_CONNECTION 42 | 809 | #define OPCODE_ISCSI_INI_DRIVER_INVALIDATE_CONNECTION 42 |
810 | #define OPCODE_ISCSI_INI_BOOT_GET_BOOT_TARGET 52 | ||
811 | |||
812 | /* --- CMD_ISCSI_INVALIDATE_CONNECTION_TYPE --- */ | ||
813 | #define CMD_ISCSI_COMMAND_INVALIDATE 1 | ||
814 | #define CMD_ISCSI_CONNECTION_INVALIDATE 0x8001 | ||
815 | #define CMD_ISCSI_CONNECTION_ISSUE_TCP_RST 0x8002 | ||
703 | 816 | ||
704 | #define INI_WR_CMD 1 /* Initiator write command */ | 817 | #define INI_WR_CMD 1 /* Initiator write command */ |
705 | #define INI_TMF_CMD 2 /* Initiator TMF command */ | 818 | #define INI_TMF_CMD 2 /* Initiator TMF command */ |
diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c index 6d63e7b312cf..7d4d2275573c 100644 --- a/drivers/scsi/be2iscsi/be_iscsi.c +++ b/drivers/scsi/be2iscsi/be_iscsi.c | |||
@@ -300,40 +300,16 @@ int beiscsi_get_host_param(struct Scsi_Host *shost, | |||
300 | enum iscsi_host_param param, char *buf) | 300 | enum iscsi_host_param param, char *buf) |
301 | { | 301 | { |
302 | struct beiscsi_hba *phba = (struct beiscsi_hba *)iscsi_host_priv(shost); | 302 | struct beiscsi_hba *phba = (struct beiscsi_hba *)iscsi_host_priv(shost); |
303 | struct be_cmd_resp_get_mac_addr *resp; | ||
304 | struct be_mcc_wrb *wrb; | ||
305 | unsigned int tag, wrb_num; | ||
306 | int len = 0; | 303 | int len = 0; |
307 | unsigned short status, extd_status; | 304 | int status; |
308 | struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q; | ||
309 | 305 | ||
310 | SE_DEBUG(DBG_LVL_8, "In beiscsi_get_host_param, param= %d\n", param); | 306 | SE_DEBUG(DBG_LVL_8, "In beiscsi_get_host_param, param= %d\n", param); |
311 | switch (param) { | 307 | switch (param) { |
312 | case ISCSI_HOST_PARAM_HWADDRESS: | 308 | case ISCSI_HOST_PARAM_HWADDRESS: |
313 | tag = be_cmd_get_mac_addr(phba); | 309 | status = beiscsi_get_macaddr(buf, phba); |
314 | if (!tag) { | 310 | if (status < 0) { |
315 | SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed\n"); | 311 | SE_DEBUG(DBG_LVL_1, "beiscsi_get_macaddr Failed\n"); |
316 | return -EAGAIN; | 312 | return status; |
317 | } else | ||
318 | wait_event_interruptible(phba->ctrl.mcc_wait[tag], | ||
319 | phba->ctrl.mcc_numtag[tag]); | ||
320 | |||
321 | wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16; | ||
322 | extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8; | ||
323 | status = phba->ctrl.mcc_numtag[tag] & 0x000000FF; | ||
324 | if (status || extd_status) { | ||
325 | SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed" | ||
326 | " status = %d extd_status = %d\n", | ||
327 | status, extd_status); | ||
328 | free_mcc_tag(&phba->ctrl, tag); | ||
329 | return -EAGAIN; | ||
330 | } else { | ||
331 | wrb = queue_get_wrb(mccq, wrb_num); | ||
332 | free_mcc_tag(&phba->ctrl, tag); | ||
333 | resp = embedded_payload(wrb); | ||
334 | memcpy(phba->mac_address, resp->mac_address, ETH_ALEN); | ||
335 | len = sysfs_format_mac(buf, phba->mac_address, | ||
336 | ETH_ALEN); | ||
337 | } | 313 | } |
338 | break; | 314 | break; |
339 | default: | 315 | default: |
@@ -342,6 +318,48 @@ int beiscsi_get_host_param(struct Scsi_Host *shost, | |||
342 | return len; | 318 | return len; |
343 | } | 319 | } |
344 | 320 | ||
321 | int beiscsi_get_macaddr(char *buf, struct beiscsi_hba *phba) | ||
322 | { | ||
323 | struct be_cmd_resp_get_mac_addr *resp; | ||
324 | struct be_mcc_wrb *wrb; | ||
325 | unsigned int tag, wrb_num; | ||
326 | unsigned short status, extd_status; | ||
327 | struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q; | ||
328 | int rc; | ||
329 | |||
330 | if (phba->read_mac_address) | ||
331 | return sysfs_format_mac(buf, phba->mac_address, | ||
332 | ETH_ALEN); | ||
333 | |||
334 | tag = be_cmd_get_mac_addr(phba); | ||
335 | if (!tag) { | ||
336 | SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed\n"); | ||
337 | return -EBUSY; | ||
338 | } else | ||
339 | wait_event_interruptible(phba->ctrl.mcc_wait[tag], | ||
340 | phba->ctrl.mcc_numtag[tag]); | ||
341 | |||
342 | wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16; | ||
343 | extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8; | ||
344 | status = phba->ctrl.mcc_numtag[tag] & 0x000000FF; | ||
345 | if (status || extd_status) { | ||
346 | SE_DEBUG(DBG_LVL_1, "Failed to get be_cmd_get_mac_addr" | ||
347 | " status = %d extd_status = %d\n", | ||
348 | status, extd_status); | ||
349 | free_mcc_tag(&phba->ctrl, tag); | ||
350 | return -EAGAIN; | ||
351 | } | ||
352 | wrb = queue_get_wrb(mccq, wrb_num); | ||
353 | free_mcc_tag(&phba->ctrl, tag); | ||
354 | resp = embedded_payload(wrb); | ||
355 | memcpy(phba->mac_address, resp->mac_address, ETH_ALEN); | ||
356 | rc = sysfs_format_mac(buf, phba->mac_address, | ||
357 | ETH_ALEN); | ||
358 | phba->read_mac_address = 1; | ||
359 | return rc; | ||
360 | } | ||
361 | |||
362 | |||
345 | /** | 363 | /** |
346 | * beiscsi_conn_get_stats - get the iscsi stats | 364 | * beiscsi_conn_get_stats - get the iscsi stats |
347 | * @cls_conn: pointer to iscsi cls conn | 365 | * @cls_conn: pointer to iscsi cls conn |
diff --git a/drivers/scsi/be2iscsi/be_iscsi.h b/drivers/scsi/be2iscsi/be_iscsi.h index 870cdb2a73e4..8950a702b9f4 100644 --- a/drivers/scsi/be2iscsi/be_iscsi.h +++ b/drivers/scsi/be2iscsi/be_iscsi.h | |||
@@ -54,6 +54,8 @@ int beiscsi_conn_get_param(struct iscsi_cls_conn *cls_conn, | |||
54 | int beiscsi_get_host_param(struct Scsi_Host *shost, | 54 | int beiscsi_get_host_param(struct Scsi_Host *shost, |
55 | enum iscsi_host_param param, char *buf); | 55 | enum iscsi_host_param param, char *buf); |
56 | 56 | ||
57 | int beiscsi_get_macaddr(char *buf, struct beiscsi_hba *phba); | ||
58 | |||
57 | int beiscsi_set_param(struct iscsi_cls_conn *cls_conn, | 59 | int beiscsi_set_param(struct iscsi_cls_conn *cls_conn, |
58 | enum iscsi_param param, char *buf, int buflen); | 60 | enum iscsi_param param, char *buf, int buflen); |
59 | 61 | ||
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index 7436c5ad5697..8220bde6c04c 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/string.h> | 26 | #include <linux/string.h> |
27 | #include <linux/kernel.h> | 27 | #include <linux/kernel.h> |
28 | #include <linux/semaphore.h> | 28 | #include <linux/semaphore.h> |
29 | #include <linux/iscsi_boot_sysfs.h> | ||
29 | 30 | ||
30 | #include <scsi/libiscsi.h> | 31 | #include <scsi/libiscsi.h> |
31 | #include <scsi/scsi_transport_iscsi.h> | 32 | #include <scsi/scsi_transport_iscsi.h> |
@@ -211,6 +212,218 @@ unlock: | |||
211 | return rc; | 212 | return rc; |
212 | } | 213 | } |
213 | 214 | ||
215 | static ssize_t beiscsi_show_boot_tgt_info(void *data, int type, char *buf) | ||
216 | { | ||
217 | struct beiscsi_hba *phba = data; | ||
218 | char *str = buf; | ||
219 | int rc; | ||
220 | |||
221 | switch (type) { | ||
222 | case ISCSI_BOOT_TGT_NAME: | ||
223 | rc = sprintf(buf, "%.*s\n", | ||
224 | (int)strlen(phba->boot_sess.target_name), | ||
225 | (char *)&phba->boot_sess.target_name); | ||
226 | break; | ||
227 | case ISCSI_BOOT_TGT_IP_ADDR: | ||
228 | if (phba->boot_sess.conn_list[0].dest_ipaddr.ip_type == 0x1) | ||
229 | rc = sprintf(buf, "%pI4\n", | ||
230 | (char *)&phba->boot_sess.conn_list[0]. | ||
231 | dest_ipaddr.ip_address); | ||
232 | else | ||
233 | rc = sprintf(str, "%pI6\n", | ||
234 | (char *)&phba->boot_sess.conn_list[0]. | ||
235 | dest_ipaddr.ip_address); | ||
236 | break; | ||
237 | case ISCSI_BOOT_TGT_PORT: | ||
238 | rc = sprintf(str, "%d\n", phba->boot_sess.conn_list[0]. | ||
239 | dest_port); | ||
240 | break; | ||
241 | |||
242 | case ISCSI_BOOT_TGT_CHAP_NAME: | ||
243 | rc = sprintf(str, "%.*s\n", | ||
244 | phba->boot_sess.conn_list[0]. | ||
245 | negotiated_login_options.auth_data.chap. | ||
246 | target_chap_name_length, | ||
247 | (char *)&phba->boot_sess.conn_list[0]. | ||
248 | negotiated_login_options.auth_data.chap. | ||
249 | target_chap_name); | ||
250 | break; | ||
251 | case ISCSI_BOOT_TGT_CHAP_SECRET: | ||
252 | rc = sprintf(str, "%.*s\n", | ||
253 | phba->boot_sess.conn_list[0]. | ||
254 | negotiated_login_options.auth_data.chap. | ||
255 | target_secret_length, | ||
256 | (char *)&phba->boot_sess.conn_list[0]. | ||
257 | negotiated_login_options.auth_data.chap. | ||
258 | target_secret); | ||
259 | |||
260 | break; | ||
261 | case ISCSI_BOOT_TGT_REV_CHAP_NAME: | ||
262 | rc = sprintf(str, "%.*s\n", | ||
263 | phba->boot_sess.conn_list[0]. | ||
264 | negotiated_login_options.auth_data.chap. | ||
265 | intr_chap_name_length, | ||
266 | (char *)&phba->boot_sess.conn_list[0]. | ||
267 | negotiated_login_options.auth_data.chap. | ||
268 | intr_chap_name); | ||
269 | |||
270 | break; | ||
271 | case ISCSI_BOOT_TGT_REV_CHAP_SECRET: | ||
272 | rc = sprintf(str, "%.*s\n", | ||
273 | phba->boot_sess.conn_list[0]. | ||
274 | negotiated_login_options.auth_data.chap. | ||
275 | intr_secret_length, | ||
276 | (char *)&phba->boot_sess.conn_list[0]. | ||
277 | negotiated_login_options.auth_data.chap. | ||
278 | intr_secret); | ||
279 | break; | ||
280 | case ISCSI_BOOT_TGT_FLAGS: | ||
281 | rc = sprintf(str, "2\n"); | ||
282 | break; | ||
283 | case ISCSI_BOOT_TGT_NIC_ASSOC: | ||
284 | rc = sprintf(str, "0\n"); | ||
285 | break; | ||
286 | default: | ||
287 | rc = -ENOSYS; | ||
288 | break; | ||
289 | } | ||
290 | return rc; | ||
291 | } | ||
292 | |||
293 | static ssize_t beiscsi_show_boot_ini_info(void *data, int type, char *buf) | ||
294 | { | ||
295 | struct beiscsi_hba *phba = data; | ||
296 | char *str = buf; | ||
297 | int rc; | ||
298 | |||
299 | switch (type) { | ||
300 | case ISCSI_BOOT_INI_INITIATOR_NAME: | ||
301 | rc = sprintf(str, "%s\n", phba->boot_sess.initiator_iscsiname); | ||
302 | break; | ||
303 | default: | ||
304 | rc = -ENOSYS; | ||
305 | break; | ||
306 | } | ||
307 | return rc; | ||
308 | } | ||
309 | |||
310 | static ssize_t beiscsi_show_boot_eth_info(void *data, int type, char *buf) | ||
311 | { | ||
312 | struct beiscsi_hba *phba = data; | ||
313 | char *str = buf; | ||
314 | int rc; | ||
315 | |||
316 | switch (type) { | ||
317 | case ISCSI_BOOT_ETH_FLAGS: | ||
318 | rc = sprintf(str, "2\n"); | ||
319 | break; | ||
320 | case ISCSI_BOOT_ETH_INDEX: | ||
321 | rc = sprintf(str, "0\n"); | ||
322 | break; | ||
323 | case ISCSI_BOOT_ETH_MAC: | ||
324 | rc = beiscsi_get_macaddr(buf, phba); | ||
325 | if (rc < 0) { | ||
326 | SE_DEBUG(DBG_LVL_1, "beiscsi_get_macaddr Failed\n"); | ||
327 | return rc; | ||
328 | } | ||
329 | break; | ||
330 | default: | ||
331 | rc = -ENOSYS; | ||
332 | break; | ||
333 | } | ||
334 | return rc; | ||
335 | } | ||
336 | |||
337 | |||
338 | static mode_t beiscsi_tgt_get_attr_visibility(void *data, int type) | ||
339 | { | ||
340 | int rc; | ||
341 | |||
342 | switch (type) { | ||
343 | case ISCSI_BOOT_TGT_NAME: | ||
344 | case ISCSI_BOOT_TGT_IP_ADDR: | ||
345 | case ISCSI_BOOT_TGT_PORT: | ||
346 | case ISCSI_BOOT_TGT_CHAP_NAME: | ||
347 | case ISCSI_BOOT_TGT_CHAP_SECRET: | ||
348 | case ISCSI_BOOT_TGT_REV_CHAP_NAME: | ||
349 | case ISCSI_BOOT_TGT_REV_CHAP_SECRET: | ||
350 | case ISCSI_BOOT_TGT_NIC_ASSOC: | ||
351 | case ISCSI_BOOT_TGT_FLAGS: | ||
352 | rc = S_IRUGO; | ||
353 | break; | ||
354 | default: | ||
355 | rc = 0; | ||
356 | break; | ||
357 | } | ||
358 | return rc; | ||
359 | } | ||
360 | |||
361 | static mode_t beiscsi_ini_get_attr_visibility(void *data, int type) | ||
362 | { | ||
363 | int rc; | ||
364 | |||
365 | switch (type) { | ||
366 | case ISCSI_BOOT_INI_INITIATOR_NAME: | ||
367 | rc = S_IRUGO; | ||
368 | break; | ||
369 | default: | ||
370 | rc = 0; | ||
371 | break; | ||
372 | } | ||
373 | return rc; | ||
374 | } | ||
375 | |||
376 | |||
377 | static mode_t beiscsi_eth_get_attr_visibility(void *data, int type) | ||
378 | { | ||
379 | int rc; | ||
380 | |||
381 | switch (type) { | ||
382 | case ISCSI_BOOT_ETH_FLAGS: | ||
383 | case ISCSI_BOOT_ETH_MAC: | ||
384 | case ISCSI_BOOT_ETH_INDEX: | ||
385 | rc = S_IRUGO; | ||
386 | break; | ||
387 | default: | ||
388 | rc = 0; | ||
389 | break; | ||
390 | } | ||
391 | return rc; | ||
392 | } | ||
393 | |||
394 | static int beiscsi_setup_boot_info(struct beiscsi_hba *phba) | ||
395 | { | ||
396 | struct iscsi_boot_kobj *boot_kobj; | ||
397 | |||
398 | phba->boot_kset = iscsi_boot_create_host_kset(phba->shost->host_no); | ||
399 | if (!phba->boot_kset) | ||
400 | return -ENOMEM; | ||
401 | |||
402 | /* get boot info using mgmt cmd */ | ||
403 | boot_kobj = iscsi_boot_create_target(phba->boot_kset, 0, phba, | ||
404 | beiscsi_show_boot_tgt_info, | ||
405 | beiscsi_tgt_get_attr_visibility); | ||
406 | if (!boot_kobj) | ||
407 | goto free_kset; | ||
408 | |||
409 | boot_kobj = iscsi_boot_create_initiator(phba->boot_kset, 0, phba, | ||
410 | beiscsi_show_boot_ini_info, | ||
411 | beiscsi_ini_get_attr_visibility); | ||
412 | if (!boot_kobj) | ||
413 | goto free_kset; | ||
414 | |||
415 | boot_kobj = iscsi_boot_create_ethernet(phba->boot_kset, 0, phba, | ||
416 | beiscsi_show_boot_eth_info, | ||
417 | beiscsi_eth_get_attr_visibility); | ||
418 | if (!boot_kobj) | ||
419 | goto free_kset; | ||
420 | return 0; | ||
421 | |||
422 | free_kset: | ||
423 | iscsi_boot_destroy_kset(phba->boot_kset); | ||
424 | return -ENOMEM; | ||
425 | } | ||
426 | |||
214 | /*------------------- PCI Driver operations and data ----------------- */ | 427 | /*------------------- PCI Driver operations and data ----------------- */ |
215 | static DEFINE_PCI_DEVICE_TABLE(beiscsi_pci_id_table) = { | 428 | static DEFINE_PCI_DEVICE_TABLE(beiscsi_pci_id_table) = { |
216 | { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) }, | 429 | { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) }, |
@@ -268,6 +481,15 @@ static struct beiscsi_hba *beiscsi_hba_alloc(struct pci_dev *pcidev) | |||
268 | 481 | ||
269 | if (iscsi_host_add(shost, &phba->pcidev->dev)) | 482 | if (iscsi_host_add(shost, &phba->pcidev->dev)) |
270 | goto free_devices; | 483 | goto free_devices; |
484 | |||
485 | if (beiscsi_setup_boot_info(phba)) | ||
486 | /* | ||
487 | * log error but continue, because we may not be using | ||
488 | * iscsi boot. | ||
489 | */ | ||
490 | shost_printk(KERN_ERR, phba->shost, "Could not set up " | ||
491 | "iSCSI boot info."); | ||
492 | |||
271 | return phba; | 493 | return phba; |
272 | 494 | ||
273 | free_devices: | 495 | free_devices: |
@@ -3279,6 +3501,89 @@ static void hwi_disable_intr(struct beiscsi_hba *phba) | |||
3279 | "In hwi_disable_intr, Already Disabled\n"); | 3501 | "In hwi_disable_intr, Already Disabled\n"); |
3280 | } | 3502 | } |
3281 | 3503 | ||
3504 | static int beiscsi_get_boot_info(struct beiscsi_hba *phba) | ||
3505 | { | ||
3506 | struct be_cmd_resp_get_boot_target *boot_resp; | ||
3507 | struct be_cmd_resp_get_session *session_resp; | ||
3508 | struct be_mcc_wrb *wrb; | ||
3509 | struct be_dma_mem nonemb_cmd; | ||
3510 | unsigned int tag, wrb_num; | ||
3511 | unsigned short status, extd_status; | ||
3512 | struct be_queue_info *mccq = &phba->ctrl.mcc_obj.q; | ||
3513 | |||
3514 | tag = beiscsi_get_boot_target(phba); | ||
3515 | if (!tag) { | ||
3516 | SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed\n"); | ||
3517 | return -EAGAIN; | ||
3518 | } else | ||
3519 | wait_event_interruptible(phba->ctrl.mcc_wait[tag], | ||
3520 | phba->ctrl.mcc_numtag[tag]); | ||
3521 | |||
3522 | wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16; | ||
3523 | extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8; | ||
3524 | status = phba->ctrl.mcc_numtag[tag] & 0x000000FF; | ||
3525 | if (status || extd_status) { | ||
3526 | SE_DEBUG(DBG_LVL_1, "be_cmd_get_mac_addr Failed" | ||
3527 | " status = %d extd_status = %d\n", | ||
3528 | status, extd_status); | ||
3529 | free_mcc_tag(&phba->ctrl, tag); | ||
3530 | return -EBUSY; | ||
3531 | } | ||
3532 | wrb = queue_get_wrb(mccq, wrb_num); | ||
3533 | free_mcc_tag(&phba->ctrl, tag); | ||
3534 | boot_resp = embedded_payload(wrb); | ||
3535 | |||
3536 | if (boot_resp->boot_session_handle < 0) { | ||
3537 | printk(KERN_ERR "No Boot Session for this pci_func," | ||
3538 | "session Hndl = %d\n", boot_resp->boot_session_handle); | ||
3539 | return -ENXIO; | ||
3540 | } | ||
3541 | |||
3542 | nonemb_cmd.va = pci_alloc_consistent(phba->ctrl.pdev, | ||
3543 | sizeof(*session_resp), | ||
3544 | &nonemb_cmd.dma); | ||
3545 | if (nonemb_cmd.va == NULL) { | ||
3546 | SE_DEBUG(DBG_LVL_1, | ||
3547 | "Failed to allocate memory for" | ||
3548 | "beiscsi_get_session_info\n"); | ||
3549 | return -ENOMEM; | ||
3550 | } | ||
3551 | |||
3552 | memset(nonemb_cmd.va, 0, sizeof(*session_resp)); | ||
3553 | tag = beiscsi_get_session_info(phba, | ||
3554 | boot_resp->boot_session_handle, &nonemb_cmd); | ||
3555 | if (!tag) { | ||
3556 | SE_DEBUG(DBG_LVL_1, "beiscsi_get_session_info" | ||
3557 | " Failed\n"); | ||
3558 | goto boot_freemem; | ||
3559 | } else | ||
3560 | wait_event_interruptible(phba->ctrl.mcc_wait[tag], | ||
3561 | phba->ctrl.mcc_numtag[tag]); | ||
3562 | |||
3563 | wrb_num = (phba->ctrl.mcc_numtag[tag] & 0x00FF0000) >> 16; | ||
3564 | extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8; | ||
3565 | status = phba->ctrl.mcc_numtag[tag] & 0x000000FF; | ||
3566 | if (status || extd_status) { | ||
3567 | SE_DEBUG(DBG_LVL_1, "beiscsi_get_session_info Failed" | ||
3568 | " status = %d extd_status = %d\n", | ||
3569 | status, extd_status); | ||
3570 | free_mcc_tag(&phba->ctrl, tag); | ||
3571 | goto boot_freemem; | ||
3572 | } | ||
3573 | wrb = queue_get_wrb(mccq, wrb_num); | ||
3574 | free_mcc_tag(&phba->ctrl, tag); | ||
3575 | session_resp = nonemb_cmd.va ; | ||
3576 | memcpy(&phba->boot_sess, &session_resp->session_info, | ||
3577 | sizeof(struct mgmt_session_info)); | ||
3578 | pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, | ||
3579 | nonemb_cmd.va, nonemb_cmd.dma); | ||
3580 | return 0; | ||
3581 | boot_freemem: | ||
3582 | pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size, | ||
3583 | nonemb_cmd.va, nonemb_cmd.dma); | ||
3584 | return -ENOMEM; | ||
3585 | } | ||
3586 | |||
3282 | static int beiscsi_init_port(struct beiscsi_hba *phba) | 3587 | static int beiscsi_init_port(struct beiscsi_hba *phba) |
3283 | { | 3588 | { |
3284 | int ret; | 3589 | int ret; |
@@ -3841,6 +4146,7 @@ static void beiscsi_remove(struct pci_dev *pcidev) | |||
3841 | iscsi_host_remove(phba->shost); | 4146 | iscsi_host_remove(phba->shost); |
3842 | pci_dev_put(phba->pcidev); | 4147 | pci_dev_put(phba->pcidev); |
3843 | iscsi_host_free(phba->shost); | 4148 | iscsi_host_free(phba->shost); |
4149 | iscsi_boot_destroy_kset(phba->boot_kset); | ||
3844 | } | 4150 | } |
3845 | 4151 | ||
3846 | static void beiscsi_msix_enable(struct beiscsi_hba *phba) | 4152 | static void beiscsi_msix_enable(struct beiscsi_hba *phba) |
@@ -3996,6 +4302,11 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev, | |||
3996 | goto free_blkenbld; | 4302 | goto free_blkenbld; |
3997 | } | 4303 | } |
3998 | hwi_enable_intr(phba); | 4304 | hwi_enable_intr(phba); |
4305 | ret = beiscsi_get_boot_info(phba); | ||
4306 | if (ret < 0) { | ||
4307 | shost_printk(KERN_ERR, phba->shost, "beiscsi_dev_probe-" | ||
4308 | "No Boot Devices !!!!!\n"); | ||
4309 | } | ||
3999 | SE_DEBUG(DBG_LVL_8, "\n\n\n SUCCESS - DRIVER LOADED\n\n\n"); | 4310 | SE_DEBUG(DBG_LVL_8, "\n\n\n SUCCESS - DRIVER LOADED\n\n\n"); |
4000 | return 0; | 4311 | return 0; |
4001 | 4312 | ||
diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h index c643bb3736fc..48b7d4d28d9d 100644 --- a/drivers/scsi/be2iscsi/be_main.h +++ b/drivers/scsi/be2iscsi/be_main.h | |||
@@ -312,6 +312,7 @@ struct beiscsi_hba { | |||
312 | struct list_head hba_queue; | 312 | struct list_head hba_queue; |
313 | unsigned short *cid_array; | 313 | unsigned short *cid_array; |
314 | struct iscsi_endpoint **ep_array; | 314 | struct iscsi_endpoint **ep_array; |
315 | struct iscsi_boot_kset *boot_kset; | ||
315 | struct Scsi_Host *shost; | 316 | struct Scsi_Host *shost; |
316 | struct { | 317 | struct { |
317 | /** | 318 | /** |
@@ -342,6 +343,8 @@ struct beiscsi_hba { | |||
342 | struct work_struct work_cqs; /* The work being queued */ | 343 | struct work_struct work_cqs; /* The work being queued */ |
343 | struct be_ctrl_info ctrl; | 344 | struct be_ctrl_info ctrl; |
344 | unsigned int generation; | 345 | unsigned int generation; |
346 | unsigned int read_mac_address; | ||
347 | struct mgmt_session_info boot_sess; | ||
345 | struct invalidate_command_table inv_tbl[128]; | 348 | struct invalidate_command_table inv_tbl[128]; |
346 | 349 | ||
347 | }; | 350 | }; |
diff --git a/drivers/scsi/be2iscsi/be_mgmt.c b/drivers/scsi/be2iscsi/be_mgmt.c index 3f3fab91a7d1..26350e470bcc 100644 --- a/drivers/scsi/be2iscsi/be_mgmt.c +++ b/drivers/scsi/be2iscsi/be_mgmt.c | |||
@@ -20,6 +20,77 @@ | |||
20 | 20 | ||
21 | #include "be_mgmt.h" | 21 | #include "be_mgmt.h" |
22 | #include "be_iscsi.h" | 22 | #include "be_iscsi.h" |
23 | #include <scsi/scsi_transport_iscsi.h> | ||
24 | |||
25 | unsigned int beiscsi_get_boot_target(struct beiscsi_hba *phba) | ||
26 | { | ||
27 | struct be_ctrl_info *ctrl = &phba->ctrl; | ||
28 | struct be_mcc_wrb *wrb; | ||
29 | struct be_cmd_req_get_mac_addr *req; | ||
30 | unsigned int tag = 0; | ||
31 | |||
32 | SE_DEBUG(DBG_LVL_8, "In bescsi_get_boot_target\n"); | ||
33 | spin_lock(&ctrl->mbox_lock); | ||
34 | tag = alloc_mcc_tag(phba); | ||
35 | if (!tag) { | ||
36 | spin_unlock(&ctrl->mbox_lock); | ||
37 | return tag; | ||
38 | } | ||
39 | |||
40 | wrb = wrb_from_mccq(phba); | ||
41 | req = embedded_payload(wrb); | ||
42 | wrb->tag0 |= tag; | ||
43 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); | ||
44 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI, | ||
45 | OPCODE_ISCSI_INI_BOOT_GET_BOOT_TARGET, | ||
46 | sizeof(*req)); | ||
47 | |||
48 | be_mcc_notify(phba); | ||
49 | spin_unlock(&ctrl->mbox_lock); | ||
50 | return tag; | ||
51 | } | ||
52 | |||
53 | unsigned int beiscsi_get_session_info(struct beiscsi_hba *phba, | ||
54 | u32 boot_session_handle, | ||
55 | struct be_dma_mem *nonemb_cmd) | ||
56 | { | ||
57 | struct be_ctrl_info *ctrl = &phba->ctrl; | ||
58 | struct be_mcc_wrb *wrb; | ||
59 | unsigned int tag = 0; | ||
60 | struct be_cmd_req_get_session *req; | ||
61 | struct be_cmd_resp_get_session *resp; | ||
62 | struct be_sge *sge; | ||
63 | |||
64 | SE_DEBUG(DBG_LVL_8, "In beiscsi_get_session_info\n"); | ||
65 | spin_lock(&ctrl->mbox_lock); | ||
66 | tag = alloc_mcc_tag(phba); | ||
67 | if (!tag) { | ||
68 | spin_unlock(&ctrl->mbox_lock); | ||
69 | return tag; | ||
70 | } | ||
71 | |||
72 | nonemb_cmd->size = sizeof(*resp); | ||
73 | req = nonemb_cmd->va; | ||
74 | memset(req, 0, sizeof(*req)); | ||
75 | wrb = wrb_from_mccq(phba); | ||
76 | sge = nonembedded_sgl(wrb); | ||
77 | wrb->tag0 |= tag; | ||
78 | |||
79 | |||
80 | wrb->tag0 |= tag; | ||
81 | be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1); | ||
82 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_ISCSI_INI, | ||
83 | OPCODE_ISCSI_INI_SESSION_GET_A_SESSION, | ||
84 | sizeof(*resp)); | ||
85 | req->session_handle = boot_session_handle; | ||
86 | sge->pa_hi = cpu_to_le32(upper_32_bits(nonemb_cmd->dma)); | ||
87 | sge->pa_lo = cpu_to_le32(nonemb_cmd->dma & 0xFFFFFFFF); | ||
88 | sge->len = cpu_to_le32(nonemb_cmd->size); | ||
89 | |||
90 | be_mcc_notify(phba); | ||
91 | spin_unlock(&ctrl->mbox_lock); | ||
92 | return tag; | ||
93 | } | ||
23 | 94 | ||
24 | int mgmt_get_fw_config(struct be_ctrl_info *ctrl, | 95 | int mgmt_get_fw_config(struct be_ctrl_info *ctrl, |
25 | struct beiscsi_hba *phba) | 96 | struct beiscsi_hba *phba) |