Commit b7fb14d3 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Jens Axboe

ide: remove the legacy ide driver

The legay ide driver has been replace with libata starting in 2003 and has
been scheduled for removal for a while.  Finally kill it off so that we
can start cleaning up various bits of cruft it forced on the block layer.
Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent b90257bf
This diff is collapsed.
...@@ -8763,22 +8763,6 @@ L: linux-i2c@vger.kernel.org ...@@ -8763,22 +8763,6 @@ L: linux-i2c@vger.kernel.org
S: Maintained S: Maintained
F: drivers/i2c/busses/i2c-icy.c F: drivers/i2c/busses/i2c-icy.c
IDE SUBSYSTEM
M: "David S. Miller" <davem@davemloft.net>
L: linux-ide@vger.kernel.org
S: Maintained
Q: http://patchwork.ozlabs.org/project/linux-ide/list/
T: git git://git.kernel.org/pub/scm/linux/kernel/git/davem/ide.git
F: Documentation/ide/
F: drivers/ide/
F: include/linux/ide.h
IDE/ATAPI DRIVERS
L: linux-ide@vger.kernel.org
S: Orphan
F: Documentation/cdrom/ide-cd.rst
F: drivers/ide/ide-cd*
IDEAPAD LAPTOP EXTRAS DRIVER IDEAPAD LAPTOP EXTRAS DRIVER
M: Ike Panhc <ike.pan@canonical.com> M: Ike Panhc <ike.pan@canonical.com>
L: platform-driver-x86@vger.kernel.org L: platform-driver-x86@vger.kernel.org
......
...@@ -33,8 +33,6 @@ source "drivers/nvme/Kconfig" ...@@ -33,8 +33,6 @@ source "drivers/nvme/Kconfig"
source "drivers/misc/Kconfig" source "drivers/misc/Kconfig"
source "drivers/ide/Kconfig"
source "drivers/scsi/Kconfig" source "drivers/scsi/Kconfig"
source "drivers/ata/Kconfig" source "drivers/ata/Kconfig"
......
...@@ -78,7 +78,6 @@ obj-$(CONFIG_CXL_BUS) += cxl/ ...@@ -78,7 +78,6 @@ obj-$(CONFIG_CXL_BUS) += cxl/
obj-$(CONFIG_DMA_SHARED_BUFFER) += dma-buf/ obj-$(CONFIG_DMA_SHARED_BUFFER) += dma-buf/
obj-$(CONFIG_NUBUS) += nubus/ obj-$(CONFIG_NUBUS) += nubus/
obj-y += macintosh/ obj-y += macintosh/
obj-$(CONFIG_IDE) += ide/
obj-y += scsi/ obj-y += scsi/
obj-y += nvme/ obj-y += nvme/
obj-$(CONFIG_ATA) += ata/ obj-$(CONFIG_ATA) += ata/
......
This diff is collapsed.
# SPDX-License-Identifier: GPL-2.0
#
# link order is important here
#
ide-core-y += ide.o ide-ioctls.o ide-io.o ide-iops.o ide-lib.o ide-probe.o \
ide-taskfile.o ide-pm.o ide-park.o ide-sysfs.o ide-devsets.o \
ide-io-std.o ide-eh.o
# core IDE code
ide-core-$(CONFIG_IDE_XFER_MODE) += ide-pio-blacklist.o ide-xfer-mode.o
ide-core-$(CONFIG_IDE_TIMINGS) += ide-timings.o
ide-core-$(CONFIG_IDE_ATAPI) += ide-atapi.o
ide-core-$(CONFIG_BLK_DEV_IDEPCI) += setup-pci.o
ide-core-$(CONFIG_BLK_DEV_IDEDMA) += ide-dma.o
ide-core-$(CONFIG_BLK_DEV_IDEDMA_SFF) += ide-dma-sff.o
ide-core-$(CONFIG_IDE_PROC_FS) += ide-proc.o
ide-core-$(CONFIG_BLK_DEV_IDEACPI) += ide-acpi.o
ide-core-$(CONFIG_IDE_LEGACY) += ide-legacy.o
obj-$(CONFIG_IDE) += ide-core.o
obj-$(CONFIG_BLK_DEV_ALI14XX) += ali14xx.o
obj-$(CONFIG_BLK_DEV_UMC8672) += umc8672.o
obj-$(CONFIG_BLK_DEV_DTC2278) += dtc2278.o
obj-$(CONFIG_BLK_DEV_HT6560B) += ht6560b.o
obj-$(CONFIG_BLK_DEV_QD65XX) += qd65xx.o
obj-$(CONFIG_BLK_DEV_4DRIVES) += ide-4drives.o
obj-$(CONFIG_BLK_DEV_GAYLE) += gayle.o
obj-$(CONFIG_BLK_DEV_FALCON_IDE) += falconide.o
obj-$(CONFIG_BLK_DEV_BUDDHA) += buddha.o
obj-$(CONFIG_BLK_DEV_AEC62XX) += aec62xx.o
obj-$(CONFIG_BLK_DEV_ALI15X3) += alim15x3.o
obj-$(CONFIG_BLK_DEV_AMD74XX) += amd74xx.o
obj-$(CONFIG_BLK_DEV_ATIIXP) += atiixp.o
obj-$(CONFIG_BLK_DEV_CMD64X) += cmd64x.o
obj-$(CONFIG_BLK_DEV_CS5520) += cs5520.o
obj-$(CONFIG_BLK_DEV_CS5530) += cs5530.o
obj-$(CONFIG_BLK_DEV_CS5535) += cs5535.o
obj-$(CONFIG_BLK_DEV_CS5536) += cs5536.o
obj-$(CONFIG_BLK_DEV_SC1200) += sc1200.o
obj-$(CONFIG_BLK_DEV_CY82C693) += cy82c693.o
obj-$(CONFIG_BLK_DEV_DELKIN) += delkin_cb.o
obj-$(CONFIG_BLK_DEV_HPT366) += hpt366.o
obj-$(CONFIG_BLK_DEV_IT8172) += it8172.o
obj-$(CONFIG_BLK_DEV_IT8213) += it8213.o
obj-$(CONFIG_BLK_DEV_IT821X) += it821x.o
obj-$(CONFIG_BLK_DEV_JMICRON) += jmicron.o
obj-$(CONFIG_BLK_DEV_NS87415) += ns87415.o
obj-$(CONFIG_BLK_DEV_OPTI621) += opti621.o
obj-$(CONFIG_BLK_DEV_PDC202XX_OLD) += pdc202xx_old.o
obj-$(CONFIG_BLK_DEV_PDC202XX_NEW) += pdc202xx_new.o
obj-$(CONFIG_BLK_DEV_PIIX) += piix.o
obj-$(CONFIG_BLK_DEV_RZ1000) += rz1000.o
obj-$(CONFIG_BLK_DEV_SVWKS) += serverworks.o
obj-$(CONFIG_BLK_DEV_SIIMAGE) += siimage.o
obj-$(CONFIG_BLK_DEV_SIS5513) += sis5513.o
obj-$(CONFIG_BLK_DEV_SL82C105) += sl82c105.o
obj-$(CONFIG_BLK_DEV_SLC90E66) += slc90e66.o
obj-$(CONFIG_BLK_DEV_TC86C001) += tc86c001.o
obj-$(CONFIG_BLK_DEV_TRIFLEX) += triflex.o
obj-$(CONFIG_BLK_DEV_TRM290) += trm290.o
obj-$(CONFIG_BLK_DEV_VIA82CXXX) += via82cxxx.o
# Must appear at the end of the block
obj-$(CONFIG_BLK_DEV_GENERIC) += ide-pci-generic.o
obj-$(CONFIG_IDEPCI_PCIBUS_ORDER) += ide-scan-pci.o
obj-$(CONFIG_BLK_DEV_CMD640) += cmd640.o
obj-$(CONFIG_BLK_DEV_IDE_PMAC) += pmac.o
obj-$(CONFIG_IDE_GENERIC) += ide-generic.o
obj-$(CONFIG_BLK_DEV_IDEPNP) += ide-pnp.o
ide-gd_mod-y += ide-gd.o
ide-cd_mod-y += ide-cd.o ide-cd_ioctl.o ide-cd_verbose.o
ifeq ($(CONFIG_IDE_GD_ATA), y)
ide-gd_mod-y += ide-disk.o ide-disk_ioctl.o
ifeq ($(CONFIG_IDE_PROC_FS), y)
ide-gd_mod-y += ide-disk_proc.o
endif
endif
ifeq ($(CONFIG_IDE_GD_ATAPI), y)
ide-gd_mod-y += ide-floppy.o ide-floppy_ioctl.o
ifeq ($(CONFIG_IDE_PROC_FS), y)
ide-gd_mod-y += ide-floppy_proc.o
endif
endif
obj-$(CONFIG_IDE_GD) += ide-gd_mod.o
obj-$(CONFIG_BLK_DEV_IDECD) += ide-cd_mod.o
obj-$(CONFIG_BLK_DEV_IDETAPE) += ide-tape.o
obj-$(CONFIG_BLK_DEV_IDECS) += ide-cs.o
obj-$(CONFIG_BLK_DEV_PLATFORM) += ide_platform.o
obj-$(CONFIG_BLK_DEV_IDE_ICSIDE) += icside.o
obj-$(CONFIG_BLK_DEV_IDE_RAPIDE) += rapide.o
obj-$(CONFIG_BLK_DEV_PALMCHIP_BK3710) += palm_bk3710.o
obj-$(CONFIG_BLK_DEV_IDE_TX4938) += tx4938ide.o
obj-$(CONFIG_BLK_DEV_IDE_TX4939) += tx4939ide.o
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 1999-2002 Andre Hedrick <andre@linux-ide.org>
* Copyright (C) 2007 MontaVista Software, Inc. <source@mvista.com>
*
*/
#include <linux/module.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/ide.h>
#include <linux/init.h>
#include <asm/io.h>
#define DRV_NAME "aec62xx"
struct chipset_bus_clock_list_entry {
u8 xfer_speed;
u8 chipset_settings;
u8 ultra_settings;
};
static const struct chipset_bus_clock_list_entry aec6xxx_33_base [] = {
{ XFER_UDMA_6, 0x31, 0x07 },
{ XFER_UDMA_5, 0x31, 0x06 },
{ XFER_UDMA_4, 0x31, 0x05 },
{ XFER_UDMA_3, 0x31, 0x04 },
{ XFER_UDMA_2, 0x31, 0x03 },
{ XFER_UDMA_1, 0x31, 0x02 },
{ XFER_UDMA_0, 0x31, 0x01 },
{ XFER_MW_DMA_2, 0x31, 0x00 },
{ XFER_MW_DMA_1, 0x31, 0x00 },
{ XFER_MW_DMA_0, 0x0a, 0x00 },
{ XFER_PIO_4, 0x31, 0x00 },
{ XFER_PIO_3, 0x33, 0x00 },
{ XFER_PIO_2, 0x08, 0x00 },
{ XFER_PIO_1, 0x0a, 0x00 },
{ XFER_PIO_0, 0x00, 0x00 },
{ 0, 0x00, 0x00 }
};
static const struct chipset_bus_clock_list_entry aec6xxx_34_base [] = {
{ XFER_UDMA_6, 0x41, 0x06 },
{ XFER_UDMA_5, 0x41, 0x05 },
{ XFER_UDMA_4, 0x41, 0x04 },
{ XFER_UDMA_3, 0x41, 0x03 },
{ XFER_UDMA_2, 0x41, 0x02 },
{ XFER_UDMA_1, 0x41, 0x01 },
{ XFER_UDMA_0, 0x41, 0x01 },
{ XFER_MW_DMA_2, 0x41, 0x00 },
{ XFER_MW_DMA_1, 0x42, 0x00 },
{ XFER_MW_DMA_0, 0x7a, 0x00 },
{ XFER_PIO_4, 0x41, 0x00 },
{ XFER_PIO_3, 0x43, 0x00 },
{ XFER_PIO_2, 0x78, 0x00 },
{ XFER_PIO_1, 0x7a, 0x00 },
{ XFER_PIO_0, 0x70, 0x00 },
{ 0, 0x00, 0x00 }
};
/*
* TO DO: active tuning and correction of cards without a bios.
*/
static u8 pci_bus_clock_list (u8 speed, struct chipset_bus_clock_list_entry * chipset_table)
{
for ( ; chipset_table->xfer_speed ; chipset_table++)
if (chipset_table->xfer_speed == speed) {
return chipset_table->chipset_settings;
}
return chipset_table->chipset_settings;
}
static u8 pci_bus_clock_list_ultra (u8 speed, struct chipset_bus_clock_list_entry * chipset_table)
{
for ( ; chipset_table->xfer_speed ; chipset_table++)
if (chipset_table->xfer_speed == speed) {
return chipset_table->ultra_settings;
}
return chipset_table->ultra_settings;
}
static void aec6210_set_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
struct pci_dev *dev = to_pci_dev(hwif->dev);
struct ide_host *host = pci_get_drvdata(dev);
struct chipset_bus_clock_list_entry *bus_clock = host->host_priv;
u16 d_conf = 0;
u8 ultra = 0, ultra_conf = 0;
u8 tmp0 = 0, tmp1 = 0, tmp2 = 0;
const u8 speed = drive->dma_mode;
unsigned long flags;
local_irq_save(flags);
/* 0x40|(2*drive->dn): Active, 0x41|(2*drive->dn): Recovery */
pci_read_config_word(dev, 0x40|(2*drive->dn), &d_conf);
tmp0 = pci_bus_clock_list(speed, bus_clock);
d_conf = ((tmp0 & 0xf0) << 4) | (tmp0 & 0xf);
pci_write_config_word(dev, 0x40|(2*drive->dn), d_conf);
tmp1 = 0x00;
tmp2 = 0x00;
pci_read_config_byte(dev, 0x54, &ultra);
tmp1 = ((0x00 << (2*drive->dn)) | (ultra & ~(3 << (2*drive->dn))));
ultra_conf = pci_bus_clock_list_ultra(speed, bus_clock);
tmp2 = ((ultra_conf << (2*drive->dn)) | (tmp1 & ~(3 << (2*drive->dn))));
pci_write_config_byte(dev, 0x54, tmp2);
local_irq_restore(flags);
}
static void aec6260_set_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
struct pci_dev *dev = to_pci_dev(hwif->dev);
struct ide_host *host = pci_get_drvdata(dev);
struct chipset_bus_clock_list_entry *bus_clock = host->host_priv;
u8 unit = drive->dn & 1;
u8 tmp1 = 0, tmp2 = 0;
u8 ultra = 0, drive_conf = 0, ultra_conf = 0;
const u8 speed = drive->dma_mode;
unsigned long flags;
local_irq_save(flags);
/* high 4-bits: Active, low 4-bits: Recovery */
pci_read_config_byte(dev, 0x40|drive->dn, &drive_conf);
drive_conf = pci_bus_clock_list(speed, bus_clock);
pci_write_config_byte(dev, 0x40|drive->dn, drive_conf);
pci_read_config_byte(dev, (0x44|hwif->channel), &ultra);
tmp1 = ((0x00 << (4*unit)) | (ultra & ~(7 << (4*unit))));
ultra_conf = pci_bus_clock_list_ultra(speed, bus_clock);
tmp2 = ((ultra_conf << (4*unit)) | (tmp1 & ~(7 << (4*unit))));
pci_write_config_byte(dev, (0x44|hwif->channel), tmp2);
local_irq_restore(flags);
}
static void aec_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
drive->dma_mode = drive->pio_mode;
hwif->port_ops->set_dma_mode(hwif, drive);
}
static int init_chipset_aec62xx(struct pci_dev *dev)
{
/* These are necessary to get AEC6280 Macintosh cards to work */
if ((dev->device == PCI_DEVICE_ID_ARTOP_ATP865) ||
(dev->device == PCI_DEVICE_ID_ARTOP_ATP865R)) {
u8 reg49h = 0, reg4ah = 0;
/* Clear reset and test bits. */
pci_read_config_byte(dev, 0x49, &reg49h);
pci_write_config_byte(dev, 0x49, reg49h & ~0x30);
/* Enable chip interrupt output. */
pci_read_config_byte(dev, 0x4a, &reg4ah);
pci_write_config_byte(dev, 0x4a, reg4ah & ~0x01);
/* Enable burst mode. */
pci_read_config_byte(dev, 0x4a, &reg4ah);
pci_write_config_byte(dev, 0x4a, reg4ah | 0x80);
}
return 0;
}
static u8 atp86x_cable_detect(ide_hwif_t *hwif)
{
struct pci_dev *dev = to_pci_dev(hwif->dev);
u8 ata66 = 0, mask = hwif->channel ? 0x02 : 0x01;
pci_read_config_byte(dev, 0x49, &ata66);
return (ata66 & mask) ? ATA_CBL_PATA40 : ATA_CBL_PATA80;
}
static const struct ide_port_ops atp850_port_ops = {
.set_pio_mode = aec_set_pio_mode,
.set_dma_mode = aec6210_set_mode,
};
static const struct ide_port_ops atp86x_port_ops = {
.set_pio_mode = aec_set_pio_mode,
.set_dma_mode = aec6260_set_mode,
.cable_detect = atp86x_cable_detect,
};
static const struct ide_port_info aec62xx_chipsets[] = {
{ /* 0: AEC6210 */
.name = DRV_NAME,
.init_chipset = init_chipset_aec62xx,
.enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
.port_ops = &atp850_port_ops,
.host_flags = IDE_HFLAG_SERIALIZE |
IDE_HFLAG_NO_ATAPI_DMA |
IDE_HFLAG_NO_DSC |
IDE_HFLAG_OFF_BOARD,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA2,
},
{ /* 1: AEC6260 */
.name = DRV_NAME,
.init_chipset = init_chipset_aec62xx,
.port_ops = &atp86x_port_ops,
.host_flags = IDE_HFLAG_NO_ATAPI_DMA | IDE_HFLAG_NO_AUTODMA |
IDE_HFLAG_OFF_BOARD,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA4,
},
{ /* 2: AEC6260R */
.name = DRV_NAME,
.init_chipset = init_chipset_aec62xx,
.enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
.port_ops = &atp86x_port_ops,
.host_flags = IDE_HFLAG_NO_ATAPI_DMA |
IDE_HFLAG_NON_BOOTABLE,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA4,
},
{ /* 3: AEC6280 */
.name = DRV_NAME,
.init_chipset = init_chipset_aec62xx,
.port_ops = &atp86x_port_ops,
.host_flags = IDE_HFLAG_NO_ATAPI_DMA |
IDE_HFLAG_OFF_BOARD,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
},
{ /* 4: AEC6280R */
.name = DRV_NAME,
.init_chipset = init_chipset_aec62xx,
.enablebits = {{0x4a,0x02,0x02}, {0x4a,0x04,0x04}},
.port_ops = &atp86x_port_ops,
.host_flags = IDE_HFLAG_NO_ATAPI_DMA |
IDE_HFLAG_OFF_BOARD,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
}
};
/**
* aec62xx_init_one - called when a AEC is found
* @dev: the aec62xx device
* @id: the matching pci id
*
* Called when the PCI registration layer (or the IDE initialization)
* finds a device matching our IDE device tables.
*
* NOTE: since we're going to modify the 'name' field for AEC-6[26]80[R]
* chips, pass a local copy of 'struct ide_port_info' down the call chain.
*/
static int aec62xx_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
const struct chipset_bus_clock_list_entry *bus_clock;
struct ide_port_info d;
u8 idx = id->driver_data;
int bus_speed = ide_pci_clk ? ide_pci_clk : 33;
int err;
if (bus_speed <= 33)
bus_clock = aec6xxx_33_base;
else
bus_clock = aec6xxx_34_base;
err = pci_enable_device(dev);
if (err)
return err;
d = aec62xx_chipsets[idx];
if (idx == 3 || idx == 4) {
unsigned long dma_base = pci_resource_start(dev, 4);
if (inb(dma_base + 2) & 0x10) {
printk(KERN_INFO DRV_NAME " %s: AEC6880%s card detected"
"\n", pci_name(dev), (idx == 4) ? "R" : "");
d.udma_mask = ATA_UDMA6;
}
}
err = ide_pci_init_one(dev, &d, (void *)bus_clock);
if (err)
pci_disable_device(dev);
return err;
}
static void aec62xx_remove(struct pci_dev *dev)
{
ide_pci_remove(dev);
pci_disable_device(dev);
}
static const struct pci_device_id aec62xx_pci_tbl[] = {
{ PCI_VDEVICE(ARTOP, PCI_DEVICE_ID_ARTOP_ATP850UF), 0 },
{ PCI_VDEVICE(ARTOP, PCI_DEVICE_ID_ARTOP_ATP860), 1 },
{ PCI_VDEVICE(ARTOP, PCI_DEVICE_ID_ARTOP_ATP860R), 2 },
{ PCI_VDEVICE(ARTOP, PCI_DEVICE_ID_ARTOP_ATP865), 3 },
{ PCI_VDEVICE(ARTOP, PCI_DEVICE_ID_ARTOP_ATP865R), 4 },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, aec62xx_pci_tbl);
static struct pci_driver aec62xx_pci_driver = {
.name = "AEC62xx_IDE",
.id_table = aec62xx_pci_tbl,
.probe = aec62xx_init_one,
.remove = aec62xx_remove,
.suspend = ide_pci_suspend,
.resume = ide_pci_resume,
};
static int __init aec62xx_ide_init(void)
{
return ide_pci_register_driver(&aec62xx_pci_driver);
}
static void __exit aec62xx_ide_exit(void)
{
pci_unregister_driver(&aec62xx_pci_driver);
}
module_init(aec62xx_ide_init);
module_exit(aec62xx_ide_exit);
MODULE_AUTHOR("Andre Hedrick");
MODULE_DESCRIPTION("PCI driver module for ARTOP AEC62xx IDE");
MODULE_LICENSE("GPL");
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 1996 Linus Torvalds & author (see below)
*/
/*
* ALI M14xx chipset EIDE controller
*
* Works for ALI M1439/1443/1445/1487/1489 chipsets.
*
* Adapted from code developed by derekn@vw.ece.cmu.edu. -ml
* Derek's notes follow:
*
* I think the code should be pretty understandable,
* but I'll be happy to (try to) answer questions.
*
* The critical part is in the setupDrive function. The initRegisters
* function doesn't seem to be necessary, but the DOS driver does it, so
* I threw it in.
*
* I've only tested this on my system, which only has one disk. I posted
* it to comp.sys.linux.hardware, so maybe some other people will try it
* out.
*
* Derek Noonburg (derekn@ece.cmu.edu)
* 95-sep-26
*
* Update 96-jul-13:
*
* I've since upgraded to two disks and a CD-ROM, with no trouble, and
* I've also heard from several others who have used it successfully.
* This driver appears to work with both the 1443/1445 and the 1487/1489
* chipsets. I've added support for PIO mode 4 for the 1487. This
* seems to work just fine on the 1443 also, although I'm not sure it's
* advertised as supporting mode 4. (I've been running a WDC AC21200 in
* mode 4 for a while now with no trouble.) -Derek
*/
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/timer.h>
#include <linux/mm.h>
#include <linux/ioport.h>
#include <linux/blkdev.h>
#include <linux/ide.h>
#include <linux/init.h>
#include <asm/io.h>
#define DRV_NAME "ali14xx"
/* port addresses for auto-detection */
#define ALI_NUM_PORTS 4
static const int ports[ALI_NUM_PORTS] __initconst =
{ 0x074, 0x0f4, 0x034, 0x0e4 };
/* register initialization data */
typedef struct { u8 reg, data; } RegInitializer;
static const RegInitializer initData[] __initconst = {
{0x01, 0x0f}, {0x02, 0x00}, {0x03, 0x00}, {0x04, 0x00},
{0x05, 0x00}, {0x06, 0x00}, {0x07, 0x2b}, {0x0a, 0x0f},
{0x25, 0x00}, {0x26, 0x00}, {0x27, 0x00}, {0x28, 0x00},
{0x29, 0x00}, {0x2a, 0x00}, {0x2f, 0x00}, {0x2b, 0x00},
{0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x00}, {0x30, 0x00},
{0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00}, {0x34, 0xff},
{0x35, 0x03}, {0x00, 0x00}
};
/* timing parameter registers for each drive */
static struct { u8 reg1, reg2, reg3, reg4; } regTab[4] = {
{0x03, 0x26, 0x04, 0x27}, /* drive 0 */
{0x05, 0x28, 0x06, 0x29}, /* drive 1 */
{0x2b, 0x30, 0x2c, 0x31}, /* drive 2 */
{0x2d, 0x32, 0x2e, 0x33}, /* drive 3 */
};
static int basePort; /* base port address */
static int regPort; /* port for register number */
static int dataPort; /* port for register data */
static u8 regOn; /* output to base port to access registers */
static u8 regOff; /* output to base port to close registers */
/*------------------------------------------------------------------------*/
/*
* Read a controller register.
*/
static inline u8 inReg(u8 reg)
{
outb_p(reg, regPort);
return inb(dataPort);
}
/*
* Write a controller register.
*/
static void outReg(u8 data, u8 reg)
{
outb_p(reg, regPort);
outb_p(data, dataPort);
}
static DEFINE_SPINLOCK(ali14xx_lock);
/*
* Set PIO mode for the specified drive.
* This function computes timing parameters
* and sets controller registers accordingly.
*/
static void ali14xx_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
int driveNum;
int time1, time2;
u8 param1, param2, param3, param4;
unsigned long flags;
int bus_speed = ide_vlb_clk ? ide_vlb_clk : 50;
const u8 pio = drive->pio_mode - XFER_PIO_0;
struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio);
/* calculate timing, according to PIO mode */
time1 = ide_pio_cycle_time(drive, pio);
time2 = t->active;
param3 = param1 = (time2 * bus_speed + 999) / 1000;
param4 = param2 = (time1 * bus_speed + 999) / 1000 - param1;
if (pio < 3) {
param3 += 8;
param4 += 8;
}
printk(KERN_DEBUG "%s: PIO mode%d, t1=%dns, t2=%dns, cycles = %d+%d, %d+%d\n",
drive->name, pio, time1, time2, param1, param2, param3, param4);
/* stuff timing parameters into controller registers */
driveNum = (drive->hwif->index << 1) + (drive->dn & 1);
spin_lock_irqsave(&ali14xx_lock, flags);
outb_p(regOn, basePort);
outReg(param1, regTab[driveNum].reg1);
outReg(param2, regTab[driveNum].reg2);
outReg(param3, regTab[driveNum].reg3);
outReg(param4, regTab[driveNum].reg4);
outb_p(regOff, basePort);
spin_unlock_irqrestore(&ali14xx_lock, flags);
}
/*
* Auto-detect the IDE controller port.
*/
static int __init findPort(void)
{
int i;
u8 t;
unsigned long flags;
local_irq_save(flags);
for (i = 0; i < ALI_NUM_PORTS; ++i) {
basePort = ports[i];
regOff = inb(basePort);
for (regOn = 0x30; regOn <= 0x33; ++regOn) {
outb_p(regOn, basePort);
if (inb(basePort) == regOn) {
regPort = basePort + 4;
dataPort = basePort + 8;
t = inReg(0) & 0xf0;
outb_p(regOff, basePort);
local_irq_restore(flags);
if (t != 0x50)
return 0;
return 1; /* success */
}
}
outb_p(regOff, basePort);
}
local_irq_restore(flags);
return 0;
}
/*
* Initialize controller registers with default values.
*/
static int __init initRegisters(void)
{
const RegInitializer *p;
u8 t;
unsigned long flags;
local_irq_save(flags);
outb_p(regOn, basePort);
for (p = initData; p->reg != 0; ++p)
outReg(p->data, p->reg);
outb_p(0x01, regPort);
t = inb(regPort) & 0x01;
outb_p(regOff, basePort);
local_irq_restore(flags);
return t;
}
static const struct ide_port_ops ali14xx_port_ops = {
.set_pio_mode = ali14xx_set_pio_mode,
};
static const struct ide_port_info ali14xx_port_info = {
.name = DRV_NAME,
.chipset = ide_ali14xx,
.port_ops = &ali14xx_port_ops,
.host_flags = IDE_HFLAG_NO_DMA,
.pio_mask = ATA_PIO4,
};
static int __init ali14xx_probe(void)
{
printk(KERN_DEBUG "ali14xx: base=0x%03x, regOn=0x%02x.\n",
basePort, regOn);
/* initialize controller registers */
if (!initRegisters()) {
printk(KERN_ERR "ali14xx: Chip initialization failed.\n");
return 1;
}
return ide_legacy_device_add(&ali14xx_port_info, 0);
}
static bool probe_ali14xx;
module_param_named(probe, probe_ali14xx, bool, 0);
MODULE_PARM_DESC(probe, "probe for ALI M14xx chipsets");
static int __init ali14xx_init(void)
{
if (probe_ali14xx == 0)
goto out;
/* auto-detect IDE controller port */
if (findPort()) {
if (ali14xx_probe())
return -ENODEV;
return 0;
}
printk(KERN_ERR "ali14xx: not found.\n");
out:
return -ENODEV;
}
module_init(ali14xx_init);
MODULE_AUTHOR("see local file");
MODULE_DESCRIPTION("support of ALI 14XX IDE chipsets");
MODULE_LICENSE("GPL");
This diff is collapsed.
This diff is collapsed.
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2003 ATI Inc. <hyu@ati.com>
* Copyright (C) 2004,2007 Bartlomiej Zolnierkiewicz
*/
#include <linux/types.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/ide.h>
#include <linux/init.h>
#define DRV_NAME "atiixp"
#define ATIIXP_IDE_PIO_TIMING 0x40
#define ATIIXP_IDE_MDMA_TIMING 0x44
#define ATIIXP_IDE_PIO_CONTROL 0x48
#define ATIIXP_IDE_PIO_MODE 0x4a
#define ATIIXP_IDE_UDMA_CONTROL 0x54
#define ATIIXP_IDE_UDMA_MODE 0x56
struct atiixp_ide_timing {
u8 command_width;
u8 recover_width;
};
static struct atiixp_ide_timing pio_timing[] = {
{ 0x05, 0x0d },
{ 0x04, 0x07 },
{ 0x03, 0x04 },
{ 0x02, 0x02 },
{ 0x02, 0x00 },
};
static struct atiixp_ide_timing mdma_timing[] = {
{ 0x07, 0x07 },
{ 0x02, 0x01 },
{ 0x02, 0x00 },
};
static DEFINE_SPINLOCK(atiixp_lock);
/**
* atiixp_set_pio_mode - set host controller for PIO mode
* @hwif: port
* @drive: drive
*
* Set the interface PIO mode.
*/
static void atiixp_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
struct pci_dev *dev = to_pci_dev(hwif->dev);
unsigned long flags;
int timing_shift = (drive->dn ^ 1) * 8;
u32 pio_timing_data;
u16 pio_mode_data;
const u8 pio = drive->pio_mode - XFER_PIO_0;
spin_lock_irqsave(&atiixp_lock, flags);
pci_read_config_word(dev, ATIIXP_IDE_PIO_MODE, &pio_mode_data);
pio_mode_data &= ~(0x07 << (drive->dn * 4));
pio_mode_data |= (pio << (drive->dn * 4));
pci_write_config_word(dev, ATIIXP_IDE_PIO_MODE, pio_mode_data);
pci_read_config_dword(dev, ATIIXP_IDE_PIO_TIMING, &pio_timing_data);
pio_timing_data &= ~(0xff << timing_shift);
pio_timing_data |= (pio_timing[pio].recover_width << timing_shift) |
(pio_timing[pio].command_width << (timing_shift + 4));
pci_write_config_dword(dev, ATIIXP_IDE_PIO_TIMING, pio_timing_data);
spin_unlock_irqrestore(&atiixp_lock, flags);
}
/**
* atiixp_set_dma_mode - set host controller for DMA mode
* @hwif: port
* @drive: drive
*
* Set a ATIIXP host controller to the desired DMA mode. This involves
* programming the right timing data into the PCI configuration space.
*/
static void atiixp_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
struct pci_dev *dev = to_pci_dev(hwif->dev);
unsigned long flags;
int timing_shift = (drive->dn ^ 1) * 8;
u32 tmp32;
u16 tmp16;
u16 udma_ctl = 0;
const u8 speed = drive->dma_mode;
spin_lock_irqsave(&atiixp_lock, flags);
pci_read_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, &udma_ctl);
if (speed >= XFER_UDMA_0) {
pci_read_config_word(dev, ATIIXP_IDE_UDMA_MODE, &tmp16);
tmp16 &= ~(0x07 << (drive->dn * 4));
tmp16 |= ((speed & 0x07) << (drive->dn * 4));
pci_write_config_word(dev, ATIIXP_IDE_UDMA_MODE, tmp16);
udma_ctl |= (1 << drive->dn);
} else if (speed >= XFER_MW_DMA_0) {
u8 i = speed & 0x03;
pci_read_config_dword(dev, ATIIXP_IDE_MDMA_TIMING, &tmp32);
tmp32 &= ~(0xff << timing_shift);
tmp32 |= (mdma_timing[i].recover_width << timing_shift) |
(mdma_timing[i].command_width << (timing_shift + 4));
pci_write_config_dword(dev, ATIIXP_IDE_MDMA_TIMING, tmp32);
udma_ctl &= ~(1 << drive->dn);
}
pci_write_config_word(dev, ATIIXP_IDE_UDMA_CONTROL, udma_ctl);
spin_unlock_irqrestore(&atiixp_lock, flags);
}
static u8 atiixp_cable_detect(ide_hwif_t *hwif)
{
struct pci_dev *pdev = to_pci_dev(hwif->dev);
u8 udma_mode = 0, ch = hwif->channel;
pci_read_config_byte(pdev, ATIIXP_IDE_UDMA_MODE + ch, &udma_mode);
if ((udma_mode & 0x07) >= 0x04 || (udma_mode & 0x70) >= 0x40)
return ATA_CBL_PATA80;
else
return ATA_CBL_PATA40;
}
static const struct ide_port_ops atiixp_port_ops = {
.set_pio_mode = atiixp_set_pio_mode,
.set_dma_mode = atiixp_set_dma_mode,
.cable_detect = atiixp_cable_detect,
};
static const struct ide_port_info atiixp_pci_info[] = {
{ /* 0: IXP200/300/400/700 */
.name = DRV_NAME,
.enablebits = {{0x48,0x01,0x00}, {0x48,0x08,0x00}},
.port_ops = &atiixp_port_ops,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
},
{ /* 1: IXP600 */
.name = DRV_NAME,
.enablebits = {{0x48,0x01,0x00}, {0x00,0x00,0x00}},
.port_ops = &atiixp_port_ops,
.host_flags = IDE_HFLAG_SINGLE,
.pio_mask = ATA_PIO4,
.mwdma_mask = ATA_MWDMA2,
.udma_mask = ATA_UDMA5,
},
};
/**
* atiixp_init_one - called when a ATIIXP is found
* @dev: the atiixp device
* @id: the matching pci id
*
* Called when the PCI registration layer (or the IDE initialization)
* finds a device matching our IDE device tables.
*/
static int atiixp_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
return ide_pci_init_one(dev, &atiixp_pci_info[id->driver_data], NULL);
}
static const struct pci_device_id atiixp_pci_tbl[] = {
{ PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP200_IDE), 0 },
{ PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP300_IDE), 0 },
{ PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP400_IDE), 0 },
{ PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP600_IDE), 1 },
{ PCI_VDEVICE(ATI, PCI_DEVICE_ID_ATI_IXP700_IDE), 0 },
{ PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_HUDSON2_IDE), 0 },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, atiixp_pci_tbl);
static struct pci_driver atiixp_pci_driver = {
.name = "ATIIXP_IDE",
.id_table = atiixp_pci_tbl,
.probe = atiixp_init_one,
.remove = ide_pci_remove,
.suspend = ide_pci_suspend,
.resume = ide_pci_resume,
};
static int __init atiixp_ide_init(void)
{
return ide_pci_register_driver(&atiixp_pci_driver);
}
static void __exit atiixp_ide_exit(void)
{
pci_unregister_driver(&atiixp_pci_driver);
}
module_init(atiixp_ide_init);
module_exit(atiixp_ide_exit);
MODULE_AUTHOR("HUI YU");
MODULE_DESCRIPTION("PCI driver module for ATI IXP IDE");
MODULE_LICENSE("GPL");
/*
* Amiga Buddha, Catweasel and X-Surf IDE Driver
*
* Copyright (C) 1997, 2001 by Geert Uytterhoeven and others
*
* This driver was written based on the specifications in README.buddha and
* the X-Surf info from Inside_XSurf.txt available at
* http://www.jschoenfeld.com
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive for
* more details.
*
* TODO:
* - test it :-)
* - tune the timings using the speed-register
*/
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/blkdev.h>
#include <linux/zorro.h>
#include <linux/ide.h>
#include <linux/init.h>
#include <linux/module.h>
#include <asm/amigahw.h>
#include <asm/amigaints.h>
/*
* The Buddha has 2 IDE interfaces, the Catweasel has 3, X-Surf has 2
*/
#define BUDDHA_NUM_HWIFS 2
#define CATWEASEL_NUM_HWIFS 3
#define XSURF_NUM_HWIFS 2
#define MAX_NUM_HWIFS 3
/*
* Bases of the IDE interfaces (relative to the board address)
*/
#define BUDDHA_BASE1 0x800
#define BUDDHA_BASE2 0xa00
#define BUDDHA_BASE3 0xc00
#define XSURF_BASE1 0xb000 /* 2.5" Interface */
#define XSURF_BASE2 0xd000 /* 3.5" Interface */
static u_int buddha_bases[CATWEASEL_NUM_HWIFS] __initdata = {
BUDDHA_BASE1, BUDDHA_BASE2, BUDDHA_BASE3
};
static u_int xsurf_bases[XSURF_NUM_HWIFS] __initdata = {
XSURF_BASE1, XSURF_BASE2
};
/*
* Offsets from one of the above bases
*/
#define BUDDHA_CONTROL 0x11a
/*
* Other registers
*/
#define BUDDHA_IRQ1 0xf00 /* MSB = 1, Harddisk is source of */
#define BUDDHA_IRQ2 0xf40 /* interrupt */
#define BUDDHA_IRQ3 0xf80
#define XSURF_IRQ1 0x7e
#define XSURF_IRQ2 0x7e
static int buddha_irqports[CATWEASEL_NUM_HWIFS] __initdata = {
BUDDHA_IRQ1, BUDDHA_IRQ2, BUDDHA_IRQ3
};
static int xsurf_irqports[XSURF_NUM_HWIFS] __initdata = {
XSURF_IRQ1, XSURF_IRQ2
};
#define BUDDHA_IRQ_MR 0xfc0 /* master interrupt enable */
/*
* Board information
*/
typedef enum BuddhaType_Enum {
BOARD_BUDDHA, BOARD_CATWEASEL, BOARD_XSURF
} BuddhaType;
static const char *buddha_board_name[] = { "Buddha", "Catweasel", "X-Surf" };
/*
* Check and acknowledge the interrupt status
*/
static int buddha_test_irq(ide_hwif_t *hwif)
{
unsigned char ch;
ch = z_readb(hwif->io_ports.irq_addr);
if (!(ch & 0x80))
return 0;
return 1;
}
static void xsurf_clear_irq(ide_drive_t *drive)
{
/*
* X-Surf needs 0 written to IRQ register to ensure ISA bit A11 stays at 0
*/
z_writeb(0, drive->hwif->io_ports.irq_addr);
}
static void __init buddha_setup_ports(struct ide_hw *hw, unsigned long base,
unsigned long ctl, unsigned long irq_port)
{
int i;
memset(hw, 0, sizeof(*hw));
hw->io_ports.data_addr = base;
for (i = 1; i < 8; i++)
hw->io_ports_array[i] = base + 2 + i * 4;
hw->io_ports.ctl_addr = ctl;
hw->io_ports.irq_addr = irq_port;
hw->irq = IRQ_AMIGA_PORTS;
}
static const struct ide_port_ops buddha_port_ops = {
.test_irq = buddha_test_irq,
};
static const struct ide_port_ops xsurf_port_ops = {
.clear_irq = xsurf_clear_irq,
.test_irq = buddha_test_irq,
};
static const struct ide_port_info buddha_port_info = {
.port_ops = &buddha_port_ops,
.host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA,
.irq_flags = IRQF_SHARED,
.chipset = ide_generic,
};
/*
* Probe for a Buddha or Catweasel IDE interface
*/
static int __init buddha_init(void)
{
struct zorro_dev *z = NULL;
u_long buddha_board = 0;
BuddhaType type;
int buddha_num_hwifs, i;
while ((z = zorro_find_device(ZORRO_WILDCARD, z))) {
unsigned long board;
struct ide_hw hw[MAX_NUM_HWIFS], *hws[MAX_NUM_HWIFS];
struct ide_port_info d = buddha_port_info;
if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_BUDDHA) {
buddha_num_hwifs = BUDDHA_NUM_HWIFS;
type=BOARD_BUDDHA;
} else if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_CATWEASEL) {
buddha_num_hwifs = CATWEASEL_NUM_HWIFS;
type=BOARD_CATWEASEL;
} else if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF) {
buddha_num_hwifs = XSURF_NUM_HWIFS;
type=BOARD_XSURF;
d.port_ops = &xsurf_port_ops;
} else
continue;
board = z->resource.start;
if(type != BOARD_XSURF) {
if (!request_mem_region(board+BUDDHA_BASE1, 0x800, "IDE"))
continue;
} else {
if (!request_mem_region(board+XSURF_BASE1, 0x1000, "IDE"))
continue;
if (!request_mem_region(board+XSURF_BASE2, 0x1000, "IDE"))
goto fail_base2;
if (!request_mem_region(board+XSURF_IRQ1, 0x8, "IDE")) {
release_mem_region(board+XSURF_BASE2, 0x1000);
fail_base2:
release_mem_region(board+XSURF_BASE1, 0x1000);
continue;
}
}
buddha_board = (unsigned long)ZTWO_VADDR(board);
/* write to BUDDHA_IRQ_MR to enable the board IRQ */
/* X-Surf doesn't have this. IRQs are always on */
if (type != BOARD_XSURF)
z_writeb(0, buddha_board+BUDDHA_IRQ_MR);
printk(KERN_INFO "ide: %s IDE controller\n",
buddha_board_name[type]);
for (i = 0; i < buddha_num_hwifs; i++) {
unsigned long base, ctl, irq_port;
if (type != BOARD_XSURF) {
base = buddha_board + buddha_bases[i];
ctl = base + BUDDHA_CONTROL;
irq_port = buddha_board + buddha_irqports[i];
} else {
base = buddha_board + xsurf_bases[i];
/* X-Surf has no CS1* (Control/AltStat) */
ctl = 0;
irq_port = buddha_board + xsurf_irqports[i];
}
buddha_setup_ports(&hw[i], base, ctl, irq_port);
hws[i] = &hw[i];
}
ide_host_add(&d, hws, i, NULL);
}
return 0;
}
module_init(buddha_init);
MODULE_LICENSE("GPL");
This diff is collapsed.
This diff is collapsed.
/*
* IDE tuning and bus mastering support for the CS5510/CS5520
* chipsets
*
* The CS5510/CS5520 are slightly unusual devices. Unlike the
* typical IDE controllers they do bus mastering with the drive in
* PIO mode and smarter silicon.
*
* The practical upshot of this is that we must always tune the
* drive for the right PIO mode. We must also ignore all the blacklists
* and the drive bus mastering DMA information.
*
* *** This driver is strictly experimental ***
*
* (c) Copyright Red Hat Inc 2002
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* For the avoidance of doubt the "preferred form" of this code is one which
* is in an open non patent encumbered format. Where cryptographic key signing
* forms part of the process of creating an executable the information
* including keys needed to generate an equivalently functional executable
* are deemed to be part of the source code.
*
*/
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/ide.h>
#include <linux/dma-mapping.h>
#define DRV_NAME "cs5520"
struct pio_clocks
{
int address;
int assert;
int recovery;
};
static struct pio_clocks cs5520_pio_clocks[]={
{3, 6, 11},
{2, 5, 6},
{1, 4, 3},
{1, 3, 2},
{1, 2, 1}
};
static void cs5520_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
struct pci_dev *pdev = to_pci_dev(hwif->dev);
int controller = drive->dn > 1 ? 1 : 0;
const u8 pio = drive->pio_mode - XFER_PIO_0;
/* 8bit CAT/CRT - 8bit command timing for channel */
pci_write_config_byte(pdev, 0x62 + controller,
(cs5520_pio_clocks[pio].recovery << 4) |
(cs5520_pio_clocks[pio].assert));
/* 0x64 - 16bit Primary, 0x68 - 16bit Secondary */
/* FIXME: should these use address ? */
/* Data read timing */
pci_write_config_byte(pdev, 0x64 + 4*controller + (drive->dn&1),
(cs5520_pio_clocks[pio].recovery << 4) |
(cs5520_pio_clocks[pio].assert));
/* Write command timing */
pci_write_config_byte(pdev, 0x66 + 4*controller + (drive->dn&1),
(cs5520_pio_clocks[pio].recovery << 4) |
(cs5520_pio_clocks[pio].assert));
}
static void cs5520_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
{
printk(KERN_ERR "cs55x0: bad ide timing.\n");
drive->pio_mode = XFER_PIO_0 + 0;
cs5520_set_pio_mode(hwif, drive);
}
static const struct ide_port_ops cs5520_port_ops = {
.set_pio_mode = cs5520_set_pio_mode,
.set_dma_mode = cs5520_set_dma_mode,
};
static const struct ide_port_info cyrix_chipset = {
.name = DRV_NAME,
.enablebits = { { 0x60, 0x01, 0x01 }, { 0x60, 0x02, 0x02 } },
.port_ops = &cs5520_port_ops,
.host_flags = IDE_HFLAG_ISA_PORTS | IDE_HFLAG_CS5520,
.pio_mask = ATA_PIO4,
};
/*
* The 5510/5520 are a bit weird. They don't quite set up the way
* the PCI helper layer expects so we must do much of the set up
* work longhand.
*/
static int cs5520_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
const struct ide_port_info *d = &cyrix_chipset;
struct ide_hw hw[2], *hws[] = { NULL, NULL };
ide_setup_pci_noise(dev, d);
/* We must not grab the entire device, it has 'ISA' space in its
* BARS too and we will freak out other bits of the kernel
*/
if (pci_enable_device_io(dev)) {
printk(KERN_WARNING "%s: Unable to enable 55x0.\n", d->name);
return -ENODEV;
}
pci_set_master(dev);
if (dma_set_mask(&dev->dev, DMA_BIT_MASK(32))) {
printk(KERN_WARNING "%s: No suitable DMA available.\n",
d->name);
return -ENODEV;
}
/*
* Now the chipset is configured we can let the core
* do all the device setup for us
*/
ide_pci_setup_ports(dev, d, &hw[0], &hws[0]);
hw[0].irq = 14;
hw[1].irq = 15;
return ide_host_add(d, hws, 2, NULL);
}
static const struct pci_device_id cs5520_pci_tbl[] = {
{ PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5510), 0 },
{ PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5520), 1 },
{ 0, },
};
MODULE_DEVICE_TABLE(pci, cs5520_pci_tbl);
static struct pci_driver cs5520_pci_driver = {
.name = "Cyrix_IDE",
.id_table = cs5520_pci_tbl,
.probe = cs5520_init_one,
.suspend = ide_pci_suspend,
.resume = ide_pci_resume,
};
static int __init cs5520_ide_init(void)
{
return ide_pci_register_driver(&cs5520_pci_driver);
}
module_init(cs5520_ide_init);
MODULE_AUTHOR("Alan Cox");
MODULE_DESCRIPTION("PCI driver module for Cyrix 5510/5520 IDE");
MODULE_LICENSE("GPL");
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
// SPDX-License-Identifier: GPL-2.0-only
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/ide.h>
#define DRV_NAME "ide-4drives"
static bool probe_4drives;
module_param_named(probe, probe_4drives, bool, 0);
MODULE_PARM_DESC(probe, "probe for generic IDE chipset with 4 drives/port");
static void ide_4drives_init_dev(ide_drive_t *drive)
{
if (drive->hwif->channel)
drive->select ^= 0x20;
}
static const struct ide_port_ops ide_4drives_port_ops = {
.init_dev = ide_4drives_init_dev,
};
static const struct ide_port_info ide_4drives_port_info = {
.port_ops = &ide_4drives_port_ops,
.host_flags = IDE_HFLAG_SERIALIZE | IDE_HFLAG_NO_DMA |
IDE_HFLAG_4DRIVES,
.chipset = ide_4drives,
};
static int __init ide_4drives_init(void)
{
unsigned long base = 0x1f0, ctl = 0x3f6;
struct ide_hw hw, *hws[] = { &hw, &hw };
if (probe_4drives == 0)
return -ENODEV;
if (!request_region(base, 8, DRV_NAME)) {
printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX not free.\n",
DRV_NAME, base, base + 7);
return -EBUSY;
}
if (!request_region(ctl, 1, DRV_NAME)) {
printk(KERN_ERR "%s: I/O resource 0x%lX not free.\n",
DRV_NAME, ctl);
release_region(base, 8);
return -EBUSY;
}
memset(&hw, 0, sizeof(hw));
ide_std_init_ports(&hw, base, ctl);
hw.irq = 14;
return ide_host_add(&ide_4drives_port_info, hws, 2, NULL);
}
module_init(ide_4drives_init);
MODULE_AUTHOR("Bartlomiej Zolnierkiewicz");
MODULE_DESCRIPTION("generic IDE chipset with 4 drives/port support");
MODULE_LICENSE("GPL");
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __IDE_DISK_H
#define __IDE_DISK_H
#include "ide-gd.h"
#ifdef CONFIG_IDE_GD_ATA
/* ide-disk.c */
extern const struct ide_disk_ops ide_ata_disk_ops;
ide_decl_devset(address);
ide_decl_devset(multcount);
ide_decl_devset(nowerr);
ide_decl_devset(wcache);
ide_decl_devset(acoustic);
/* ide-disk_ioctl.c */
int ide_disk_ioctl(ide_drive_t *, struct block_device *, fmode_t, unsigned int,
unsigned long);
#ifdef CONFIG_IDE_PROC_FS
/* ide-disk_proc.c */
extern ide_proc_entry_t ide_disk_proc[];
extern const struct ide_proc_devset ide_disk_settings[];
#endif
#else
#define ide_disk_proc NULL
#define ide_disk_settings NULL
#endif
#endif /* __IDE_DISK_H */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment