17836SJohn.Forte@Sun.COM /* 27836SJohn.Forte@Sun.COM * CDDL HEADER START 37836SJohn.Forte@Sun.COM * 47836SJohn.Forte@Sun.COM * The contents of this file are subject to the terms of the 57836SJohn.Forte@Sun.COM * Common Development and Distribution License (the "License"). 67836SJohn.Forte@Sun.COM * You may not use this file except in compliance with the License. 77836SJohn.Forte@Sun.COM * 87836SJohn.Forte@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97836SJohn.Forte@Sun.COM * or http://www.opensolaris.org/os/licensing. 107836SJohn.Forte@Sun.COM * See the License for the specific language governing permissions 117836SJohn.Forte@Sun.COM * and limitations under the License. 127836SJohn.Forte@Sun.COM * 137836SJohn.Forte@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 147836SJohn.Forte@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157836SJohn.Forte@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 167836SJohn.Forte@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 177836SJohn.Forte@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 187836SJohn.Forte@Sun.COM * 197836SJohn.Forte@Sun.COM * CDDL HEADER END 207836SJohn.Forte@Sun.COM */ 217836SJohn.Forte@Sun.COM /* 22*12682SSrivijitha.Dugganapalli@Sun.COM * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 237836SJohn.Forte@Sun.COM */ 247836SJohn.Forte@Sun.COM #ifndef _STMF_IOCTL_H 257836SJohn.Forte@Sun.COM #define _STMF_IOCTL_H 267836SJohn.Forte@Sun.COM 277836SJohn.Forte@Sun.COM #ifdef __cplusplus 287836SJohn.Forte@Sun.COM extern "C" { 297836SJohn.Forte@Sun.COM #endif 307836SJohn.Forte@Sun.COM 317836SJohn.Forte@Sun.COM #define STMF_VERSION_1 1 327836SJohn.Forte@Sun.COM 337836SJohn.Forte@Sun.COM #define STMF_IOCTL (((uint32_t)'S') << 24) 347836SJohn.Forte@Sun.COM #define STMF_IOCTL_LU_LIST (STMF_IOCTL | 1) 357836SJohn.Forte@Sun.COM #define STMF_IOCTL_TARGET_PORT_LIST (STMF_IOCTL | 2) 367836SJohn.Forte@Sun.COM #define STMF_IOCTL_SESSION_LIST (STMF_IOCTL | 3) 377836SJohn.Forte@Sun.COM #define STMF_IOCTL_GET_LU_PROPERTIES (STMF_IOCTL | 4) 387836SJohn.Forte@Sun.COM #define STMF_IOCTL_GET_TARGET_PORT_PROPERTIES (STMF_IOCTL | 5) 397836SJohn.Forte@Sun.COM #define STMF_IOCTL_SET_STMF_STATE (STMF_IOCTL | 6) 407836SJohn.Forte@Sun.COM #define STMF_IOCTL_GET_STMF_STATE (STMF_IOCTL | 7) 417836SJohn.Forte@Sun.COM #define STMF_IOCTL_SET_LU_STATE (STMF_IOCTL | 8) 427836SJohn.Forte@Sun.COM #define STMF_IOCTL_SET_TARGET_PORT_STATE (STMF_IOCTL | 9) 437836SJohn.Forte@Sun.COM #define STMF_IOCTL_CREATE_HOST_GROUP (STMF_IOCTL | 10) 447836SJohn.Forte@Sun.COM #define STMF_IOCTL_REMOVE_HOST_GROUP (STMF_IOCTL | 11) 457836SJohn.Forte@Sun.COM #define STMF_IOCTL_ADD_HG_ENTRY (STMF_IOCTL | 12) 467836SJohn.Forte@Sun.COM #define STMF_IOCTL_REMOVE_HG_ENTRY (STMF_IOCTL | 13) 477836SJohn.Forte@Sun.COM #define STMF_IOCTL_CREATE_TARGET_GROUP (STMF_IOCTL | 14) 487836SJohn.Forte@Sun.COM #define STMF_IOCTL_REMOVE_TARGET_GROUP (STMF_IOCTL | 15) 497836SJohn.Forte@Sun.COM #define STMF_IOCTL_ADD_TG_ENTRY (STMF_IOCTL | 16) 507836SJohn.Forte@Sun.COM #define STMF_IOCTL_REMOVE_TG_ENTRY (STMF_IOCTL | 17) 517836SJohn.Forte@Sun.COM #define STMF_IOCTL_ADD_VIEW_ENTRY (STMF_IOCTL | 18) 527836SJohn.Forte@Sun.COM #define STMF_IOCTL_REMOVE_VIEW_ENTRY (STMF_IOCTL | 19) 537836SJohn.Forte@Sun.COM #define STMF_IOCTL_GET_HG_LIST (STMF_IOCTL | 20) 547836SJohn.Forte@Sun.COM #define STMF_IOCTL_GET_TG_LIST (STMF_IOCTL | 21) 557836SJohn.Forte@Sun.COM #define STMF_IOCTL_GET_HG_ENTRIES (STMF_IOCTL | 22) 567836SJohn.Forte@Sun.COM #define STMF_IOCTL_GET_TG_ENTRIES (STMF_IOCTL | 23) 577836SJohn.Forte@Sun.COM #define STMF_IOCTL_GET_VE_LIST (STMF_IOCTL | 24) 587836SJohn.Forte@Sun.COM #define STMF_IOCTL_LOAD_PP_DATA (STMF_IOCTL | 25) 597836SJohn.Forte@Sun.COM #define STMF_IOCTL_CLEAR_PP_DATA (STMF_IOCTL | 26) 609585STim.Szeto@Sun.COM #define STMF_IOCTL_GET_PP_DATA (STMF_IOCTL | 27) 619585STim.Szeto@Sun.COM #define STMF_IOCTL_CLEAR_TRACE (STMF_IOCTL | 28) 629585STim.Szeto@Sun.COM #define STMF_IOCTL_ADD_TRACE (STMF_IOCTL | 29) 639585STim.Szeto@Sun.COM #define STMF_IOCTL_GET_TRACE_POSITION (STMF_IOCTL | 30) 649585STim.Szeto@Sun.COM #define STMF_IOCTL_GET_TRACE (STMF_IOCTL | 31) 659585STim.Szeto@Sun.COM #define STMF_IOCTL_REG_LU_LIST (STMF_IOCTL | 32) 669585STim.Szeto@Sun.COM #define STMF_IOCTL_VE_LU_LIST (STMF_IOCTL | 33) 679585STim.Szeto@Sun.COM #define STMF_IOCTL_LU_VE_LIST (STMF_IOCTL | 34) 6810691STim.Szeto@Sun.COM #define STMF_IOCTL_VALIDATE_VIEW (STMF_IOCTL | 35) 6910725SJohn.Forte@Sun.COM #define STMF_IOCTL_SET_ALUA_STATE (STMF_IOCTL | 36) 7010725SJohn.Forte@Sun.COM #define STMF_IOCTL_GET_ALUA_STATE (STMF_IOCTL | 37) 71*12682SSrivijitha.Dugganapalli@Sun.COM #define STMF_IOCTL_SET_STMF_PROPS (STMF_IOCTL | 38) 727836SJohn.Forte@Sun.COM 737836SJohn.Forte@Sun.COM typedef struct stmf_iocdata { 747836SJohn.Forte@Sun.COM uint32_t stmf_version; 757836SJohn.Forte@Sun.COM uint32_t stmf_error; 767836SJohn.Forte@Sun.COM uint32_t stmf_ibuf_size; 777836SJohn.Forte@Sun.COM uint32_t stmf_obuf_size; 787836SJohn.Forte@Sun.COM uint32_t stmf_obuf_nentries; /* # entries xferred */ 797836SJohn.Forte@Sun.COM uint32_t stmf_obuf_max_nentries; /* #,could have been xferred */ 807836SJohn.Forte@Sun.COM uint64_t stmf_ibuf; 817836SJohn.Forte@Sun.COM uint64_t stmf_obuf; 827836SJohn.Forte@Sun.COM } stmf_iocdata_t; 837836SJohn.Forte@Sun.COM 847836SJohn.Forte@Sun.COM typedef struct slist_lu { 857836SJohn.Forte@Sun.COM uint8_t lu_guid[16]; 867836SJohn.Forte@Sun.COM } slist_lu_t; 877836SJohn.Forte@Sun.COM 887836SJohn.Forte@Sun.COM typedef struct slist_target_port { 897836SJohn.Forte@Sun.COM uint8_t target[260]; 907836SJohn.Forte@Sun.COM } slist_target_port_t; 917836SJohn.Forte@Sun.COM 927836SJohn.Forte@Sun.COM typedef struct slist_scsi_session { 937836SJohn.Forte@Sun.COM uint8_t initiator[260]; 947836SJohn.Forte@Sun.COM /* creation_time is really time_t. But time_t is defined as long. */ 957836SJohn.Forte@Sun.COM uint32_t creation_time; 967836SJohn.Forte@Sun.COM char alias[256]; 977836SJohn.Forte@Sun.COM } slist_scsi_session_t; 987836SJohn.Forte@Sun.COM 997836SJohn.Forte@Sun.COM /* 1007836SJohn.Forte@Sun.COM * States for LUs and LPORTs 1017836SJohn.Forte@Sun.COM */ 1027836SJohn.Forte@Sun.COM #define STMF_STATE_OFFLINE 0 1037836SJohn.Forte@Sun.COM #define STMF_STATE_ONLINING 1 1047836SJohn.Forte@Sun.COM #define STMF_STATE_ONLINE 2 1057836SJohn.Forte@Sun.COM #define STMF_STATE_OFFLINING 3 1067836SJohn.Forte@Sun.COM 1077836SJohn.Forte@Sun.COM /* 1087836SJohn.Forte@Sun.COM * States for the STMF config. 1097836SJohn.Forte@Sun.COM */ 1107836SJohn.Forte@Sun.COM #define STMF_CONFIG_NONE 0 1117836SJohn.Forte@Sun.COM #define STMF_CONFIG_INIT 1 1127836SJohn.Forte@Sun.COM #define STMF_CONFIG_INIT_DONE 2 1137836SJohn.Forte@Sun.COM 1147836SJohn.Forte@Sun.COM typedef struct sioc_lu_props { 1157836SJohn.Forte@Sun.COM uint8_t lu_guid[16]; 1167836SJohn.Forte@Sun.COM uint8_t lu_state:4, 1177836SJohn.Forte@Sun.COM lu_present:1, 1187836SJohn.Forte@Sun.COM lu_rsvd:3; 1197836SJohn.Forte@Sun.COM char lu_provider_name[255]; 1207836SJohn.Forte@Sun.COM char lu_alias[256]; 1217836SJohn.Forte@Sun.COM } sioc_lu_props_t; 1227836SJohn.Forte@Sun.COM 1237836SJohn.Forte@Sun.COM typedef struct sioc_target_port_props { 1247836SJohn.Forte@Sun.COM uint8_t tgt_id[260]; 1257836SJohn.Forte@Sun.COM uint8_t tgt_state:4, 1267836SJohn.Forte@Sun.COM tgt_present:1, 1277836SJohn.Forte@Sun.COM tgt_rsvd:3; 1287836SJohn.Forte@Sun.COM char tgt_provider_name[255]; 1297836SJohn.Forte@Sun.COM char tgt_alias[256]; 1307836SJohn.Forte@Sun.COM } sioc_target_port_props_t; 1317836SJohn.Forte@Sun.COM 1327836SJohn.Forte@Sun.COM /* 1337836SJohn.Forte@Sun.COM * This struct is used for getting and setting state of LU/LPORT or STMF. 1347836SJohn.Forte@Sun.COM */ 1357836SJohn.Forte@Sun.COM typedef struct stmf_state_desc { 1367836SJohn.Forte@Sun.COM uint8_t ident[260]; /* N/A for STMF itself */ 1377836SJohn.Forte@Sun.COM uint8_t state; 1387836SJohn.Forte@Sun.COM uint8_t config_state; /* N/A for LU/LPORTs */ 1397836SJohn.Forte@Sun.COM } stmf_state_desc_t; 1407836SJohn.Forte@Sun.COM 14110725SJohn.Forte@Sun.COM /* 14210725SJohn.Forte@Sun.COM * This struct is used for setting the alua state 14310725SJohn.Forte@Sun.COM */ 14410725SJohn.Forte@Sun.COM typedef struct stmf_alua_state_desc { 14510725SJohn.Forte@Sun.COM uint8_t alua_state; 14610725SJohn.Forte@Sun.COM uint16_t alua_node; 14710725SJohn.Forte@Sun.COM } stmf_alua_state_desc_t; 14810725SJohn.Forte@Sun.COM 1499585STim.Szeto@Sun.COM /* Error definitions for group/view entry/provider dataioctls */ 1507836SJohn.Forte@Sun.COM #define STMF_IOCERR_NONE 0 1517836SJohn.Forte@Sun.COM #define STMF_IOCERR_HG_EXISTS 1 1527836SJohn.Forte@Sun.COM #define STMF_IOCERR_INVALID_HG 2 1537836SJohn.Forte@Sun.COM #define STMF_IOCERR_TG_EXISTS 3 1547836SJohn.Forte@Sun.COM #define STMF_IOCERR_INVALID_TG 4 1557836SJohn.Forte@Sun.COM #define STMF_IOCERR_HG_ENTRY_EXISTS 5 1567836SJohn.Forte@Sun.COM #define STMF_IOCERR_INVALID_HG_ENTRY 6 1577836SJohn.Forte@Sun.COM #define STMF_IOCERR_TG_ENTRY_EXISTS 7 1587836SJohn.Forte@Sun.COM #define STMF_IOCERR_INVALID_TG_ENTRY 8 1597836SJohn.Forte@Sun.COM #define STMF_IOCERR_TG_UPDATE_NEED_SVC_OFFLINE 9 1607836SJohn.Forte@Sun.COM #define STMF_IOCERR_LU_NUMBER_IN_USE 10 1617836SJohn.Forte@Sun.COM #define STMF_IOCERR_INVALID_LU_ID 11 1627836SJohn.Forte@Sun.COM #define STMF_IOCERR_VIEW_ENTRY_CONFLICT 12 1637836SJohn.Forte@Sun.COM #define STMF_IOCERR_HG_IN_USE 13 1647836SJohn.Forte@Sun.COM #define STMF_IOCERR_TG_IN_USE 14 1657836SJohn.Forte@Sun.COM #define STMF_IOCERR_INVALID_VIEW_ENTRY 15 1667836SJohn.Forte@Sun.COM #define STMF_IOCERR_INVALID_VE_ID 16 1677836SJohn.Forte@Sun.COM #define STMF_IOCERR_UPDATE_NEED_CFG_INIT 17 1689585STim.Szeto@Sun.COM #define STMF_IOCERR_PPD_UPDATED 18 1699585STim.Szeto@Sun.COM #define STMF_IOCERR_INSUFFICIENT_BUF 19 1709884STim.Szeto@Sun.COM #define STMF_IOCERR_TG_NEED_TG_OFFLINE 20 1719585STim.Szeto@Sun.COM 1727836SJohn.Forte@Sun.COM 1737836SJohn.Forte@Sun.COM typedef struct stmf_group_name { 1747836SJohn.Forte@Sun.COM uint16_t name_size; /* in bytes */ 1757836SJohn.Forte@Sun.COM uint16_t rsvd_1; 1767836SJohn.Forte@Sun.COM uint32_t rsvd_2; 1777836SJohn.Forte@Sun.COM uint8_t name[512]; /* 256 * wchar_t */ 1787836SJohn.Forte@Sun.COM } stmf_group_name_t; 1797836SJohn.Forte@Sun.COM 1807836SJohn.Forte@Sun.COM /* 1817836SJohn.Forte@Sun.COM * struct used to operate (add/remove entry) on a group. 1827836SJohn.Forte@Sun.COM */ 1839585STim.Szeto@Sun.COM 1849585STim.Szeto@Sun.COM typedef struct stmf_ge_ident { 1859585STim.Szeto@Sun.COM uint16_t ident_size; 1869585STim.Szeto@Sun.COM uint8_t ident[256]; 1879585STim.Szeto@Sun.COM } stmf_ge_ident_t; 1887836SJohn.Forte@Sun.COM 1897836SJohn.Forte@Sun.COM typedef struct stmf_group_op_data { 1907836SJohn.Forte@Sun.COM stmf_group_name_t group; 1917836SJohn.Forte@Sun.COM uint8_t ident[260]; 1927836SJohn.Forte@Sun.COM } stmf_group_op_data_t; 1937836SJohn.Forte@Sun.COM 1947836SJohn.Forte@Sun.COM typedef struct stmf_view_op_entry { 1957836SJohn.Forte@Sun.COM uint32_t ve_ndx_valid:1, 1967836SJohn.Forte@Sun.COM ve_lu_number_valid:1, 1977836SJohn.Forte@Sun.COM ve_all_hosts:1, 1987836SJohn.Forte@Sun.COM ve_all_targets:1, 1997836SJohn.Forte@Sun.COM rsvd:28; 2007836SJohn.Forte@Sun.COM uint32_t ve_ndx; 2017836SJohn.Forte@Sun.COM uint8_t ve_lu_nbr[8]; 2027836SJohn.Forte@Sun.COM uint8_t ve_guid[16]; 2037836SJohn.Forte@Sun.COM stmf_group_name_t ve_host_group; 2047836SJohn.Forte@Sun.COM stmf_group_name_t ve_target_group; 2057836SJohn.Forte@Sun.COM } stmf_view_op_entry_t; 2067836SJohn.Forte@Sun.COM 2077836SJohn.Forte@Sun.COM typedef struct stmf_ppioctl_data { 2087836SJohn.Forte@Sun.COM char ppi_name[255]; /* Provider name including \0 */ 2097836SJohn.Forte@Sun.COM uint8_t ppi_port_provider:1, 2107836SJohn.Forte@Sun.COM ppi_lu_provider:1, 2119585STim.Szeto@Sun.COM ppi_token_valid:1, 2129585STim.Szeto@Sun.COM ppt_rsvd:5; 2139585STim.Szeto@Sun.COM uint64_t ppi_token; 2147836SJohn.Forte@Sun.COM uint64_t ppi_data_size; 2157836SJohn.Forte@Sun.COM uint8_t ppi_data[8]; 2167836SJohn.Forte@Sun.COM } stmf_ppioctl_data_t; 2177836SJohn.Forte@Sun.COM 218*12682SSrivijitha.Dugganapalli@Sun.COM typedef struct stmf_set_props { 219*12682SSrivijitha.Dugganapalli@Sun.COM uint32_t default_lu_state_value; 220*12682SSrivijitha.Dugganapalli@Sun.COM uint32_t default_target_state_value; 221*12682SSrivijitha.Dugganapalli@Sun.COM } stmf_set_props_t; 222*12682SSrivijitha.Dugganapalli@Sun.COM 2237836SJohn.Forte@Sun.COM /* 2247836SJohn.Forte@Sun.COM * SCSI device ID descriptor as per SPC3 7.6.3 2257836SJohn.Forte@Sun.COM */ 2267836SJohn.Forte@Sun.COM typedef struct scsi_devid_desc { 2277836SJohn.Forte@Sun.COM #ifdef _BIT_FIELDS_HTOL 2287836SJohn.Forte@Sun.COM uint8_t protocol_id:4, 2297836SJohn.Forte@Sun.COM code_set:4; 2307836SJohn.Forte@Sun.COM uint8_t piv:1, 2317836SJohn.Forte@Sun.COM rsvd1:1, 2327836SJohn.Forte@Sun.COM association:2, 2337836SJohn.Forte@Sun.COM ident_type:4; 2347836SJohn.Forte@Sun.COM #else 2357836SJohn.Forte@Sun.COM uint8_t code_set:4, 2367836SJohn.Forte@Sun.COM protocol_id:4; 2377836SJohn.Forte@Sun.COM uint8_t ident_type:4, 2387836SJohn.Forte@Sun.COM association:2, 2397836SJohn.Forte@Sun.COM rsvd1:1, 2407836SJohn.Forte@Sun.COM piv:1; 2417836SJohn.Forte@Sun.COM #endif 2427836SJohn.Forte@Sun.COM uint8_t rsvd2; 2437836SJohn.Forte@Sun.COM uint8_t ident_length; 2447836SJohn.Forte@Sun.COM uint8_t ident[1]; 2457836SJohn.Forte@Sun.COM } scsi_devid_desc_t; 2467836SJohn.Forte@Sun.COM 2477836SJohn.Forte@Sun.COM /* 2487836SJohn.Forte@Sun.COM * Protocol Identifier 2497836SJohn.Forte@Sun.COM */ 2507836SJohn.Forte@Sun.COM #define PROTOCOL_FIBRE_CHANNEL 0 2517836SJohn.Forte@Sun.COM #define PROTOCOL_PARALLEL_SCSI 1 2527836SJohn.Forte@Sun.COM #define PROTOCOL_SSA 2 2537836SJohn.Forte@Sun.COM #define PROTOCOL_IEEE_1394 3 2547836SJohn.Forte@Sun.COM #define PROTOCOL_SRP 4 2557836SJohn.Forte@Sun.COM #define PROTOCOL_iSCSI 5 2567836SJohn.Forte@Sun.COM #define PROTOCOL_SAS 6 2577836SJohn.Forte@Sun.COM #define PROTOCOL_ADT 7 2587836SJohn.Forte@Sun.COM #define PROTOCOL_ATAPI 8 2597836SJohn.Forte@Sun.COM #define PROTOCOL_ANY 15 2607836SJohn.Forte@Sun.COM 2617836SJohn.Forte@Sun.COM /* 2627836SJohn.Forte@Sun.COM * Code set definitions 2637836SJohn.Forte@Sun.COM */ 2647836SJohn.Forte@Sun.COM #define CODE_SET_BINARY 1 2657836SJohn.Forte@Sun.COM #define CODE_SET_ASCII 2 2667836SJohn.Forte@Sun.COM #define CODE_SET_UTF8 3 2677836SJohn.Forte@Sun.COM 2687836SJohn.Forte@Sun.COM /* 2697836SJohn.Forte@Sun.COM * Association values 2707836SJohn.Forte@Sun.COM */ 2717836SJohn.Forte@Sun.COM #define ID_IS_LOGICAL_UNIT 0 2727836SJohn.Forte@Sun.COM #define ID_IS_TARGET_PORT 1 2737836SJohn.Forte@Sun.COM #define ID_IS_TARGET_CONTAINING_LU 2 2747836SJohn.Forte@Sun.COM 2757836SJohn.Forte@Sun.COM /* 2767836SJohn.Forte@Sun.COM * ident type 2777836SJohn.Forte@Sun.COM */ 2787836SJohn.Forte@Sun.COM #define ID_TYPE_VENDOR_SPECIFIC 0 2797836SJohn.Forte@Sun.COM #define ID_TYPE_T10_VID 1 2807836SJohn.Forte@Sun.COM #define ID_TYPE_EUI64 2 2817836SJohn.Forte@Sun.COM #define ID_TYPE_NAA 3 2827836SJohn.Forte@Sun.COM #define ID_TYPE_RELATIVE_TARGET_PORT 4 2837836SJohn.Forte@Sun.COM #define ID_TYPE_TARGET_PORT_GROUP 5 2847836SJohn.Forte@Sun.COM #define ID_TYPE_LOGICAL_UNIT_GROUP 6 2857836SJohn.Forte@Sun.COM #define ID_TYPE_MD5_LOGICAL_UNIT 7 2867836SJohn.Forte@Sun.COM #define ID_TYPE_SCSI_NAME_STRING 8 2877836SJohn.Forte@Sun.COM 2887836SJohn.Forte@Sun.COM int stmf_copyin_iocdata(intptr_t data, int mode, stmf_iocdata_t **iocd, 2897836SJohn.Forte@Sun.COM void **ibuf, void **obuf); 2907836SJohn.Forte@Sun.COM int stmf_copyout_iocdata(intptr_t data, int mode, stmf_iocdata_t *iocd, 2917836SJohn.Forte@Sun.COM void *obuf); 2927836SJohn.Forte@Sun.COM 2937836SJohn.Forte@Sun.COM #ifdef __cplusplus 2947836SJohn.Forte@Sun.COM } 2957836SJohn.Forte@Sun.COM #endif 2967836SJohn.Forte@Sun.COM 2977836SJohn.Forte@Sun.COM #endif /* _STMF_IOCTL_H */ 298