| /* SPDX-License-Identifier: GPL-2.0 */ |
| #ifndef SCM_BLK_H |
| #define SCM_BLK_H |
| |
| #include <linux/interrupt.h> |
| #include <linux/spinlock.h> |
| #include <linux/blkdev.h> |
| #include <linux/blk-mq.h> |
| #include <linux/list.h> |
| |
| #include <asm/debug.h> |
| #include <asm/eadm.h> |
| |
| #define SCM_NR_PARTS 8 |
| #define SCM_QUEUE_DELAY 5 |
| |
| struct scm_blk_dev { |
| struct request_queue *rq; |
| struct gendisk *gendisk; |
| struct blk_mq_tag_set tag_set; |
| struct scm_device *scmdev; |
| spinlock_t lock; |
| atomic_t queued_reqs; |
| enum {SCM_OPER, SCM_WR_PROHIBIT} state; |
| struct list_head finished_requests; |
| }; |
| |
| struct scm_request { |
| struct scm_blk_dev *bdev; |
| struct aidaw *next_aidaw; |
| struct request **request; |
| struct aob *aob; |
| struct list_head list; |
| u8 retries; |
| blk_status_t error; |
| }; |
| |
| #define to_aobrq(rq) container_of((void *) rq, struct aob_rq_header, data) |
| |
| int scm_blk_dev_setup(struct scm_blk_dev *, struct scm_device *); |
| void scm_blk_dev_cleanup(struct scm_blk_dev *); |
| void scm_blk_set_available(struct scm_blk_dev *); |
| void scm_blk_irq(struct scm_device *, void *, blk_status_t); |
| |
| struct aidaw *scm_aidaw_fetch(struct scm_request *scmrq, unsigned int bytes); |
| |
| int scm_drv_init(void); |
| void scm_drv_cleanup(void); |
| |
| extern debug_info_t *scm_debug; |
| |
| #define SCM_LOG(imp, txt) do { \ |
| debug_text_event(scm_debug, imp, txt); \ |
| } while (0) |
| |
| static inline void SCM_LOG_HEX(int level, void *data, int length) |
| { |
| debug_event(scm_debug, level, data, length); |
| } |
| |
| static inline void SCM_LOG_STATE(int level, struct scm_device *scmdev) |
| { |
| struct { |
| u64 address; |
| u8 oper_state; |
| u8 rank; |
| } __packed data = { |
| .address = scmdev->address, |
| .oper_state = scmdev->attrs.oper_state, |
| .rank = scmdev->attrs.rank, |
| }; |
| |
| SCM_LOG_HEX(level, &data, sizeof(data)); |
| } |
| |
| #endif /* SCM_BLK_H */ |