xref: /onnv-gate/usr/src/uts/common/io/comstar/port/pppt/pppt.h (revision 12750:f559965e4a2f)
110725SJohn.Forte@Sun.COM /*
210725SJohn.Forte@Sun.COM  * CDDL HEADER START
310725SJohn.Forte@Sun.COM  *
410725SJohn.Forte@Sun.COM  * The contents of this file are subject to the terms of the
510725SJohn.Forte@Sun.COM  * Common Development and Distribution License (the "License").
610725SJohn.Forte@Sun.COM  * You may not use this file except in compliance with the License.
710725SJohn.Forte@Sun.COM  *
810725SJohn.Forte@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
910725SJohn.Forte@Sun.COM  * or http://www.opensolaris.org/os/licensing.
1010725SJohn.Forte@Sun.COM  * See the License for the specific language governing permissions
1110725SJohn.Forte@Sun.COM  * and limitations under the License.
1210725SJohn.Forte@Sun.COM  *
1310725SJohn.Forte@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
1410725SJohn.Forte@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1510725SJohn.Forte@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
1610725SJohn.Forte@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
1710725SJohn.Forte@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
1810725SJohn.Forte@Sun.COM  *
1910725SJohn.Forte@Sun.COM  * CDDL HEADER END
2010725SJohn.Forte@Sun.COM  */
2110725SJohn.Forte@Sun.COM /*
22*12750SNattuvetty.Bhavyan@Sun.COM  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
2310725SJohn.Forte@Sun.COM  */
2410725SJohn.Forte@Sun.COM #ifndef _PPPT_H
2510725SJohn.Forte@Sun.COM #define	_PPPT_H
2610725SJohn.Forte@Sun.COM 
2710725SJohn.Forte@Sun.COM #include <sys/pppt_ic_if.h>
2810725SJohn.Forte@Sun.COM 
2910725SJohn.Forte@Sun.COM #ifdef	__cplusplus
3010725SJohn.Forte@Sun.COM extern "C" {
3110725SJohn.Forte@Sun.COM #endif
3210725SJohn.Forte@Sun.COM 
3310725SJohn.Forte@Sun.COM #define	PPPT_GLOBAL_LOCK() mutex_enter(&pppt_global.global_lock)
3410725SJohn.Forte@Sun.COM #define	PPPT_GLOBAL_UNLOCK() mutex_exit(&pppt_global.global_lock)
3510725SJohn.Forte@Sun.COM 
3610725SJohn.Forte@Sun.COM extern int pppt_logging;
3710725SJohn.Forte@Sun.COM 
3810725SJohn.Forte@Sun.COM #define	PPPT_LOG if (pppt_logging) cmn_err
3910725SJohn.Forte@Sun.COM 
4010725SJohn.Forte@Sun.COM #define	TGT_DEREG_RETRY_SECONDS	1
4110725SJohn.Forte@Sun.COM 
4210725SJohn.Forte@Sun.COM typedef enum {
4310725SJohn.Forte@Sun.COM 	PPPT_STATUS_SUCCESS = 0,
4410725SJohn.Forte@Sun.COM 	PPPT_STATUS_FAIL,
4510725SJohn.Forte@Sun.COM 	PPPT_STATUS_ABORTED,
4610725SJohn.Forte@Sun.COM 	PPPT_STATUS_DONE
4710725SJohn.Forte@Sun.COM } pppt_status_t;
4810725SJohn.Forte@Sun.COM 
4910725SJohn.Forte@Sun.COM #define	PPPT_MODNAME "pppt"
5010725SJohn.Forte@Sun.COM 
5110725SJohn.Forte@Sun.COM /* Target states and events, update pppt_ts_name table whenever modified */
5210725SJohn.Forte@Sun.COM typedef enum {
5310725SJohn.Forte@Sun.COM 	TS_UNDEFINED = 0,
5410725SJohn.Forte@Sun.COM 	TS_CREATED,
5510725SJohn.Forte@Sun.COM 	TS_ONLINING,
5610725SJohn.Forte@Sun.COM 	TS_ONLINE,
5710725SJohn.Forte@Sun.COM 	TS_STMF_ONLINE,
5810725SJohn.Forte@Sun.COM 	TS_DELETING_NEED_OFFLINE,
5910725SJohn.Forte@Sun.COM 	TS_OFFLINING,
6010725SJohn.Forte@Sun.COM 	TS_OFFLINE,
6110725SJohn.Forte@Sun.COM 	TS_STMF_OFFLINE,
6210725SJohn.Forte@Sun.COM 	TS_DELETING_STMF_DEREG,
6310725SJohn.Forte@Sun.COM 	TS_DELETING_STMF_DEREG_FAIL,
6410725SJohn.Forte@Sun.COM 	TS_DELETING,
6510725SJohn.Forte@Sun.COM 	TS_MAX_STATE
6610725SJohn.Forte@Sun.COM } pppt_tgt_state_t;
6710725SJohn.Forte@Sun.COM 
6810725SJohn.Forte@Sun.COM #ifdef PPPT_TGT_SM_STRINGS
6910725SJohn.Forte@Sun.COM static const char *pppt_ts_name[TS_MAX_STATE+1] = {
7010725SJohn.Forte@Sun.COM 	"TS_UNDEFINED",
7110725SJohn.Forte@Sun.COM 	"TS_CREATED",
7210725SJohn.Forte@Sun.COM 	"TS_ONLINING",
7310725SJohn.Forte@Sun.COM 	"TS_ONLINE",
7410725SJohn.Forte@Sun.COM 	"TS_STMF_ONLINE",
7510725SJohn.Forte@Sun.COM 	"TS_DELETING_NEED_OFFLINE",
7610725SJohn.Forte@Sun.COM 	"TS_OFFLINING",
7710725SJohn.Forte@Sun.COM 	"TS_OFFLINE",
7810725SJohn.Forte@Sun.COM 	"TS_STMF_OFFLINE",
7910725SJohn.Forte@Sun.COM 	"TS_DELETING_STMF_DEREG",
8010725SJohn.Forte@Sun.COM 	"TS_DELETING_STMF_DEREG_FAIL",
8110725SJohn.Forte@Sun.COM 	"TS_DELETING",
8210725SJohn.Forte@Sun.COM 	"TS_MAX_STATE"
8310725SJohn.Forte@Sun.COM };
8410725SJohn.Forte@Sun.COM #endif
8510725SJohn.Forte@Sun.COM 
8610725SJohn.Forte@Sun.COM typedef enum {
8710725SJohn.Forte@Sun.COM 	TE_UNDEFINED = 0,
8810725SJohn.Forte@Sun.COM 	TE_STMF_ONLINE_REQ,
8910725SJohn.Forte@Sun.COM 	TE_ONLINE_SUCCESS,
9010725SJohn.Forte@Sun.COM 	TE_ONLINE_FAIL,
9110725SJohn.Forte@Sun.COM 	TE_STMF_ONLINE_COMPLETE_ACK,
9210725SJohn.Forte@Sun.COM 	TE_STMF_OFFLINE_REQ,
9310725SJohn.Forte@Sun.COM 	TE_OFFLINE_COMPLETE,
9410725SJohn.Forte@Sun.COM 	TE_STMF_OFFLINE_COMPLETE_ACK,
9510725SJohn.Forte@Sun.COM 	TE_DELETE,
9610725SJohn.Forte@Sun.COM 	TE_STMF_DEREG_SUCCESS,
9710725SJohn.Forte@Sun.COM 	TE_STMF_DEREG_FAIL,
9810725SJohn.Forte@Sun.COM 	TE_STMF_DEREG_RETRY,
9910725SJohn.Forte@Sun.COM 	TE_WAIT_REF_COMPLETE, /* XXX */
10010725SJohn.Forte@Sun.COM 	TE_MAX_EVENT
10110725SJohn.Forte@Sun.COM } pppt_tgt_event_t;
10210725SJohn.Forte@Sun.COM 
10310725SJohn.Forte@Sun.COM #ifdef PPPT_TGT_SM_STRINGS
10410725SJohn.Forte@Sun.COM static const char *pppt_te_name[TE_MAX_EVENT+1] = {
10510725SJohn.Forte@Sun.COM 	"TE_UNDEFINED",
10610725SJohn.Forte@Sun.COM 	"TE_STMF_ONLINE_REQ",
10710725SJohn.Forte@Sun.COM 	"TE_ONLINE_SUCCESS",
10810725SJohn.Forte@Sun.COM 	"TE_ONLINE_FAIL",
10910725SJohn.Forte@Sun.COM 	"TE_STMF_ONLINE_COMPLETE_ACK",
11010725SJohn.Forte@Sun.COM 	"TE_STMF_OFFLINE_REQ",
11110725SJohn.Forte@Sun.COM 	"TE_OFFLINE_COMPLETE",
11210725SJohn.Forte@Sun.COM 	"TE_STMF_OFFLINE_COMPLETE_ACK",
11310725SJohn.Forte@Sun.COM 	"TE_DELETE",
11410725SJohn.Forte@Sun.COM 	"TE_STMF_DEREG_SUCCESS",
11510725SJohn.Forte@Sun.COM 	"TE_STMF_DEREG_FAIL",
11610725SJohn.Forte@Sun.COM 	"TE_STMF_DEREG_RETRY",
11710725SJohn.Forte@Sun.COM 	"TE_WAIT_REF_COMPLETE",
11810725SJohn.Forte@Sun.COM 	"TE_MAX_EVENT"
11910725SJohn.Forte@Sun.COM };
12010725SJohn.Forte@Sun.COM #endif
12110725SJohn.Forte@Sun.COM 
12210725SJohn.Forte@Sun.COM typedef struct pppt_tgt_s {
12310725SJohn.Forte@Sun.COM 	kmutex_t		target_mutex;
12410725SJohn.Forte@Sun.COM 	kcondvar_t		target_cv;
12510725SJohn.Forte@Sun.COM 	avl_node_t		target_global_ln;
12610725SJohn.Forte@Sun.COM 	scsi_devid_desc_t	*target_devid;
12710725SJohn.Forte@Sun.COM 	stmf_local_port_t	*target_stmf_lport;
12810725SJohn.Forte@Sun.COM 	avl_tree_t		target_sess_list;
12910725SJohn.Forte@Sun.COM 
13010725SJohn.Forte@Sun.COM 	/* Target state */
13110725SJohn.Forte@Sun.COM 	boolean_t		target_sm_busy;
13210725SJohn.Forte@Sun.COM 	boolean_t		target_deleting;
13310725SJohn.Forte@Sun.COM 	pppt_tgt_state_t	target_state;
13410725SJohn.Forte@Sun.COM 	pppt_tgt_state_t	target_last_state;
13510725SJohn.Forte@Sun.COM 	int			target_refcount;
13610725SJohn.Forte@Sun.COM 	list_t			target_events;
13710725SJohn.Forte@Sun.COM } pppt_tgt_t;
13810725SJohn.Forte@Sun.COM 
13910725SJohn.Forte@Sun.COM typedef struct {
14010725SJohn.Forte@Sun.COM 	struct pppt_tgt_s	*ps_target;
14110725SJohn.Forte@Sun.COM 	uint64_t		ps_session_id;
14210725SJohn.Forte@Sun.COM 	int			ps_refcnt;
14310725SJohn.Forte@Sun.COM 	kmutex_t		ps_mutex;
14410725SJohn.Forte@Sun.COM 	kcondvar_t		ps_cv;
14510725SJohn.Forte@Sun.COM 	boolean_t		ps_closed;
14610725SJohn.Forte@Sun.COM 	avl_node_t		ps_global_ln;
14710725SJohn.Forte@Sun.COM 	avl_node_t		ps_target_ln;
14810725SJohn.Forte@Sun.COM 	avl_tree_t		ps_task_list;
14910725SJohn.Forte@Sun.COM 	stmf_scsi_session_t	*ps_stmf_sess;
15010725SJohn.Forte@Sun.COM } pppt_sess_t;
15110725SJohn.Forte@Sun.COM 
15210725SJohn.Forte@Sun.COM typedef struct {
15310725SJohn.Forte@Sun.COM 	stmf_data_buf_t		*pbuf_stmf_buf;
15410725SJohn.Forte@Sun.COM 	boolean_t		pbuf_is_immed;
15510725SJohn.Forte@Sun.COM 	stmf_ic_msg_t		*pbuf_immed_msg;
15610725SJohn.Forte@Sun.COM } pppt_buf_t;
15710725SJohn.Forte@Sun.COM 
15810725SJohn.Forte@Sun.COM typedef enum {
15910725SJohn.Forte@Sun.COM 	PTS_INIT = 0,
16010725SJohn.Forte@Sun.COM 	PTS_ACTIVE,
16110725SJohn.Forte@Sun.COM 	PTS_DONE,
16210725SJohn.Forte@Sun.COM 	PTS_SENT_STATUS,
16310725SJohn.Forte@Sun.COM 	PTS_ABORTED
16410725SJohn.Forte@Sun.COM } pppt_task_state_t;
16510725SJohn.Forte@Sun.COM 
16610725SJohn.Forte@Sun.COM typedef struct {
16710725SJohn.Forte@Sun.COM 	pppt_sess_t		*pt_sess;
16810725SJohn.Forte@Sun.COM 	avl_node_t		pt_sess_ln;
16910725SJohn.Forte@Sun.COM 	int			pt_refcnt;
17010725SJohn.Forte@Sun.COM 	kmutex_t		pt_mutex;
17110725SJohn.Forte@Sun.COM 	kcondvar_t		pt_cv;
17210725SJohn.Forte@Sun.COM 	stmf_ic_msgid_t		pt_task_id;
17310725SJohn.Forte@Sun.COM 	uint8_t			pt_lun_id[16];
17410725SJohn.Forte@Sun.COM 	pppt_task_state_t	pt_state;
17510725SJohn.Forte@Sun.COM 	scsi_task_t		*pt_stmf_task;
17610725SJohn.Forte@Sun.COM 	pppt_buf_t		*pt_immed_data;
17710725SJohn.Forte@Sun.COM 	pppt_buf_t		*pt_read_buf;
17810725SJohn.Forte@Sun.COM 	stmf_ic_msgid_t		pt_read_xfer_msgid;
17910725SJohn.Forte@Sun.COM } pppt_task_t;
18010725SJohn.Forte@Sun.COM 
18110725SJohn.Forte@Sun.COM /*
18210725SJohn.Forte@Sun.COM  * Error statistics
18310725SJohn.Forte@Sun.COM  */
18410725SJohn.Forte@Sun.COM typedef struct {
18510725SJohn.Forte@Sun.COM 	uint64_t		es_tgt_reg_svc_disabled;
18610725SJohn.Forte@Sun.COM 	uint64_t		es_tgt_reg_duplicate;
18710725SJohn.Forte@Sun.COM 	uint64_t		es_tgt_reg_create_fail;
18810725SJohn.Forte@Sun.COM 	uint64_t		es_tgt_dereg_svc_disabled;
18910725SJohn.Forte@Sun.COM 	uint64_t		es_tgt_dereg_not_found;
19010725SJohn.Forte@Sun.COM 	uint64_t		es_sess_destroy_no_session;
19110725SJohn.Forte@Sun.COM 	uint64_t		es_sess_lookup_no_session;
19210725SJohn.Forte@Sun.COM 	uint64_t		es_sess_lookup_ident_mismatch;
19310725SJohn.Forte@Sun.COM 	uint64_t		es_sess_lookup_bad_tgt_state;
19410725SJohn.Forte@Sun.COM 	uint64_t		es_scmd_ptask_alloc_fail;
19510725SJohn.Forte@Sun.COM 	uint64_t		es_scmd_sess_create_fail;
19610725SJohn.Forte@Sun.COM 	uint64_t		es_scmd_stask_alloc_fail;
19710725SJohn.Forte@Sun.COM 	uint64_t		es_scmd_dup_task_count;
19810725SJohn.Forte@Sun.COM } pppt_error_stats_t;
19910725SJohn.Forte@Sun.COM 
20010725SJohn.Forte@Sun.COM #define	PPPT_INC_STAT(stat_field) \
20110725SJohn.Forte@Sun.COM 	atomic_inc_64(&pppt_global.global_error_stats.stat_field);
20210725SJohn.Forte@Sun.COM 
20310725SJohn.Forte@Sun.COM /*
20410725SJohn.Forte@Sun.COM  * State values for the iscsit service
20510725SJohn.Forte@Sun.COM  */
20610725SJohn.Forte@Sun.COM typedef enum {
20710725SJohn.Forte@Sun.COM 	PSS_UNDEFINED = 0,
20810725SJohn.Forte@Sun.COM 	PSS_DETACHED,
20910725SJohn.Forte@Sun.COM 	PSS_DISABLED,
21010725SJohn.Forte@Sun.COM 	PSS_ENABLING,
21110725SJohn.Forte@Sun.COM 	PSS_ENABLED,
21210725SJohn.Forte@Sun.COM 	PSS_BUSY,
21310725SJohn.Forte@Sun.COM 	PSS_DISABLING
21410725SJohn.Forte@Sun.COM } pppt_service_state_t;
21510725SJohn.Forte@Sun.COM 
21610725SJohn.Forte@Sun.COM 
21710725SJohn.Forte@Sun.COM typedef struct {
21810725SJohn.Forte@Sun.COM 	pppt_service_state_t	global_svc_state;
21910725SJohn.Forte@Sun.COM 	dev_info_t		*global_dip;
22010725SJohn.Forte@Sun.COM 	stmf_port_provider_t	*global_pp;
22110725SJohn.Forte@Sun.COM 	stmf_dbuf_store_t	*global_dbuf_store;
22210725SJohn.Forte@Sun.COM 	taskq_t			*global_dispatch_taskq;
22310725SJohn.Forte@Sun.COM 	taskq_t			*global_sess_taskq;
22410725SJohn.Forte@Sun.COM 	avl_tree_t		global_sess_list;
22510725SJohn.Forte@Sun.COM 	avl_tree_t		global_target_list;
22610725SJohn.Forte@Sun.COM 	kmutex_t		global_lock;
22710725SJohn.Forte@Sun.COM 	door_handle_t		global_door;
22810725SJohn.Forte@Sun.COM 	kmutex_t		global_door_lock;
22910725SJohn.Forte@Sun.COM 	pppt_error_stats_t	global_error_stats;
23010725SJohn.Forte@Sun.COM } pppt_global_t;
23110725SJohn.Forte@Sun.COM 
23210725SJohn.Forte@Sun.COM extern pppt_global_t pppt_global;
23310725SJohn.Forte@Sun.COM 
23410725SJohn.Forte@Sun.COM stmf_status_t pppt_lport_xfer_data(scsi_task_t *task, stmf_data_buf_t *dbuf,
23510725SJohn.Forte@Sun.COM     uint32_t ioflags);
23610725SJohn.Forte@Sun.COM 
23710725SJohn.Forte@Sun.COM void pppt_xfer_read_complete(pppt_task_t *pppt_task, stmf_status_t status);
23810725SJohn.Forte@Sun.COM 
23910725SJohn.Forte@Sun.COM stmf_status_t pppt_lport_send_status(scsi_task_t *task, uint32_t ioflags);
24010725SJohn.Forte@Sun.COM 
24110725SJohn.Forte@Sun.COM void pppt_lport_task_free(scsi_task_t *task);
24210725SJohn.Forte@Sun.COM 
24310725SJohn.Forte@Sun.COM stmf_status_t pppt_lport_abort(stmf_local_port_t *lport, int abort_cmd,
24410725SJohn.Forte@Sun.COM     void *arg, uint32_t flags);
24510725SJohn.Forte@Sun.COM 
24610725SJohn.Forte@Sun.COM void pppt_lport_ctl(stmf_local_port_t *lport, int cmd, void *arg);
24710725SJohn.Forte@Sun.COM 
24810725SJohn.Forte@Sun.COM pppt_sess_t *pppt_sess_lookup_locked(uint64_t session_id,
24910725SJohn.Forte@Sun.COM     scsi_devid_desc_t *lport_devid,
250*12750SNattuvetty.Bhavyan@Sun.COM     stmf_remote_port_t *rport);
25110725SJohn.Forte@Sun.COM 
25210725SJohn.Forte@Sun.COM pppt_sess_t *pppt_sess_lookup_by_id_locked(uint64_t session_id);
25310725SJohn.Forte@Sun.COM 
25410725SJohn.Forte@Sun.COM pppt_sess_t *pppt_sess_lookup_create(scsi_devid_desc_t *lport_devid,
255*12750SNattuvetty.Bhavyan@Sun.COM     scsi_devid_desc_t *rport_devid, stmf_remote_port_t *rport,
256*12750SNattuvetty.Bhavyan@Sun.COM     uint64_t session_id, stmf_status_t *statusp);
25710725SJohn.Forte@Sun.COM 
25810725SJohn.Forte@Sun.COM void pppt_sess_rele(pppt_sess_t *sks);
25910725SJohn.Forte@Sun.COM 
26010725SJohn.Forte@Sun.COM void pppt_sess_rele_locked(pppt_sess_t *sks);
26110725SJohn.Forte@Sun.COM 
26210725SJohn.Forte@Sun.COM void pppt_sess_close_locked(pppt_sess_t *ps);
26310725SJohn.Forte@Sun.COM 
26410725SJohn.Forte@Sun.COM int pppt_sess_avl_compare_by_id(const void *void_sess1,
26510725SJohn.Forte@Sun.COM     const void *void_sess2);
26610725SJohn.Forte@Sun.COM 
26710725SJohn.Forte@Sun.COM int pppt_sess_avl_compare_by_name(const void *void_sess1,
26810725SJohn.Forte@Sun.COM     const void *void_sess2);
26910725SJohn.Forte@Sun.COM 
27010725SJohn.Forte@Sun.COM pppt_task_t *pppt_task_alloc(void);
27110725SJohn.Forte@Sun.COM 
27210725SJohn.Forte@Sun.COM void pppt_task_free(pppt_task_t *ptask);
27310725SJohn.Forte@Sun.COM 
27410725SJohn.Forte@Sun.COM pppt_status_t pppt_task_start(pppt_task_t *ptask);
27510725SJohn.Forte@Sun.COM 
27610725SJohn.Forte@Sun.COM pppt_status_t pppt_task_done(pppt_task_t *ptask);
27710725SJohn.Forte@Sun.COM 
27810725SJohn.Forte@Sun.COM pppt_task_t *pppt_task_lookup(stmf_ic_msgid_t msgid);
27910725SJohn.Forte@Sun.COM 
28010725SJohn.Forte@Sun.COM void pppt_msg_rx(stmf_ic_msg_t *msg);
28110725SJohn.Forte@Sun.COM 
28210725SJohn.Forte@Sun.COM void pppt_msg_tx_status(stmf_ic_msg_t *orig_msg, stmf_status_t status);
28310725SJohn.Forte@Sun.COM 
28410725SJohn.Forte@Sun.COM pppt_tgt_t *pppt_tgt_lookup(scsi_devid_desc_t *tgt_devid);
28510725SJohn.Forte@Sun.COM 
28610725SJohn.Forte@Sun.COM pppt_tgt_t *pppt_tgt_lookup_locked(scsi_devid_desc_t *tgt_devid);
28710725SJohn.Forte@Sun.COM 
28810725SJohn.Forte@Sun.COM pppt_tgt_t *pppt_tgt_create(stmf_ic_reg_port_msg_t *reg_port,
28910725SJohn.Forte@Sun.COM     stmf_status_t *errcode);
29010725SJohn.Forte@Sun.COM 
29110725SJohn.Forte@Sun.COM void pppt_tgt_async_delete(pppt_tgt_t *tgt);
29210725SJohn.Forte@Sun.COM 
29310725SJohn.Forte@Sun.COM void pppt_tgt_destroy(pppt_tgt_t *tgt);
29410725SJohn.Forte@Sun.COM 
29510725SJohn.Forte@Sun.COM int pppt_tgt_avl_compare(const void *void_tgt1, const void *void_tgt2);
29610725SJohn.Forte@Sun.COM 
29710725SJohn.Forte@Sun.COM void pppt_tgt_sm_ctl(stmf_local_port_t *lport, int cmd, void *arg);
29810725SJohn.Forte@Sun.COM 
29910725SJohn.Forte@Sun.COM #ifdef	__cplusplus
30010725SJohn.Forte@Sun.COM }
30110725SJohn.Forte@Sun.COM #endif
30210725SJohn.Forte@Sun.COM 
30310725SJohn.Forte@Sun.COM #endif	/* _PPPT_H */
304