linux/drivers/usb/misc/sisusbvga/sisusbvga.c

// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
/*
 * sisusb - usb kernel driver for SiS315(E) based USB2VGA dongles
 *
 * Main part
 *
 * Copyright (C) 2005 by Thomas Winischhofer, Vienna, Austria
 *
 * If distributed as part of the Linux kernel, this code is licensed under the
 * terms of the GPL v2.
 *
 * Otherwise, the following license terms apply:
 *
 * * Redistribution and use in source and binary forms, with or without
 * * modification, are permitted provided that the following conditions
 * * are met:
 * * 1) Redistributions of source code must retain the above copyright
 * *    notice, this list of conditions and the following disclaimer.
 * * 2) Redistributions in binary form must reproduce the above copyright
 * *    notice, this list of conditions and the following disclaimer in the
 * *    documentation and/or other materials provided with the distribution.
 * * 3) The name of the author may not be used to endorse or promote products
 * *    derived from this software without specific psisusbr written permission.
 * *
 * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR
 * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Author:	Thomas Winischhofer <[email protected]>
 *
 */

#include <linux/mutex.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/signal.h>
#include <linux/errno.h>
#include <linux/poll.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/kref.h>
#include <linux/usb.h>
#include <linux/vmalloc.h>

#include "sisusb.h"

#define SISUSB_DONTSYNC

/* Forward declarations / clean-up routines */

static struct usb_driver sisusb_driver;

static void sisusb_free_buffers(struct sisusb_usb_data *sisusb)
{}

static void sisusb_free_urbs(struct sisusb_usb_data *sisusb)
{}

/* Level 0: USB transport layer */

/* 1. out-bulks */

/* out-urb management */

/* Return 1 if all free, 0 otherwise */
static int sisusb_all_free(struct sisusb_usb_data *sisusb)
{}

/* Kill all busy URBs */
static void sisusb_kill_all_busy(struct sisusb_usb_data *sisusb)
{}

/* Return 1 if ok, 0 if error (not all complete within timeout) */
static int sisusb_wait_all_out_complete(struct sisusb_usb_data *sisusb)
{}

static int sisusb_outurb_available(struct sisusb_usb_data *sisusb)
{}

static int sisusb_get_free_outbuf(struct sisusb_usb_data *sisusb)
{}

static int sisusb_alloc_outbuf(struct sisusb_usb_data *sisusb)
{}

static void sisusb_free_outbuf(struct sisusb_usb_data *sisusb, int index)
{}

/* completion callback */

static void sisusb_bulk_completeout(struct urb *urb)
{}

static int sisusb_bulkout_msg(struct sisusb_usb_data *sisusb, int index,
		unsigned int pipe, void *data, int len, int *actual_length,
		int timeout, unsigned int tflags)
{}

/* 2. in-bulks */

/* completion callback */

static void sisusb_bulk_completein(struct urb *urb)
{}

static int sisusb_bulkin_msg(struct sisusb_usb_data *sisusb,
		unsigned int pipe, void *data, int len,
		int *actual_length, int timeout, unsigned int tflags)
{}


/* Level 1:  */

/* Send a bulk message of variable size
 *
 * To copy the data from userspace, give pointer to "userbuffer",
 * to copy from (non-DMA) kernel memory, give "kernbuffer". If
 * both of these are NULL, it is assumed, that the transfer
 * buffer "sisusb->obuf[index]" is set up with the data to send.
 * Index is ignored if either kernbuffer or userbuffer is set.
 * If async is nonzero, URBs will be sent without waiting for
 * completion of the previous URB.
 *
 * (return 0 on success)
 */

static int sisusb_send_bulk_msg(struct sisusb_usb_data *sisusb, int ep, int len,
		char *kernbuffer, const char __user *userbuffer, int index,
		ssize_t *bytes_written, unsigned int tflags, int async)
{}

/* Receive a bulk message of variable size
 *
 * To copy the data to userspace, give pointer to "userbuffer",
 * to copy to kernel memory, give "kernbuffer". One of them
 * MUST be set. (There is no technique for letting the caller
 * read directly from the ibuf.)
 *
 */

static int sisusb_recv_bulk_msg(struct sisusb_usb_data *sisusb, int ep, int len,
		void *kernbuffer, char __user *userbuffer, ssize_t *bytes_read,
		unsigned int tflags)
{}

