summaryrefslogtreecommitdiffstats
path: root/kernel/include/linux/enclosure.h
blob: a4cf57cd0f7512d66b15a036cb76114d5bf633e0 (plain)
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
/*
 * Enclosure Services
 *
 * Copyright (C) 2008 James Bottomley <James.Bottomley@HansenPartnership.com>
 *
**-----------------------------------------------------------------------------
**
**  This program is free software; you can redistribute it and/or
**  modify it under the terms of the GNU General Public License
**  version 2 as published by the Free Software Foundation.
**
**  This program is distributed in the hope that it will be useful,
**  but WITHOUT ANY WARRANTY; without even the implied warranty of
**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
**  GNU General Public License for more details.
**
**  You should have received a copy of the GNU General Public License
**  along with this program; if not, write to the Free Software
**  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
**
**-----------------------------------------------------------------------------
*/
#ifndef _LINUX_ENCLOSURE_H_
#define _LINUX_ENCLOSURE_H_

#include <linux/device.h>
#include <linux/list.h>

/* A few generic types ... taken from ses-2 */
enum enclosure_component_type {
	ENCLOSURE_COMPONENT_DEVICE = 0x01,
	ENCLOSURE_COMPONENT_CONTROLLER_ELECTRONICS = 0x07,
	ENCLOSURE_COMPONENT_SCSI_TARGET_PORT = 0x14,
	ENCLOSURE_COMPONENT_SCSI_INITIATOR_PORT = 0x15,
	ENCLOSURE_COMPONENT_ARRAY_DEVICE = 0x17,
	ENCLOSURE_COMPONENT_SAS_EXPANDER = 0x18,
};

/* ses-2 common element status */
enum enclosure_status {
	ENCLOSURE_STATUS_UNSUPPORTED = 0,
	ENCLOSURE_STATUS_OK,
	ENCLOSURE_STATUS_CRITICAL,
	ENCLOSURE_STATUS_NON_CRITICAL,
	ENCLOSURE_STATUS_UNRECOVERABLE,
	ENCLOSURE_STATUS_NOT_INSTALLED,
	ENCLOSURE_STATUS_UNKNOWN,
	ENCLOSURE_STATUS_UNAVAILABLE,
	/* last element for counting purposes */
	ENCLOSURE_STATUS_MAX
};

/* SFF-8485 activity light settings */
enum enclosure_component_setting {
	ENCLOSURE_SETTING_DISABLED = 0,
	ENCLOSURE_SETTING_ENABLED = 1,
	ENCLOSURE_SETTING_BLINK_A_ON_OFF = 2,
	ENCLOSURE_SETTING_BLINK_A_OFF_ON = 3,
	ENCLOSURE_SETTING_BLINK_B_ON_OFF = 6,
	ENCLOSURE_SETTING_BLINK_B_OFF_ON = 7,
};

struct enclosure_device;
struct enclosure_component;
struct enclosure_component_callbacks {
	void (*get_status)(struct enclosure_device *,
			     struct enclosure_component *);
	int (*set_status)(struct enclosure_device *,
			  struct enclosure_component *,
			  enum enclosure_status);
	void (*get_fault)(struct enclosure_device *,
			  struct enclosure_component *);
	int (*set_fault)(struct enclosure_device *,
			 struct enclosure_component *,
			 enum enclosure_component_setting);
	void (*get_active)(struct enclosure_device *,
			   struct enclosure_component *);
	int (*set_active)(struct enclosure_device *,
			  struct enclosure_component *,
			  enum enclosure_component_setting);
	void (*get_locate)(struct enclosure_device *,
			   struct enclosure_component *);
	int (*set_locate)(struct enclosure_device *,
			  struct enclosure_component *,
			  enum enclosure_component_setting);
	void (*get_power_status)(struct enclosure_device *,
				 struct enclosure_component *);
	int (*set_power_status)(struct enclosure_device *,
				struct enclosure_component *,
				int);
	int (*show_id)(struct enclosure_device *, char *buf);
};


struct enclosure_component {
	void *scratch;
	struct device cdev;
	struct device *dev;
	enum enclosure_component_type type;
	int number;
	int fault;
	int active;
	int locate;
	int slot;
	enum enclosure_status status;
	int power_status;
};

struct enclosure_device {
	void *scratch;
	struct list_head node;
	struct device edev;
	struct enclosure_component_callbacks *cb;
	int components;
	struct enclosure_component component[0];
};

static inline struct enclosure_device *
to_enclosure_device(struct device *dev)
{
	return container_of(dev, struct enclosure_device, edev);
}

static inline struct enclosure_component *
to_enclosure_component(struct device *dev)
{
	return container_of(dev, struct enclosure_component, cdev);
}

struct enclosure_device *
enclosure_register(struct device *, const char *, int,
		   struct enclosure_component_callbacks *);
void enclosure_unregister(struct enclosure_device *);
struct enclosure_component *
enclosure_component_alloc(struct enclosure_device *, unsigned int,
			  enum enclosure_component_type, const char *);
int enclosure_component_register(struct enclosure_component *);
int enclosure_add_device(struct enclosure_device *enclosure, int component,
			 struct device *dev);
int enclosure_remove_device(struct enclosure_device *, struct device *);
struct enclosure_device *enclosure_find(struct device *dev,
					struct enclosure_device *start);
int enclosure_for_each_device(int (*fn)(struct enclosure_device *, void *),
			      void *data);

#endif /* _LINUX_ENCLOSURE_H_ */