linux/drivers/s390/block/scm_blk.h
<<
>>
Prefs
   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
  16struct 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
  31struct 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
  50int scm_blk_dev_setup(struct scm_blk_dev *, struct scm_device *);
  51void scm_blk_dev_cleanup(struct scm_blk_dev *);
  52void scm_blk_set_available(struct scm_blk_dev *);
  53void scm_blk_irq(struct scm_device *, void *, int);
  54
  55void scm_request_finish(struct scm_request *);
  56void scm_request_requeue(struct scm_request *);
  57
  58struct aidaw *scm_aidaw_fetch(struct scm_request *scmrq, unsigned int bytes);
  59
  60int scm_drv_init(void);
  61void scm_drv_cleanup(void);
  62
  63#ifdef CONFIG_SCM_BLOCK_CLUSTER_WRITE
  64void __scm_free_rq_cluster(struct scm_request *);
  65int __scm_alloc_rq_cluster(struct scm_request *);
  66void scm_request_cluster_init(struct scm_request *);
  67bool scm_reserve_cluster(struct scm_request *);
  68void scm_release_cluster(struct scm_request *);
  69void scm_blk_dev_cluster_setup(struct scm_blk_dev *);
  70bool scm_need_cluster_request(struct scm_request *);
  71void scm_initiate_cluster_request(struct scm_request *);
  72void scm_cluster_request_irq(struct scm_request *);
  73bool scm_test_cluster_request(struct scm_request *);
  74bool scm_cluster_size_valid(void);
  75#else /* CONFIG_SCM_BLOCK_CLUSTER_WRITE */
  76static inline void __scm_free_rq_cluster(struct scm_request *scmrq) {}
  77static inline int __scm_alloc_rq_cluster(struct scm_request *scmrq)
  78{
  79        return 0;
  80}
  81static inline void scm_request_cluster_init(struct scm_request *scmrq) {}
  82static inline bool scm_reserve_cluster(struct scm_request *scmrq)
  83{
  84        return true;
  85}
  86static inline void scm_release_cluster(struct scm_request *scmrq) {}
  87static inline void scm_blk_dev_cluster_setup(struct scm_blk_dev *bdev) {}
  88static inline bool scm_need_cluster_request(struct scm_request *scmrq)
  89{
  90        return false;
  91}
  92static inline void scm_initiate_cluster_request(struct scm_request *scmrq) {}
  93static inline void scm_cluster_request_irq(struct scm_request *scmrq) {}
  94static inline bool scm_test_cluster_request(struct scm_request *scmrq)
  95{
  96        return false;
  97}
  98static inline bool scm_cluster_size_valid(void)
  99{
 100        return true;
 101}
 102#endif /* CONFIG_SCM_BLOCK_CLUSTER_WRITE */
 103
 104extern 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
 110static 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
 121static 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