linux/drivers/ata/pata_it821x.c

/*
 * pata_it821x.c 	- IT821x PATA for new ATA layer
 *			  (C) 2005 Red Hat Inc
 *			  Alan Cox <[email protected]>
 *			  (C) 2007 Bartlomiej Zolnierkiewicz
 *
 * based upon
 *
 * it821x.c
 *
 * linux/drivers/ide/pci/it821x.c		Version 0.09	December 2004
 *
 * Copyright (C) 2004		Red Hat
 *
 *  May be copied or modified under the terms of the GNU General Public License
 *  Based in part on the ITE vendor provided SCSI driver.
 *
 *  Documentation available from IT8212F_V04.pdf
 * 	http://www.ite.com.tw/EN/products_more.aspx?CategoryID=3&ID=5,91
 *  Some other documents are NDA.
 *
 *  The ITE8212 isn't exactly a standard IDE controller. It has two
 *  modes. In pass through mode then it is an IDE controller. In its smart
 *  mode its actually quite a capable hardware raid controller disguised
 *  as an IDE controller. Smart mode only understands DMA read/write and
 *  identify, none of the fancier commands apply. The IT8211 is identical
 *  in other respects but lacks the raid mode.
 *
 *  Errata:
 *  o	Rev 0x10 also requires master/slave hold the same DMA timings and
 *	cannot do ATAPI MWDMA.
 *  o	The identify data for raid volumes lacks CHS info (technically ok)
 *	but also fails to set the LBA28 and other bits. We fix these in
 *	the IDE probe quirk code.
 *  o	If you write LBA48 sized I/O's (ie > 256 sector) in smart mode
 *	raid then the controller firmware dies
 *  o	Smart mode without RAID doesn't clear all the necessary identify
 *	bits to reduce the command set to the one used
 *
 *  This has a few impacts on the driver
 *  - In pass through mode we do all the work you would expect
 *  - In smart mode the clocking set up is done by the controller generally
 *    but we must watch the other limits and filter.
 *  - There are a few extra vendor commands that actually talk to the
 *    controller but only work PIO with no IRQ.
 *
 *  Vendor areas of the identify block in smart mode are used for the
 *  timing and policy set up. Each HDD in raid mode also has a serial
 *  block on the disk. The hardware extra commands are get/set chip status,
 *  rebuild, get rebuild status.
 *
 *  In Linux the driver supports pass through mode as if the device was
 *  just another IDE controller. If the smart mode is running then
 *  volumes are managed by the controller firmware and each IDE "disk"
 *  is a raid volume. Even more cute - the controller can do automated
 *  hotplug and rebuild.
 *
 *  The pass through controller itself is a little demented. It has a
 *  flaw that it has a single set of PIO/MWDMA timings per channel so
 *  non UDMA devices restrict each others performance. It also has a
 *  single clock source per channel so mixed UDMA100/133 performance
 *  isn't perfect and we have to pick a clock. Thankfully none of this
 *  matters in smart mode. ATAPI DMA is not currently supported.
 *
 *  It seems the smart mode is a win for RAID1/RAID10 but otherwise not.
 *
 *  TODO
 *	-	ATAPI and other speed filtering
 *	-	RAID configuration ioctls
 */

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <scsi/scsi_host.h>
#include <linux/libata.h>


#define DRV_NAME
#define DRV_VERSION

struct it821x_dev
{};

#define ATA_66
#define ATA_50
#define ATA_ANY

#define UDMA_OFF
#define MWDMA_OFF

/*
 *	We allow users to force the card into non raid mode without
 *	flashing the alternative BIOS. This is also necessary right now
 *	for embedded platforms that cannot run a PC BIOS but are using this
 *	device.
 */

static int it8212_noraid;

