linux/drivers/mmc/host/vub300.c

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Remote VUB300 SDIO/SDmem Host Controller Driver
 *
 * Copyright (C) 2010 Elan Digital Systems Limited
 *
 * based on USB Skeleton driver - 2.2
 *
 * Copyright (C) 2001-2004 Greg Kroah-Hartman ([email protected])
 *
 * VUB300: is a USB 2.0 client device with a single SDIO/SDmem/MMC slot
 *         Any SDIO/SDmem/MMC device plugged into the VUB300 will appear,
 *         by virtue of this driver, to have been plugged into a local
 *         SDIO host controller, similar to, say, a PCI Ricoh controller
 *         This is because this kernel device driver is both a USB 2.0
 *         client device driver AND an MMC host controller driver. Thus
 *         if there is an existing driver for the inserted SDIO/SDmem/MMC
 *         device then that driver will be used by the kernel to manage
 *         the device in exactly the same fashion as if it had been
 *         directly plugged into, say, a local pci bus Ricoh controller
 *
 * RANT: this driver was written using a display 128x48 - converting it
 *       to a line width of 80 makes it very difficult to support. In
 *       particular functions have been broken down into sub functions
 *       and the original meaningful names have been shortened into
 *       cryptic ones.
 *       The problem is that executing a fragment of code subject to
 *       two conditions means an indentation of 24, thus leaving only
 *       56 characters for a C statement. And that is quite ridiculous!
 *
 * Data types: data passed to/from the VUB300 is fixed to a number of
 *             bits and driver data fields reflect that limit by using
 *             u8, u16, u32
 */
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/kref.h>
#include <linux/uaccess.h>
#include <linux/usb.h>
#include <linux/mutex.h>
#include <linux/mmc/host.h>
#include <linux/mmc/card.h>
#include <linux/mmc/sdio_func.h>
#include <linux/mmc/sdio_ids.h>
#include <linux/workqueue.h>
#include <linux/ctype.h>
#include <linux/firmware.h>
#include <linux/scatterlist.h>

struct host_controller_info {} __packed;

#define FIRMWARE_BLOCK_BOUNDARY
struct sd_command_header {} __packed;

struct sd_irqpoll_header {} __packed;

struct sd_common_header {} __packed;

struct sd_response_header {} __packed;

struct sd_status_header {} __packed;

struct sd_error_header {} __packed;

struct sd_interrupt_header {} __packed;

struct offload_registers_access {} __packed;

#define INTERRUPT_REGISTER_ACCESSES
struct sd_offloaded_interrupt {} __packed;

struct sd_register_header {} __packed;

#define PIGGYBACK_REGISTER_ACCESSES
struct sd_offloaded_piggyback {} __packed;

sd_response __packed;

sd_command __packed;

enum SD_RESPONSE_TYPE {};

#define RESPONSE_INTERRUPT
#define RESPONSE_ERROR
#define RESPONSE_STATUS
#define RESPONSE_IRQ_DISABLED
#define RESPONSE_IRQ_ENABLED
#define RESPONSE_PIGGYBACKED
#define RESPONSE_NO_INTERRUPT
#define RESPONSE_PIG_DISABLED
#define RESPONSE_PIG_ENABLED
#define SD_ERROR_1BIT_TIMEOUT
#define SD_ERROR_4BIT_TIMEOUT
#define SD_ERROR_1BIT_CRC_WRONG
#define SD_ERROR_4BIT_CRC_WRONG
#define SD_ERROR_1BIT_CRC_ERROR
#define SD_ERROR_4BIT_CRC_ERROR
#define SD_ERROR_NO_CMD_ENDBIT
#define SD_ERROR_NO_1BIT_DATEND
#define SD_ERROR_NO_4BIT_DATEND
#define SD_ERROR_1BIT_UNEXPECTED_TIMEOUT
#define SD_ERROR_4BIT_UNEXPECTED_TIMEOUT
#define SD_ERROR_ILLEGAL_COMMAND
#define SD_ERROR_NO_DEVICE
#define SD_ERROR_TRANSFER_LENGTH
#define SD_ERROR_1BIT_DATA_TIMEOUT
#define SD_ERROR_4BIT_DATA_TIMEOUT
#define SD_ERROR_ILLEGAL_STATE
#define SD_ERROR_UNKNOWN_ERROR
#define SD_ERROR_RESERVED_ERROR
#define SD_ERROR_INVALID_FUNCTION
#define SD_ERROR_OUT_OF_RANGE
#define SD_ERROR_STAT_CMD
#define SD_ERROR_STAT_DATA
#define SD_ERROR_STAT_CMD_TIMEOUT
#define SD_ERROR_SDCRDY_STUCK
#define SD_ERROR_UNHANDLED
#define SD_ERROR_OVERRUN
#define SD_ERROR_PIO_TIMEOUT

