/*
* printer.c -- Printer gadget driver
*
* Copyright (C) 2003-2005 David Brownell
* Copyright (C) 2006 Craig W. Nadler
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/mutex.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/timer.h>
#include <linux/list.h>
#include <linux/interrupt.h>
#include <linux/utsname.h>
#include <linux/device.h>
#include <linux/moduleparam.h>
#include <linux/fs.h>
#include <linux/poll.h>
#include <linux/types.h>
#include <linux/ctype.h>
#include <linux/cdev.h>
#include <asm/byteorder.h>
#include <linux/io.h>
#include <linux/irq.h>
#include <linux/uaccess.h>
#include <asm/unaligned.h>
#include <linux/usb/ch9.h>
#include <linux/usb/gadget.h>
#include <linux/usb/g_printer.h>
#include "gadget_chips.h"
/*
* Kbuild is not very cooperative with respect to linking separately
* compiled library objects into one module. So for now we won't use
* separate compilation ... ensuring init/exit sections work to shrink
* the runtime footprint, and giving us at least some parts of what
* a "gcc --combine ... part1.c part2.c part3.c ... " build would.
*/
#include "composite.c"
#include "usbstring.c"
#include "config.c"
#include "epautoconf.c"
/*-------------------------------------------------------------------------*/
#define DRIVER_DESC "Printer Gadget"
#define DRIVER_VERSION "2007 OCT 06"
static DEFINE_MUTEX(printer_mutex);
static const char shortname [] = "printer";
static const char driver_desc [] = DRIVER_DESC;
static dev_t g_printer_devno;
static struct class *usb_gadget_class;
/*-------------------------------------------------------------------------*/
struct printer_dev {
spinlock_t lock; /* lock this structure */
/* lock buffer lists during read/write calls */
struct mutex lock_printer_io;
struct usb_gadget *gadget;
s8 interface;
struct usb_ep *in_ep, *out_ep;
struct list_head rx_reqs; /* List of free RX structs */
struct list_head rx_reqs_active; /* List of Active RX xfers */
struct list_head rx_buffers; /* List of completed xfers */
/* wait until there is data to be read. */
wait_queue_head_t rx_wait;
struct list_head tx_reqs; /* List of free TX structs */
struct list_head tx_reqs_active; /* List of Active TX xfers */
/* Wait until there are write buffers available to use. */
wait_queue_head_t tx_wait;
/* Wait until all write buffers have been sent. */
wait_queue_head_t tx_flush_wait;
struct usb_request *current_rx_req;
size_t current_rx_bytes;
u8 *current_rx_buf;
u8 printer_status;
u8 reset_printer;
struct cdev printer_cdev;
struct device *pdev;
u8 printer_cdev_open;
wait_queue_head_t wait;
struct usb_function function;
};
static struct printer_dev usb_printer_gadget;
/*-------------------------------------------------------------------------*/
/* DO NOT REUSE THESE IDs with a protocol-incompatible driver!! Ever!!
* Instead: allocate your own, using normal USB-IF procedures.
*/
/* Thanks to NetChip Technologies for donating this product ID.
*/
#define PRINTER_VENDOR_NUM 0x0525 /* NetChip */
#define PRINTER_PRODUCT_NUM 0xa4a8 /* Linux-USB Printer Gadget */
/* Some systems will want different product identifiers published in the
* device descriptor, either numbers or strings or both. These string
* parameters are in UTF-8 (superset of ASCII's 7 bit characters).
*/
static char *iSerialNum;
module_param(iSerialNum, charp, S_IRUGO);
MODULE_PARM_DESC(iSerialNum, "1");
static char *iPNPstring;
module_param(iPNPstring, charp, S_IRUGO);
MODULE_PARM_DESC(iPNPstring, "MFG:linux;MDL:g_printer;CLS:PRINTER;SN:1;");
/* Number of requests to allocate per endpoint, not used for ep0. */
static unsigned qlen = 10;
module_param(qlen, uint, S_IRUGO|S_IWUSR);
#define QLEN qlen
/*-------------------------------------------------------------------------*/
/*
* DESCRIPTORS ... most are static, but strings and (full) configuration
* descriptors are built on demand.
*/
#define STRING_MANUFACTURER 1
#define STRING_PRODUCT 2
#define STRING_SERIALNUM 3
/* holds our biggest descriptor */
#define USB_DESC_BUFSIZE 256
#define USB_BUFSIZE 8192
/* This device advertises one configuration. */
#define DEV_CONFIG_VALUE 1
#define PRINTER_INTERFACE 0
static struct usb_device_descriptor device_desc = {
.bLength = sizeof device_desc,
.bDescriptorType = USB_DT_DEVICE,
.bcdUSB = cpu_to_le16(0x0200),
.bDeviceClass = USB_CLASS_PER_INTERFACE,
.bDeviceSubClass = 0,
.bDeviceProtocol = 0,
.idVendor = cpu_to_le16(PRINTER_VENDOR_NUM),
.idProduct = cpu_to_le16(PRINTER_PRODUCT_NUM),
.iManufacturer = STRING_MANUFACTURER,
.iProduct = STRING_PRODUCT,
.iSerialNumber = STRING_SERIALNUM,
.bNumConfigurations = 1
};
static struct usb_interface_descriptor intf_desc = {
.bLength = sizeof intf_desc,
.bDescriptorType = USB_DT_INTERFACE,
.bInterfaceNumber = PRINTER_INTERFACE,
.bNumEndpoints = 2,
.bInterfaceClass = USB_CLASS_PRINTER,
.bInterfaceSubClass = 1, /* Printer Sub-Class */
.bInterfaceProtocol = 2, /* Bi-Directional */
.iInterface = 0
};
static struct usb_endpoint_descriptor fs_ep_in_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_BULK
};
static struct usb_endpoint_descriptor fs_ep_out_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_OUT,
.bmAttributes = USB_ENDPOINT_XFER_BULK
};
static struct usb_descriptor_header *<
|