/**
 *	it821x_program	-	program the PIO/MWDMA registers
 *	@ap: ATA port
 *	@adev: Device to program
 *	@timing: Timing value (66Mhz in top 8bits, 50 in the low 8)
 *
 *	Program the PIO/MWDMA timing for this channel according to the
 *	current clock. These share the same register so are managed by
 *	the DMA start/stop sequence as with the old driver.
 */

static void it821x_program(struct ata_port *ap, struct ata_device *adev, u16 timing)
{}


/**
 *	it821x_program_udma	-	program the UDMA registers
 *	@ap: ATA port
 *	@adev: ATA device to update
 *	@timing: Timing bits. Top 8 are for 66Mhz bottom for 50Mhz
 *
 *	Program the UDMA timing for this drive according to the
 *	current clock. Handles the dual clocks and also knows about
 *	the errata on the 0x10 revision. The UDMA errata is partly handled
 *	here and partly in start_dma.
 */

static void it821x_program_udma(struct ata_port *ap, struct ata_device *adev, u16 timing)
{}

/**
 *	it821x_clock_strategy
 *	@ap: ATA interface
 *	@adev: ATA device being updated
 *
 *	Select between the 50 and 66Mhz base clocks to get the best
 *	results for this interface.
 */

static void it821x_clock_strategy(struct ata_port *ap, struct ata_device *adev)
{}

/**
 *	it821x_passthru_set_piomode	-	set PIO mode data
 *	@ap: ATA interface
 *	@adev: ATA device
 *
 *	Configure for PIO mode. This is complicated as the register is
 *	shared by PIO and MWDMA and for both channels.
 */

static void it821x_passthru_set_piomode(struct ata_port *ap, struct ata_device *adev)
{}

/**
 *	it821x_passthru_set_dmamode	-	set initial DMA mode data
 *	@ap: ATA interface
 *	@adev: ATA device
 *
 *	Set up the DMA modes. The actions taken depend heavily on the mode
 *	to use. If UDMA is used as is hopefully the usual case then the
 *	timing register is private and we need only consider the clock. If
 *	we are using MWDMA then we have to manage the setting ourself as
 *	we switch devices and mode.
 */

static void it821x_passthru_set_dmamode(struct ata_port *ap, struct ata_device *adev)
{}

/**
 *	it821x_passthru_bmdma_start	-	DMA start callback
 *	@qc: Command in progress
 *
 *	Usually drivers set the DMA timing at the point the set_dmamode call
 *	is made. IT821x however requires we load new timings on the
 *	transitions in some cases.
 */

static void it821x_passthru_bmdma_start(struct ata_queued_cmd *qc)
{}

/**
 *	it821x_passthru_bmdma_stop	-	DMA stop callback
 *	@qc: ATA command
 *
 *	We loaded new timings in dma_start, as a result we need to restore
 *	the PIO timings in dma_stop so that the next command issue gets the
 *	right clock values.
 */

static void it821x_passthru_bmdma_stop(struct ata_queued_cmd *qc)
{}


/**
 *	it821x_passthru_dev_select	-	Select master/slave
 *	@ap: ATA port
 *	@device: Device number (not pointer)
 *
 *	Device selection hook. If necessary perform clock switching
 */

static void it821x_passthru_dev_select(struct ata_port *ap,
				       unsigned int device)
{}

/**
 *	it821x_smart_qc_issue		-	wrap qc issue prot
 *	@qc: command
 *
 *	Wrap the command issue sequence for the IT821x. We need to
 *	perform out own device selection timing loads before the
 *	usual happenings kick off
 */

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

/**
 *	it821x_passthru_qc_issue	-	wrap qc issue prot
 *	@qc: command
 *
 *	Wrap the command issue sequence for the IT821x. We need to
 *	perform out own device selection timing loads before the
 *	usual happenings kick off
 */

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

/**
 *	it821x_smart_set_mode	-	mode setting
 *	@link: interface to set up
 *	@unused: device that failed (error only)
 *
 *	Use a non standard set_mode function. We don't want to be tuned.
 *	The BIOS configured everything. Our job is not to fiddle. We
 *	read the dma enabled bits from the PCI configuration of the device
 *	and respect them.
 */

