diff --git a/include/socks/device.h b/include/socks/device.h new file mode 100644 index 0000000..f7bb62f --- /dev/null +++ b/include/socks/device.h @@ -0,0 +1,120 @@ +#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); + +enum device_type { + DEV_TYPE_BLOCK, + DEV_TYPE_CHAR, + DEV_TYPE_NET, + DEV_TYPE_INPUT, +}; + +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; + queue_t dev_children; + queue_entry_t 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 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