aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/block/scm_blk.h
diff options
context:
space:
mode:
authorSebastian Ott <sebott@linux.vnet.ibm.com>2012-08-28 10:50:38 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2012-09-26 09:45:01 -0400
commitf30664e2c85c7804f07c636bbe99f35e0b2d4c76 (patch)
tree17b6c655cd9f7eddc8980e05c7f378ff774cac0d /drivers/s390/block/scm_blk.h
parent2e73c2cf78f797f3ff299ca39b210bceb40ab804 (diff)
s390: add scm block driver
Block device driver for Storage Class Memory (SCM). This driver provides a block device interface for each available SCM increment. Signed-off-by: Sebastian Ott <sebott@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/block/scm_blk.h')
-rw-r--r--drivers/s390/block/scm_blk.h79
1 files changed, 79 insertions, 0 deletions
diff --git a/drivers/s390/block/scm_blk.h b/drivers/s390/block/scm_blk.h
new file mode 100644
index 000000000000..5aba5612588f
--- /dev/null
+++ b/drivers/s390/block/scm_blk.h
@@ -0,0 +1,79 @@
1#ifndef SCM_BLK_H
2#define SCM_BLK_H
3
4#include <linux/interrupt.h>
5#include <linux/spinlock.h>
6#include <linux/blkdev.h>
7#include <linux/genhd.h>
8#include <linux/list.h>
9
10#include <asm/debug.h>
11#include <asm/eadm.h>
12
13#define SCM_NR_PARTS 8
14#define SCM_QUEUE_DELAY 5
15
16struct scm_blk_dev {
17 struct tasklet_struct tasklet;
18 struct request_queue *rq;
19 struct gendisk *gendisk;
20 struct scm_device *scmdev;
21 spinlock_t rq_lock; /* guard the request queue */
22 spinlock_t lock; /* guard the rest of the blockdev */
23 atomic_t queued_reqs;
24 struct list_head finished_requests;
25};
26
27struct scm_request {
28 struct scm_blk_dev *bdev;
29 struct request *request;
30 struct aidaw *aidaw;
31 struct aob *aob;
32 struct list_head list;
33 u8 retries;
34 int error;
35};
36
37#define to_aobrq(rq) container_of((void *) rq, struct aob_rq_header, data)
38
39int scm_blk_dev_setup(struct scm_blk_dev *, struct scm_device *);
40void scm_blk_dev_cleanup(struct scm_blk_dev *);
41void scm_blk_irq(struct scm_device *, void *, int);
42
43int scm_drv_init(void);
44void scm_drv_cleanup(void);
45
46
47extern debug_info_t *scm_debug;
48
49#define SCM_LOG(imp, txt) do { \
50 debug_text_event(scm_debug, imp, txt); \
51 } while (0)
52
53static inline void SCM_LOG_HEX(int level, void *data, int length)
54{
55 if (level > scm_debug->level)
56 return;
57 while (length > 0) {
58 debug_event(scm_debug, level, data, length);
59 length -= scm_debug->buf_size;
60 data += scm_debug->buf_size;
61 }
62}
63
64static inline void SCM_LOG_STATE(int level, struct scm_device *scmdev)
65{
66 struct {
67 u64 address;
68 u8 oper_state;
69 u8 rank;
70 } __packed data = {
71 .address = scmdev->address,
72 .oper_state = scmdev->attrs.oper_state,
73 .rank = scmdev->attrs.rank,
74 };
75
76 SCM_LOG_HEX(level, &data, sizeof(data));
77}
78
79#endif /* SCM_BLK_H */