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