0001
0002 #ifndef SCM_BLK_H
0003 #define SCM_BLK_H
0004
0005 #include <linux/interrupt.h>
0006 #include <linux/spinlock.h>
0007 #include <linux/blkdev.h>
0008 #include <linux/blk-mq.h>
0009 #include <linux/list.h>
0010
0011 #include <asm/debug.h>
0012 #include <asm/eadm.h>
0013
0014 #define SCM_NR_PARTS 8
0015 #define SCM_QUEUE_DELAY 5
0016
0017 struct scm_blk_dev {
0018 struct request_queue *rq;
0019 struct gendisk *gendisk;
0020 struct blk_mq_tag_set tag_set;
0021 struct scm_device *scmdev;
0022 spinlock_t lock;
0023 atomic_t queued_reqs;
0024 enum {SCM_OPER, SCM_WR_PROHIBIT} state;
0025 struct list_head finished_requests;
0026 };
0027
0028 struct scm_request {
0029 struct scm_blk_dev *bdev;
0030 struct aidaw *next_aidaw;
0031 struct request **request;
0032 struct aob *aob;
0033 struct list_head list;
0034 u8 retries;
0035 blk_status_t error;
0036 };
0037
0038 #define to_aobrq(rq) container_of((void *) rq, struct aob_rq_header, data)
0039
0040 int scm_blk_dev_setup(struct scm_blk_dev *, struct scm_device *);
0041 void scm_blk_dev_cleanup(struct scm_blk_dev *);
0042 void scm_blk_set_available(struct scm_blk_dev *);
0043 void scm_blk_irq(struct scm_device *, void *, blk_status_t);
0044
0045 struct aidaw *scm_aidaw_fetch(struct scm_request *scmrq, unsigned int bytes);
0046
0047 int scm_drv_init(void);
0048 void scm_drv_cleanup(void);
0049
0050 extern debug_info_t *scm_debug;
0051
0052 #define SCM_LOG(imp, txt) do { \
0053 debug_text_event(scm_debug, imp, txt); \
0054 } while (0)
0055
0056 static inline void SCM_LOG_HEX(int level, void *data, int length)
0057 {
0058 debug_event(scm_debug, level, data, length);
0059 }
0060
0061 static inline void SCM_LOG_STATE(int level, struct scm_device *scmdev)
0062 {
0063 struct {
0064 u64 address;
0065 u8 oper_state;
0066 u8 rank;
0067 } __packed data = {
0068 .address = scmdev->address,
0069 .oper_state = scmdev->attrs.oper_state,
0070 .rank = scmdev->attrs.rank,
0071 };
0072
0073 SCM_LOG_HEX(level, &data, sizeof(data));
0074 }
0075
0076 #endif