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 16 struct 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; 24 enum {SCM_OPER, SCM_WR_PROHIBIT} state; 25 struct list_head finished_requests; 26 #ifdef CONFIG_SCM_BLOCK_CLUSTER_WRITE 27 struct list_head cluster_list; 28 #endif 29 }; 30 31 struct scm_request { 32 struct scm_blk_dev *bdev; 33 struct aidaw *next_aidaw; 34 struct request **request; 35 struct aob *aob; 36 struct list_head list; 37 u8 retries; 38 int error; 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 46 }; 47 48 #define to_aobrq(rq) container_of((void *) rq, struct aob_rq_header, data) 49 50 int scm_blk_dev_setup(struct scm_blk_dev *, struct scm_device *); 51 void scm_blk_dev_cleanup(struct scm_blk_dev *); 52 void scm_blk_set_available(struct scm_blk_dev *); 53 void scm_blk_irq(struct scm_device *, void *, int); 54 55 void scm_request_finish(struct scm_request *); 56 void scm_request_requeue(struct scm_request *); 57 58 struct aidaw *scm_aidaw_fetch(struct scm_request *scmrq, unsigned int bytes); 59 60 int scm_drv_init(void); 61 void scm_drv_cleanup(void); 62 63 #ifdef CONFIG_SCM_BLOCK_CLUSTER_WRITE 64 void __scm_free_rq_cluster(struct scm_request *); 65 int __scm_alloc_rq_cluster(struct scm_request *); 66 void scm_request_cluster_init(struct scm_request *); 67 bool scm_reserve_cluster(struct scm_request *); 68 void scm_release_cluster(struct scm_request *); 69 void scm_blk_dev_cluster_setup(struct scm_blk_dev *); 70 bool scm_need_cluster_request(struct scm_request *); 71 void scm_initiate_cluster_request(struct scm_request *); 72 void scm_cluster_request_irq(struct scm_request *); 73 bool scm_test_cluster_request(struct scm_request *); 74 bool scm_cluster_size_valid(void); 75 #else /* CONFIG_SCM_BLOCK_CLUSTER_WRITE */ 76 static inline void __scm_free_rq_cluster(struct scm_request *scmrq) {} 77 static inline int __scm_alloc_rq_cluster(struct scm_request *scmrq) 78 { 79 return 0; 80 } 81 static inline void scm_request_cluster_init(struct scm_request *scmrq) {} 82 static inline bool scm_reserve_cluster(struct scm_request *scmrq) 83 { 84 return true; 85 } 86 static inline void scm_release_cluster(struct scm_request *scmrq) {} 87 static inline void scm_blk_dev_cluster_setup(struct scm_blk_dev *bdev) {} 88 static inline bool scm_need_cluster_request(struct scm_request *scmrq) 89 { 90 return false; 91 } 92 static inline void scm_initiate_cluster_request(struct scm_request *scmrq) {} 93 static inline void scm_cluster_request_irq(struct scm_request *scmrq) {} 94 static inline bool scm_test_cluster_request(struct scm_request *scmrq) 95 { 96 return false; 97 } 98 static inline bool scm_cluster_size_valid(void) 99 { 100 return true; 101 } 102 #endif /* CONFIG_SCM_BLOCK_CLUSTER_WRITE */ 103 104 extern 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 110 static inline void SCM_LOG_HEX(int level, void *data, int length) 111 { 112 if (!debug_level_enabled(scm_debug, level)) 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 121 static 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 */ 137