]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blame - drivers/s390/block/scm_blk.h
block: introduce new block status code type
[mirror_ubuntu-bionic-kernel.git] / drivers / s390 / block / scm_blk.h
CommitLineData
f30664e2
SO
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;
4fa3c019 24 enum {SCM_OPER, SCM_WR_PROHIBIT} state;
f30664e2 25 struct list_head finished_requests;
0d804b20
SO
26#ifdef CONFIG_SCM_BLOCK_CLUSTER_WRITE
27 struct list_head cluster_list;
28#endif
f30664e2
SO
29};
30
31struct scm_request {
32 struct scm_blk_dev *bdev;
de88d0d2 33 struct aidaw *next_aidaw;
8622384f 34 struct request **request;
f30664e2
SO
35 struct aob *aob;
36 struct list_head list;
37 u8 retries;
2a842aca 38 blk_status_t error;
0d804b20
SO
39#ifdef CONFIG_SCM_BLOCK_CLUSTER_WRITE
40 struct {
41 enum {CLUSTER_NONE, CLUSTER_READ, CLUSTER_WRITE} state;
42 struct list_head list;
43 void **buf;
44 } cluster;
45#endif
f30664e2
SO
46};
47
48#define to_aobrq(rq) container_of((void *) rq, struct aob_rq_header, data)
49
50int scm_blk_dev_setup(struct scm_blk_dev *, struct scm_device *);
51void scm_blk_dev_cleanup(struct scm_blk_dev *);
4fa3c019 52void scm_blk_set_available(struct scm_blk_dev *);
2a842aca 53void scm_blk_irq(struct scm_device *, void *, blk_status_t);
f30664e2 54
0d804b20
SO
55void scm_request_finish(struct scm_request *);
56void scm_request_requeue(struct scm_request *);
57
de88d0d2 58struct aidaw *scm_aidaw_fetch(struct scm_request *scmrq, unsigned int bytes);
9d4df77f 59
f30664e2
SO
60int scm_drv_init(void);
61void scm_drv_cleanup(void);
62
0d804b20
SO
63#ifdef CONFIG_SCM_BLOCK_CLUSTER_WRITE
64void __scm_free_rq_cluster(struct scm_request *);
65int __scm_alloc_rq_cluster(struct scm_request *);
66void scm_request_cluster_init(struct scm_request *);
67bool scm_reserve_cluster(struct scm_request *);
68void scm_release_cluster(struct scm_request *);
69void scm_blk_dev_cluster_setup(struct scm_blk_dev *);
70bool scm_need_cluster_request(struct scm_request *);
71void scm_initiate_cluster_request(struct scm_request *);
72void scm_cluster_request_irq(struct scm_request *);
73bool scm_test_cluster_request(struct scm_request *);
74bool scm_cluster_size_valid(void);
58fece78
SO
75#else /* CONFIG_SCM_BLOCK_CLUSTER_WRITE */
76static inline void __scm_free_rq_cluster(struct scm_request *scmrq) {}
77static inline int __scm_alloc_rq_cluster(struct scm_request *scmrq)
78{
79 return 0;
80}
81static inline void scm_request_cluster_init(struct scm_request *scmrq) {}
82static inline bool scm_reserve_cluster(struct scm_request *scmrq)
83{
84 return true;
85}
86static inline void scm_release_cluster(struct scm_request *scmrq) {}
87static inline void scm_blk_dev_cluster_setup(struct scm_blk_dev *bdev) {}
88static inline bool scm_need_cluster_request(struct scm_request *scmrq)
89{
90 return false;
91}
92static inline void scm_initiate_cluster_request(struct scm_request *scmrq) {}
93static inline void scm_cluster_request_irq(struct scm_request *scmrq) {}
94static inline bool scm_test_cluster_request(struct scm_request *scmrq)
95{
96 return false;
97}
98static inline bool scm_cluster_size_valid(void)
99{
100 return true;
101}
102#endif /* CONFIG_SCM_BLOCK_CLUSTER_WRITE */
f30664e2
SO
103
104extern debug_info_t *scm_debug;
105
106#define SCM_LOG(imp, txt) do { \
107 debug_text_event(scm_debug, imp, txt); \
108 } while (0)
109
110static inline void SCM_LOG_HEX(int level, void *data, int length)
111{
8e6a8285 112 if (!debug_level_enabled(scm_debug, level))
f30664e2
SO
113 return;
114 while (length > 0) {
115 debug_event(scm_debug, level, data, length);
116 length -= scm_debug->buf_size;
117 data += scm_debug->buf_size;
118 }
119}
120
121static inline void SCM_LOG_STATE(int level, struct scm_device *scmdev)
122{
123 struct {
124 u64 address;
125 u8 oper_state;
126 u8 rank;
127 } __packed data = {
128 .address = scmdev->address,
129 .oper_state = scmdev->attrs.oper_state,
130 .rank = scmdev->attrs.rank,
131 };
132
133 SCM_LOG_HEX(level, &data, sizeof(data));
134}
135
136#endif /* SCM_BLK_H */