#define FUN(c)
#define REG(c)

static bool limit_speed_to_24_MHz;
module_param(limit_speed_to_24_MHz, bool, 0644);
MODULE_PARM_DESC();

static bool pad_input_to_usb_pkt;
module_param(pad_input_to_usb_pkt, bool, 0644);
MODULE_PARM_DESC();

static bool disable_offload_processing;
module_param(disable_offload_processing, bool, 0644);
MODULE_PARM_DESC();

static bool force_1_bit_data_xfers;
module_param(force_1_bit_data_xfers, bool, 0644);
MODULE_PARM_DESC();

static bool force_polling_for_irqs;
module_param(force_polling_for_irqs, bool, 0644);
MODULE_PARM_DESC();

static int firmware_irqpoll_timeout =;
module_param(firmware_irqpoll_timeout, int, 0644);
MODULE_PARM_DESC();

static int force_max_req_size =;
module_param(force_max_req_size, int, 0644);
MODULE_PARM_DESC();

#ifdef SMSC_DEVELOPMENT_BOARD
static int firmware_rom_wait_states = 0x04;
#else
static int firmware_rom_wait_states =;
#endif

module_param(firmware_rom_wait_states, int, 0644);
MODULE_PARM_DESC();

#define ELAN_VENDOR_ID
#define VUB300_VENDOR_ID
#define VUB300_PRODUCT_ID
static const struct usb_device_id vub300_table[] =;
MODULE_DEVICE_TABLE(usb, vub300_table);

static struct workqueue_struct *cmndworkqueue;
static struct workqueue_struct *pollworkqueue;
static struct workqueue_struct *deadworkqueue;

static inline int interface_to_InterfaceNumber(struct usb_interface *interface)
{}

struct sdio_register {};

struct vub300_mmc_host {};

#define kref_to_vub300_mmc_host(d)
#define SET_TRANSFER_PSEUDOCODE
#define SET_INTERRUPT_PSEUDOCODE
#define SET_FAILURE_MODE
#define SET_ROM_WAIT_STATES
#define SET_IRQ_ENABLE
#define SET_CLOCK_SPEED
#define SET_FUNCTION_BLOCK_SIZE
#define SET_SD_DATA_MODE
#define SET_SD_POWER
#define ENTER_DFU_MODE
#define GET_HC_INF0
#define GET_SYSTEM_PORT_STATUS

static void vub300_delete(struct kref *kref)
{}

static void vub300_queue_cmnd_work(struct vub300_mmc_host *vub300)
{}

static void vub300_queue_poll_work(struct vub300_mmc_host *vub300, int delay)
{}

static void vub300_queue_dead_work(struct vub300_mmc_host *vub300)
{}

static void irqpoll_res_completed(struct urb *urb)
{}

static void irqpoll_out_completed(struct urb *urb)
{}

static void send_irqpoll(struct vub300_mmc_host *vub300)
{}

static void new_system_port_status(struct vub300_mmc_host *vub300)
{}

static void __add_offloaded_reg_to_fifo(struct vub300_mmc_host *vub300,
					struct offload_registers_access
					*register_access, u8 func)
{}

static void add_offloaded_reg(struct vub300_mmc_host *vub300,
			      struct offload_registers_access *register_access)
{}

