g_my_mass.c
[Posted July 13, 2010 by jake]
/******************** Includes ********************/
#include <linux/kernel.h>
#include <linux/usb/ch9.h>
#include "composite.c"
#include "usbstring.c"
#include "config.c"
#include "epautoconf.c"
#include "f_mass_storage.c"
/******************** Standard Module Stuff ********************/
#define MSG_DRIVER_DESC "My Own Mass Storage Gadget"
#define MSG_DRIVER_VERSION "2010/06/11"
MODULE_DESCRIPTION(MSG_DRIVER_DESC);
MODULE_AUTHOR("Michal Nazarewicz");
MODULE_LICENSE("GPL");
static int __ref msg_do_config(struct usb_configuration *c);
static void msg_exit(void);
/******************** Device Descriptor ********************/
static struct usb_device_descriptor msg_dev_desc = {
.bLength = sizeof msg_dev_desc,
.bDescriptorType = USB_DT_DEVICE,
.bcdUSB = cpu_to_le16(0x0200),
.bDeviceClass = USB_CLASS_PER_INTERFACE,
.idVendor = cpu_to_le16(FSG_VENDOR_ID),
.idProduct = cpu_to_le16(FSG_PRODUCT_ID),
};
/******************** Configuration ********************/
static struct usb_configuration msg_config = {
.label = "Linux Mass Storage",
.bind = msg_do_config,
.bConfigurationValue = 1,
.bmAttributes = USB_CONFIG_ATT_SELFPOWER,
};
/******************** Mass Storage Function ********************/
static struct fsg_module_parameters msg_mod_data = { .stall = 1 };
FSG_MODULE_PARAMETERS(/* no prefix */, msg_mod_data);
static struct fsg_common msg_fsg_common;
static int msg_thread_exits(struct fsg_common *common)
{
msg_exit();
return 0;
}
static int msg_fsg_init(struct usb_composite_dev *cdev)
{
struct fsg_config config;
struct fsg_common *retp;
fsg_config_from_params(&config, &msg_mod_data);
config.thread_exits = msg_thread_exits;
retp = fsg_common_init(&msg_fsg_common, cdev, &config);
return IS_ERR(retp) ? PTR_ERR(retp) : 0;
}
/******************** Device Bind Function ********************/
static unsigned long msg_registered;
static int __ref msg_bind(struct usb_composite_dev *cdev)
{
int ret;
ret = msg_fsg_init(cdev);
if (ret < 0)
return ret;
ret = usb_add_config(cdev, &msg_config);
if (ret >= 0)
set_bit(0, &msg_registered);
fsg_common_put(&msg_fsg_common);
return ret;
}
/******************** Configuration Bind Function ********************/
static int __ref msg_do_config(struct usb_configuration *c)
{
return fsg_add(c->cdev, c, &msg_fsg_common);
}
/******************** Composite Device ********************/
static struct usb_composite_driver msg_device = {
.name = "g_my_mass_storage",
.dev = &msg_dev_desc,
.bind = msg_bind,
};
/******************** Module Init/Exit ********************/
static int __init msg_init(void)
{
return usb_composite_register(&msg_device);
}
module_init(msg_init);
static void msg_exit(void)
{
if (test_and_clear_bit(0, &msg_registered))
usb_composite_unregister(&msg_device);
}
module_exit(msg_exit);
(
Log in to post comments)