static int it821x_smart_set_mode(struct ata_link *link, struct ata_device **unused)
{}

/**
 *	it821x_dev_config	-	Called each device identify
 *	@adev: Device that has just been identified
 *
 *	Perform the initial setup needed for each device that is chip
 *	special. In our case we need to lock the sector count to avoid
 *	blowing the brains out of the firmware with large LBA48 requests
 *
 */

static void it821x_dev_config(struct ata_device *adev)
{}

/**
 *	it821x_read_id	-	Hack identify data up
 *	@adev: device to read
 *	@tf: proposed taskfile
 *	@id: buffer for returned ident data
 *
 *	Query the devices on this firmware driven port and slightly
 *	mash the identify data to stop us and common tools trying to
 *	use features not firmware supported. The firmware itself does
 *	some masking (eg SMART) but not enough.
 */

static unsigned int it821x_read_id(struct ata_device *adev,
				   struct ata_taskfile *tf, __le16 *id)
{}

/**
 *	it821x_check_atapi_dma	-	ATAPI DMA handler
 *	@qc: Command we are about to issue
 *
 *	Decide if this ATAPI command can be issued by DMA on this
 *	controller. Return 0 if it can be.
 */

static int it821x_check_atapi_dma(struct ata_queued_cmd *qc)
{}

/**
 *	it821x_display_disk	-	display disk setup
 *	@ap: ATA port
 *	@n: Device number
 *	@buf: Buffer block from firmware
 *
 *	Produce a nice informative display of the device setup as provided
 *	by the firmware.
 */

static void it821x_display_disk(struct ata_port *ap, int n, u8 *buf)
{}

/**
 *	it821x_firmware_command		-	issue firmware command
 *	@ap: IT821x port to interrogate
 *	@cmd: command
 *	@len: length
 *
 *	Issue firmware commands expecting data back from the controller. We
 *	use this to issue commands that do not go via the normal paths. Other
 *	commands such as 0xFC can be issued normally.
 */

static u8 *it821x_firmware_command(struct ata_port *ap, u8 cmd, int len)
{}

/**
 *	it821x_probe_firmware	-	firmware reporting/setup
 *	@ap: IT821x port being probed
 *
 *	Probe the firmware of the controller by issuing firmware command
 *	0xFA and analysing the returned data.
 */

static void it821x_probe_firmware(struct ata_port *ap)
{}



/**
 *	it821x_port_start	-	port setup
 *	@ap: ATA port being set up
 *
 *	The it821x needs to maintain private data structures and also to
 *	use the standard PCI interface which lacks support for this
 *	functionality. We instead set up the private data on the port
 *	start hook, and tear it down on port stop
 */

static int it821x_port_start(struct ata_port *ap)
{}

/**
 *	it821x_rdc_cable	-	Cable detect for RDC1010
 *	@ap: port we are checking
 *
 *	Return the RDC1010 cable type. Unlike the IT821x we know how to do
 *	this and can do host side cable detect
 */

static int it821x_rdc_cable(struct ata_port *ap)
{}

static const struct scsi_host_template it821x_sht =;

static struct ata_port_operations it821x_smart_port_ops =;

static struct ata_port_operations it821x_passthru_port_ops =;

static struct ata_port_operations it821x_rdc_port_ops =;

static void it821x_disable_raid(struct pci_dev *pdev)
{}


static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{}

#ifdef CONFIG_PM_SLEEP
static int it821x_reinit_one(struct pci_dev *pdev)
{}
#endif

static const struct pci_device_id it821x[] =;

static struct pci_driver it821x_pci_driver =;

module_pci_driver();

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

module_param_named(noraid, it8212_noraid, int, S_IRUGO);
MODULE_PARM_DESC();