#define GET_PORT_STATUS 1
#define SOFT_RESET 2
+#define PRINTER_MINORS 4
+
static const char shortname [] = "printer";
static const char driver_desc [] = DRIVER_DESC;
-static dev_t g_printer_devno;
-
+static int major, minors;
static struct class *usb_gadget_class;
/*-------------------------------------------------------------------------*/
u8 *current_rx_buf;
u8 printer_status;
u8 reset_printer;
+ int minor;
struct cdev printer_cdev;
u8 printer_cdev_open;
wait_queue_head_t wait;
return container_of(f, struct printer_dev, function);
}
-static struct printer_dev usb_printer_gadget;
-
/*-------------------------------------------------------------------------*/
/* DO NOT REUSE THESE IDs with a protocol-incompatible driver!! Ever!!
struct usb_ep *in_ep;
struct usb_ep *out_ep = NULL;
struct usb_request *req;
+ dev_t devt;
int id;
int ret;
u32 i;
}
/* Setup the sysfs files for the printer gadget. */
- pdev = device_create(usb_gadget_class, NULL, g_printer_devno,
- NULL, "g_printer");
+ devt = MKDEV(major, dev->minor);
+ pdev = device_create(usb_gadget_class, NULL, devt,
+ NULL, "g_printer%d", dev->minor);
if (IS_ERR(pdev)) {
ERROR(dev, "Failed to create device: g_printer\n");
ret = PTR_ERR(pdev);
*/
cdev_init(&dev->printer_cdev, &printer_io_operations);
dev->printer_cdev.owner = THIS_MODULE;
- ret = cdev_add(&dev->printer_cdev, g_printer_devno, 1);
+ ret = cdev_add(&dev->printer_cdev, devt, 1);
if (ret) {
ERROR(dev, "Failed to open char device\n");
goto fail_cdev_add;
return 0;
fail_cdev_add:
- device_destroy(usb_gadget_class, g_printer_devno);
+ device_destroy(usb_gadget_class, devt);
fail_rx_reqs:
while (!list_empty(&dev->rx_reqs)) {
dev = func_to_printer(f);
- device_destroy(usb_gadget_class, g_printer_devno);
+ device_destroy(usb_gadget_class, MKDEV(major, dev->minor));
/* Remove Character Device */
cdev_del(&dev->printer_cdev);
printer_req_free(dev->out_ep, req);
}
usb_free_all_descriptors(f);
+ kfree(dev);
}
static int printer_func_set_alt(struct usb_function *f,
};
static int f_printer_bind_config(struct usb_configuration *c, char *pnp_str,
- char *pnp_string, unsigned q_len)
+ char *pnp_string, unsigned q_len, int minor)
{
struct printer_dev *dev;
int status = -ENOMEM;
size_t len;
- dev = &usb_printer_gadget;
+ if (minor >= minors)
+ return -ENOENT;
+
+ dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+ if (!dev)
+ return -ENOMEM;
+
dev->pnp_string = pnp_string;
+ dev->minor = minor;
dev->function.name = shortname;
dev->function.bind = printer_func_bind;
dev->q_len = q_len;
status = usb_add_function(c, &dev->function);
- if (status)
+ if (status) {
+ kfree(dev);
return status;
+ }
INFO(dev, "%s, version: " DRIVER_VERSION "\n", driver_desc);
return 0;
}
printer_cfg_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP;
}
- return f_printer_bind_config(c, iPNPstring, pnp_string, QLEN);
-
+ return f_printer_bind_config(c, iPNPstring, pnp_string, QLEN, 0);
}
-static int gprinter_setup(void)
+static int gprinter_setup(int count)
{
int status;
+ dev_t devt;
usb_gadget_class = class_create(THIS_MODULE, "usb_printer_gadget");
if (IS_ERR(usb_gadget_class)) {
status = PTR_ERR(usb_gadget_class);
+ usb_gadget_class = NULL;
pr_err("unable to create usb_gadget class %d\n", status);
return status;
}
- status = alloc_chrdev_region(&g_printer_devno, 0, 1,
- "USB printer gadget");
+ status = alloc_chrdev_region(&devt, 0, count, "USB printer gadget");
if (status) {
pr_err("alloc_chrdev_region %d\n", status);
class_destroy(usb_gadget_class);
+ usb_gadget_class = NULL;
+ return status;
}
+ major = MAJOR(devt);
+ minors = count;
+
return status;
}
-/* must be called with struct printer_dev's lock_printer_io held */
static void gprinter_cleanup(void)
{
- unregister_chrdev_region(g_printer_devno, 1);
+ if (major) {
+ unregister_chrdev_region(MKDEV(major, 0), minors);
+ major = minors = 0;
+ }
class_destroy(usb_gadget_class);
+ usb_gadget_class = NULL;
}
static int __init printer_bind(struct usb_composite_dev *cdev)
{
int ret;
- ret = gprinter_setup();
+ ret = gprinter_setup(PRINTER_MINORS);
if (ret)
return ret;
static void __exit
cleanup(void)
{
- mutex_lock(&usb_printer_gadget.lock_printer_io);
usb_composite_unregister(&printer_driver);
- mutex_unlock(&usb_printer_gadget.lock_printer_io);
}
module_exit(cleanup);