#ifndef SOCKS_DEVICE_H_ #define SOCKS_DEVICE_H_ #include #include #include #include #include #include #include struct device; struct input_event; struct input_event_hook; struct tty_device; #define DEV_NAME_MAX OBJECT_NAME_MAX #define DEV_MODEL_NAME_MAX 64 #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 BLOCK_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(*read)(struct device *, void *, size_t, size_t *, socks_flags_t); kern_status_t(*write)(struct device *, const void *, size_t, size_t *, socks_flags_t); kern_status_t(*register_device)(struct device *); }; struct block_device_ops { kern_status_t(*read_blocks)(struct device *, void *, size_t, size_t *, socks_flags_t); kern_status_t(*write_blocks)(struct device *, const void *, size_t, size_t *, 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 *, void *, size_t, size_t *, socks_flags_t); kern_status_t(*write)(struct device *, const void *, size_t, size_t *, 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(*set_varinfo)(struct device *, const struct framebuffer_varinfo *); }; struct block_device { struct block_device_ops *b_ops; unsigned int b_id; unsigned int sector_size; sectors_t capacity; }; struct char_device { struct char_device_ops *c_ops; /* only valid for TTY devices */ struct tty_device *c_tty; }; 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 queue i_hooks; }; struct bus_device { struct queue_entry b_buslist; 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]; char dev_model_name[DEV_MODEL_NAME_MAX]; void *dev_bus_priv; 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 { /* called when a bus driver finds a device for this driver to manage. */ kern_status_t(*bind)(struct driver *, struct device *, struct device *); /* called when driver is registered. */ kern_status_t(*install)(struct driver *); /* called when driver is unregistered. */ kern_status_t(*uninstall)(struct driver *); }; 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; }; struct iovec { void *io_buf; size_t io_len; }; 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 device *generic_device_create(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); extern struct framebuffer_device *framebuffer_device_create(void); extern struct char_device *char_device_from_generic(struct device *dev); extern struct block_device *block_device_from_generic(struct device *dev); extern struct net_device *net_device_from_generic(struct device *dev); extern struct input_device *input_device_from_generic(struct device *dev); extern struct bus_device *bus_device_from_generic(struct device *dev); extern struct framebuffer_device *framebuffer_device_from_generic(struct device *dev); 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)); } static inline struct object *char_device_object(struct char_device *dev) { return &char_device_base(dev)->dev_base; } static inline struct object *block_device_object(struct block_device *dev) { return &block_device_base(dev)->dev_base; } static inline struct object *net_device_object(struct net_device *dev) { return &net_device_base(dev)->dev_base; } static inline struct object *input_device_object(struct input_device *dev) { return &input_device_base(dev)->dev_base; } static inline struct object *bus_device_object(struct bus_device *dev) { return &bus_device_base(dev)->dev_base; } static inline struct object *framebuffer_device_object(struct framebuffer_device *dev) { return &framebuffer_device_base(dev)->dev_base; } extern kern_status_t device_register(struct device *dev, struct driver *owner, struct device *parent); static inline struct device *device_ref(struct device *dev) { return cast_to_device(object_ref(&dev->dev_base)); } static inline void device_deref(struct device *dev) { object_deref(&dev->dev_base); } 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 kern_status_t input_device_add_hook(struct device *dev, struct input_event_hook *hook); extern kern_status_t input_device_remove_hook(struct device *dev, struct input_event_hook *hook); 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_init(struct driver *driver, struct kext *self, const char *name); extern kern_status_t driver_deinit(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 kern_status_t driver_remove_device(struct driver *driver, struct device *dev); extern struct driver *system_driver(void); extern kern_status_t framebuffer_get_fixedinfo(struct device *dev, struct framebuffer_fixedinfo *out); extern kern_status_t framebuffer_get_varinfo(struct device *dev, struct framebuffer_varinfo *out); extern kern_status_t framebuffer_set_varinfo(struct device *dev, const struct framebuffer_varinfo *varinfo); 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); } extern kern_status_t scan_all_buses(void); #endif