dasd_int.h
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:13k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* 
  2.  * File...........: linux/drivers/s390/block/dasd.c
  3.  * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
  4.  * Bugreports.to..: <Linux390@de.ibm.com>
  5.  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
  6.  *
  7.  * History of changes (starts July 2000)
  8.  * 02/01/01 added dynamic registration of ioctls
  9.  */
  10. #ifndef DASD_INT_H
  11. #define DASD_INT_H
  12. #define DASD_API_VERSION 0
  13. #include <asm/dasd.h>
  14. #define CONFIG_DASD_DYNAMIC
  15. typedef int(*dasd_ioctl_fn_t) (void *inp, int no, long args);
  16. int dasd_ioctl_no_register(struct module *, int no, dasd_ioctl_fn_t handler);
  17. int dasd_ioctl_no_unregister(struct module *, int no, dasd_ioctl_fn_t handler);
  18. #define DASD_NAME "dasd"
  19. #define DASD_PER_MAJOR ( 1U<<(MINORBITS-DASD_PARTN_BITS))
  20. #define DASD_FORMAT_INTENS_WRITE_RECZERO 0x01
  21. #define DASD_FORMAT_INTENS_WRITE_HOMEADR 0x02
  22. #define DASD_STATE_DEL   -1
  23. #define DASD_STATE_NEW    0
  24. #define DASD_STATE_KNOWN  1
  25. #define DASD_STATE_ACCEPT 2
  26. #define DASD_STATE_INIT   3
  27. #define DASD_STATE_READY  4
  28. #define DASD_STATE_ONLINE 5
  29. #define DASD_FORMAT_INTENS_WRITE_RECZERO 0x01
  30. #define DASD_FORMAT_INTENS_WRITE_HOMEADR 0x02
  31. #define DASD_FORMAT_INTENS_INVALIDATE    0x04
  32. #define DASD_FORMAT_INTENS_CDL 0x08
  33. #ifdef __KERNEL__
  34. #include <linux/module.h>
  35. #include <linux/version.h>
  36. #include <linux/major.h>
  37. #include <linux/wait.h>
  38. #include <linux/blk.h> 
  39. #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
  40. #include <linux/blkdev.h> 
  41. #include <linux/devfs_fs_kernel.h>
  42. #endif
  43. #include <linux/genhd.h>
  44. #include <linux/hdreg.h>
  45. #include <linux/compatmac.h>
  46. #include <asm/ccwcache.h>
  47. #include <asm/irq.h>
  48. #include <asm/s390dyn.h>
  49. #include <asm/todclk.h>
  50. #include <asm/debug.h>
  51. /* Kernel Version Compatibility section */
  52. #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,98))
  53. typedef struct request *request_queue_t;
  54. #define block_device_operations file_operations
  55. #define __setup(x,y) struct dasd_device_t
  56. #define devfs_register_blkdev(major,name,ops) register_blkdev(major,name,ops)
  57. #define register_disk(dd,dev,partn,ops,size) 
  58. do { 
  59. dd->sizes[MINOR(dev)] = size >> 1; 
  60. resetup_one_dev(dd,MINOR(dev)>>DASD_PARTN_BITS); 
  61. } while(0)
  62. #define init_waitqueue_head(x) do { *x = NULL; } while(0)
  63. #define blk_cleanup_queue(x) do {} while(0)
  64. #define blk_init_queue(x...) do {} while(0)
  65. #define blk_queue_headactive(x...) do {} while(0)
  66. #define blk_queue_make_request(x) do {} while(0)
  67. #define list_empty(x) (0)
  68. #define INIT_BLK_DEV(d_major,d_request_fn,d_queue_fn,d_current) 
  69. do { 
  70.         blk_dev[d_major].request_fn = d_request_fn; 
  71.         blk_dev[d_major].queue = d_queue_fn; 
  72.         blk_dev[d_major].current_request = d_current; 
  73. } while(0)
  74. #define INIT_GENDISK(D_MAJOR,D_NAME,D_PARTN_BITS,D_PER_MAJOR) 
  75. major:D_MAJOR, 
  76. major_name:D_NAME, 
  77. minor_shift:D_PARTN_BITS, 
  78. max_p:1 << D_PARTN_BITS, 
  79. max_nr:D_PER_MAJOR, 
  80. nr_real:D_PER_MAJOR,
  81. static inline struct request * 
  82. dasd_next_request( request_queue_t *queue ) 
  83. {
  84.     return *queue;
  85. }
  86. static inline void 
  87. dasd_dequeue_request( request_queue_t * q, struct request *req )
  88. {
  89.         *q = req->next;
  90.         req->next = NULL;
  91. }
  92. #else
  93. #define INIT_BLK_DEV(d_major,d_request_fn,d_queue_fn,d_current) 
  94. do { 
  95.         blk_dev[d_major].queue = d_queue_fn; 
  96. } while(0)
  97. #define INIT_GENDISK(D_MAJOR,D_NAME,D_PARTN_BITS,D_PER_MAJOR) 
  98. major:D_MAJOR, 
  99. major_name:D_NAME, 
  100. minor_shift:D_PARTN_BITS, 
  101. max_p:1 << D_PARTN_BITS, 
  102. nr_real:D_PER_MAJOR, 
  103.         fops:&dasd_device_operations, 
  104. static inline struct request * 
  105. dasd_next_request( request_queue_t *queue ) 
  106. {
  107.         return blkdev_entry_next_request(&queue->queue_head);
  108. }
  109. static inline void 
  110. dasd_dequeue_request( request_queue_t * q, struct request *req )
  111. {
  112.         blkdev_dequeue_request (req);
  113. }
  114. #endif
  115. /* dasd_range_t are used for dynamic device att-/detachment */
  116. typedef struct dasd_devreg_t {
  117.         devreg_t devreg; /* the devreg itself */
  118.         /* build a linked list of devregs, needed for cleanup */
  119.         struct list_head list;
  120. } dasd_devreg_t;
  121. typedef struct {
  122. struct list_head list;
  123. struct module *owner;
  124. int no;
  125. dasd_ioctl_fn_t handler;
  126. } dasd_ioctl_list_t;
  127. typedef enum {
  128. dasd_era_fatal = -1, /* no chance to recover              */
  129. dasd_era_none = 0, /* don't recover, everything alright */
  130. dasd_era_msg = 1, /* don't recover, just report...     */
  131. dasd_era_recover = 2 /* recovery action recommended       */
  132. } dasd_era_t;
  133. /* BIT DEFINITIONS FOR SENSE DATA */
  134. #define DASD_SENSE_BIT_0 0x80
  135. #define DASD_SENSE_BIT_1 0x40
  136. #define DASD_SENSE_BIT_2 0x20
  137. #define DASD_SENSE_BIT_3 0x10
  138. #define check_then_set(where,from,to) 
  139. do { 
  140.         if ((*(where)) != (from) ) { 
  141.                 printk (KERN_ERR PRINTK_HEADER "was %dn", *(where)); 
  142.                 BUG(); 
  143.         } 
  144.         (*(where)) = (to); 
  145. } while (0)
  146. #define DASD_MESSAGE(d_loglevel,d_device,d_string,d_args...)
  147. do { 
  148.         int d_devno = d_device->devinfo.devno; 
  149.         int d_irq = d_device->devinfo.irq; 
  150.         char *d_name = d_device->name; 
  151.         int d_major = MAJOR(d_device->kdev); 
  152.         int d_minor = MINOR(d_device->kdev); 
  153.         printk(d_loglevel PRINTK_HEADER 
  154.                "/dev/%s(%d:%d),%04x@0x%x:" 
  155.                d_string "n",d_name,d_major,d_minor,d_devno,d_irq,d_args ); 
  156. } while(0)
  157. /* 
  158.  * struct dasd_sizes_t
  159.  * represents all data needed to access dasd with properly set up sectors
  160.  */
  161. typedef
  162. struct dasd_sizes_t {
  163. unsigned long blocks; /* size of volume in blocks */
  164. unsigned int bp_block; /* bytes per block */
  165. unsigned int s2b_shift; /* log2 (bp_block/512) */
  166.         unsigned int pt_block; /* from which block to read the partn table */
  167. } dasd_sizes_t;
  168. /* 
  169.  * struct dasd_chanq_t 
  170.  * represents a queue of channel programs related to a single device
  171.  */
  172. typedef
  173. struct dasd_chanq_t {
  174. ccw_req_t *head;
  175. ccw_req_t *tail;
  176. } dasd_chanq_t;
  177. #define DASD_DEVICE_FORMAT_STRING "Device: %p"
  178. #define DASD_DEVICE_DEBUG_EVENT(d_level, d_device, d_str, d_data...)
  179. do {
  180.         if ( d_device->debug_area != NULL )
  181.         debug_sprintf_event(d_device->debug_area,d_level,
  182.                     DASD_DEVICE_FORMAT_STRING d_str "n",
  183.                     d_device, d_data);
  184. } while(0)
  185. #define DASD_DEVICE_DEBUG_EXCEPTION(d_level, d_device, d_str, d_data...)
  186. do {
  187.         if ( d_device->debug_area != NULL )
  188.         debug_sprintf_exception(d_device->debug_area,d_level,
  189.                         DASD_DEVICE_FORMAT_STRING d_str "n",
  190.                         d_device, d_data);
  191. } while(0)
  192. #define DASD_DRIVER_FORMAT_STRING "Driver: <[%p]>"
  193. #define DASD_DRIVER_DEBUG_EVENT(d_level, d_fn, d_str, d_data...)
  194. do {
  195.         if ( dasd_debug_area != NULL )
  196.         debug_sprintf_event(dasd_debug_area, d_level,
  197.                     DASD_DRIVER_FORMAT_STRING #d_fn ":" d_str "n",
  198.                     d_fn, d_data);
  199. } while(0)
  200. #define DASD_DRIVER_DEBUG_EXCEPTION(d_level, d_fn, d_str, d_data...)
  201. do {
  202.         if ( dasd_debug_area != NULL )
  203.         debug_sprintf_exception(dasd_debug_area, d_level,
  204.                         DASD_DRIVER_FORMAT_STRING #d_fn ":" d_str "n",
  205.                         d_fn, d_data);
  206. } while(0)
  207. struct dasd_device_t;
  208. struct request;
  209. /* 
  210.  * signatures for the functions of dasd_discipline_t 
  211.  * make typecasts much easier
  212.  */
  213. typedef ccw_req_t *(*dasd_erp_action_fn_t) (ccw_req_t * cqr);
  214. typedef ccw_req_t *(*dasd_erp_postaction_fn_t) (ccw_req_t * cqr);
  215. typedef int (*dasd_ck_id_fn_t) (s390_dev_info_t *);
  216. typedef int (*dasd_ck_characteristics_fn_t) (struct dasd_device_t *);
  217. typedef int (*dasd_fill_geometry_fn_t) (struct dasd_device_t *, struct hd_geometry *);
  218. typedef ccw_req_t *(*dasd_format_fn_t) (struct dasd_device_t *, struct format_data_t *);
  219. typedef ccw_req_t *(*dasd_init_analysis_fn_t) (struct dasd_device_t *);
  220. typedef int (*dasd_do_analysis_fn_t) (struct dasd_device_t *);
  221. typedef int (*dasd_io_starter_fn_t) (ccw_req_t *);
  222. typedef int (*dasd_io_stopper_fn_t) (ccw_req_t *);
  223. typedef void (*dasd_int_handler_fn_t)(int irq, void *, struct pt_regs *);
  224. typedef dasd_era_t (*dasd_error_examine_fn_t) (ccw_req_t *, devstat_t * stat);
  225. typedef dasd_erp_action_fn_t (*dasd_error_analyse_fn_t) (ccw_req_t *);
  226. typedef dasd_erp_postaction_fn_t (*dasd_erp_analyse_fn_t) (ccw_req_t *);
  227. typedef ccw_req_t *(*dasd_cp_builder_fn_t)(struct dasd_device_t *,struct request *);
  228. typedef char *(*dasd_dump_sense_fn_t)(struct dasd_device_t *,ccw_req_t *);
  229. typedef ccw_req_t *(*dasd_reserve_fn_t)(struct dasd_device_t *);
  230. typedef ccw_req_t *(*dasd_release_fn_t)(struct dasd_device_t *);
  231. typedef ccw_req_t *(*dasd_steal_lock_fn_t)(struct dasd_device_t *);
  232. typedef ccw_req_t *(*dasd_merge_cp_fn_t)(struct dasd_device_t *);
  233. typedef int (*dasd_info_fn_t) (struct dasd_device_t *, dasd_information_t *);
  234. typedef int (*dasd_use_count_fn_t) (int);
  235. /*
  236.  * the dasd_discipline_t is
  237.  * sth like a table of virtual functions, if you think of dasd_eckd
  238.  * inheriting dasd...
  239.  * no, currently we are not planning to reimplement the driver in C++
  240.  */
  241. typedef struct dasd_discipline_t {
  242.         struct module *owner;
  243. char ebcname[8]; /* a name used for tagging and printks */
  244.         char name[8]; /* a name used for tagging and printks */
  245. int max_blocks; /* maximum number of blocks to be chained */
  246. dasd_ck_id_fn_t id_check; /* to check sense data */
  247. dasd_ck_characteristics_fn_t check_characteristics; /* to check the characteristics */
  248. dasd_init_analysis_fn_t init_analysis; /* to start the analysis of the volume */
  249. dasd_do_analysis_fn_t do_analysis; /* to complete the analysis of the volume */
  250. dasd_fill_geometry_fn_t fill_geometry; /* to set up hd_geometry */
  251. dasd_io_starter_fn_t start_IO;
  252. dasd_io_stopper_fn_t term_IO;
  253.         dasd_format_fn_t format_device; /* to format the device */
  254. dasd_error_examine_fn_t examine_error;
  255. dasd_error_analyse_fn_t erp_action;
  256. dasd_erp_analyse_fn_t erp_postaction;
  257.         dasd_cp_builder_fn_t build_cp_from_req;
  258.         dasd_dump_sense_fn_t dump_sense;
  259.         dasd_int_handler_fn_t int_handler;
  260.         dasd_reserve_fn_t reserve;
  261.         dasd_release_fn_t release;
  262.         dasd_steal_lock_fn_t steal_lock;
  263.         dasd_merge_cp_fn_t merge_cp;
  264.         dasd_info_fn_t fill_info;
  265. struct list_head list; /* used for list of disciplines */
  266. } dasd_discipline_t;
  267. #define DASD_DEFAULT_FEATURES 0
  268. #define DASD_FEATURE_READONLY 1
  269. /* dasd_range_t are used for ordering the DASD devices */
  270. typedef struct dasd_range_t {
  271. unsigned int from; /* first DASD in range */
  272. unsigned int to; /* last DASD in range */
  273. char discipline[4]; /* placeholder to force discipline */
  274.         int features;
  275. struct list_head list; /* next one in linked list */
  276. } dasd_range_t;
  277. #define DASD_MAJOR_INFO_REGISTERED 1
  278. #define DASD_MAJOR_INFO_IS_STATIC 2
  279. typedef struct major_info_t {
  280. struct list_head list;
  281. struct dasd_device_t **dasd_device;
  282. int flags;
  283. struct gendisk gendisk; /* actually contains the major number */
  284. } __attribute__ ((packed)) major_info_t;
  285. typedef struct dasd_device_t {
  286. s390_dev_info_t devinfo;
  287. dasd_discipline_t *discipline;
  288. int level;
  289.         atomic_t open_count;
  290.         kdev_t kdev;
  291.         major_info_t *major_info;
  292. struct dasd_chanq_t queue;
  293.         wait_queue_head_t wait_q;
  294.         request_queue_t *request_queue;
  295.         struct timer_list timer;      
  296. devstat_t dev_status; /* needed ONLY!! for request_irq */
  297.         dasd_sizes_t sizes;
  298.         char name[16]; /* The name of the device in /dev */
  299. char *private; /* to be used by the discipline internally */
  300. #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
  301.         devfs_handle_t devfs_entry;
  302. #endif /* LINUX_IS_24 */
  303. struct tq_struct bh_tq;
  304.         atomic_t bh_scheduled;
  305.         debug_info_t *debug_area;
  306.         dasd_profile_info_t profile;
  307.         ccw_req_t *init_cqr;
  308.         atomic_t plugged;
  309.         void* lowmem_cqr;
  310.         void* lowmem_ccws;
  311.         void* lowmem_idals;
  312.         void* lowmem_idal_ptr;
  313. }  dasd_device_t;
  314. int dasd_init (void);
  315. void dasd_discipline_add(dasd_discipline_t *);
  316. void dasd_discipline_del(dasd_discipline_t *);
  317. int dasd_start_IO (ccw_req_t *);
  318. int dasd_term_IO (ccw_req_t *);
  319. void dasd_int_handler (int , void *, struct pt_regs *);
  320. ccw_req_t *dasd_default_erp_action (ccw_req_t *);
  321. ccw_req_t *dasd_default_erp_postaction (ccw_req_t *);
  322. inline void dasd_chanq_deq (dasd_chanq_t *, ccw_req_t *);
  323. inline void dasd_chanq_enq (dasd_chanq_t *, ccw_req_t *);
  324. inline void dasd_chanq_enq_head (dasd_chanq_t *, ccw_req_t *);
  325. ccw_req_t *dasd_alloc_request (char *, int, int, dasd_device_t *);
  326. void dasd_free_request (ccw_req_t *, dasd_device_t *);
  327. int dasd_oper_handler (int irq, devreg_t * devreg);
  328. void dasd_schedule_bh (dasd_device_t *);
  329. int dasd_sleep_on_req(ccw_req_t*);
  330. int  dasd_set_normalized_cda ( ccw1_t * cp, unsigned long address, ccw_req_t* request, dasd_device_t* device );
  331. dasd_device_t * dasd_device_from_kdev (kdev_t kdev);
  332. extern debug_info_t *dasd_debug_area;
  333. extern int (*genhd_dasd_name) (char *, int, int, struct gendisk *);
  334. extern int (*genhd_dasd_ioctl) (struct inode *inp, struct file *filp,
  335.                             unsigned int no, unsigned long data);
  336. #endif /* __KERNEL__ */
  337. #endif /* DASD_H */
  338. /*
  339.  * Overrides for Emacs so that we follow Linus's tabbing style.
  340.  * Emacs will notice this stuff at the end of the file and automatically
  341.  * adjust the settings for this buffer only.  This must remain at the end
  342.  * of the file.
  343.  * ---------------------------------------------------------------------------
  344.  * Local variables:
  345.  * c-indent-level: 4 
  346.  * c-brace-imaginary-offset: 0
  347.  * c-brace-offset: -4
  348.  * c-argdecl-indent: 4
  349.  * c-label-offset: -4
  350.  * c-continued-statement-offset: 4
  351.  * c-continued-brace-offset: 0
  352.  * indent-tabs-mode: nil
  353.  * tab-width: 8
  354.  * End:
  355.  */