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 request *request;
  34        struct aidaw *aidaw;
  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
  58int scm_drv_init(void);
  59void scm_drv_cleanup(void);
  60
  61#ifdef CONFIG_SCM_BLOCK_CLUSTER_WRITE
  62void __scm_free_rq_cluster(struct scm_request *);
  63int __scm_alloc_rq_cluster(struct scm_request *);
  64void scm_request_cluster_init(struct scm_request *);
  65bool scm_reserve_cluster(struct scm_request *);
  66void scm_release_cluster(struct scm_request *);
  67void scm_blk_dev_cluster_setup(struct scm_blk_dev *);
  68bool scm_need_cluster_request(struct scm_request *);
  69void scm_initiate_cluster_request(struct scm_request *);
  70void scm_cluster_request_irq(struct scm_request *);
  71bool scm_test_cluster_request(struct scm_request *);
  72bool scm_cluster_size_valid(void);
  73#else /* CONFIG_SCM_BLOCK_CLUSTER_WRITE */
  74static inline void __scm_free_rq_cluster(struct scm_request *scmrq) {}
  75static inline int __scm_alloc_rq_cluster(struct scm_request *scmrq)
  76{
  77        return 0;
  78}
  79static inline void scm_request_cluster_init(struct scm_request *scmrq) {}
  80static inline bool scm_reserve_cluster(struct scm_request *scmrq)
  81{
  82        return true;
  83}
  84static inline void scm_release_cluster(struct scm_request *scmrq) {}
  85static inline void scm_blk_dev_cluster_setup(struct scm_blk_dev *bdev) {}
  86static inline bool scm_need_cluster_request(struct scm_request *scmrq)
  87{
  88        return false;
  89}
  90static inline void scm_initiate_cluster_request(struct scm_request *scmrq) {}
  91static inline void scm_cluster_request_irq(struct scm_request *scmrq) {}
  92static inline bool scm_test_cluster_request(struct scm_request *scmrq)
  93{
  94        return false;
  95}
  96static inline bool scm_cluster_size_valid(void)
  97{
  98        return true;
  99}
 100#endif /* CONFIG_SCM_BLOCK_CLUSTER_WRITE */
 101
 102extern debug_info_t *scm_debug;
 103
 104#define SCM_LOG(imp, txt) do {                                  \
 105                debug_text_event(scm_debug, imp, txt);          \
 106        } while (0)
 107
 108static inline void SCM_LOG_HEX(int level, void *data, int length)
 109{
 110        if (level > scm_debug->level)
 111                return;
 112        while (length > 0) {
 113                debug_event(scm_debug, level, data, length);
 114                length -= scm_debug->buf_size;
 115                data += scm_debug->buf_size;
 116        }
 117}
 118
 119static inline void SCM_LOG_STATE(int level, struct scm_device *scmdev)
 120{
 121        struct {
 122                u64 address;
 123                u8 oper_state;
 124                u8 rank;
 125        } __packed data = {
 126                .address = scmdev->address,
 127                .oper_state = scmdev->attrs.oper_state,
 128                .rank = scmdev->attrs.rank,
 129        };
 130
 131        SCM_LOG_HEX(level, &data, sizeof(data));
 132}
 133
 134#endif /* SCM_BLK_H */
 135