blob: 71288dd9dd7f51e8ced7e4eb799096d313f51cf3 [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 {
Sebastian Ottf30664e2012-08-28 16:50:38 +020018 struct request_queue *rq;
19 struct gendisk *gendisk;
Sebastian Ott12d90762017-01-25 16:18:53 +010020 struct blk_mq_tag_set tag_set;
Sebastian Ottf30664e2012-08-28 16:50:38 +020021 struct scm_device *scmdev;
Sebastian Ott9861dbd2017-02-24 17:50:17 +010022 spinlock_t lock;
Sebastian Ottf30664e2012-08-28 16:50:38 +020023 atomic_t queued_reqs;
Sebastian Ott4fa3c012013-02-28 12:07:48 +010024 enum {SCM_OPER, SCM_WR_PROHIBIT} state;
Sebastian Ottf30664e2012-08-28 16:50:38 +020025 struct list_head finished_requests;
26};
27
28struct scm_request {
29 struct scm_blk_dev *bdev;
Sebastian Ottde88d0d2014-12-05 16:41:47 +010030 struct aidaw *next_aidaw;
Sebastian Ott86223842014-12-05 16:47:17 +010031 struct request **request;
Sebastian Ottf30664e2012-08-28 16:50:38 +020032 struct aob *aob;
33 struct list_head list;
34 u8 retries;
Christoph Hellwig2a842ac2017-06-03 09:38:04 +020035 blk_status_t error;
Sebastian Ottf30664e2012-08-28 16:50:38 +020036};
37
38#define to_aobrq(rq) container_of((void *) rq, struct aob_rq_header, data)
39
40int scm_blk_dev_setup(struct scm_blk_dev *, struct scm_device *);
41void scm_blk_dev_cleanup(struct scm_blk_dev *);
Sebastian Ott4fa3c012013-02-28 12:07:48 +010042void scm_blk_set_available(struct scm_blk_dev *);
Christoph Hellwig2a842ac2017-06-03 09:38:04 +020043void scm_blk_irq(struct scm_device *, void *, blk_status_t);
Sebastian Ottf30664e2012-08-28 16:50:38 +020044
Sebastian Ottde88d0d2014-12-05 16:41:47 +010045struct aidaw *scm_aidaw_fetch(struct scm_request *scmrq, unsigned int bytes);
Sebastian Ott9d4df772014-12-05 16:32:13 +010046
Sebastian Ottf30664e2012-08-28 16:50:38 +020047int scm_drv_init(void);
48void scm_drv_cleanup(void);
49
Sebastian Ottf30664e2012-08-28 16:50:38 +020050extern debug_info_t *scm_debug;
51
52#define SCM_LOG(imp, txt) do { \
53 debug_text_event(scm_debug, imp, txt); \
54 } while (0)
55
56static inline void SCM_LOG_HEX(int level, void *data, int length)
57{
Hendrik Brueckner8e6a8282013-09-18 17:21:34 +020058 if (!debug_level_enabled(scm_debug, level))
Sebastian Ottf30664e2012-08-28 16:50:38 +020059 return;
60 while (length > 0) {
61 debug_event(scm_debug, level, data, length);
62 length -= scm_debug->buf_size;
63 data += scm_debug->buf_size;
64 }
65}
66
67static inline void SCM_LOG_STATE(int level, struct scm_device *scmdev)
68{
69 struct {
70 u64 address;
71 u8 oper_state;
72 u8 rank;
73 } __packed data = {
74 .address = scmdev->address,
75 .oper_state = scmdev->attrs.oper_state,
76 .rank = scmdev->attrs.rank,
77 };
78
79 SCM_LOG_HEX(level, &data, sizeof(data));
80}
81
82#endif /* SCM_BLK_H */