summaryrefslogtreecommitdiff
path: root/drivers/fc4/fcp_impl.h
blob: e44d652a83dc055ba1a24118b26d78518bc99b33 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
/* fcp_impl.h: Generic SCSI on top of FC4 - our interface defines.
 *
 * Copyright (C) 1997-1999 Jakub Jelinek (jj@ultra.linux.cz)
 * Copyright (C) 1998 Jirka Hanika (geo@ff.cuni.cz)
 */

#ifndef _FCP_SCSI_H
#define _FCP_SCSI_H

#include <linux/types.h>
#include "../scsi/scsi.h"

#include "fc.h"
#include "fcp.h"
#include "fc-al.h"

#include <asm/io.h>
#ifdef __sparc__
#include <asm/sbus.h>
#endif

/* 0 or 1 */
#define	FCP_SCSI_USE_NEW_EH_CODE	0

#define FC_CLASS_OUTBOUND	0x01
#define FC_CLASS_INBOUND	0x02
#define FC_CLASS_SIMPLE		0x03
#define FC_CLASS_IO_WRITE	0x04
#define FC_CLASS_IO_READ	0x05
#define FC_CLASS_UNSOLICITED	0x06
#define FC_CLASS_OFFLINE	0x08

#define PROTO_OFFLINE		0x02
#define PROTO_REPORT_AL_MAP	0x03
#define PROTO_FORCE_LIP		0x06

struct _fc_channel; 

typedef struct fcp_cmnd {
	struct fcp_cmnd		*next;
	struct fcp_cmnd		*prev;
	void			(*done)(Scsi_Cmnd *);
	unsigned short		proto;
	unsigned short		token;
	unsigned int		did;
	/* FCP SCSI stuff */
	dma_addr_t		data;
	/* From now on this cannot be touched for proto == TYPE_SCSI_FCP */
	fc_hdr			fch;
	dma_addr_t		cmd;
	dma_addr_t		rsp;
	int			cmdlen;
	int			rsplen;
	int			class;
	int			datalen;
	/* This is just used as a verification during login */
	struct _fc_channel	*fc;
	void			*ls;
} fcp_cmnd;

typedef struct {
	unsigned int		len;
	unsigned char		list[0];
} fcp_posmap;

typedef struct _fc_channel {
	struct _fc_channel	*next;
	int			irq;
	int			state;
	int			sid;
	int			did;
	char			name[16];
	void			(*fcp_register)(struct _fc_channel *, u8, int);
	void			(*reset)(struct _fc_channel *);
	int			(*hw_enque)(struct _fc_channel *, fcp_cmnd *);
	fc_wwn			wwn_node;
	fc_wwn			wwn_nport;
	fc_wwn			wwn_dest;
	common_svc_parm		*common_svc;
	svc_parm		*class_svcs;
#ifdef __sparc__	
	struct sbus_dev		*dev;
#else
	struct pci_dev		*dev;
#endif
	struct module		*module;
	/* FCP SCSI stuff */
	short			can_queue;
	short			abort_count;
	int			rsp_size;
	fcp_cmd			*scsi_cmd_pool;
	char			*scsi_rsp_pool;
	dma_addr_t		dma_scsi_cmd, dma_scsi_rsp;
	long			*scsi_bitmap;
	long			scsi_bitmap_end;
	int			scsi_free;
	int			(*encode_addr)(Scsi_Cmnd *, u16 *, struct _fc_channel *, fcp_cmnd *);
	fcp_cmnd		*scsi_que;
	char			scsi_name[4];
	fcp_cmnd		**cmd_slots;
	int			channels;
	int			targets;
	long			*ages;
	Scsi_Cmnd		*rst_pkt;
	fcp_posmap		*posmap;
	/* LOGIN stuff */
	fcp_cmnd		*login;
	void			*ls;
} fc_channel;

extern fc_channel *fc_channels;

#define FC_STATE_UNINITED	0
#define FC_STATE_ONLINE		1
#define FC_STATE_OFFLINE	2
#define FC_STATE_RESETING	3
#define FC_STATE_FPORT_OK	4
#define FC_STATE_MAYBEOFFLINE	5

#define FC_STATUS_OK			0
#define FC_STATUS_P_RJT			2
#define FC_STATUS_F_RJT			3
#define FC_STATUS_P_BSY			4
#define FC_STATUS_F_BSY			5
#define FC_STATUS_ERR_OFFLINE		0x11
#define FC_STATUS_TIMEOUT		0x12
#define FC_STATUS_ERR_OVERRUN		0x13
#define FC_STATUS_POINTTOPOINT		0x15
#define FC_STATUS_AL			0x16
#define FC_STATUS_UNKNOWN_CQ_TYPE	0x20
#define FC_STATUS_BAD_SEG_CNT		0x21
#define FC_STATUS_MAX_XCHG_EXCEEDED	0x22
#define FC_STATUS_BAD_XID		0x23
#define FC_STATUS_XCHG_BUSY		0x24
#define FC_STATUS_BAD_POOL_ID		0x25
#define FC_STATUS_INSUFFICIENT_CQES	0x26
#define FC_STATUS_ALLOC_FAIL		0x27
#define FC_STATUS_BAD_SID		0x28
#define FC_STATUS_NO_SEQ_INIT		0x29
#define FC_STATUS_TIMED_OUT		-1
#define FC_STATUS_BAD_RSP		-2

void fcp_queue_empty(fc_channel *);
int fcp_init(fc_channel *);
void fcp_release(fc_channel *fc_chain, int count);
void fcp_receive_solicited(fc_channel *, int, int, int, fc_hdr *);
void fcp_state_change(fc_channel *, int);
int fc_do_plogi(fc_channel *, unsigned char, fc_wwn *, fc_wwn *);
int fc_do_prli(fc_channel *, unsigned char);

#define for_each_fc_channel(fc)				\
	for (fc = fc_channels; fc; fc = fc->next)
	
#define for_each_online_fc_channel(fc) 			\
	for_each_fc_channel(fc)				\
		if (fc->state == FC_STATE_ONLINE)

int fcp_scsi_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *));
int fcp_scsi_abort(Scsi_Cmnd *);
int fcp_scsi_dev_reset(Scsi_Cmnd *);
int fcp_scsi_bus_reset(Scsi_Cmnd *);
int fcp_scsi_host_reset(Scsi_Cmnd *);

#endif /* !(_FCP_SCSI_H) */