static void check_vub300_port_status(struct vub300_mmc_host *vub300)
{}

static void __vub300_irqpoll_response(struct vub300_mmc_host *vub300)
{}

static void __do_poll(struct vub300_mmc_host *vub300)
{}

/* this thread runs only when the driver
 * is trying to poll the device for an IRQ
 */
static void vub300_pollwork_thread(struct work_struct *work)
{}

static void vub300_deadwork_thread(struct work_struct *work)
{}

static void vub300_inactivity_timer_expired(struct timer_list *t)
{}

static int vub300_response_error(u8 error_code)
{}

static void command_res_completed(struct urb *urb)
{}

static void command_out_completed(struct urb *urb)
{}

/*
 * the STUFF bits are masked out for the comparisons
 */
static void snoop_block_size_and_bus_width(struct vub300_mmc_host *vub300,
					   u32 cmd_arg)
{}

static void send_command(struct vub300_mmc_host *vub300)
{}

/*
 * timer callback runs in atomic mode
 *       so it cannot call usb_kill_urb()
 */
static void vub300_sg_timed_out(struct timer_list *t)
{}

static u16 roundup_to_multiple_of_64(u16 number)
{}

/*
 * this is a separate function to solve the 80 column width restriction
 */
static void __download_offload_pseudocode(struct vub300_mmc_host *vub300,
					  const struct firmware *fw)
{}

/*
 * if the binary containing the EMPTY PseudoCode can not be found
 * vub300->vub_name is set anyway in order to prevent an automatic retry
 */
static void download_offload_pseudocode(struct vub300_mmc_host *vub300)
{}

static void vub300_usb_bulk_msg_completion(struct urb *urb)
{}

static int vub300_usb_bulk_msg(struct vub300_mmc_host *vub300,
			       unsigned int pipe, void *data, int len,
			       int *actual_length, int timeout_msecs)
{}

static int __command_read_data(struct vub300_mmc_host *vub300,
			       struct mmc_command *cmd, struct mmc_data *data)
{}

static int __command_write_data(struct vub300_mmc_host *vub300,
				struct mmc_command *cmd, struct mmc_data *data)
{}

static void __vub300_command_response(struct vub300_mmc_host *vub300,
				      struct mmc_command *cmd,
				      struct mmc_data *data, int data_length)
{}

static void construct_request_response(struct vub300_mmc_host *vub300,
				       struct mmc_command *cmd)
{}

/* this thread runs only when there is an upper level command req outstanding */
static void vub300_cmndwork_thread(struct work_struct *work)
{}

static int examine_cyclic_buffer(struct vub300_mmc_host *vub300,
				 struct mmc_command *cmd, u8 Function)
{}

static int satisfy_request_from_offloaded_data(struct vub300_mmc_host *vub300,
					       struct mmc_command *cmd)
{}

static void vub300_mmc_request(struct mmc_host *mmc, struct mmc_request *req)
{}

static void __set_clock_speed(struct vub300_mmc_host *vub300, u8 buf[8],
			      struct mmc_ios *ios)
{}

static void vub300_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
{}

static int vub300_mmc_get_ro(struct mmc_host *mmc)
{}

static void vub300_enable_sdio_irq(struct mmc_host *mmc, int enable)
{}

static const struct mmc_host_ops vub300_mmc_ops =;

static int vub300_probe(struct usb_interface *interface,
			const struct usb_device_id *id)
{}

static void vub300_disconnect(struct usb_interface *interface)
{}

#ifdef CONFIG_PM
static int vub300_suspend(struct usb_interface *intf, pm_message_t message)
{}

static int vub300_resume(struct usb_interface *intf)
{}
#else
#define vub300_suspend
#define vub300_resume
#endif
static int vub300_pre_reset(struct usb_interface *intf)
{}

static int vub300_post_reset(struct usb_interface *intf)
{}

static struct usb_driver vub300_driver =;

static int __init vub300_init(void)
{}

static void __exit vub300_exit(void)
{}

module_init();
module_exit(vub300_exit);

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