From f8d9d654fcc7dd87f5d0b222e233eaab15d650c4 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 29 Jan 2008 00:11:27 +0200 Subject: [SCSI] libiscsi: make __iscsi_complete_pdu() static __iscsi_complete_pdu() can now become static. Signed-off-by: Adrian Bunk Acked-by: Mike Christie Signed-off-by: James Bottomley --- include/scsi/libiscsi.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include') diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index 889f51f..71eda241 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h @@ -349,8 +349,6 @@ extern int iscsi_conn_send_pdu(struct iscsi_cls_conn *, struct iscsi_hdr *, char *, uint32_t); extern int iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *, char *, int); -extern int __iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *, - char *, int); extern int iscsi_verify_itt(struct iscsi_conn *, struct iscsi_hdr *, uint32_t *); extern void iscsi_requeue_ctask(struct iscsi_cmd_task *ctask); -- cgit v1.1 From 6eabafbe6616266e8de61980a7dac5ecc1ba1113 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Thu, 31 Jan 2008 13:36:43 -0600 Subject: [SCSI] iscsi class, libiscsi: add iscsi sysfs session state file This adds a iscsi session state file which exports the session state for both software and hardware iscsi. It also hooks libiscsi in. Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- include/scsi/libiscsi.h | 19 +++++++++++++++++++ include/scsi/scsi_transport_iscsi.h | 27 ++++++++++++--------------- 2 files changed, 31 insertions(+), 15 deletions(-) (limited to 'include') diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index 71eda241..278011f 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h @@ -135,6 +135,14 @@ static inline void* iscsi_next_hdr(struct iscsi_cmd_task *ctask) return (void*)ctask->hdr + ctask->hdr_len; } +/* Connection's states */ +enum { + ISCSI_CONN_INITIAL_STAGE, + ISCSI_CONN_STARTED, + ISCSI_CONN_STOPPED, + ISCSI_CONN_CLEANUP_WAIT, +}; + struct iscsi_conn { struct iscsi_cls_conn *cls_conn; /* ptr to class connection */ void *dd_data; /* iscsi_transport data */ @@ -227,6 +235,17 @@ struct iscsi_pool { int max; /* Max number of elements */ }; +/* Session's states */ +enum { + ISCSI_STATE_FREE = 1, + ISCSI_STATE_LOGGED_IN, + ISCSI_STATE_FAILED, + ISCSI_STATE_TERMINATE, + ISCSI_STATE_IN_RECOVERY, + ISCSI_STATE_RECOVERY_FAILED, + ISCSI_STATE_LOGGING_OUT, +}; + struct iscsi_session { /* * Syncs up the scsi eh thread with the iscsi eh thread when sending diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h index 404f11d..0e869d9 100644 --- a/include/scsi/scsi_transport_iscsi.h +++ b/include/scsi/scsi_transport_iscsi.h @@ -149,13 +149,6 @@ extern void iscsi_conn_error(struct iscsi_cls_conn *conn, enum iscsi_err error); extern int iscsi_recv_pdu(struct iscsi_cls_conn *conn, struct iscsi_hdr *hdr, char *data, uint32_t data_size); - -/* Connection's states */ -#define ISCSI_CONN_INITIAL_STAGE 0 -#define ISCSI_CONN_STARTED 1 -#define ISCSI_CONN_STOPPED 2 -#define ISCSI_CONN_CLEANUP_WAIT 3 - struct iscsi_cls_conn { struct list_head conn_list; /* item in connlist */ void *dd_data; /* LLD private data */ @@ -169,19 +162,21 @@ struct iscsi_cls_conn { #define iscsi_dev_to_conn(_dev) \ container_of(_dev, struct iscsi_cls_conn, dev) -/* Session's states */ -#define ISCSI_STATE_FREE 1 -#define ISCSI_STATE_LOGGED_IN 2 -#define ISCSI_STATE_FAILED 3 -#define ISCSI_STATE_TERMINATE 4 -#define ISCSI_STATE_IN_RECOVERY 5 -#define ISCSI_STATE_RECOVERY_FAILED 6 -#define ISCSI_STATE_LOGGING_OUT 7 +#define iscsi_conn_to_session(_conn) \ + iscsi_dev_to_session(_conn->dev.parent) + +/* iscsi class session state */ +enum { + ISCSI_SESSION_LOGGED_IN, + ISCSI_SESSION_FAILED, + ISCSI_SESSION_FREE, +}; struct iscsi_cls_session { struct list_head sess_list; /* item in session_list */ struct list_head host_list; struct iscsi_transport *transport; + spinlock_t lock; /* recovery fields */ int recovery_tmo; @@ -190,6 +185,7 @@ struct iscsi_cls_session { int target_id; + int state; int sid; /* session id */ void *dd_data; /* LLD private data */ struct device dev; /* sysfs transport/container device */ @@ -214,6 +210,7 @@ struct iscsi_host { /* * session and connection functions that can be used by HW iSCSI LLDs */ +extern int iscsi_session_chkready(struct iscsi_cls_session *session); extern struct iscsi_cls_session *iscsi_alloc_session(struct Scsi_Host *shost, struct iscsi_transport *transport); extern int iscsi_add_session(struct iscsi_cls_session *session, -- cgit v1.1 From bd976f62cd6c6dda1ce57bf3e84447e94844868a Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Thu, 31 Jan 2008 13:36:46 -0600 Subject: [SCSI] iscsi class: add session scanning This just adds iscsi session scanning which works like fc rport scanning. The future patches will hook the drivers into Mathew Wilcox's async scanning infrastructure, so userspace does not have to special case iscsi and so userspace does not have to make a extra special case for hardware iscsi root scanning. Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- include/scsi/scsi_transport_iscsi.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h index 0e869d9..1f0ec46 100644 --- a/include/scsi/scsi_transport_iscsi.h +++ b/include/scsi/scsi_transport_iscsi.h @@ -177,11 +177,12 @@ struct iscsi_cls_session { struct list_head host_list; struct iscsi_transport *transport; spinlock_t lock; + struct work_struct scan_work; + struct work_struct unbind_work; /* recovery fields */ int recovery_tmo; struct delayed_work recovery_work; - struct work_struct unbind_work; int target_id; @@ -203,8 +204,8 @@ struct iscsi_cls_session { struct iscsi_host { struct list_head sessions; struct mutex mutex; - struct workqueue_struct *unbind_workq; - char unbind_workq_name[KOBJ_NAME_LEN]; + struct workqueue_struct *scan_workq; + char scan_workq_name[KOBJ_NAME_LEN]; }; /* -- cgit v1.1 From 8aae18adb240a9eb1999b8245c56522cbefc9047 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Thu, 31 Jan 2008 13:36:48 -0600 Subject: [SCSI] iscsi class: add async scan helper In qla4xxx's probe it will call the iscsi session setup functions for session that got setup on the initial start. This then makes it easy for the iscsi class to export a helper which indicates when those scans are done. Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- include/scsi/scsi_transport_iscsi.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h index 1f0ec46..83693ba 100644 --- a/include/scsi/scsi_transport_iscsi.h +++ b/include/scsi/scsi_transport_iscsi.h @@ -203,6 +203,7 @@ struct iscsi_cls_session { struct iscsi_host { struct list_head sessions; + atomic_t nr_scans; struct mutex mutex; struct workqueue_struct *scan_workq; char scan_workq_name[KOBJ_NAME_LEN]; @@ -229,6 +230,6 @@ extern struct iscsi_cls_conn *iscsi_create_conn(struct iscsi_cls_session *sess, extern int iscsi_destroy_conn(struct iscsi_cls_conn *conn); extern void iscsi_unblock_session(struct iscsi_cls_session *session); extern void iscsi_block_session(struct iscsi_cls_session *session); - +extern int iscsi_scan_finished(struct Scsi_Host *shost, unsigned long time); #endif -- cgit v1.1 From 322d739da83bbff0309c202181f79c08d9534880 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Thu, 31 Jan 2008 13:36:52 -0600 Subject: [SCSI] iscsi: fix up iscsi printk prefix Some iscsi class messages have the dev_printk prefix and some libiscsi and iscsi_tcp messages have "iscsi" or the module name as a prefix which is normally pretty useless when trying to figure out which session or connection the message is attached to. This patch adds iscsi lib and class dev_printks so all messages have a common prefix that can be used to figure out which object printed it. Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- include/scsi/libiscsi.h | 7 +++++++ include/scsi/scsi_transport_iscsi.h | 6 ++++++ 2 files changed, 13 insertions(+) (limited to 'include') diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index 278011f..5784e4f 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h @@ -344,6 +344,10 @@ extern int iscsi_session_get_param(struct iscsi_cls_session *cls_session, #define session_to_cls(_sess) \ hostdata_session(_sess->host->hostdata) +#define iscsi_session_printk(prefix, _sess, fmt, a...) \ + iscsi_cls_session_printk(prefix, \ + (struct iscsi_cls_session *)session_to_cls(_sess), fmt, ##a) + /* * connection management */ @@ -358,6 +362,9 @@ extern void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err); extern int iscsi_conn_get_param(struct iscsi_cls_conn *cls_conn, enum iscsi_param param, char *buf); +#define iscsi_conn_printk(prefix, _c, fmt, a...) \ + iscsi_cls_conn_printk(prefix, _c->cls_conn, fmt, ##a) + /* * pdu and task processing */ diff --git a/include/scsi/scsi_transport_iscsi.h b/include/scsi/scsi_transport_iscsi.h index 83693ba..dbc96ef 100644 --- a/include/scsi/scsi_transport_iscsi.h +++ b/include/scsi/scsi_transport_iscsi.h @@ -212,6 +212,12 @@ struct iscsi_host { /* * session and connection functions that can be used by HW iSCSI LLDs */ +#define iscsi_cls_session_printk(prefix, _cls_session, fmt, a...) \ + dev_printk(prefix, &(_cls_session)->dev, fmt, ##a) + +#define iscsi_cls_conn_printk(prefix, _cls_conn, fmt, a...) \ + dev_printk(prefix, &(_cls_conn)->dev, fmt, ##a) + extern int iscsi_session_chkready(struct iscsi_cls_session *session); extern struct iscsi_cls_session *iscsi_alloc_session(struct Scsi_Host *shost, struct iscsi_transport *transport); -- cgit v1.1 From 8b1d03434ee44b08c57f50403eaeab099facebf5 Mon Sep 17 00:00:00 2001 From: Mike Christie Date: Thu, 31 Jan 2008 13:36:53 -0600 Subject: [SCSI] libiscsi: fix session age rollover and remove cid encoding The session age mask is only 4 bits, but session->age is 32. When it gets larger then 15 and we try to or the bits some bits get dropped and the check for session age in iscsi_verify_itt is useless. The ISCSI_CID_MASK related bits are also useless since cid is always one. Signed-off-by: Mike Christie Signed-off-by: James Bottomley --- include/scsi/iscsi_proto.h | 4 ++-- include/scsi/libiscsi.h | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/scsi/iscsi_proto.h b/include/scsi/iscsi_proto.h index 318a909..5ffec8a 100644 --- a/include/scsi/iscsi_proto.h +++ b/include/scsi/iscsi_proto.h @@ -45,8 +45,8 @@ /* initiator tags; opaque for target */ typedef uint32_t __bitwise__ itt_t; /* below makes sense only for initiator that created this tag */ -#define build_itt(itt, id, age) ((__force itt_t)\ - ((itt) | ((id) << ISCSI_CID_SHIFT) | ((age) << ISCSI_AGE_SHIFT))) +#define build_itt(itt, age) ((__force itt_t)\ + ((itt) | ((age) << ISCSI_AGE_SHIFT))) #define get_itt(itt) ((__force uint32_t)(itt_t)(itt) & ISCSI_ITT_MASK) #define RESERVED_ITT ((__force itt_t)0xffffffff) diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index 5784e4f..7b90b63 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h @@ -70,8 +70,6 @@ enum { #define ISCSI_SUSPEND_BIT 1 #define ISCSI_ITT_MASK (0xfff) -#define ISCSI_CID_SHIFT 12 -#define ISCSI_CID_MASK (0xffff << ISCSI_CID_SHIFT) #define ISCSI_AGE_SHIFT 28 #define ISCSI_AGE_MASK (0xf << ISCSI_AGE_SHIFT) -- cgit v1.1 From 89dddbce9c6ec7663af81a74be6a6aa720301994 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Sun, 3 Feb 2008 15:32:59 -0600 Subject: [SCSI] add protocol definitions A lot of SCSI command replies have a protocol ID field. Add definitions for the interpretation of that from SPC-3. Signed-off-by: James Bottomley --- include/scsi/scsi.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'include') diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h index 8225157..1f74bcd 100644 --- a/include/scsi/scsi.h +++ b/include/scsi/scsi.h @@ -235,6 +235,20 @@ static inline int scsi_status_is_good(int status) #define TYPE_RBC 0x0e #define TYPE_NO_LUN 0x7f +/* SCSI protocols; these are taken from SPC-3 section 7.5 */ +enum scsi_protocol { + SCSI_PROTOCOL_FCP = 0, /* Fibre Channel */ + SCSI_PROTOCOL_SPI = 1, /* parallel SCSI */ + SCSI_PROTOCOL_SSA = 2, /* Serial Storage Architecture - Obsolete */ + SCSI_PROTOCOL_SBP = 3, /* firewire */ + SCSI_PROTOCOL_SRP = 4, /* Infiniband RDMA */ + SCSI_PROTOCOL_ISCSI = 5, + SCSI_PROTOCOL_SAS = 6, + SCSI_PROTOCOL_ADT = 7, /* Media Changers */ + SCSI_PROTOCOL_ATA = 8, + SCSI_PROTOCOL_UNSPEC = 0xf, /* No specific protocol */ +}; + /* Returns a human-readable name for the device */ extern const char * scsi_device_type(unsigned type); -- cgit v1.1 From d850bd34f5b2a52ccec90188ad86165f940693e9 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Mon, 4 Feb 2008 23:53:24 -0800 Subject: [SCSI] Small cleanups for scsi_host.h Small cleanups in scsi_host.h. Few #defines make me wonder if their description is still up to date..? Signed-off-by: Pavel Machek Signed-off-by: Andrew Morton Signed-off-by: James Bottomley --- include/scsi/scsi_host.h | 44 +++++++++++++++++++++++++------------------- 1 file changed, 25 insertions(+), 19 deletions(-) (limited to 'include') diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index 5c58d59..d1299e9 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -280,39 +280,45 @@ struct scsi_host_template { * If the host wants to be called before the scan starts, but * after the midlayer has set up ready for the scan, it can fill * in this function. + * + * Status: OPTIONAL */ void (* scan_start)(struct Scsi_Host *); /* - * fill in this function to allow the queue depth of this host - * to be changeable (on a per device basis). returns either + * Fill in this function to allow the queue depth of this host + * to be changeable (on a per device basis). Returns either * the current queue depth setting (may be different from what * was passed in) or an error. An error should only be * returned if the requested depth is legal but the driver was * unable to set it. If the requested depth is illegal, the * driver should set and return the closest legal queue depth. * + * Status: OPTIONAL */ int (* change_queue_depth)(struct scsi_device *, int); /* - * fill in this function to allow the changing of tag types + * Fill in this function to allow the changing of tag types * (this also allows the enabling/disabling of tag command * queueing). An error should only be returned if something * went wrong in the driver while trying to set the tag type. * If the driver doesn't support the requested tag type, then * it should set the closest type it does support without * returning an error. Returns the actual tag type set. + * + * Status: OPTIONAL */ int (* change_queue_type)(struct scsi_device *, int); /* - * This function determines the bios parameters for a given + * This function determines the BIOS parameters for a given * harddisk. These tend to be numbers that are made up by * the host adapter. Parameters: * size, device, list (heads, sectors, cylinders) * - * Status: OPTIONAL */ + * Status: OPTIONAL + */ int (* bios_param)(struct scsi_device *, struct block_device *, sector_t, int []); @@ -351,7 +357,7 @@ struct scsi_host_template { /* * This determines if we will use a non-interrupt driven - * or an interrupt driven scheme, It is set to the maximum number + * or an interrupt driven scheme. It is set to the maximum number * of simultaneous commands a given host adapter will accept. */ int can_queue; @@ -372,12 +378,12 @@ struct scsi_host_template { unsigned short sg_tablesize; /* - * If the host adapter has limitations beside segment count + * Set this if the host adapter has limitations beside segment count. */ unsigned short max_sectors; /* - * dma scatter gather segment boundary limit. a segment crossing this + * DMA scatter gather segment boundary limit. A segment crossing this * boundary will be split in two. */ unsigned long dma_boundary; @@ -386,7 +392,7 @@ struct scsi_host_template { * This specifies "machine infinity" for host templates which don't * limit the transfer size. Note this limit represents an absolute * maximum, and may be over the transfer limits allowed for - * individual devices (e.g. 256 for SCSI-1) + * individual devices (e.g. 256 for SCSI-1). */ #define SCSI_DEFAULT_MAX_SECTORS 1024 @@ -413,12 +419,12 @@ struct scsi_host_template { unsigned supported_mode:2; /* - * true if this host adapter uses unchecked DMA onto an ISA bus. + * True if this host adapter uses unchecked DMA onto an ISA bus. */ unsigned unchecked_isa_dma:1; /* - * true if this host adapter can make good use of clustering. + * True if this host adapter can make good use of clustering. * I originally thought that if the tablesize was large that it * was a waste of CPU cycles to prepare a cluster list, but * it works out that the Buslogic is faster if you use a smaller @@ -428,7 +434,7 @@ struct scsi_host_template { unsigned use_clustering:1; /* - * True for emulated SCSI host adapters (e.g. ATAPI) + * True for emulated SCSI host adapters (e.g. ATAPI). */ unsigned emulated:1; @@ -438,12 +444,12 @@ struct scsi_host_template { unsigned skip_settle_delay:1; /* - * ordered write support + * True if we are using ordered write support. */ unsigned ordered_tag:1; /* - * Countdown for host blocking with no commands outstanding + * Countdown for host blocking with no commands outstanding. */ unsigned int max_host_blocked; @@ -522,8 +528,8 @@ struct Scsi_Host { struct scsi_transport_template *transportt; /* - * area to keep a shared tag map (if needed, will be - * NULL if not) + * Area to keep a shared tag map (if needed, will be + * NULL if not). */ struct blk_queue_tag *bqt; @@ -596,16 +602,16 @@ struct Scsi_Host { /* * Host uses correct SCSI ordering not PC ordering. The bit is * set for the minority of drivers whose authors actually read - * the spec ;) + * the spec ;). */ unsigned reverse_ordering:1; /* - * ordered write support + * Ordered write support */ unsigned ordered_tag:1; - /* task mgmt function in progress */ + /* Task mgmt function in progress */ unsigned tmf_in_progress:1; /* Asynchronous scan in progress */ -- cgit v1.1 From d569d5bb3fd96d2907acaddd7c4ea5cb07d02ab8 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Sun, 3 Feb 2008 15:40:56 -0600 Subject: [SCSI] enclosure: add support for enclosure services The enclosure misc device is really just a library providing sysfs support for physical enclosure devices and their components. Signed-off-by: James Bottomley --- include/linux/enclosure.h | 129 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 include/linux/enclosure.h (limited to 'include') diff --git a/include/linux/enclosure.h b/include/linux/enclosure.h new file mode 100644 index 0000000..a5978f1 --- /dev/null +++ b/include/linux/enclosure.h @@ -0,0 +1,129 @@ +/* + * Enclosure Services + * + * Copyright (C) 2008 James Bottomley + * +**----------------------------------------------------------------------------- +** +** 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 +#include + +/* A few generic types ... taken from ses-2 */ +enum enclosure_component_type { + ENCLOSURE_COMPONENT_DEVICE = 0x01, + ENCLOSURE_COMPONENT_ARRAY_DEVICE = 0x17, +}; + +/* 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, +}; + +/* 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); +}; + + +struct enclosure_component { + void *scratch; + struct class_device cdev; + enum enclosure_component_type type; + int number; + int fault; + int active; + int locate; + enum enclosure_status status; +}; + +struct enclosure_device { + void *scratch; + struct list_head node; + struct class_device cdev; + struct enclosure_component_callbacks *cb; + int components; + struct enclosure_component component[0]; +}; + +static inline struct enclosure_device * +to_enclosure_device(struct class_device *dev) +{ + return container_of(dev, struct enclosure_device, cdev); +} + +static inline struct enclosure_component * +to_enclosure_component(struct class_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_register(struct enclosure_device *, unsigned int, + enum enclosure_component_type, const char *); +int enclosure_add_device(struct enclosure_device *enclosure, int component, + struct device *dev); +int enclosure_remove_device(struct enclosure_device *enclosure, int component); +struct enclosure_device *enclosure_find(struct device *dev); +int enclosure_for_each_device(int (*fn)(struct enclosure_device *, void *), + void *data); + +#endif /* _LINUX_ENCLOSURE_H_ */ -- cgit v1.1