static int sisusb_send_packet(struct sisusb_usb_data *sisusb, int len,
		struct sisusb_packet *packet)
{}

static int sisusb_send_bridge_packet(struct sisusb_usb_data *sisusb, int len,
		struct sisusb_packet *packet, unsigned int tflags)
{}

/* access video memory and mmio (return 0 on success) */

/* Low level */

/* The following routines assume being used to transfer byte, word,
 * long etc.
 * This means that
 *   - the write routines expect "data" in machine endianness format.
 *     The data will be converted to leXX in sisusb_xxx_packet.
 *   - the read routines can expect read data in machine-endianess.
 */

static int sisusb_write_memio_byte(struct sisusb_usb_data *sisusb, int type,
		u32 addr, u8 data)
{}

static int sisusb_write_memio_word(struct sisusb_usb_data *sisusb, int type,
		u32 addr, u16 data)
{}

static int sisusb_write_memio_24bit(struct sisusb_usb_data *sisusb, int type,
		u32 addr, u32 data)
{}

static int sisusb_write_memio_long(struct sisusb_usb_data *sisusb, int type,
		u32 addr, u32 data)
{}

/* The xxx_bulk routines copy a buffer of variable size. They treat the
 * buffer as chars, therefore lsb/msb has to be corrected if using the
 * byte/word/long/etc routines for speed-up
 *
 * If data is from userland, set "userbuffer" (and clear "kernbuffer"),
 * if data is in kernel space, set "kernbuffer" (and clear "userbuffer");
 * if neither "kernbuffer" nor "userbuffer" are given, it is assumed
 * that the data already is in the transfer buffer "sisusb->obuf[index]".
 */

static int sisusb_write_mem_bulk(struct sisusb_usb_data *sisusb, u32 addr,
		char *kernbuffer, int length, const char __user *userbuffer,
		int index, ssize_t *bytes_written)
{}

/* Remember: Read data in packet is in machine-endianess! So for
 * byte, word, 24bit, long no endian correction is necessary.
 */

static int sisusb_read_memio_byte(struct sisusb_usb_data *sisusb, int type,
		u32 addr, u8 *data)
{}

static int sisusb_read_memio_word(struct sisusb_usb_data *sisusb, int type,
		u32 addr, u16 *data)
{}

static int sisusb_read_memio_24bit(struct sisusb_usb_data *sisusb, int type,
		u32 addr, u32 *data)
{}

static int sisusb_read_memio_long(struct sisusb_usb_data *sisusb, int type,
		u32 addr, u32 *data)
{}

static int sisusb_read_mem_bulk(struct sisusb_usb_data *sisusb, u32 addr,
		char *kernbuffer, int length, char __user *userbuffer,
		ssize_t *bytes_read)
{}

/* High level: Gfx (indexed) register access */

static int sisusb_setidxreg(struct sisusb_usb_data *sisusb, u32 port,
		u8 index, u8 data)
{}

static int sisusb_getidxreg(struct sisusb_usb_data *sisusb, u32 port,
		u8 index, u8 *data)
{}

static int sisusb_setidxregandor(struct sisusb_usb_data *sisusb, u32 port, u8 idx,
		u8 myand, u8 myor)
{}

static int sisusb_setidxregmask(struct sisusb_usb_data *sisusb,
		u32 port, u8 idx, u8 data, u8 mask)
{}

static int sisusb_setidxregor(struct sisusb_usb_data *sisusb, u32 port,
		u8 index, u8 myor)
{}

static int sisusb_setidxregand(struct sisusb_usb_data *sisusb, u32 port,
		u8 idx, u8 myand)
{}

/* Write/read video ram */

#ifdef SISUSBENDIANTEST
static void sisusb_testreadwrite(struct sisusb_usb_data *sisusb)
{
	static u8 srcbuffer[] = { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77 };
	char destbuffer[10];
	int i, j;

	sisusb_copy_memory(sisusb, srcbuffer, sisusb->vrambase, 7);

	for (i = 1; i <= 7; i++) {
		dev_dbg(&sisusb->sisusb_dev->dev,
				"sisusb: rwtest %d bytes\n", i);
		sisusb_read_memory(sisusb, destbuffer, sisusb->vrambase, i);
		for (j = 0; j < i; j++) {
			dev_dbg(&sisusb->sisusb_dev->dev,
					"rwtest read[%d] = %x\n",
					j, destbuffer[j]);
		}
	}
}
#endif

