blob: 160564399ff4eaf4f89bed53e827768845304b3b [file] [log] [blame]
Sebastian Ottf30664e2012-08-28 16:50:38 +02001#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>
Sebastian Ott12d90762017-01-25 16:18:53 +01007#include <linux/blk-mq.h>
Sebastian Ottf30664e2012-08-28 16:50:38 +02008#include <linux/genhd.h>
9#include <linux/list.h>
10
11#include <asm/debug.h>
12#include <asm/eadm.h>
13
14#define SCM_NR_PARTS 8
15#define SCM_QUEUE_DELAY 5
16
17struct scm_blk_dev {
18 struct tasklet_struct tasklet;
19 struct request_queue *rq;
20 struct gendisk *gendisk;
Sebastian Ott12d90762017-01-25 16:18:53 +010021 struct blk_mq_tag_set tag_set;
Sebastian Ottf30664e2012-08-28 16:50:38 +020022 struct scm_device *scmdev;
23 spinlock_t rq_lock; /* guard the request queue */
24 spinlock_t lock; /* guard the rest of the blockdev */
25 atomic_t queued_reqs;
Sebastian Ott4fa3c012013-02-28 12:07:48 +010026 enum {SCM_OPER, SCM_WR_PROHIBIT} state;
Sebastian Ottf30664e2012-08-28 16:50:38 +020027 struct list_head finished_requests;
28};
29
30struct scm_request {
31 struct scm_blk_dev *bdev;
Sebastian Ottde88d0d2014-12-05 16:41:47 +010032 struct aidaw *next_aidaw;
Sebastian Ott86223842014-12-05 16:47:17 +010033 struct request **request;
Sebastian Ottf30664e2012-08-28 16:50:38 +020034 struct aob *aob;
35 struct list_head list;
36 u8 retries;
37 int error;
38};
39
40#define to_aobrq(rq) container_of((void *) rq, struct aob_rq_header, data)
41
42int scm_blk_dev_setup(struct scm_blk_dev *, struct scm_device *);
43void scm_blk_dev_cleanup(struct scm_blk_dev *);
Sebastian Ott4fa3c012013-02-28 12:07:48 +010044void scm_blk_set_available(struct scm_blk_dev *);
Sebastian Ottf30664e2012-08-28 16:50:38 +020045void scm_blk_irq(struct scm_device *, void *, int);
46
Sebastian Ottde88d0d2014-12-05 16:41:47 +010047struct aidaw *scm_aidaw_fetch(struct scm_request *scmrq, unsigned int bytes);
Sebastian Ott9d4df772014-12-05 16:32:13 +010048
Sebastian Ottf30664e2012-08-28 16:50:38 +020049int scm_drv_init(void);
50void scm_drv_cleanup(void);
51
Sebastian Ottf30664e2012-08-28 16:50:38 +020052extern debug_info_t *scm_debug;
53
54#define SCM_LOG(imp, txt) do { \
55 debug_text_event(scm_debug, imp, txt); \
56 } while (0)
57
58static inline void SCM_LOG_HEX(int level, void *data, int length)
59{
Hendrik Brueckner8e6a8282013-09-18 17:21:34 +020060 if (!debug_level_enabled(scm_debug, level))
Sebastian Ottf30664e2012-08-28 16:50:38 +020061 return;
62 while (length > 0) {
63 debug_event(scm_debug, level, data, length);
64 length -= scm_debug->buf_size;
65 data += scm_debug->buf_size;
66 }
67}
68
69static inline void SCM_LOG_STATE(int level, struct scm_device *scmdev)
70{
71 struct {
72 u64 address;
73 u8 oper_state;
74 u8 rank;
75 } __packed data = {
76 .address = scmdev->address,
77 .oper_state = scmdev->attrs.oper_state,
78 .rank = scmdev->attrs.rank,
79 };
80
81 SCM_LOG_HEX(level, &data, sizeof(data));
82}
83
84#endif /* SCM_BLK_H */