16cefaae1SJack Meng /*
26cefaae1SJack Meng * CDDL HEADER START
36cefaae1SJack Meng *
46cefaae1SJack Meng * The contents of this file are subject to the terms of the
56cefaae1SJack Meng * Common Development and Distribution License (the "License").
66cefaae1SJack Meng * You may not use this file except in compliance with the License.
76cefaae1SJack Meng *
86cefaae1SJack Meng * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
96cefaae1SJack Meng * or http://www.opensolaris.org/os/licensing.
106cefaae1SJack Meng * See the License for the specific language governing permissions
116cefaae1SJack Meng * and limitations under the License.
126cefaae1SJack Meng *
136cefaae1SJack Meng * When distributing Covered Code, include this CDDL HEADER in each
146cefaae1SJack Meng * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
156cefaae1SJack Meng * If applicable, add the following below this CDDL HEADER, with the
166cefaae1SJack Meng * fields enclosed by brackets "[]" replaced with your own identifying
176cefaae1SJack Meng * information: Portions Copyright [yyyy] [name of copyright owner]
186cefaae1SJack Meng *
196cefaae1SJack Meng * CDDL HEADER END
206cefaae1SJack Meng */
216cefaae1SJack Meng
226cefaae1SJack Meng /*
23474eb465Svitezslav batrla - Sun Microsystems - Prague Czech Republic * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
246cefaae1SJack Meng * Use is subject to license terms.
256cefaae1SJack Meng */
266cefaae1SJack Meng
276cefaae1SJack Meng /*
286cefaae1SJack Meng * This is the place to implement ld_ib_props()
296cefaae1SJack Meng * For x86 it is to load iBFT and costruct the global ib props
306cefaae1SJack Meng */
316cefaae1SJack Meng
326cefaae1SJack Meng #include <sys/types.h>
33*4870e0a7SRichard PALO #include <sys/null.h>
346cefaae1SJack Meng #include <sys/cmn_err.h>
356cefaae1SJack Meng #include <sys/socket.h>
366cefaae1SJack Meng #include <netinet/in.h>
376cefaae1SJack Meng #include <sys/mman.h>
386cefaae1SJack Meng #include <sys/bootprops.h>
396cefaae1SJack Meng #include <sys/kmem.h>
406cefaae1SJack Meng #include <sys/psm.h>
41474eb465Svitezslav batrla - Sun Microsystems - Prague Czech Republic #include <sys/bootconf.h>
426cefaae1SJack Meng
436cefaae1SJack Meng typedef enum ibft_structure_type {
446cefaae1SJack Meng Reserved = 0,
456cefaae1SJack Meng Control = 1,
466cefaae1SJack Meng Initiator = 2,
476cefaae1SJack Meng Nic = 3,
486cefaae1SJack Meng Target = 4,
496cefaae1SJack Meng Extensions = 5,
506cefaae1SJack Meng Type_End
516cefaae1SJack Meng }ibft_struct_type;
526cefaae1SJack Meng
536cefaae1SJack Meng typedef enum _chap_type {
546cefaae1SJack Meng NO_CHAP = 0,
556cefaae1SJack Meng CHAP = 1,
566cefaae1SJack Meng Mutual_CHAP = 2,
576cefaae1SJack Meng TYPE_UNKNOWN
586cefaae1SJack Meng }chap_type;
596cefaae1SJack Meng
606cefaae1SJack Meng typedef struct ibft_entry {
616cefaae1SJack Meng int af;
626cefaae1SJack Meng int e_port;
636cefaae1SJack Meng char target_name[224];
646cefaae1SJack Meng char target_addr[INET6_ADDRSTRLEN];
656cefaae1SJack Meng }ibft_entry_t;
666cefaae1SJack Meng
676cefaae1SJack Meng typedef struct iSCSI_ibft_tbl_hdr {
686cefaae1SJack Meng char Signature[4];
696cefaae1SJack Meng int Length;
706cefaae1SJack Meng char Revision;
716cefaae1SJack Meng char Checksum;
726cefaae1SJack Meng char oem_id[6];
736cefaae1SJack Meng char oem_table_id[8];
746cefaae1SJack Meng char Reserved[24];
756cefaae1SJack Meng }iscsi_ibft_tbl_hdr_t;
766cefaae1SJack Meng
776cefaae1SJack Meng typedef struct iSCSI_ibft_hdr {
786cefaae1SJack Meng char Structure_id;
796cefaae1SJack Meng char Version;
806cefaae1SJack Meng ushort_t Length;
816cefaae1SJack Meng char Index;
826cefaae1SJack Meng char Flags;
836cefaae1SJack Meng }iscsi_ibft_hdr_t;
846cefaae1SJack Meng
856cefaae1SJack Meng typedef struct iSCSI_ibft_control {
866cefaae1SJack Meng iscsi_ibft_hdr_t header;
876cefaae1SJack Meng ushort_t Extensions;
886cefaae1SJack Meng ushort_t Initiator_offset;
896cefaae1SJack Meng ushort_t Nic0_offset;
906cefaae1SJack Meng ushort_t Target0_offset;
916cefaae1SJack Meng ushort_t Nic1_offset;
926cefaae1SJack Meng ushort_t Target1_offset;
936cefaae1SJack Meng }iscsi_ibft_ctl_t;
946cefaae1SJack Meng
956cefaae1SJack Meng typedef struct iSCSI_ibft_initiator {
966cefaae1SJack Meng iscsi_ibft_hdr_t header;
976cefaae1SJack Meng uchar_t iSNS_Server[16];
986cefaae1SJack Meng uchar_t SLP_Server[16];
996cefaae1SJack Meng uchar_t Pri_Radius_Server[16];
1006cefaae1SJack Meng uchar_t Sec_Radius_Server[16];
1016cefaae1SJack Meng ushort_t ini_name_len;
1026cefaae1SJack Meng ushort_t ini_name_offset;
1036cefaae1SJack Meng }iscsi_ibft_initiator_t;
1046cefaae1SJack Meng
1056cefaae1SJack Meng typedef struct iSCSI_ibft_nic {
1066cefaae1SJack Meng iscsi_ibft_hdr_t header;
1076cefaae1SJack Meng uchar_t ip_addr[16];
1086cefaae1SJack Meng char Subnet_Mask_Prefix;
1096cefaae1SJack Meng char Origin;
1106cefaae1SJack Meng uchar_t Gateway[16];
1116cefaae1SJack Meng uchar_t Primary_dns[16];
1126cefaae1SJack Meng uchar_t Secondary_dns[16];
1136cefaae1SJack Meng uchar_t dhcp[16];
1146cefaae1SJack Meng ushort_t vlan;
1156cefaae1SJack Meng char mac[6];
1166cefaae1SJack Meng ushort_t pci_BDF;
1176cefaae1SJack Meng ushort_t Hostname_len;
1186cefaae1SJack Meng ushort_t Hostname_offset;
1196cefaae1SJack Meng }iscsi_ibft_nic_t;
1206cefaae1SJack Meng
1216cefaae1SJack Meng typedef struct iSCSI_ibft_target {
1226cefaae1SJack Meng iscsi_ibft_hdr_t header;
1236cefaae1SJack Meng uchar_t ip_addr[16];
1246cefaae1SJack Meng ushort_t port;
1256cefaae1SJack Meng uchar_t boot_lun[8];
1266cefaae1SJack Meng uchar_t chap_type;
1276cefaae1SJack Meng uchar_t nic_association;
1286cefaae1SJack Meng ushort_t target_name_len;
1296cefaae1SJack Meng ushort_t target_name_offset;
1306cefaae1SJack Meng ushort_t chap_name_len;
1316cefaae1SJack Meng ushort_t chap_name_offset;
1326cefaae1SJack Meng ushort_t chap_secret_len;
1336cefaae1SJack Meng ushort_t chap_secret_offset;
1346cefaae1SJack Meng ushort_t rev_chap_name_len;
1356cefaae1SJack Meng ushort_t rev_chap_name_offset;
1366cefaae1SJack Meng ushort_t rev_chap_secret_len;
1376cefaae1SJack Meng ushort_t rev_chap_secret_offset;
1386cefaae1SJack Meng }iscsi_ibft_tgt_t;
1396cefaae1SJack Meng
1406cefaae1SJack Meng #define ISCSI_IBFT_LOWER_ADDR 0x80000 /* 512K */
1416cefaae1SJack Meng #define ISCSI_IBFT_HIGHER_ADDR 0x100000 /* 1024K */
1426cefaae1SJack Meng #define ISCSI_IBFT_SIGNATRUE "iBFT"
1436cefaae1SJack Meng #define ISCSI_IBFT_SIGNATURE_LEN 4
1446cefaae1SJack Meng #define ISCSI_IBFT_TBL_BUF_LEN 1024
1456cefaae1SJack Meng #define ISCSI_IBFT_ALIGNED 16
1466cefaae1SJack Meng #define ISCSI_IBFT_CTL_OFFSET 48
1476cefaae1SJack Meng
1486cefaae1SJack Meng #define IBFT_BLOCK_VALID_YES 0x01 /* bit 0 */
1496cefaae1SJack Meng #define IBFT_FIRMWARE_BOOT_SELECTED 0x02 /* bit 1 */
1506cefaae1SJack Meng #define IBFT_USE_RADIUS_CHAP 0x04 /* bit 2 */
1516cefaae1SJack Meng #define IBFT_USE_GLOBLE 0x04 /* NIC structure */
1526cefaae1SJack Meng #define IBFT_USE_RADIUS_RHCAP 0x08 /* bit 3 */
1536cefaae1SJack Meng
1546cefaae1SJack Meng /*
1556cefaae1SJack Meng * Currently, we only support initiator offset, NIC0 offset, Target0 offset,
1566cefaae1SJack Meng * NIC1 offset and Target1 offset. So the length is 5. If we want to support
1576cefaae1SJack Meng * extensions, we should change this number.
1586cefaae1SJack Meng */
1596cefaae1SJack Meng #define IBFT_OFFSET_BUF_LEN 5
1606cefaae1SJack Meng #define IPV4_OFFSET 12
1616cefaae1SJack Meng
1626cefaae1SJack Meng #define IBFT_INVALID_MSG "Invalid iBFT table 0x%x"
163474eb465Svitezslav batrla - Sun Microsystems - Prague Czech Republic #define IBFT_NOPROBE_MSG "iSCSI boot is disabled"
1646cefaae1SJack Meng
1656cefaae1SJack Meng typedef enum ibft_status {
1666cefaae1SJack Meng IBFT_STATUS_OK = 0,
1676cefaae1SJack Meng /* General error */
1686cefaae1SJack Meng IBFT_STATUS_ERR,
1696cefaae1SJack Meng /* Bad header */
1706cefaae1SJack Meng IBFT_STATUS_BADHDR,
1716cefaae1SJack Meng /* Bad control ID */
1726cefaae1SJack Meng IBFT_STATUS_BADCID,
1736cefaae1SJack Meng /* Bad ip addr */
1746cefaae1SJack Meng IBFT_STATUS_BADIP,
1756cefaae1SJack Meng /* Bad af */
1766cefaae1SJack Meng IBFT_STATUS_BADAF,
1776cefaae1SJack Meng /* Bad chap name */
1786cefaae1SJack Meng IBFT_STATUS_BADCHAPNAME,
1796cefaae1SJack Meng /* Bad chap secret */
1806cefaae1SJack Meng IBFT_STATUS_BADCHAPSEC,
1816cefaae1SJack Meng /* Bad checksum */
1826cefaae1SJack Meng IBFT_STATUS_BADCHECKSUM,
1836cefaae1SJack Meng /* Low memory */
1846cefaae1SJack Meng IBFT_STATUS_LOWMEM,
1856cefaae1SJack Meng /* No table */
1866cefaae1SJack Meng IBFT_STATUS_NOTABLE
1876cefaae1SJack Meng } ibft_status_t;
1886cefaae1SJack Meng
1896cefaae1SJack Meng extern void *memset(void *s, int c, size_t n);
1906cefaae1SJack Meng extern int memcmp(const void *s1, const void *s2, size_t n);
1916cefaae1SJack Meng extern void bcopy(const void *s1, void *s2, size_t n);
1926cefaae1SJack Meng extern void iscsi_print_boot_property();
1936cefaae1SJack Meng
194474eb465Svitezslav batrla - Sun Microsystems - Prague Czech Republic int ibft_noprobe = 0;
1956cefaae1SJack Meng ib_boot_prop_t boot_property; /* static allocated */
1966cefaae1SJack Meng extern ib_boot_prop_t *iscsiboot_prop; /* to be filled */
1976cefaae1SJack Meng
1986cefaae1SJack Meng static ibft_status_t iscsi_parse_ibft_control(iscsi_ibft_ctl_t *ctl_hdr,
1996cefaae1SJack Meng ushort_t *iscsi_offset_buf);
2006cefaae1SJack Meng
2016cefaae1SJack Meng static ibft_status_t iscsi_parse_ibft_initiator(char *begin_of_ibft,
2026cefaae1SJack Meng iscsi_ibft_initiator_t *initiator);
2036cefaae1SJack Meng
2046cefaae1SJack Meng static ibft_status_t iscsi_parse_ibft_NIC(iscsi_ibft_nic_t *nicp);
2056cefaae1SJack Meng
2066cefaae1SJack Meng static ibft_status_t iscsi_parse_ibft_target(char *begin_of_ibft,
2076cefaae1SJack Meng iscsi_ibft_tgt_t *tgtp);
2086cefaae1SJack Meng
2096cefaae1SJack Meng
2106cefaae1SJack Meng /*
2116cefaae1SJack Meng * Return value:
2126cefaae1SJack Meng * Success: IBFT_STATUS_OK
2136cefaae1SJack Meng * Fail: IBFT_STATUS_BADCHECKSUM
2146cefaae1SJack Meng */
2156cefaae1SJack Meng static ibft_status_t
iscsi_ibft_hdr_checksum(iscsi_ibft_tbl_hdr_t * tbl_hdr)2166cefaae1SJack Meng iscsi_ibft_hdr_checksum(iscsi_ibft_tbl_hdr_t *tbl_hdr)
2176cefaae1SJack Meng {
2186cefaae1SJack Meng uchar_t checksum = 0;
2196cefaae1SJack Meng uchar_t *start = NULL;
2206cefaae1SJack Meng int length = 0;
2216cefaae1SJack Meng int i = 0;
2226cefaae1SJack Meng
2236cefaae1SJack Meng if (tbl_hdr == NULL) {
2246cefaae1SJack Meng return (IBFT_STATUS_BADHDR);
2256cefaae1SJack Meng }
2266cefaae1SJack Meng
2276cefaae1SJack Meng length = tbl_hdr->Length;
2286cefaae1SJack Meng start = (uchar_t *)tbl_hdr;
2296cefaae1SJack Meng
2306cefaae1SJack Meng for (i = 0; i < length; i++) {
2316cefaae1SJack Meng checksum = checksum + start[i];
2326cefaae1SJack Meng }
2336cefaae1SJack Meng
2346cefaae1SJack Meng if (!checksum)
2356cefaae1SJack Meng return (IBFT_STATUS_OK);
2366cefaae1SJack Meng else
2376cefaae1SJack Meng return (IBFT_STATUS_BADCHECKSUM);
2386cefaae1SJack Meng }
2396cefaae1SJack Meng
2406cefaae1SJack Meng /*
2416cefaae1SJack Meng * Now we only support one control structure in the IBFT.
2426cefaae1SJack Meng * So there is no Control ID here.
2436cefaae1SJack Meng */
2446cefaae1SJack Meng static ibft_status_t
iscsi_parse_ibft_structure(char * begin_of_ibft,char * buf)2456cefaae1SJack Meng iscsi_parse_ibft_structure(char *begin_of_ibft, char *buf)
2466cefaae1SJack Meng {
2476cefaae1SJack Meng iscsi_ibft_hdr_t *hdr = NULL;
2486cefaae1SJack Meng ibft_status_t ret = IBFT_STATUS_OK;
2496cefaae1SJack Meng
2506cefaae1SJack Meng if (buf == NULL) {
2516cefaae1SJack Meng return (IBFT_STATUS_ERR);
2526cefaae1SJack Meng }
2536cefaae1SJack Meng
2546cefaae1SJack Meng hdr = (iscsi_ibft_hdr_t *)buf;
2556cefaae1SJack Meng switch (hdr->Structure_id) {
2566cefaae1SJack Meng case Initiator:
2576cefaae1SJack Meng ret = iscsi_parse_ibft_initiator(
2586cefaae1SJack Meng begin_of_ibft,
2596cefaae1SJack Meng (iscsi_ibft_initiator_t *)buf);
2606cefaae1SJack Meng break;
2616cefaae1SJack Meng case Nic:
2626cefaae1SJack Meng ret = iscsi_parse_ibft_NIC(
2636cefaae1SJack Meng (iscsi_ibft_nic_t *)buf);
2646cefaae1SJack Meng break;
2656cefaae1SJack Meng case Target:
2666cefaae1SJack Meng ret = iscsi_parse_ibft_target(
2676cefaae1SJack Meng begin_of_ibft,
2686cefaae1SJack Meng (iscsi_ibft_tgt_t *)buf);
2696cefaae1SJack Meng break;
2706cefaae1SJack Meng default:
2716cefaae1SJack Meng ret = IBFT_STATUS_BADHDR;
2726cefaae1SJack Meng break;
2736cefaae1SJack Meng }
2746cefaae1SJack Meng
2756cefaae1SJack Meng return (ret);
2766cefaae1SJack Meng }
2776cefaae1SJack Meng
2786cefaae1SJack Meng /*
2796cefaae1SJack Meng * Parse the iBFT table
2806cefaae1SJack Meng * return IBFT_STATUS_OK upon sucess
2816cefaae1SJack Meng */
2826cefaae1SJack Meng static ibft_status_t
iscsi_parse_ibft_tbl(iscsi_ibft_tbl_hdr_t * tbl_hdr)2836cefaae1SJack Meng iscsi_parse_ibft_tbl(iscsi_ibft_tbl_hdr_t *tbl_hdr)
2846cefaae1SJack Meng {
2856cefaae1SJack Meng char *outbuf = NULL;
2866cefaae1SJack Meng int i = 0;
2876cefaae1SJack Meng ibft_status_t ret = IBFT_STATUS_OK;
2886cefaae1SJack Meng ushort_t iscsi_offset_buf[IBFT_OFFSET_BUF_LEN] = {0};
2896cefaae1SJack Meng
2906cefaae1SJack Meng if (tbl_hdr == NULL) {
2916cefaae1SJack Meng return (IBFT_STATUS_ERR);
2926cefaae1SJack Meng }
2936cefaae1SJack Meng
2946cefaae1SJack Meng if (iscsi_ibft_hdr_checksum(tbl_hdr) != IBFT_STATUS_OK) {
2956cefaae1SJack Meng return (IBFT_STATUS_BADCHECKSUM);
2966cefaae1SJack Meng }
2976cefaae1SJack Meng
2986cefaae1SJack Meng outbuf = (char *)tbl_hdr;
2996cefaae1SJack Meng
3006cefaae1SJack Meng ret = iscsi_parse_ibft_control(
3016cefaae1SJack Meng (iscsi_ibft_ctl_t *)&outbuf[ISCSI_IBFT_CTL_OFFSET],
3026cefaae1SJack Meng iscsi_offset_buf);
3036cefaae1SJack Meng
3046cefaae1SJack Meng if (ret == IBFT_STATUS_OK) {
3056cefaae1SJack Meng ret = IBFT_STATUS_ERR;
3066cefaae1SJack Meng for (i = 0; i < IBFT_OFFSET_BUF_LEN; i++) {
3076cefaae1SJack Meng if (iscsi_offset_buf[i] != 0) {
3086cefaae1SJack Meng ret = iscsi_parse_ibft_structure(
3096cefaae1SJack Meng (char *)tbl_hdr,
3106cefaae1SJack Meng (char *)tbl_hdr +
3116cefaae1SJack Meng iscsi_offset_buf[i]);
3126cefaae1SJack Meng if (ret != IBFT_STATUS_OK) {
3136cefaae1SJack Meng return (ret);
3146cefaae1SJack Meng }
3156cefaae1SJack Meng }
3166cefaae1SJack Meng }
3176cefaae1SJack Meng }
3186cefaae1SJack Meng
3196cefaae1SJack Meng return (ret);
3206cefaae1SJack Meng }
3216cefaae1SJack Meng
3226cefaae1SJack Meng static ibft_status_t
iscsi_parse_ibft_control(iscsi_ibft_ctl_t * ctl_hdr,ushort_t * iscsi_offset_buf)3236cefaae1SJack Meng iscsi_parse_ibft_control(iscsi_ibft_ctl_t *ctl_hdr,
3246cefaae1SJack Meng ushort_t *iscsi_offset_buf)
3256cefaae1SJack Meng {
3266cefaae1SJack Meng int i = 0;
3276cefaae1SJack Meng ushort_t *offsetp = NULL;
3286cefaae1SJack Meng
3296cefaae1SJack Meng if (ctl_hdr == NULL) {
3306cefaae1SJack Meng return (IBFT_STATUS_BADHDR);
3316cefaae1SJack Meng }
3326cefaae1SJack Meng
3336cefaae1SJack Meng if (ctl_hdr->header.Structure_id != Control) {
3346cefaae1SJack Meng return (IBFT_STATUS_BADCID);
3356cefaae1SJack Meng }
3366cefaae1SJack Meng
3376cefaae1SJack Meng /*
3386cefaae1SJack Meng * Copy the offsets to offset buffer.
3396cefaae1SJack Meng */
3406cefaae1SJack Meng for (offsetp = &(ctl_hdr->Initiator_offset); i < IBFT_OFFSET_BUF_LEN;
3416cefaae1SJack Meng offsetp++) {
3426cefaae1SJack Meng iscsi_offset_buf[i++] = *offsetp;
3436cefaae1SJack Meng }
3446cefaae1SJack Meng
3456cefaae1SJack Meng return (IBFT_STATUS_OK);
3466cefaae1SJack Meng }
3476cefaae1SJack Meng
3486cefaae1SJack Meng /*
3496cefaae1SJack Meng * We only copy the "Firmare Boot Selseted" and valid initiator
3506cefaae1SJack Meng * to the boot property.
3516cefaae1SJack Meng */
3526cefaae1SJack Meng static ibft_status_t
iscsi_parse_ibft_initiator(char * begin_of_ibft,iscsi_ibft_initiator_t * initiator)3536cefaae1SJack Meng iscsi_parse_ibft_initiator(char *begin_of_ibft,
3546cefaae1SJack Meng iscsi_ibft_initiator_t *initiator)
3556cefaae1SJack Meng {
3566cefaae1SJack Meng if (initiator == NULL) {
3576cefaae1SJack Meng return (IBFT_STATUS_ERR);
3586cefaae1SJack Meng }
3596cefaae1SJack Meng
3606cefaae1SJack Meng if (initiator->header.Structure_id != Initiator) {
3616cefaae1SJack Meng return (IBFT_STATUS_BADHDR);
3626cefaae1SJack Meng }
3636cefaae1SJack Meng
3646cefaae1SJack Meng if ((initiator->header.Flags & IBFT_FIRMWARE_BOOT_SELECTED) &&
3656cefaae1SJack Meng (initiator->header.Flags & IBFT_BLOCK_VALID_YES)) {
3666cefaae1SJack Meng /*
3676cefaae1SJack Meng * If the initiator name exists, we will copy it to our own
3686cefaae1SJack Meng * property structure
3696cefaae1SJack Meng */
3706cefaae1SJack Meng if (initiator->ini_name_len != 0) {
3716cefaae1SJack Meng boot_property.boot_init.ini_name =
3726cefaae1SJack Meng (uchar_t *)kmem_zalloc(
3736cefaae1SJack Meng initiator->ini_name_len + 1, KM_SLEEP);
374dedec472SJack Meng boot_property.boot_init.ini_name_len =
375dedec472SJack Meng initiator->ini_name_len + 1;
3766cefaae1SJack Meng (void) snprintf(
3776cefaae1SJack Meng (char *)boot_property.boot_init.ini_name,
3786cefaae1SJack Meng initiator->ini_name_len + 1, "%s",
3796cefaae1SJack Meng begin_of_ibft + initiator->ini_name_offset);
3806cefaae1SJack Meng }
3816cefaae1SJack Meng }
3826cefaae1SJack Meng return (IBFT_STATUS_OK);
3836cefaae1SJack Meng }
3846cefaae1SJack Meng
3856cefaae1SJack Meng static ibft_status_t
iscsi_parse_ipaddr(uchar_t * source,char * dest,int * af)3866cefaae1SJack Meng iscsi_parse_ipaddr(uchar_t *source, char *dest, int *af)
3876cefaae1SJack Meng {
3886cefaae1SJack Meng int i = 0;
3896cefaae1SJack Meng
3906cefaae1SJack Meng if (source == NULL) {
3916cefaae1SJack Meng return (IBFT_STATUS_ERR);
3926cefaae1SJack Meng }
3936cefaae1SJack Meng
3946cefaae1SJack Meng if (source[0] == 0x00 && source[1] == 0x00 &&
3956cefaae1SJack Meng source[2] == 0x00 && source[3] == 0x00 &&
3966cefaae1SJack Meng source[4] == 0x00 && source[5] == 0x00 &&
3976cefaae1SJack Meng source[6] == 0x00 && source[7] == 0x00 &&
3986cefaae1SJack Meng source[8] == 0x00 && source[9] == 0x00 &&
3996cefaae1SJack Meng (source[10] == 0xff) && (source[11] == 0xff)) {
4006cefaae1SJack Meng /*
4016cefaae1SJack Meng * IPv4 address
4026cefaae1SJack Meng */
4036cefaae1SJack Meng if (dest != NULL) {
4046cefaae1SJack Meng (void) sprintf(dest, "%d.%d.%d.%d",
4056cefaae1SJack Meng source[12], source[13], source[14], source[15]);
4066cefaae1SJack Meng }
4076cefaae1SJack Meng if (af != NULL) {
4086cefaae1SJack Meng *af = AF_INET;
4096cefaae1SJack Meng }
4106cefaae1SJack Meng } else {
4116cefaae1SJack Meng if (dest != NULL) {
4126cefaae1SJack Meng for (i = 0; i < 14; i = i + 2) {
4136cefaae1SJack Meng (void) sprintf(dest, "%02x%02x:", source[i],
4146cefaae1SJack Meng source[i+1]);
4156cefaae1SJack Meng dest = dest + 5;
4166cefaae1SJack Meng }
4176cefaae1SJack Meng (void) sprintf(dest, "%02x%02x",
4186cefaae1SJack Meng source[i], source[i+1]);
4196cefaae1SJack Meng }
4206cefaae1SJack Meng if (af != NULL) {
4216cefaae1SJack Meng *af = AF_INET6;
4226cefaae1SJack Meng }
4236cefaae1SJack Meng }
4246cefaae1SJack Meng
4256cefaae1SJack Meng return (IBFT_STATUS_OK);
4266cefaae1SJack Meng }
4276cefaae1SJack Meng
4286cefaae1SJack Meng /*
4296cefaae1SJack Meng * Copy the ip address from ibft. If IPv4 is used, we should copy
4306cefaae1SJack Meng * the address from 12th byte.
4316cefaae1SJack Meng */
4326cefaae1SJack Meng static ibft_status_t
iscsi_copy_ibft_ipaddr(uchar_t * source,void * dest,int * af)4336cefaae1SJack Meng iscsi_copy_ibft_ipaddr(uchar_t *source, void *dest, int *af)
4346cefaae1SJack Meng {
4356cefaae1SJack Meng ibft_status_t ret = IBFT_STATUS_OK;
4366cefaae1SJack Meng int sin_family = 0;
4376cefaae1SJack Meng
4386cefaae1SJack Meng if (source == NULL || dest == NULL) {
4396cefaae1SJack Meng return (IBFT_STATUS_ERR);
4406cefaae1SJack Meng }
4416cefaae1SJack Meng ret = iscsi_parse_ipaddr(source, NULL, &sin_family);
4426cefaae1SJack Meng if (ret != 0) {
4436cefaae1SJack Meng return (IBFT_STATUS_BADIP);
4446cefaae1SJack Meng }
4456cefaae1SJack Meng
4466cefaae1SJack Meng if (sin_family == AF_INET) {
4476cefaae1SJack Meng bcopy(source+IPV4_OFFSET, dest, sizeof (struct in_addr));
4486cefaae1SJack Meng } else if (sin_family == AF_INET6) {
4496cefaae1SJack Meng bcopy(source, dest, sizeof (struct in6_addr));
4506cefaae1SJack Meng } else {
4516cefaae1SJack Meng return (IBFT_STATUS_BADAF);
4526cefaae1SJack Meng }
4536cefaae1SJack Meng
4546cefaae1SJack Meng if (af != NULL) {
4556cefaae1SJack Meng *af = sin_family;
4566cefaae1SJack Meng }
4576cefaae1SJack Meng return (IBFT_STATUS_OK);
4586cefaae1SJack Meng }
4596cefaae1SJack Meng
4606cefaae1SJack Meng /*
4616cefaae1SJack Meng * Maybe there are multiply NICs are available. We only copy the
4626cefaae1SJack Meng * "Firmare Boot Selseted" and valid one to the boot property.
4636cefaae1SJack Meng */
4646cefaae1SJack Meng static ibft_status_t
iscsi_parse_ibft_NIC(iscsi_ibft_nic_t * nicp)4656cefaae1SJack Meng iscsi_parse_ibft_NIC(iscsi_ibft_nic_t *nicp)
4666cefaae1SJack Meng {
4676cefaae1SJack Meng ibft_status_t ret = IBFT_STATUS_OK;
4686cefaae1SJack Meng int af = 0;
4696cefaae1SJack Meng
4706cefaae1SJack Meng if (nicp == NULL) {
4716cefaae1SJack Meng return (IBFT_STATUS_ERR);
4726cefaae1SJack Meng }
4736cefaae1SJack Meng
4746cefaae1SJack Meng if (nicp->header.Structure_id != Nic) {
4756cefaae1SJack Meng return (IBFT_STATUS_ERR);
4766cefaae1SJack Meng }
4776cefaae1SJack Meng
4786cefaae1SJack Meng if ((nicp->header.Flags & IBFT_FIRMWARE_BOOT_SELECTED) &&
4796cefaae1SJack Meng (nicp->header.Flags & IBFT_BLOCK_VALID_YES)) {
4806cefaae1SJack Meng ret = iscsi_copy_ibft_ipaddr(nicp->ip_addr,
4816cefaae1SJack Meng &boot_property.boot_nic.nic_ip_u, &af);
4826cefaae1SJack Meng if (ret != IBFT_STATUS_OK) {
4836cefaae1SJack Meng return (ret);
4846cefaae1SJack Meng }
4856cefaae1SJack Meng
4866cefaae1SJack Meng boot_property.boot_nic.sin_family = af;
4876cefaae1SJack Meng
4886cefaae1SJack Meng ret = iscsi_copy_ibft_ipaddr(nicp->Gateway,
4896cefaae1SJack Meng &boot_property.boot_nic.nic_gw_u, NULL);
4906cefaae1SJack Meng if (ret != IBFT_STATUS_OK) {
4916cefaae1SJack Meng return (ret);
4926cefaae1SJack Meng }
4936cefaae1SJack Meng
4946cefaae1SJack Meng ret = iscsi_copy_ibft_ipaddr(nicp->dhcp,
4956cefaae1SJack Meng &boot_property.boot_nic.nic_dhcp_u, NULL);
4966cefaae1SJack Meng if (ret != IBFT_STATUS_OK) {
4976cefaae1SJack Meng return (ret);
4986cefaae1SJack Meng }
4996cefaae1SJack Meng
5006cefaae1SJack Meng bcopy(nicp->mac, boot_property.boot_nic.nic_mac, 6);
5016cefaae1SJack Meng boot_property.boot_nic.sub_mask_prefix =
5026cefaae1SJack Meng nicp->Subnet_Mask_Prefix;
5036cefaae1SJack Meng }
5046cefaae1SJack Meng
5056cefaae1SJack Meng return (IBFT_STATUS_OK);
5066cefaae1SJack Meng }
5076cefaae1SJack Meng
5086cefaae1SJack Meng /*
5096cefaae1SJack Meng * Maybe there are multiply targets are available. We only copy the
5106cefaae1SJack Meng * "Firmare Boot Selseted" and valid one to the boot property.
5116cefaae1SJack Meng */
5126cefaae1SJack Meng static ibft_status_t
iscsi_parse_ibft_target(char * begin_of_ibft,iscsi_ibft_tgt_t * tgtp)5136cefaae1SJack Meng iscsi_parse_ibft_target(char *begin_of_ibft, iscsi_ibft_tgt_t *tgtp)
5146cefaae1SJack Meng {
5156cefaae1SJack Meng char *tmp = NULL;
5166cefaae1SJack Meng int af = 0;
5176cefaae1SJack Meng ibft_status_t ret = IBFT_STATUS_OK;
5186cefaae1SJack Meng
5196cefaae1SJack Meng if (tgtp == NULL) {
5206cefaae1SJack Meng return (IBFT_STATUS_ERR);
5216cefaae1SJack Meng }
5226cefaae1SJack Meng
5236cefaae1SJack Meng if (tgtp->header.Structure_id != Target) {
5246cefaae1SJack Meng return (IBFT_STATUS_BADHDR);
5256cefaae1SJack Meng }
5266cefaae1SJack Meng
5276cefaae1SJack Meng if ((tgtp->header.Flags & IBFT_FIRMWARE_BOOT_SELECTED) &&
5286cefaae1SJack Meng (tgtp->header.Flags & IBFT_BLOCK_VALID_YES)) {
5296cefaae1SJack Meng /*
5306cefaae1SJack Meng * Get Target Address
5316cefaae1SJack Meng */
5326cefaae1SJack Meng ret = iscsi_copy_ibft_ipaddr(tgtp->ip_addr,
5336cefaae1SJack Meng &boot_property.boot_tgt.tgt_ip_u, &af);
5346cefaae1SJack Meng if (ret != IBFT_STATUS_OK) {
5356cefaae1SJack Meng return (ret);
5366cefaae1SJack Meng }
5376cefaae1SJack Meng boot_property.boot_tgt.sin_family = af;
5386cefaae1SJack Meng /*
5396cefaae1SJack Meng * Get Target Name
5406cefaae1SJack Meng */
5416cefaae1SJack Meng if (tgtp->target_name_len != 0) {
5426cefaae1SJack Meng boot_property.boot_tgt.tgt_name =
5436cefaae1SJack Meng (uchar_t *)kmem_zalloc(tgtp->target_name_len + 1,
5446cefaae1SJack Meng KM_SLEEP);
545dedec472SJack Meng boot_property.boot_tgt.tgt_name_len =
546dedec472SJack Meng tgtp->target_name_len + 1;
5476cefaae1SJack Meng (void) snprintf(
5486cefaae1SJack Meng (char *)boot_property.boot_tgt.tgt_name,
5496cefaae1SJack Meng tgtp->target_name_len + 1, "%s",
5506cefaae1SJack Meng begin_of_ibft + tgtp->target_name_offset);
5516cefaae1SJack Meng } else {
5526cefaae1SJack Meng boot_property.boot_tgt.tgt_name = NULL;
5536cefaae1SJack Meng }
5546cefaae1SJack Meng
5556cefaae1SJack Meng /* Get Dest Port */
5566cefaae1SJack Meng boot_property.boot_tgt.tgt_port = tgtp->port;
5576cefaae1SJack Meng
5586cefaae1SJack Meng boot_property.boot_tgt.lun_online = 0;
5596cefaae1SJack Meng
5606cefaae1SJack Meng /*
5616cefaae1SJack Meng * Get CHAP secret and name.
5626cefaae1SJack Meng */
5636cefaae1SJack Meng if (tgtp->chap_type != NO_CHAP) {
5646cefaae1SJack Meng if (tgtp->chap_name_len != 0) {
5656cefaae1SJack Meng boot_property.boot_init.ini_chap_name =
5666cefaae1SJack Meng (uchar_t *)kmem_zalloc(
5676cefaae1SJack Meng tgtp->chap_name_len + 1,
5686cefaae1SJack Meng KM_SLEEP);
569dedec472SJack Meng boot_property.boot_init.ini_chap_name_len =
570dedec472SJack Meng tgtp->chap_name_len + 1;
5716cefaae1SJack Meng tmp = (char *)
5726cefaae1SJack Meng boot_property.boot_init.ini_chap_name;
5736cefaae1SJack Meng (void) snprintf(
5746cefaae1SJack Meng tmp,
5756cefaae1SJack Meng tgtp->chap_name_len + 1, "%s",
5766cefaae1SJack Meng begin_of_ibft + tgtp->chap_name_offset);
5776cefaae1SJack Meng } else {
5786cefaae1SJack Meng /*
5796cefaae1SJack Meng * Just set NULL, initiator is able to deal
5806cefaae1SJack Meng * with this
5816cefaae1SJack Meng */
5826cefaae1SJack Meng boot_property.boot_init.ini_chap_name = NULL;
5836cefaae1SJack Meng }
5846cefaae1SJack Meng
5856cefaae1SJack Meng if (tgtp->chap_secret_len != 0) {
5866cefaae1SJack Meng boot_property.boot_init.ini_chap_sec =
5876cefaae1SJack Meng (uchar_t *)kmem_zalloc(
5886cefaae1SJack Meng tgtp->chap_secret_len + 1,
5896cefaae1SJack Meng KM_SLEEP);
590dedec472SJack Meng boot_property.boot_init.ini_chap_sec_len =
591dedec472SJack Meng tgtp->chap_secret_len + 1;
5926cefaae1SJack Meng bcopy(begin_of_ibft +
5936cefaae1SJack Meng tgtp->chap_secret_offset,
5946cefaae1SJack Meng boot_property.boot_init.ini_chap_sec,
5956cefaae1SJack Meng tgtp->chap_secret_len);
5966cefaae1SJack Meng } else {
5976cefaae1SJack Meng boot_property.boot_init.ini_chap_sec = NULL;
5986cefaae1SJack Meng return (IBFT_STATUS_ERR);
5996cefaae1SJack Meng }
6006cefaae1SJack Meng
6016cefaae1SJack Meng if (tgtp->chap_type == Mutual_CHAP) {
6026cefaae1SJack Meng if (tgtp->rev_chap_name_len != 0) {
6036cefaae1SJack Meng boot_property.boot_tgt.tgt_chap_name =
6046cefaae1SJack Meng (uchar_t *)kmem_zalloc(
605dedec472SJack Meng tgtp->rev_chap_name_len + 1,
6066cefaae1SJack Meng KM_SLEEP);
607dedec472SJack Meng boot_property.boot_tgt.tgt_chap_name_len
608dedec472SJack Meng = tgtp->rev_chap_name_len + 1;
6096cefaae1SJack Meng #define TGT_CHAP_NAME boot_property.boot_tgt.tgt_chap_name
6106cefaae1SJack Meng tmp = (char *)TGT_CHAP_NAME;
6116cefaae1SJack Meng #undef TGT_CHAP_NAME
6126cefaae1SJack Meng (void) snprintf(
6136cefaae1SJack Meng tmp,
614dedec472SJack Meng tgtp->rev_chap_name_len + 1,
6156cefaae1SJack Meng "%s",
6166cefaae1SJack Meng begin_of_ibft +
6176cefaae1SJack Meng tgtp->rev_chap_name_offset);
6186cefaae1SJack Meng } else {
6196cefaae1SJack Meng /*
6206cefaae1SJack Meng * Just set NULL, initiator is able
6216cefaae1SJack Meng * to deal with this
6226cefaae1SJack Meng */
6236cefaae1SJack Meng boot_property.boot_tgt.tgt_chap_name =
6246cefaae1SJack Meng NULL;
6256cefaae1SJack Meng }
6266cefaae1SJack Meng
6276cefaae1SJack Meng if (tgtp->rev_chap_secret_len != 0) {
6286cefaae1SJack Meng boot_property.boot_tgt.tgt_chap_sec =
6296cefaae1SJack Meng (uchar_t *)kmem_zalloc(
6306cefaae1SJack Meng tgtp->rev_chap_secret_len + 1,
6316cefaae1SJack Meng KM_SLEEP);
632dedec472SJack Meng boot_property.boot_tgt.tgt_chap_sec_len
633dedec472SJack Meng = tgtp->rev_chap_secret_len + 1;
6346cefaae1SJack Meng tmp = (char *)
6356cefaae1SJack Meng boot_property.boot_tgt.tgt_chap_sec;
6366cefaae1SJack Meng (void) snprintf(
6376cefaae1SJack Meng tmp,
6386cefaae1SJack Meng tgtp->rev_chap_secret_len + 1,
6396cefaae1SJack Meng "%s",
6406cefaae1SJack Meng begin_of_ibft +
6416cefaae1SJack Meng tgtp->chap_secret_offset);
6426cefaae1SJack Meng } else {
6436cefaae1SJack Meng boot_property.boot_tgt.tgt_chap_sec =
6446cefaae1SJack Meng NULL;
6456cefaae1SJack Meng return (IBFT_STATUS_BADCHAPSEC);
6466cefaae1SJack Meng }
6476cefaae1SJack Meng }
6486cefaae1SJack Meng } else {
6496cefaae1SJack Meng boot_property.boot_init.ini_chap_name = NULL;
6506cefaae1SJack Meng boot_property.boot_init.ini_chap_sec = NULL;
6516cefaae1SJack Meng }
6526cefaae1SJack Meng
6536cefaae1SJack Meng /*
6546cefaae1SJack Meng * Get Boot LUN
6556cefaae1SJack Meng */
6566cefaae1SJack Meng (void) bcopy(tgtp->boot_lun,
6576cefaae1SJack Meng boot_property.boot_tgt.tgt_boot_lun, 8);
6586cefaae1SJack Meng }
6596cefaae1SJack Meng
6606cefaae1SJack Meng return (IBFT_STATUS_OK);
6616cefaae1SJack Meng }
6626cefaae1SJack Meng
6636cefaae1SJack Meng /*
6646cefaae1SJack Meng * This function is used for scanning iBFT from the physical memory.
6656cefaae1SJack Meng * Return Value:
6666cefaae1SJack Meng * IBFT_STATUS_OK
6676cefaae1SJack Meng * IBFT_STATUS_ERR
6686cefaae1SJack Meng */
6696cefaae1SJack Meng static ibft_status_t
iscsi_scan_ibft_tbl(char * ibft_tbl_buf)6706cefaae1SJack Meng iscsi_scan_ibft_tbl(char *ibft_tbl_buf)
6716cefaae1SJack Meng {
6726cefaae1SJack Meng int start;
6736cefaae1SJack Meng void *va = NULL;
6746cefaae1SJack Meng int *len = NULL;
6756cefaae1SJack Meng ibft_status_t ret = IBFT_STATUS_NOTABLE;
6766cefaae1SJack Meng
6776cefaae1SJack Meng for (start = ISCSI_IBFT_LOWER_ADDR; start < ISCSI_IBFT_HIGHER_ADDR;
6786cefaae1SJack Meng start = start + ISCSI_IBFT_ALIGNED) {
6796cefaae1SJack Meng va = (void *)psm_map((paddr_t)(start&0xffffffff),
6806cefaae1SJack Meng ISCSI_IBFT_SIGNATURE_LEN,
6816cefaae1SJack Meng PROT_READ);
6826cefaae1SJack Meng
6836cefaae1SJack Meng if (va == NULL) {
6846cefaae1SJack Meng continue;
6856cefaae1SJack Meng }
6866cefaae1SJack Meng if (memcmp(va, ISCSI_IBFT_SIGNATRUE,
6876cefaae1SJack Meng ISCSI_IBFT_SIGNATURE_LEN) == 0) {
6886cefaae1SJack Meng ret = IBFT_STATUS_ERR;
6896cefaae1SJack Meng /* Acquire table length */
6906cefaae1SJack Meng len = (int *)psm_map(
6916cefaae1SJack Meng (paddr_t)((start+\
6926cefaae1SJack Meng ISCSI_IBFT_SIGNATURE_LEN)&0xffffffff),
6936cefaae1SJack Meng ISCSI_IBFT_SIGNATURE_LEN, PROT_READ);
6946cefaae1SJack Meng if (len == NULL) {
6956cefaae1SJack Meng psm_unmap((caddr_t)va,
6966cefaae1SJack Meng ISCSI_IBFT_SIGNATURE_LEN);
6976cefaae1SJack Meng continue;
6986cefaae1SJack Meng }
6996cefaae1SJack Meng if (ISCSI_IBFT_LOWER_ADDR + *len <
7006cefaae1SJack Meng ISCSI_IBFT_HIGHER_ADDR - 1) {
7016cefaae1SJack Meng psm_unmap(va,
7026cefaae1SJack Meng ISCSI_IBFT_SIGNATURE_LEN);
7036cefaae1SJack Meng va = psm_map((paddr_t)(start&0xffffffff),
7046cefaae1SJack Meng *len,
7056cefaae1SJack Meng PROT_READ);
7066cefaae1SJack Meng if (va != NULL) {
7076cefaae1SJack Meng /*
7086cefaae1SJack Meng * Copy data to our own buffer
7096cefaae1SJack Meng */
7106cefaae1SJack Meng bcopy(va, ibft_tbl_buf, *len);
7116cefaae1SJack Meng ret = IBFT_STATUS_OK;
7126cefaae1SJack Meng }
7136cefaae1SJack Meng psm_unmap((caddr_t)va, *len);
7146cefaae1SJack Meng psm_unmap((caddr_t)len,
7156cefaae1SJack Meng ISCSI_IBFT_SIGNATURE_LEN);
7166cefaae1SJack Meng break;
7176cefaae1SJack Meng } else {
7186cefaae1SJack Meng psm_unmap((caddr_t)va,
7196cefaae1SJack Meng ISCSI_IBFT_SIGNATURE_LEN);
7206cefaae1SJack Meng psm_unmap((caddr_t)len,
7216cefaae1SJack Meng ISCSI_IBFT_SIGNATURE_LEN);
7226cefaae1SJack Meng }
7236cefaae1SJack Meng } else {
7246cefaae1SJack Meng psm_unmap((caddr_t)va, ISCSI_IBFT_SIGNATURE_LEN);
7256cefaae1SJack Meng }
7266cefaae1SJack Meng }
7276cefaae1SJack Meng
7286cefaae1SJack Meng return (ret);
7296cefaae1SJack Meng }
7306cefaae1SJack Meng
7316cefaae1SJack Meng /*
7326cefaae1SJack Meng * Scan the ibft table and store the iSCSI boot properties
7336cefaae1SJack Meng * If there is a valid table then set the iscsiboot_prop
7346cefaae1SJack Meng * iBF should be off if the host is not intended
7356cefaae1SJack Meng * to be booted from iSCSI disk
7366cefaae1SJack Meng */
7376cefaae1SJack Meng void
ld_ib_prop()7386cefaae1SJack Meng ld_ib_prop()
7396cefaae1SJack Meng {
7406cefaae1SJack Meng ibft_status_t ret = IBFT_STATUS_OK;
7416cefaae1SJack Meng char *ibft_tbl_buf;
7426cefaae1SJack Meng
743474eb465Svitezslav batrla - Sun Microsystems - Prague Czech Republic if (do_bsys_getproplen(NULL, "ibft-noprobe") > 0)
744474eb465Svitezslav batrla - Sun Microsystems - Prague Czech Republic ibft_noprobe = 1;
745474eb465Svitezslav batrla - Sun Microsystems - Prague Czech Republic
746474eb465Svitezslav batrla - Sun Microsystems - Prague Czech Republic if (ibft_noprobe != 0) {
747474eb465Svitezslav batrla - Sun Microsystems - Prague Czech Republic /*
748474eb465Svitezslav batrla - Sun Microsystems - Prague Czech Republic * Scanning for iBFT may conflict with devices which use memory
749474eb465Svitezslav batrla - Sun Microsystems - Prague Czech Republic * in 640-1024KB of physical address space. The iBFT
750474eb465Svitezslav batrla - Sun Microsystems - Prague Czech Republic * specification suggests use of low RAM method - scanning
751474eb465Svitezslav batrla - Sun Microsystems - Prague Czech Republic * physical memory 512-1024 KB for iBFT table. However, the
752474eb465Svitezslav batrla - Sun Microsystems - Prague Czech Republic * Upper Memory Area (UMA) 640-1024 KB may contain device
753474eb465Svitezslav batrla - Sun Microsystems - Prague Czech Republic * memory or memory mapped I/O. Although reading from I/O area
754474eb465Svitezslav batrla - Sun Microsystems - Prague Czech Republic * is usually fine, the actual behavior depends on device
755474eb465Svitezslav batrla - Sun Microsystems - Prague Czech Republic * implementation. In some cases, the user may want to disable
756474eb465Svitezslav batrla - Sun Microsystems - Prague Czech Republic * low RAM method and prevent reading from device I/O area.
757474eb465Svitezslav batrla - Sun Microsystems - Prague Czech Republic *
758474eb465Svitezslav batrla - Sun Microsystems - Prague Czech Republic * To disable low RAM method:
759474eb465Svitezslav batrla - Sun Microsystems - Prague Czech Republic * 1) pass "-B ibft-noprobe=1" on kernel command line
760474eb465Svitezslav batrla - Sun Microsystems - Prague Czech Republic * 2) add line "set ibft_noprobe=1" in /etc/system
761474eb465Svitezslav batrla - Sun Microsystems - Prague Czech Republic */
762474eb465Svitezslav batrla - Sun Microsystems - Prague Czech Republic cmn_err(CE_NOTE, IBFT_NOPROBE_MSG);
763474eb465Svitezslav batrla - Sun Microsystems - Prague Czech Republic return;
764474eb465Svitezslav batrla - Sun Microsystems - Prague Czech Republic }
765474eb465Svitezslav batrla - Sun Microsystems - Prague Czech Republic
7666cefaae1SJack Meng ibft_tbl_buf = (char *)kmem_zalloc(ISCSI_IBFT_TBL_BUF_LEN,
7676cefaae1SJack Meng KM_SLEEP);
7686cefaae1SJack Meng
7696cefaae1SJack Meng if (!ibft_tbl_buf) {
7706cefaae1SJack Meng /* Unlikely to happen */
7716cefaae1SJack Meng cmn_err(CE_NOTE, IBFT_INVALID_MSG,
7726cefaae1SJack Meng IBFT_STATUS_LOWMEM);
7736cefaae1SJack Meng return;
7746cefaae1SJack Meng }
7756cefaae1SJack Meng
7766cefaae1SJack Meng (void) memset(&boot_property, 0, sizeof (boot_property));
7776cefaae1SJack Meng if ((ret = iscsi_scan_ibft_tbl(ibft_tbl_buf)) ==
7786cefaae1SJack Meng IBFT_STATUS_OK) {
7796cefaae1SJack Meng ret = iscsi_parse_ibft_tbl(
7806cefaae1SJack Meng (iscsi_ibft_tbl_hdr_t *)ibft_tbl_buf);
7816cefaae1SJack Meng if (ret == IBFT_STATUS_OK) {
7826cefaae1SJack Meng iscsiboot_prop = &boot_property;
7836cefaae1SJack Meng iscsi_print_boot_property();
7846cefaae1SJack Meng } else {
7856cefaae1SJack Meng cmn_err(CE_NOTE, IBFT_INVALID_MSG, ret);
7866cefaae1SJack Meng }
7876cefaae1SJack Meng } else if (ret != IBFT_STATUS_NOTABLE) {
7886cefaae1SJack Meng cmn_err(CE_NOTE, IBFT_INVALID_MSG, ret);
7896cefaae1SJack Meng }
7906cefaae1SJack Meng
7916cefaae1SJack Meng kmem_free(ibft_tbl_buf, ISCSI_IBFT_TBL_BUF_LEN);
7926cefaae1SJack Meng }
793