// SPDX-License-Identifier: GPL-2.0-only /* * pata_via.c - VIA PATA for new ATA layer * (C) 2005-2006 Red Hat Inc * * Documentation * Most chipset documentation available under NDA only * * VIA version guide * VIA VT82C561 - early design, uses ata_generic currently * VIA VT82C576 - MWDMA, 33Mhz * VIA VT82C586 - MWDMA, 33Mhz * VIA VT82C586a - Added UDMA to 33Mhz * VIA VT82C586b - UDMA33 * VIA VT82C596a - Nonfunctional UDMA66 * VIA VT82C596b - Working UDMA66 * VIA VT82C686 - Nonfunctional UDMA66 * VIA VT82C686a - Working UDMA66 * VIA VT82C686b - Updated to UDMA100 * VIA VT8231 - UDMA100 * VIA VT8233 - UDMA100 * VIA VT8233a - UDMA133 * VIA VT8233c - UDMA100 * VIA VT8235 - UDMA133 * VIA VT8237 - UDMA133 * VIA VT8237A - UDMA133 * VIA VT8237S - UDMA133 * VIA VT8251 - UDMA133 * * Most registers remain compatible across chips. Others start reserved * and acquire sensible semantics if set to 1 (eg cable detect). A few * exceptions exist, notably around the FIFO settings. * * One additional quirk of the VIA design is that like ALi they use few * PCI IDs for a lot of chips. * * Based heavily on: * * Version 3.38 * * VIA IDE driver for Linux. Supported southbridges: * * vt82c576, vt82c586, vt82c586a, vt82c586b, vt82c596a, vt82c596b, * vt82c686, vt82c686a, vt82c686b, vt8231, vt8233, vt8233c, vt8233a, * vt8235, vt8237 * * Copyright (c) 2000-2002 Vojtech Pavlik * * Based on the work of: * Michel Aubry * Jeff Garzik * Andre Hedrick */ #include <linux/kernel.h> #include <linux/module.h> #include <linux/pci.h> #include <linux/blkdev.h> #include <linux/delay.h> #include <linux/gfp.h> #include <scsi/scsi_host.h> #include <linux/libata.h> #include <linux/dmi.h> #define DRV_NAME … #define DRV_VERSION … enum { … }; enum { … }; /* * VIA SouthBridge chips. */ static const struct via_isa_bridge { … } via_isa_bridges[] = …; static const struct dmi_system_id no_atapi_dma_dmi_table[] = …; struct via_port { … }; /* * Cable special cases */ static const struct dmi_system_id cable_dmi_table[] = …; static int via_cable_override(struct pci_dev *pdev) { … } /** * via_cable_detect - cable detection * @ap: ATA port * * Perform cable detection. Actually for the VIA case the BIOS * already did this for us. We read the values provided by the * BIOS. If you are using an 8235 in a non-PC configuration you * may need to update this code. * * Hotplug also impacts on this. */ static int via_cable_detect(struct ata_port *ap) { … } static int via_pre_reset(struct ata_link *link, unsigned long deadline) { … } /** * via_do_set_mode - set transfer mode data * @ap: ATA interface * @adev: ATA device * @mode: ATA mode being programmed * @set_ast: Set to program address setup * @udma_type: UDMA mode/format of registers * * Program the VIA registers for DMA and PIO modes. Uses the ata timing * support in order to compute modes. * * FIXME: Hotplug will require we serialize multiple mode changes * on the two channels. */ static void via_do_set_mode(struct ata_port *ap, struct ata_device *adev, int mode, int set_ast, int udma_type) { … } static void via_set_piomode(struct ata_port *ap, struct ata_device *adev) { … } static void via_set_dmamode(struct ata_port *ap, struct ata_device *adev) { … } /** * via_mode_filter - filter buggy device/mode pairs * @dev: ATA device * @mask: Mode bitmask * * We need to apply some minimal filtering for old controllers and at least * one breed of Transcend SSD. Return the updated mask. */ static unsigned int via_mode_filter(struct ata_device *dev, unsigned int mask) { … } /** * via_tf_load - send taskfile registers to host controller * @ap: Port to which output is sent * @tf: ATA taskfile register set * * Outputs ATA taskfile to standard ATA host controller. * * Note: This is to fix the internal bug of via chipsets, which * will reset the device register after changing the IEN bit on * ctl register */ static void via_tf_load(struct ata_port *ap, const struct ata_taskfile *tf) { … } static int via_port_start(struct ata_port *ap) { … } static const struct scsi_host_template via_sht = …; static struct ata_port_operations via_port_ops = …; static struct ata_port_operations via_port_ops_noirq = …; /** * via_config_fifo - set up the FIFO * @pdev: PCI device * @flags: configuration flags * * Set the FIFO properties for this device if necessary. Used both on * set up and on and the resume path */ static void via_config_fifo(struct pci_dev *pdev, unsigned int flags) { … } static void via_fixup(struct pci_dev *pdev, const struct via_isa_bridge *config) { … } /** * via_init_one - discovery callback * @pdev: PCI device * @id: PCI table info * * A VIA IDE interface has been discovered. Figure out what revision * and perform configuration work before handing it to the ATA layer */ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id) { … } #ifdef CONFIG_PM_SLEEP /** * via_reinit_one - reinit after resume * @pdev: PCI device * * Called when the VIA PATA device is resumed. We must then * reconfigure the fifo and other setup we may have altered. In * addition the kernel needs to have the resume methods on PCI * quirk supported. */ static int via_reinit_one(struct pci_dev *pdev) { … } #endif static const struct pci_device_id via[] = …; static struct pci_driver via_pci_driver = …; module_pci_driver(…) …; MODULE_AUTHOR(…) …; MODULE_DESCRIPTION(…) …; MODULE_LICENSE(…) …; MODULE_DEVICE_TABLE(pci, via); MODULE_VERSION(…);