URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [s390/] [block/] [dasd_int.h] - Rev 1774
Go to most recent revision | Compare with Previous | Blame | View Log
/* * File...........: linux/drivers/s390/block/dasd_int.h * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> * Horst Hummel <Horst.Hummel@de.ibm.com> * Bugreports.to..: <Linux390@de.ibm.com> * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 * * $Revision: 1.1.1.1 $ * * History of changes (starts July 2000) * 02/01/01 added dynamic registration of ioctls */ #ifndef DASD_INT_H #define DASD_INT_H #include <asm/dasd.h> #define CONFIG_DASD_DYNAMIC typedef int(*dasd_ioctl_fn_t) (void *inp, int no, long args); int dasd_ioctl_no_register(struct module *, int no, dasd_ioctl_fn_t handler); int dasd_ioctl_no_unregister(struct module *, int no, dasd_ioctl_fn_t handler); #define DASD_NAME "dasd" #define DASD_PER_MAJOR ( 1U<<(MINORBITS-DASD_PARTN_BITS)) #define DASD_FORMAT_INTENS_WRITE_RECZERO 0x01 #define DASD_FORMAT_INTENS_WRITE_HOMEADR 0x02 #define DASD_STATE_DEL -1 /* "unknown" */ #define DASD_STATE_NEW 0 /* memory for dasd_device_t and lowmem ccw/idals allocated */ #define DASD_STATE_BOXED 1 /* boxed dasd could not be analysed "plugged" */ #define DASD_STATE_KNOWN 2 /* major_info/devinfo/discipline/devfs-'device'/gendisk - "detected" */ #define DASD_STATE_ACCEPT 3 /* irq requested - "accepted" */ #define DASD_STATE_INIT 4 /* init_cqr started - "busy" */ #define DASD_STATE_READY 5 /* init finished - "fenced(plugged)" */ #define DASD_STATE_ONLINE 6 /* unplugged "active" */ #define DASD_HOTPLUG_EVENT_ADD 0 #define DASD_HOTPLUG_EVENT_REMOVE 1 #define DASD_HOTPLUG_EVENT_PARTCHK 2 #define DASD_HOTPLUG_EVENT_PARTREMOVE 3 #define DASD_FORMAT_INTENS_WRITE_RECZERO 0x01 #define DASD_FORMAT_INTENS_WRITE_HOMEADR 0x02 #define DASD_FORMAT_INTENS_INVALIDATE 0x04 #define DASD_FORMAT_INTENS_CDL 0x08 #ifdef __KERNEL__ #include <linux/module.h> #include <linux/version.h> #include <linux/major.h> #include <linux/wait.h> #include <linux/blk.h> #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98)) #include <linux/blkdev.h> #include <linux/devfs_fs_kernel.h> #endif #include <linux/genhd.h> #include <linux/hdreg.h> #include <linux/compatmac.h> #include <asm/ccwcache.h> #include <asm/irq.h> #include <asm/s390dyn.h> #include <asm/todclk.h> #include <asm/debug.h> /******************************************************************************** * SECTION: Kernel Version Compatibility section ********************************************************************************/ #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,98)) typedef struct request *request_queue_t; #define block_device_operations file_operations #define __setup(x,y) struct dasd_device_t #define devfs_register_blkdev(major,name,ops) register_blkdev(major,name,ops) #define register_disk(dd,dev,partn,ops,size) \ do { \ dd->sizes[MINOR(dev)] = size >> 1; \ resetup_one_dev(dd,MINOR(dev)>>DASD_PARTN_BITS); \ } while(0) #define init_waitqueue_head(x) do { *x = NULL; } while(0) #define blk_cleanup_queue(x) do {} while(0) #define blk_init_queue(x...) do {} while(0) #define blk_queue_headactive(x...) do {} while(0) #define blk_queue_make_request(x) do {} while(0) #define list_empty(x) (0) #define INIT_BLK_DEV(d_major,d_request_fn,d_queue_fn,d_current) \ do { \ blk_dev[d_major].request_fn = d_request_fn; \ blk_dev[d_major].queue = d_queue_fn; \ blk_dev[d_major].current_request = d_current; \ } while(0) #define INIT_GENDISK(D_MAJOR,D_NAME,D_PARTN_BITS,D_PER_MAJOR) \ major:D_MAJOR, \ major_name:D_NAME, \ minor_shift:D_PARTN_BITS, \ max_p:1 << D_PARTN_BITS, \ max_nr:D_PER_MAJOR, \ nr_real:D_PER_MAJOR, static inline struct request * dasd_next_request( request_queue_t *queue ) { return *queue; } static inline void dasd_dequeue_request( request_queue_t * q, struct request *req ) { *q = req->next; req->next = NULL; } #else #define INIT_BLK_DEV(d_major,d_request_fn,d_queue_fn,d_current) \ do { \ blk_dev[d_major].queue = d_queue_fn; \ } while(0) #define INIT_GENDISK(D_MAJOR,D_NAME,D_PARTN_BITS,D_PER_MAJOR) \ major:D_MAJOR, \ major_name:D_NAME, \ minor_shift:D_PARTN_BITS, \ max_p:1 << D_PARTN_BITS, \ nr_real:D_PER_MAJOR, \ fops:&dasd_device_operations, static inline struct request * dasd_next_request( request_queue_t *queue ) { return blkdev_entry_next_request(&queue->queue_head); } static inline void dasd_dequeue_request( request_queue_t * q, struct request *req ) { blkdev_dequeue_request (req); } #endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,98)) */ /******************************************************************************** * SECTION: Type definitions ********************************************************************************/ typedef struct dasd_devreg_t { devreg_t devreg; /* the devreg itself */ /* build a linked list of devregs, needed for cleanup */ struct list_head list; } dasd_devreg_t; typedef struct { struct list_head list; struct module *owner; int no; dasd_ioctl_fn_t handler; } dasd_ioctl_list_t; typedef enum { dasd_era_fatal = -1, /* no chance to recover */ dasd_era_none = 0, /* don't recover, everything alright */ dasd_era_msg = 1, /* don't recover, just report... */ dasd_era_recover = 2 /* recovery action recommended */ } dasd_era_t; /* BIT DEFINITIONS FOR SENSE DATA */ #define DASD_SENSE_BIT_0 0x80 #define DASD_SENSE_BIT_1 0x40 #define DASD_SENSE_BIT_2 0x20 #define DASD_SENSE_BIT_3 0x10 /* * struct dasd_sizes_t * represents all data needed to access dasd with properly set up sectors */ typedef struct dasd_sizes_t { unsigned long blocks; /* size of volume in blocks */ unsigned int bp_block; /* bytes per block */ unsigned int s2b_shift; /* log2 (bp_block/512) */ unsigned int pt_block; /* from which block to read the partn table */ } dasd_sizes_t; /* * struct dasd_chanq_t * represents a queue of channel programs related to a single device */ typedef struct dasd_chanq_t { ccw_req_t *head; ccw_req_t *tail; } dasd_chanq_t; /* * struct dasd_lowmem_t * represents a queue of pages for lowmem request */ typedef struct { struct list_head list; } dasd_lowmem_t; #define DASD_LOWMEM_PAGES 2 /* # of lowmem pages per device (min 2) */ /******************************************************************************** * SECTION: MACROS ********************************************************************************/ /* * CHECK_THEN_SET * * Change 'where' value from 'from' to 'to'. ' BUG if the 'from' value doesn't match. */ #define check_then_set(where,from,to) \ do { \ if ((*(where)) != (from) ) { \ printk (KERN_ERR PRINTK_HEADER "was %d\n", *(where)); \ BUG(); \ } \ (*(where)) = (to); \ } while(0) /******************************************************************************** * SECION: MACROs for klogd and s390 debug feature (dbf) ********************************************************************************/ #define DBF_DEV_EVENT(d_level, d_device, d_str, d_data...) \ do { \ if (d_device->debug_area != NULL) \ debug_sprintf_event(d_device->debug_area, \ d_level, \ d_str "\n", \ d_data); \ } while(0) #define DBF_DEV_EXC(d_level, d_device, d_str, d_data...) \ do { \ if (d_device->debug_area != NULL) \ debug_sprintf_exception(d_device->debug_area, \ d_level, \ d_str "\n", \ d_data); \ } while(0) #define DBF_EVENT(d_level, d_str, d_data...)\ do { \ if (dasd_debug_area != NULL) \ debug_sprintf_event(dasd_debug_area, \ d_level,\ d_str "\n", \ d_data); \ } while(0) #define DBF_EXC(d_level, d_str, d_data...)\ do { \ if (dasd_debug_area != NULL) \ debug_sprintf_exception(dasd_debug_area, \ d_level,\ d_str "\n", \ d_data); \ } while(0) /* definition of dbf debug levels */ #define DBF_EMERG 0 /* system is unusable */ #define DBF_ALERT 1 /* action must be taken immediately */ #define DBF_CRIT 2 /* critical conditions */ #define DBF_ERR 3 /* error conditions */ #define DBF_WARNING 4 /* warning conditions */ #define DBF_NOTICE 5 /* normal but significant condition */ #define DBF_INFO 6 /* informational */ #define DBF_DEBUG 6 /* debug-level messages */ /* messages to be written via klogd and dbf */ #define DEV_MESSAGE(d_loglevel,d_device,d_string,d_args...)\ do { \ int d_devno = d_device->devinfo.devno; \ int d_irq = d_device->devinfo.irq; \ char *d_name = d_device->name; \ int d_major = MAJOR(d_device->kdev); \ int d_minor = MINOR(d_device->kdev); \ \ printk(d_loglevel PRINTK_HEADER \ " /dev/%-7s(%3d:%3d),%04x@%02x: " \ d_string "\n", \ d_name, \ d_major, \ d_minor, \ d_devno, \ d_irq, \ d_args); \ \ DBF_DEV_EVENT(DBF_ALERT, \ d_device, \ d_string, \ d_args); \ } while(0) /* general messages to be written via klogd and dbf */ #define MESSAGE(d_loglevel,d_string,d_args...)\ do { \ printk(d_loglevel PRINTK_HEADER \ " " d_string "\n", \ d_args); \ \ DBF_EVENT(DBF_ALERT, \ d_string, \ d_args); \ } while(0) /* general messages to be written via klogd only */ #define MESSAGE_LOG(d_loglevel,d_string,d_args...)\ do { \ printk(d_loglevel PRINTK_HEADER \ " " d_string "\n", \ d_args); \ } while(0) struct dasd_device_t; struct request; /******************************************************************************** * SECTION: signatures for the functions of dasd_discipline_t * make typecasts much easier ********************************************************************************/ typedef int (*dasd_ck_id_fn_t) (s390_dev_info_t *); typedef int (*dasd_ck_characteristics_fn_t) (struct dasd_device_t *); typedef int (*dasd_fill_geometry_fn_t) (struct dasd_device_t *, struct hd_geometry *); typedef int (*dasd_do_analysis_fn_t) (struct dasd_device_t *); typedef int (*dasd_io_starter_fn_t) (ccw_req_t *); typedef int (*dasd_io_stopper_fn_t) (ccw_req_t *); typedef int (*dasd_info_fn_t) (struct dasd_device_t *, dasd_information2_t *); typedef int (*dasd_use_count_fn_t) (int); typedef int (*dasd_get_attrib_fn_t) (struct dasd_device_t *, struct attrib_data_t *); typedef int (*dasd_set_attrib_fn_t) (struct dasd_device_t *, struct attrib_data_t *); typedef void (*dasd_int_handler_fn_t) (int irq, void *, struct pt_regs *); typedef void (*dasd_dump_sense_fn_t) (struct dasd_device_t *, ccw_req_t *); typedef ccw_req_t *(*dasd_format_fn_t) (struct dasd_device_t *, struct format_data_t *); typedef ccw_req_t *(*dasd_init_analysis_fn_t ) (struct dasd_device_t *); typedef ccw_req_t *(*dasd_cp_builder_fn_t) (struct dasd_device_t *, struct request *); typedef ccw_req_t *(*dasd_reserve_fn_t) (struct dasd_device_t *); typedef ccw_req_t *(*dasd_release_fn_t) (struct dasd_device_t *); typedef ccw_req_t *(*dasd_steal_lock_fn_t) (struct dasd_device_t *); typedef ccw_req_t *(*dasd_merge_cp_fn_t) (struct dasd_device_t *); typedef ccw_req_t *(*dasd_erp_action_fn_t) (ccw_req_t * cqr); typedef ccw_req_t *(*dasd_erp_postaction_fn_t) (ccw_req_t * cqr); typedef ccw_req_t *(*dasd_read_stats_fn_t) (struct dasd_device_t *); typedef dasd_rssd_perf_stats_t * (*dasd_ret_stats_fn_t) (ccw_req_t *); typedef dasd_era_t (*dasd_error_examine_fn_t) (ccw_req_t *, devstat_t * stat); typedef dasd_erp_action_fn_t (*dasd_error_analyse_fn_t) (ccw_req_t *); typedef dasd_erp_postaction_fn_t (*dasd_erp_analyse_fn_t) (ccw_req_t *); /* * the dasd_discipline_t is * sth like a table of virtual functions, if you think of dasd_eckd * inheriting dasd... * no, currently we are not planning to reimplement the driver in C++ */ typedef struct dasd_discipline_t { struct module *owner; char ebcname[8]; /* a name used for tagging and printks */ char name[8]; /* a name used for tagging and printks */ int max_blocks; /* maximum number of blocks to be chained */ dasd_ck_id_fn_t id_check; /* check sense data */ dasd_ck_characteristics_fn_t check_characteristics; /* check the characteristics */ dasd_init_analysis_fn_t init_analysis; /* start the analysis of the volume */ dasd_do_analysis_fn_t do_analysis; /* complete the analysis of the volume */ dasd_fill_geometry_fn_t fill_geometry; /* set up hd_geometry */ dasd_io_starter_fn_t start_IO; dasd_io_stopper_fn_t term_IO; dasd_format_fn_t format_device; /* format the device */ dasd_error_examine_fn_t examine_error; dasd_error_analyse_fn_t erp_action; dasd_erp_analyse_fn_t erp_postaction; dasd_cp_builder_fn_t build_cp_from_req; dasd_dump_sense_fn_t dump_sense; dasd_int_handler_fn_t int_handler; dasd_reserve_fn_t reserve; dasd_release_fn_t release; dasd_steal_lock_fn_t steal_lock; dasd_merge_cp_fn_t merge_cp; dasd_info_fn_t fill_info; dasd_read_stats_fn_t read_stats; dasd_ret_stats_fn_t ret_stats; /* return performance statistics */ dasd_get_attrib_fn_t get_attrib; /* get attributes (cache operations */ dasd_set_attrib_fn_t set_attrib; /* set attributes (cache operations */ struct list_head list; /* used for list of disciplines */ } dasd_discipline_t; /* dasd_range_t are used for ordering the DASD devices */ typedef struct dasd_range_t { unsigned int from; /* first DASD in range */ unsigned int to; /* last DASD in range */ char discipline[4]; /* placeholder to force discipline */ int features; struct list_head list; /* next one in linked list */ } dasd_range_t; #define DASD_MAJOR_INFO_REGISTERED 1 #define DASD_MAJOR_INFO_IS_STATIC 2 typedef struct major_info_t { struct list_head list; struct dasd_device_t **dasd_device; int flags; struct gendisk gendisk; /* actually contains the major number */ } __attribute__ ((packed)) major_info_t; typedef struct dasd_device_t { s390_dev_info_t devinfo; dasd_discipline_t *discipline; int level; atomic_t open_count; kdev_t kdev; major_info_t *major_info; struct dasd_chanq_t queue; wait_queue_head_t wait_q; request_queue_t *request_queue; struct timer_list timer; /* used for start_IO */ struct timer_list late_timer; /* to get late devices online */ struct timer_list blocking_timer; /* used for ERP */ devstat_t dev_status; /* needed ONLY!! for request_irq */ dasd_sizes_t sizes; char name[16]; /* The name of the device in /dev */ char *private; /* to be used by the discipline internally */ #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98)) devfs_handle_t devfs_entry; #endif /* LINUX_IS_24 */ struct tq_struct bh_tq; atomic_t bh_scheduled; debug_info_t *debug_area; dasd_profile_info_t profile; ccw_req_t *init_cqr; atomic_t plugged; int stopped; /* device (do_IO) was stopped */ struct list_head lowmem_pool; } dasd_device_t; /* reasons why device (do_IO) was stopped */ #define DASD_STOPPED_NOT_ACC 1 /* not accessible */ #define DASD_STOPPED_PENDING 2 /* long busy */ int dasd_init (void); void dasd_discipline_add (dasd_discipline_t *); void dasd_discipline_del (dasd_discipline_t *); int dasd_start_IO (ccw_req_t *); int dasd_term_IO (ccw_req_t *); void dasd_int_handler (int , void *, struct pt_regs *); void dasd_free_request (ccw_req_t *, dasd_device_t *); int dasd_oper_handler (int irq, devreg_t * devreg); void dasd_schedule_bh (dasd_device_t *); void dasd_schedule_bh_timed (unsigned long); int dasd_sleep_on_req (ccw_req_t*); int dasd_set_normalized_cda (ccw1_t * cp, unsigned long address, ccw_req_t* request, dasd_device_t* device ); ccw_req_t * dasd_default_erp_action (ccw_req_t *); ccw_req_t * dasd_default_erp_postaction (ccw_req_t *); inline void dasd_chanq_deq (dasd_chanq_t *, ccw_req_t *); inline void dasd_chanq_enq (dasd_chanq_t *, ccw_req_t *); inline void dasd_chanq_enq_head (dasd_chanq_t *, ccw_req_t *); ccw_req_t * dasd_alloc_request (char *, int, int, dasd_device_t *); dasd_device_t * dasd_device_from_kdev (kdev_t kdev); extern debug_info_t *dasd_debug_area; extern int (*genhd_dasd_name) (char *, int, int, struct gendisk *); extern int (*genhd_dasd_ioctl) (struct inode *inp, struct file *filp, unsigned int no, unsigned long data); #endif /* __KERNEL__ */ #endif /* DASD_H */ /* * Overrides for Emacs so that we follow Linus's tabbing style. * Emacs will notice this stuff at the end of the file and automatically * adjust the settings for this buffer only. This must remain at the end * of the file. * --------------------------------------------------------------------------- * Local variables: * c-indent-level: 4 * c-brace-imaginary-offset: 0 * c-brace-offset: -4 * c-argdecl-indent: 4 * c-label-offset: -4 * c-continued-statement-offset: 4 * c-continued-brace-offset: 0 * indent-tabs-mode: nil * tab-width: 8 * End: */
Go to most recent revision | Compare with Previous | Blame | View Log