linux/drivers/ata/sata_sx4.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 *  sata_sx4.c - Promise SATA
 *
 *  Maintained by:  Tejun Heo <[email protected]>
 *  		    Please ALWAYS copy [email protected]
 *		    on emails.
 *
 *  Copyright 2003-2004 Red Hat, Inc.
 *
 *  libata documentation is available via 'make {ps|pdf}docs',
 *  as Documentation/driver-api/libata.rst
 *
 *  Hardware documentation available under NDA.
 */

/*
	Theory of operation
	-------------------

	The SX4 (PDC20621) chip features a single Host DMA (HDMA) copy
	engine, DIMM memory, and four ATA engines (one per SATA port).
	Data is copied to/from DIMM memory by the HDMA engine, before
	handing off to one (or more) of the ATA engines.  The ATA
	engines operate solely on DIMM memory.

	The SX4 behaves like a PATA chip, with no SATA controls or
	knowledge whatsoever, leading to the presumption that
	PATA<->SATA bridges exist on SX4 boards, external to the
	PDC20621 chip itself.

	The chip is quite capable, supporting an XOR engine and linked
	hardware commands (permits a string to transactions to be
	submitted and waited-on as a single unit), and an optional
	microprocessor.

	The limiting factor is largely software.  This Linux driver was
	written to multiplex the single HDMA engine to copy disk
	transactions into a fixed DIMM memory space, from where an ATA
	engine takes over.  As a result, each WRITE looks like this:

		submit HDMA packet to hardware
		hardware copies data from system memory to DIMM
		hardware raises interrupt

		submit ATA packet to hardware
		hardware executes ATA WRITE command, w/ data in DIMM
		hardware raises interrupt

	and each READ looks like this:

		submit ATA packet to hardware
		hardware executes ATA READ command, w/ data in DIMM
		hardware raises interrupt

		submit HDMA packet to hardware
		hardware copies data from DIMM to system memory
		hardware raises interrupt

	This is a very slow, lock-step way of doing things that can
	certainly be improved by motivated kernel hackers.

 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/device.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_cmnd.h>
#include <linux/libata.h>
#include "sata_promise.h"

#define DRV_NAME
#define DRV_VERSION

static int dimm_test;
module_param(dimm_test, int, 0644);
MODULE_PARM_DESC();

enum {};

#define ECC_ERASE_BUF_SZ

struct pdc_port_priv {};

struct pdc_host_priv {};


static int pdc_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
static void pdc_error_handler(struct ata_port *ap);
static void pdc_freeze(struct ata_port *ap);
static void pdc_thaw(struct ata_port *ap);
static int pdc_port_start(struct ata_port *ap);
static enum ata_completion_errors pdc20621_qc_prep(struct ata_queued_cmd *qc);
static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf);
static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf);
static unsigned int pdc20621_dimm_init(struct ata_host *host);
static int pdc20621_detect_dimm(struct ata_host *host);
static unsigned int pdc20621_i2c_read(struct ata_host *host,
				      u32 device, u32 subaddr, u32 *pdata);
static int pdc20621_prog_dimm0(struct ata_host *host);
static unsigned int pdc20621_prog_dimm_global(struct ata_host *host);
static void pdc20621_get_from_dimm(struct ata_host *host,
				   void *psource, u32 offset, u32 size);
static void pdc20621_put_to_dimm(struct ata_host *host,
				 void *psource, u32 offset, u32 size);
static void pdc20621_irq_clear(struct ata_port *ap);
static unsigned int pdc20621_qc_issue(struct ata_queued_cmd *qc);
static int pdc_softreset(struct ata_link *link, unsigned int *class,
			 unsigned long deadline);
static void pdc_post_internal_cmd(struct ata_queued_cmd *qc);
static int pdc_check_atapi_dma(struct ata_queued_cmd *qc);


static const struct scsi_host_template pdc_sata_sht =;

static struct ata_port_operations pdc_20621_ops =;

static const struct ata_port_info pdc_port_info[] =;

static const struct pci_device_id pdc_sata_pci_tbl[] =;

static struct pci_driver pdc_sata_pci_driver =;


static int pdc_port_start(struct ata_port *ap)
{}

static inline void pdc20621_ata_sg(u8 *buf, unsigned int portno,
				   unsigned int total_len)
{}

static inline void pdc20621_host_sg(u8 *buf, unsigned int portno,
				    unsigned int total_len)
{}

static inline unsigned int pdc20621_ata_pkt(struct ata_taskfile *tf,
					    unsigned int devno, u8 *buf,
					    unsigned int portno)
{}

static inline void pdc20621_host_pkt(struct ata_taskfile *tf, u8 *buf,
				     unsigned int portno)
{}

static void pdc20621_dma_prep(struct ata_queued_cmd *qc)
{}

static void pdc20621_nodata_prep(struct ata_queued_cmd *qc)
{}

static enum ata_completion_errors pdc20621_qc_prep(struct ata_queued_cmd *qc)
{}

static void __pdc20621_push_hdma(struct ata_queued_cmd *qc,
				 unsigned int seq,
				 u32 pkt_ofs)
{}

static void pdc20621_push_hdma(struct ata_queued_cmd *qc,
				unsigned int seq,
				u32 pkt_ofs)
{}

static void pdc20621_pop_hdma(struct ata_queued_cmd *qc)
{}

static void pdc20621_dump_hdma(struct ata_queued_cmd *qc)
{}

static void pdc20621_packet_start(struct ata_queued_cmd *qc)
{}

static unsigned int pdc20621_qc_issue(struct ata_queued_cmd *qc)
{}

static inline unsigned int pdc20621_host_intr(struct ata_port *ap,
					  struct ata_queued_cmd *qc,
					  unsigned int doing_hdma,
					  void __iomem *mmio)
{}

static void pdc20621_irq_clear(struct ata_port *ap)
{}

static irqreturn_t pdc20621_interrupt(int irq, void *dev_instance)
{}

static void pdc_freeze(struct ata_port *ap)
{}

static void pdc_thaw(struct ata_port *ap)
{}

static void pdc_reset_port(struct ata_port *ap)
{}

static int pdc_softreset(struct ata_link *link, unsigned int *class,
			 unsigned long deadline)
{}

static void pdc_error_handler(struct ata_port *ap)
{}

static void pdc_post_internal_cmd(struct ata_queued_cmd *qc)
{}

static int pdc_check_atapi_dma(struct ata_queued_cmd *qc)
{}

static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
{}


static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
{}


static void pdc_sata_setup_port(struct ata_ioports *port, void __iomem *base)
{}


static void pdc20621_get_from_dimm(struct ata_host *host, void *psource,
				   u32 offset, u32 size)
{}


static void pdc20621_put_to_dimm(struct ata_host *host, void *psource,
				 u32 offset, u32 size)
{}


static unsigned int pdc20621_i2c_read(struct ata_host *host, u32 device,
				      u32 subaddr, u32 *pdata)
{}


static int pdc20621_detect_dimm(struct ata_host *host)
{}


static int pdc20621_prog_dimm0(struct ata_host *host)
{}


static unsigned int pdc20621_prog_dimm_global(struct ata_host *host)
{}


static unsigned int pdc20621_dimm_init(struct ata_host *host)
{}


static void pdc_20621_init(struct ata_host *host)
{}

static int pdc_sata_init_one(struct pci_dev *pdev,
			     const struct pci_device_id *ent)
{}

module_pci_driver();

MODULE_AUTHOR();
MODULE_DESCRIPTION();
MODULE_LICENSE();
MODULE_DEVICE_TABLE(pci, pdc_sata_pci_tbl);
MODULE_VERSION();