Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/ide/ide-generic.c
15109 views
1
/*
2
* generic/default IDE host driver
3
*
4
* Copyright (C) 2004, 2008-2009 Bartlomiej Zolnierkiewicz
5
* This code was split off from ide.c. See it for original copyrights.
6
*
7
* May be copied or modified under the terms of the GNU General Public License.
8
*/
9
10
#include <linux/kernel.h>
11
#include <linux/init.h>
12
#include <linux/module.h>
13
#include <linux/ide.h>
14
#include <linux/pci_ids.h>
15
16
/* FIXME: convert arm and m32r to use ide_platform host driver */
17
#ifdef CONFIG_ARM
18
#include <asm/irq.h>
19
#endif
20
#ifdef CONFIG_M32R
21
#include <asm/m32r.h>
22
#endif
23
24
#define DRV_NAME "ide_generic"
25
26
static int probe_mask;
27
module_param(probe_mask, int, 0);
28
MODULE_PARM_DESC(probe_mask, "probe mask for legacy ISA IDE ports");
29
30
static const struct ide_port_info ide_generic_port_info = {
31
.host_flags = IDE_HFLAG_NO_DMA,
32
.chipset = ide_generic,
33
};
34
35
#ifdef CONFIG_ARM
36
static const u16 legacy_bases[] = { 0x1f0 };
37
static const int legacy_irqs[] = { IRQ_HARDDISK };
38
#elif defined(CONFIG_PLAT_M32700UT) || defined(CONFIG_PLAT_MAPPI2) || \
39
defined(CONFIG_PLAT_OPSPUT)
40
static const u16 legacy_bases[] = { 0x1f0 };
41
static const int legacy_irqs[] = { PLD_IRQ_CFIREQ };
42
#elif defined(CONFIG_PLAT_MAPPI3)
43
static const u16 legacy_bases[] = { 0x1f0, 0x170 };
44
static const int legacy_irqs[] = { PLD_IRQ_CFIREQ, PLD_IRQ_IDEIREQ };
45
#elif defined(CONFIG_ALPHA)
46
static const u16 legacy_bases[] = { 0x1f0, 0x170, 0x1e8, 0x168 };
47
static const int legacy_irqs[] = { 14, 15, 11, 10 };
48
#else
49
static const u16 legacy_bases[] = { 0x1f0, 0x170, 0x1e8, 0x168, 0x1e0, 0x160 };
50
static const int legacy_irqs[] = { 14, 15, 11, 10, 8, 12 };
51
#endif
52
53
static void ide_generic_check_pci_legacy_iobases(int *primary, int *secondary)
54
{
55
#ifdef CONFIG_PCI
56
struct pci_dev *p = NULL;
57
u16 val;
58
59
for_each_pci_dev(p) {
60
if (pci_resource_start(p, 0) == 0x1f0)
61
*primary = 1;
62
if (pci_resource_start(p, 2) == 0x170)
63
*secondary = 1;
64
65
/* Cyrix CS55{1,2}0 pre SFF MWDMA ATA on the bridge */
66
if (p->vendor == PCI_VENDOR_ID_CYRIX &&
67
(p->device == PCI_DEVICE_ID_CYRIX_5510 ||
68
p->device == PCI_DEVICE_ID_CYRIX_5520))
69
*primary = *secondary = 1;
70
71
/* Intel MPIIX - PIO ATA on non PCI side of bridge */
72
if (p->vendor == PCI_VENDOR_ID_INTEL &&
73
p->device == PCI_DEVICE_ID_INTEL_82371MX) {
74
pci_read_config_word(p, 0x6C, &val);
75
if (val & 0x8000) {
76
/* ATA port enabled */
77
if (val & 0x4000)
78
*secondary = 1;
79
else
80
*primary = 1;
81
}
82
}
83
}
84
#endif
85
}
86
87
static int __init ide_generic_init(void)
88
{
89
struct ide_hw hw, *hws[] = { &hw };
90
unsigned long io_addr;
91
int i, rc = 0, primary = 0, secondary = 0;
92
93
ide_generic_check_pci_legacy_iobases(&primary, &secondary);
94
95
if (!probe_mask) {
96
printk(KERN_INFO DRV_NAME ": please use \"probe_mask=0x3f\" "
97
"module parameter for probing all legacy ISA IDE ports\n");
98
99
if (primary == 0)
100
probe_mask |= 0x1;
101
102
if (secondary == 0)
103
probe_mask |= 0x2;
104
} else
105
printk(KERN_INFO DRV_NAME ": enforcing probing of I/O ports "
106
"upon user request\n");
107
108
for (i = 0; i < ARRAY_SIZE(legacy_bases); i++) {
109
io_addr = legacy_bases[i];
110
111
if ((probe_mask & (1 << i)) && io_addr) {
112
if (!request_region(io_addr, 8, DRV_NAME)) {
113
printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX "
114
"not free.\n",
115
DRV_NAME, io_addr, io_addr + 7);
116
rc = -EBUSY;
117
continue;
118
}
119
120
if (!request_region(io_addr + 0x206, 1, DRV_NAME)) {
121
printk(KERN_ERR "%s: I/O resource 0x%lX "
122
"not free.\n",
123
DRV_NAME, io_addr + 0x206);
124
release_region(io_addr, 8);
125
rc = -EBUSY;
126
continue;
127
}
128
129
memset(&hw, 0, sizeof(hw));
130
ide_std_init_ports(&hw, io_addr, io_addr + 0x206);
131
#ifdef CONFIG_IA64
132
hw.irq = isa_irq_to_vector(legacy_irqs[i]);
133
#else
134
hw.irq = legacy_irqs[i];
135
#endif
136
rc = ide_host_add(&ide_generic_port_info, hws, 1, NULL);
137
if (rc) {
138
release_region(io_addr + 0x206, 1);
139
release_region(io_addr, 8);
140
}
141
}
142
}
143
144
return rc;
145
}
146
147
module_init(ide_generic_init);
148
149
MODULE_LICENSE("GPL");
150
151