#ifndef SOCKS_DEVICE_H_ #define SOCKS_DEVICE_H_ #include #include #include #include #include #include #include struct device; struct input_event; #define DEV_NAME_MAX OBJECT_NAME_MAX #define DEV_MAJOR_MAX 1024 #define DEV_MINOR_MAX 1024 #define DEV_MAJOR_INVALID ((unsigned int)0) #define DEV_MINOR_INVALID ((unsigned int)0) #define INPUT_DEVICE_EVENT_QUEUE_SIZE 128 #define INPUT_DEVICE_MAX 4096 #define FRAMEBUFFER_DEVICE_MAX 4096 #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) #define FRAMEBUFFER_DEVICE(dev) ((dev)->dev_type == DEV_TYPE_FRAMEBUFFER ? &(dev)->fb : NULL) enum device_type { DEV_TYPE_UNKNOWN = 0, DEV_TYPE_BLOCK, DEV_TYPE_CHAR, DEV_TYPE_NET, DEV_TYPE_INPUT, DEV_TYPE_BUS, DEV_TYPE_FRAMEBUFFER, }; struct device_type_ops { kern_status_t(*register_device)(struct device *); }; struct block_device_ops { kern_status_t(*read_blocks)(struct device *, size_t, size_t *, void *, socks_flags_t); kern_status_t(*write_blocks)(struct device *, size_t, size_t *, const void *, socks_flags_t); 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 *, socks_flags_t); kern_status_t(*write)(struct device *, size_t, size_t *, const void *, socks_flags_t); }; struct input_device_ops { kern_status_t(*ioctl)(struct device *, unsigned int, void *); }; struct bus_device_ops { kern_status_t(*scan)(struct device *); }; struct framebuffer_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; unsigned int i_id; struct ringbuffer i_events; }; struct bus_device { struct bus_device_ops *b_ops; }; struct framebuffer_device { unsigned int fb_id; struct framebuffer_device_ops *fb_ops; struct framebuffer_varinfo fb_varinfo; struct framebuffer_fixedinfo fb_fixedinfo; }; struct device { struct object dev_base; unsigned int dev_minor; enum device_type dev_type; struct device *dev_parent; struct driver *dev_owner; struct queue dev_children; struct queue_entry dev_childent; struct btree_node dev_driverent; char dev_name[DEV_NAME_MAX]; void *dev_priv; union { struct block_device blk; struct char_device chr; struct net_device net; struct input_device input; struct bus_device bus; struct framebuffer_device fb; }; }; struct driver; struct driver_ops { kern_status_t(*bind)(struct driver *, struct device *, struct device *); }; struct driver { struct kext *drv_owner; unsigned int drv_major; DECLARE_BITMAP(drv_minors, DEV_MINOR_MAX); char drv_name[DEV_NAME_MAX]; struct btree drv_children; struct btree_node drv_ent; spin_lock_t drv_lock; void *drv_priv; struct driver_ops *drv_ops; }; extern kern_status_t device_init(void); extern struct device *root_device(void); extern struct device *misc_device(void); extern struct device *device_alloc(void); static inline void device_lock(struct device *dev) { object_lock(&dev->dev_base); } static inline void device_unlock(struct device *dev) { object_unlock(&dev->dev_base); } static inline void device_lock_irqsave(struct device *dev, unsigned long *flags) { object_lock_irqsave(&dev->dev_base, flags); } static inline void device_unlock_irqrestore(struct device *dev, unsigned long flags) { object_unlock_irqrestore(&dev->dev_base, flags); } extern kern_status_t device_read(struct device *dev, void *buf, size_t size, size_t *bytes_read, socks_flags_t flags); extern kern_status_t device_write(struct device *dev, const void *buf, size_t size, size_t *bytes_written, socks_flags_t flags); extern struct device *cast_to_device(struct object *obj); 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); extern struct framebuffer_device *framebuffer_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)); } static inline struct device *framebuffer_device_base(struct framebuffer_device *dev) { return (struct device *)((char *)dev - offsetof(struct device, fb)); } extern kern_status_t device_register(struct device *dev, struct driver *owner, struct device *parent); extern kern_status_t input_device_report_event(struct input_device *dev, const struct input_event *ev, bool noblock); extern kern_status_t input_device_read(struct device *dev, void *buf, size_t size, size_t *bytes_read, socks_flags_t flags); extern struct driver *driver_create(struct kext *self, const char *name); extern kern_status_t driver_destroy(struct driver *driver); extern kern_status_t driver_register(struct driver *driver); extern kern_status_t driver_unregister(struct driver *driver); extern unsigned int driver_alloc_minor(struct driver *driver); extern void driver_free_minor(struct driver *driver, unsigned int minor); extern struct device *driver_get_device(struct driver *driver, unsigned int minor); extern kern_status_t driver_add_device(struct driver *driver, struct device *dev); extern struct driver *system_driver(void); static inline void driver_lock(struct driver *driver) { spin_lock(&driver->drv_lock); } static inline void driver_unlock(struct driver *driver) { spin_unlock(&driver->drv_lock); } static inline void driver_lock_irqsave(struct driver *driver, unsigned long *flags) { spin_lock_irqsave(&driver->drv_lock, flags); } static inline void driver_unlock_irqrestore(struct driver *driver, unsigned long flags) { spin_unlock_irqrestore(&driver->drv_lock, flags); } #endif