/* access pci config registers (reg numbers 0, 4, 8, etc) */

static int sisusb_write_pci_config(struct sisusb_usb_data *sisusb,
		int regnum, u32 data)
{}

static int sisusb_read_pci_config(struct sisusb_usb_data *sisusb,
		int regnum, u32 *data)
{}

/* Clear video RAM */

static int sisusb_clear_vram(struct sisusb_usb_data *sisusb,
		u32 address, int length)
{}

/* Initialize the graphics core (return 0 on success)
 * This resets the graphics hardware and puts it into
 * a defined mode (640x480@60Hz)
 */

#define GETREG
#define SETREG
#define SETIREG
#define GETIREG
#define SETIREGOR
#define SETIREGAND
#define SETIREGANDOR
#define READL
#define WRITEL
#define READB(a, d)
#define WRITEB(a, d)

static int sisusb_triggersr16(struct sisusb_usb_data *sisusb, u8 ramtype)
{}

static int sisusb_getbuswidth(struct sisusb_usb_data *sisusb,
		int *bw, int *chab)
{}

static int sisusb_verify_mclk(struct sisusb_usb_data *sisusb)
{}

static int sisusb_set_rank(struct sisusb_usb_data *sisusb, int *iret,
		int index, u8 rankno, u8 chab, const u8 dramtype[][5], int bw)
{}

static int sisusb_check_rbc(struct sisusb_usb_data *sisusb, int *iret,
		u32 inc, int testn)
{}

static int sisusb_check_ranks(struct sisusb_usb_data *sisusb,
		int *iret, int rankno, int idx, int bw, const u8 rtype[][5])
{}

static int sisusb_get_sdram_size(struct sisusb_usb_data *sisusb, int *iret,
		int bw, int chab)
{}

static int sisusb_setup_screen(struct sisusb_usb_data *sisusb,
		int clrall, int drwfr)
{}

static void sisusb_set_default_mode(struct sisusb_usb_data *sisusb,
		int touchengines)
{}

static int sisusb_init_gfxcore(struct sisusb_usb_data *sisusb)
{}

#undef SETREG
#undef GETREG
#undef SETIREG
#undef GETIREG
#undef SETIREGOR
#undef SETIREGAND
#undef SETIREGANDOR
#undef READL
#undef WRITEL

static void sisusb_get_ramconfig(struct sisusb_usb_data *sisusb)
{}

static int sisusb_do_init_gfxdevice(struct sisusb_usb_data *sisusb)
{}

/* Initialize the graphics device (return 0 on success)
 * This initializes the net2280 as well as the PCI registers
 * of the graphics board.
 */

static int sisusb_init_gfxdevice(struct sisusb_usb_data *sisusb, int initscreen)
{}

/* fops */

static int sisusb_open(struct inode *inode, struct file *file)
{}

static void sisusb_delete(struct kref *kref)
{}

static int sisusb_release(struct inode *inode, struct file *file)
{}

static ssize_t sisusb_read(struct file *file, char __user *buffer,
		size_t count, loff_t *ppos)
{}

static ssize_t sisusb_write(struct file *file, const char __user *buffer,
		size_t count, loff_t *ppos)
{}

static loff_t sisusb_lseek(struct file *file, loff_t offset, int orig)
{}

static int sisusb_handle_command(struct sisusb_usb_data *sisusb,
		struct sisusb_command *y, unsigned long arg)
{}

static long sisusb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{}

#ifdef CONFIG_COMPAT
static long sisusb_compat_ioctl(struct file *f, unsigned int cmd,
		unsigned long arg)
{}
#endif

static const struct file_operations usb_sisusb_fops =;

static struct usb_class_driver usb_sisusb_class =;

static int sisusb_probe(struct usb_interface *intf,
		const struct usb_device_id *id)
{}

static void sisusb_disconnect(struct usb_interface *intf)
{}

static const struct usb_device_id sisusb_table[] =;

MODULE_DEVICE_TABLE(usb, sisusb_table);

static struct usb_driver sisusb_driver =;

module_usb_driver();

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();