// SPDX-License-Identifier: GPL-2.0+
/*
* copyright (C) 1999/2000 by Henning Zabel <henning@uni-paderborn.de>
*/
/*
* USB-Kernel Driver for the Mustek MDC800 Digital Camera
* (c) 1999/2000 Henning Zabel <henning@uni-paderborn.de>
*
*
* The driver brings the USB functions of the MDC800 to Linux.
* To use the Camera you must support the USB Protocol of the camera
* to the Kernel Node.
* The Driver uses a misc device Node. Create it with :
* mknod /dev/mustek c 180 32
*
* The driver supports only one camera.
*
* Fix: mdc800 used sleep_on and slept with io_lock held.
* Converted sleep_on to waitqueues with schedule_timeout and made io_lock
* a semaphore from a spinlock.
* by Oliver Neukum <oliver@neukum.name>
* (02/12/2001)
*
* Identify version on module load.
* (08/04/2001) gb
*
* version 0.7.5
* Fixed potential SMP races with Spinlocks.
* Thanks to Oliver Neukum <oliver@neukum.name> who
* noticed the race conditions.
* (30/10/2000)
*
* Fixed: Setting urb->dev before submitting urb.
* by Greg KH <greg@kroah.com>
* (13/10/2000)
*
* version 0.7.3
* bugfix : The mdc800->state field gets set to READY after the
* the disconnect function sets it to NOT_CONNECTED. This makes the
* driver running like the camera is connected and causes some
* hang ups.
*
* version 0.7.1
* MOD_INC and MOD_DEC are changed in usb_probe to prevent load/unload
* problems when compiled as Module.
* (04/04/2000)
*
* The mdc800 driver gets assigned the USB Minor 32-47. The Registration
* was updated to use these values.
* (26/03/2000)
*
* The Init und Exit Module Function are updated.
* (01/03/2000)
*
* version 0.7.0
* Rewrite of the driver : The driver now uses URB's. The old stuff
* has been removed.
*
* version 0.6.0
* Rewrite of this driver: The Emulation of the rs232 protocoll
* has been removed from the driver. A special executeCommand function
* for this driver is included to gphoto.
* The driver supports two kind of communication to bulk endpoints.
* Either with the dev->bus->ops->bulk... or with callback function.
* (09/11/1999)
*
* version 0.5.0:
* first Version that gets a version number. Most of the needed
* functions work.
* (20/10/1999)
*/
#include <linux/sched/signal.h>
#include <linux/signal.h>
#include <linux/spinlock.h>
#include <linux/errno.h>
#include <linux/random.h>
#include <linux/poll.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/wait.h>
#include <linux/mutex.h>
#include <linux/usb.h>
#include <linux/fs.h>
/*
* Version Information
*/
#define DRIVER_VERSION "v0.7.5 (30/10/2000)"
#define DRIVER_AUTHOR "Henning Zabel <henning@uni-paderborn.de>"
#define DRIVER_DESC "USB Driver for Mustek MDC800 Digital Camera"
/* Vendor and Product Information */
#define MDC800_VENDOR_ID 0x055f
#define MDC800_PRODUCT_ID 0xa800
/* Timeouts (msec) */
#define TO_DOWNLOAD_GET_READY 1500
#define TO_DOWNLOAD_GET_BUSY 1500
#define TO_WRITE_GET_READY 1000
#define TO_DEFAULT_COMMAND 5000
#define TO_READ_FROM_IRQ TO_DEFAULT_COMMAND
#define TO_GET_READY TO_DEFAULT_COMMAND
/* Minor Number of the device (create with mknod /dev/mustek c 180 32) */
#define MDC800_DEVICE_MINOR_BASE 32
/**************************************************************************
Data and structs
***************************************************************************/
typedef enum {
NOT_CONNECTED, READY, WORKING, DOWNLOAD
} mdc800_state;
/* Data for the driver */
struct mdc800_data
{
struct usb_device * dev; // Device Data
mdc800_state state;
unsigned int endpoint [4];
struct urb * irq_urb;
wait_queue_head_t irq_wait;
int irq_woken;
char* irq_urb_buffer;
int camera_busy; // is camera busy ?
int camera_request_ready; // Status to synchronize with irq
char camera_response [8]; // last Bytes send after busy
struct urb * write_urb;
char* write_urb_buffer;
wait_queue_head_t write_wait;
int written;
struct urb * download_urb;
char* download_urb_buffer;
wait_queue_head_t download_wait;
int downloaded;
int download_left; // Bytes left to download ?
/* Device Data */
char out [64]; // Answer Buffer
int out_ptr; // Index to the first not readen byte
int out_count; // Bytes in the buffer
int open; // Camera device open ?
struct mutex io_lock; // IO -lock
char in [8]; // Command Input Buffer
int in_count;
int pic_index; // Cache for the Imagesize (-1 for nothing cached )
int pic_len;
int minor;
};
/* Specification of the Endpoints */
static struct usb_endpoint_descriptor mdc800_ed [4] =
{
{
.bLength = 0,
.bDescriptorType = 0,
.bEndpointAddress = 0x01,
.bmAttributes = 0x02,
.wMaxPacketSize = cpu_to_le16(8),
.bInterval = 0,
.bRefresh = 0,
.bSynchAddress = 0,
},
{
.bLength = 0,
.bDescriptorType = 0,
.bEndpointAddress = 0x82,
.bmAttributes = 0x03,
.wMaxPacketSize = cpu_to_le16(8),
.bInterval = 0,
.bRefresh = 0,
.bSynchAddress = 0,
},
{
.bLength = 0,
.bDescriptorType = 0,
.bEndpointAddress = 0x03,
.bmAttributes = 0x02,
.wMaxPacketSize = cpu_to_le16(64),
.bInterval = 0,
.bRefresh = 0,
.bSynchAddress = 0,
},
{
.bLength = 0,
.bDescriptorType = 0,
.bEndpointAddress = 0x84,
.bmAttributes = 0x02,
.wMaxPacketSize = cpu_to_le16(64),
.bInterval