#ifndef SOCKS_DEVICE_H_ #define SOCKS_DEVICE_H_ #include #include struct device; #define BLOCK_DEVICE(dev) ((dev)->dev_type == DEV_TYPE_BLOCK ? &(dev)->blk : NULL); #define CHAR_DEVICE(dev) ((dev)->dev_type == DEV_TYPE_CHAR ? &(dev)->chr : NULL); #define NET_DEVICE(dev) ((dev)->dev_type == DEV_TYPE_NET ? &(dev)->net : NULL); #define INPUT_DEVICE(dev) ((dev)->dev_type == DEV_TYPE_INPUT ? &(dev)->input : NULL); #define BUS_DEVICE(dev) ((dev)->dev_type == DEV_TYPE_BUS ? &(dev)->bus : NULL); enum device_type { DEV_TYPE_BLOCK, DEV_TYPE_CHAR, DEV_TYPE_NET, DEV_TYPE_INPUT, DEV_TYPE_BUS, }; struct block_device_ops { kern_status_t(*read_blocks)(struct device *, size_t, size_t *, void *); kern_status_t(*write_blocks)(struct device *, size_t, size_t *, const void *); kern_status_t(*ioctl)(struct device *, unsigned int, void *); }; struct net_device_ops { kern_status_t(*online)(struct device *); kern_status_t(*offline)(struct device *); kern_status_t(*transmit)(struct device *, const void *, size_t); kern_status_t(*ioctl)(struct device *, unsigned int, void *); }; struct char_device_ops { kern_status_t(*read)(struct device *, size_t, size_t *, void *); kern_status_t(*write)(struct device *, size_t, size_t *, const void *); }; struct input_device_ops { kern_status_t(*ioctl)(struct device *, unsigned int, void *); }; struct bus_device_ops { kern_status_t(*scan)(struct device *); }; struct block_device { struct block_device_ops *b_ops; }; struct char_device { struct char_device_ops *c_ops; }; struct net_device { struct net_device_ops *n_ops; }; struct input_device { struct input_device_ops *i_ops; }; struct bus_device { struct bus_device_ops *b_ops; }; struct device { enum device_type dev_type; struct device *dev_parent; struct queue dev_children; struct queue_entry dev_childent; void *dev_priv; union { struct block_device blk; struct char_device chr; struct net_device net; struct input_device input; struct bus_device bus; }; }; extern kern_status_t device_init(void); extern kern_status_t set_root_device(struct device *dev); extern struct device *device_alloc(void); extern struct char_device *char_device_create(void); extern struct block_device *block_device_create(void); extern struct net_device *net_device_create(void); extern struct input_device *input_device_create(void); extern struct bus_device *bus_device_create(void); static inline struct device *char_device_base(struct char_device *dev) { return (struct device *)((char *)dev - offsetof(struct device, chr)); } static inline struct device *block_device_base(struct block_device *dev) { return (struct device *)((char *)dev - offsetof(struct device, blk)); } static inline struct device *net_device_base(struct net_device *dev) { return (struct device *)((char *)dev - offsetof(struct device, net)); } static inline struct device *input_device_base(struct input_device *dev) { return (struct device *)((char *)dev - offsetof(struct device, input)); } static inline struct device *bus_device_base(struct bus_device *dev) { return (struct device *)((char *)dev - offsetof(struct device, bus)); } extern kern_status_t device_register(struct device *dev, struct device *parent); #endif