Blame view

drivers/ide/setup-pci.c 17 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
  /*
59bca8cc9   Bartlomiej Zolnierkiewicz   ide: update/add m...
2
3
   *  Copyright (C) 1998-2000  Andre Hedrick <andre@linux-ide.org>
   *  Copyright (C) 1995-1998  Mark Lord
ad7c52d09   Bartlomiej Zolnierkiewicz   ide: re-implement...
4
   *  Copyright (C) 2007-2009  Bartlomiej Zolnierkiewicz
58f189fcc   Bartlomiej Zolnierkiewicz   ide: delete filen...
5
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
6
   *  May be copied or modified under the terms of the GNU General Public License
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
7
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
8
9
  #include <linux/types.h>
  #include <linux/kernel.h>
38789fda2   Paul Gortmaker   ide/ata: Add expo...
10
  #include <linux/export.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
11
12
  #include <linux/pci.h>
  #include <linux/init.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
13
14
15
16
17
  #include <linux/interrupt.h>
  #include <linux/ide.h>
  #include <linux/dma-mapping.h>
  
  #include <asm/io.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
18

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
19
20
21
22
23
24
25
  /**
   *	ide_setup_pci_baseregs	-	place a PCI IDE controller native
   *	@dev: PCI device of interface to switch native
   *	@name: Name of interface
   *
   *	We attempt to place the PCI interface into PCI native mode. If
   *	we succeed the BARs are ok and the controller is in PCI mode.
846bb88ae   Paolo Ciarrocchi   IDE: Coding Style...
26
   *	Returns 0 on success or an errno code.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
27
28
29
30
   *
   *	FIXME: if we program the interface and then fail to set the BARS
   *	we don't switch it back to legacy mode. Do we actually care ??
   */
846bb88ae   Paolo Ciarrocchi   IDE: Coding Style...
31
32
  
  static int ide_setup_pci_baseregs(struct pci_dev *dev, const char *name)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
33
34
35
36
37
38
39
40
41
  {
  	u8 progif = 0;
  
  	/*
  	 * Place both IDE interfaces into PCI "native" mode:
  	 */
  	if (pci_read_config_byte(dev, PCI_CLASS_PROG, &progif) ||
  			 (progif & 5) != 5) {
  		if ((progif & 0xa) != 0xa) {
28cfd8af5   Bartlomiej Zolnierkiewicz   ide: include PCI ...
42
43
44
  			printk(KERN_INFO "%s %s: device not capable of full "
  				"native PCI mode
  ", name, pci_name(dev));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
45
46
  			return -EOPNOTSUPP;
  		}
28cfd8af5   Bartlomiej Zolnierkiewicz   ide: include PCI ...
47
48
49
  		printk(KERN_INFO "%s %s: placing both ports into native PCI "
  			"mode
  ", name, pci_name(dev));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
50
51
52
  		(void) pci_write_config_byte(dev, PCI_CLASS_PROG, progif|5);
  		if (pci_read_config_byte(dev, PCI_CLASS_PROG, &progif) ||
  		    (progif & 5) != 5) {
28cfd8af5   Bartlomiej Zolnierkiewicz   ide: include PCI ...
53
54
55
56
  			printk(KERN_ERR "%s %s: rewrite of PROGIF failed, "
  				"wanted 0x%04x, got 0x%04x
  ",
  				name, pci_name(dev), progif | 5, progif);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
57
58
59
60
61
62
63
  			return -EOPNOTSUPP;
  		}
  	}
  	return 0;
  }
  
  #ifdef CONFIG_BLK_DEV_IDEDMA_PCI
28cfd8af5   Bartlomiej Zolnierkiewicz   ide: include PCI ...
64
  static int ide_pci_clear_simplex(unsigned long dma_base, const char *name)
8ac2b42a4   Bartlomiej Zolnierkiewicz   ide: add IDE_HFLA...
65
66
67
68
69
  {
  	u8 dma_stat = inb(dma_base + 2);
  
  	outb(dma_stat & 0x60, dma_base + 2);
  	dma_stat = inb(dma_base + 2);
28cfd8af5   Bartlomiej Zolnierkiewicz   ide: include PCI ...
70
71
  
  	return (dma_stat & 0x80) ? 1 : 0;
8ac2b42a4   Bartlomiej Zolnierkiewicz   ide: add IDE_HFLA...
72
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
73
  /**
b123f56e0   Bartlomiej Zolnierkiewicz   ide: do complete ...
74
   *	ide_pci_dma_base	-	setup BMIBA
039788e15   Bartlomiej Zolnierkiewicz   ide: replace ide_...
75
   *	@hwif: IDE interface
b123f56e0   Bartlomiej Zolnierkiewicz   ide: do complete ...
76
   *	@d: IDE port info
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
77
   *
c58e79dd4   Bartlomiej Zolnierkiewicz   ide: remove CONFI...
78
   *	Fetch the DMA Bus-Master-I/O-Base-Address (BMIBA) from PCI space.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
79
   */
b123f56e0   Bartlomiej Zolnierkiewicz   ide: do complete ...
80
  unsigned long ide_pci_dma_base(ide_hwif_t *hwif, const struct ide_port_info *d)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
81
  {
36501650e   Bartlomiej Zolnierkiewicz   ide: keep pointer...
82
83
  	struct pci_dev *dev = to_pci_dev(hwif->dev);
  	unsigned long dma_base = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
84

135721446   Bartlomiej Zolnierkiewicz   ide: remove ->mmi...
85
  	if (hwif->host_flags & IDE_HFLAG_MMIO)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
86
87
88
89
90
  		return hwif->dma_base;
  
  	if (hwif->mate && hwif->mate->dma_base) {
  		dma_base = hwif->mate->dma_base - (hwif->channel ? 0 : 8);
  	} else {
9ffcf364f   Bartlomiej Zolnierkiewicz   ide: remove ->ini...
91
92
93
  		u8 baridx = (d->host_flags & IDE_HFLAG_CS5520) ? 2 : 4;
  
  		dma_base = pci_resource_start(dev, baridx);
aea5d3756   Bartlomiej Zolnierkiewicz   ide: (hopefully) ...
94
  		if (dma_base == 0) {
28cfd8af5   Bartlomiej Zolnierkiewicz   ide: include PCI ...
95
96
97
  			printk(KERN_ERR "%s %s: DMA base is invalid
  ",
  				d->name, pci_name(dev));
aea5d3756   Bartlomiej Zolnierkiewicz   ide: (hopefully) ...
98
99
  			return 0;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
100
  	}
aea5d3756   Bartlomiej Zolnierkiewicz   ide: (hopefully) ...
101
102
  	if (hwif->channel)
  		dma_base += 8;
ebb00fb55   Bartlomiej Zolnierkiewicz   ide: factor out s...
103
104
105
106
107
108
  	return dma_base;
  }
  EXPORT_SYMBOL_GPL(ide_pci_dma_base);
  
  int ide_pci_check_simplex(ide_hwif_t *hwif, const struct ide_port_info *d)
  {
28cfd8af5   Bartlomiej Zolnierkiewicz   ide: include PCI ...
109
  	struct pci_dev *dev = to_pci_dev(hwif->dev);
ebb00fb55   Bartlomiej Zolnierkiewicz   ide: factor out s...
110
111
112
  	u8 dma_stat;
  
  	if (d->host_flags & (IDE_HFLAG_MMIO | IDE_HFLAG_CS5520))
8ac2b42a4   Bartlomiej Zolnierkiewicz   ide: add IDE_HFLA...
113
114
115
  		goto out;
  
  	if (d->host_flags & IDE_HFLAG_CLEAR_SIMPLEX) {
28cfd8af5   Bartlomiej Zolnierkiewicz   ide: include PCI ...
116
117
118
119
  		if (ide_pci_clear_simplex(hwif->dma_base, d->name))
  			printk(KERN_INFO "%s %s: simplex device: DMA forced
  ",
  				d->name, pci_name(dev));
8ac2b42a4   Bartlomiej Zolnierkiewicz   ide: add IDE_HFLA...
120
121
122
123
124
125
126
127
128
129
130
131
132
  		goto out;
  	}
  
  	/*
  	 * If the device claims "simplex" DMA, this means that only one of
  	 * the two interfaces can be trusted with DMA at any point in time
  	 * (so we should enable DMA only on one of the two interfaces).
  	 *
  	 * FIXME: At this point we haven't probed the drives so we can't make
  	 * the appropriate decision.  Really we should defer this problem until
  	 * we tune the drive then try to grab DMA ownership if we want to be
  	 * the DMA end.  This has to be become dynamic to handle hot-plug.
  	 */
592b53152   Sergei Shtylyov   ide: move read_sf...
133
  	dma_stat = hwif->dma_ops->dma_sff_read_status(hwif);
8ac2b42a4   Bartlomiej Zolnierkiewicz   ide: add IDE_HFLA...
134
  	if ((dma_stat & 0x80) && hwif->mate && hwif->mate->dma_base) {
28cfd8af5   Bartlomiej Zolnierkiewicz   ide: include PCI ...
135
136
137
  		printk(KERN_INFO "%s %s: simplex device: DMA disabled
  ",
  			d->name, pci_name(dev));
ebb00fb55   Bartlomiej Zolnierkiewicz   ide: factor out s...
138
  		return -1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
139
  	}
8ac2b42a4   Bartlomiej Zolnierkiewicz   ide: add IDE_HFLA...
140
  out:
ebb00fb55   Bartlomiej Zolnierkiewicz   ide: factor out s...
141
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
142
  }
ebb00fb55   Bartlomiej Zolnierkiewicz   ide: factor out s...
143
  EXPORT_SYMBOL_GPL(ide_pci_check_simplex);
d54452fbf   Bartlomiej Zolnierkiewicz   ide: factor out s...
144
145
146
147
  
  /*
   * Set up BM-DMA capability (PnP BIOS should have done this)
   */
b123f56e0   Bartlomiej Zolnierkiewicz   ide: do complete ...
148
  int ide_pci_set_master(struct pci_dev *dev, const char *name)
d54452fbf   Bartlomiej Zolnierkiewicz   ide: factor out s...
149
150
151
152
153
154
155
156
157
158
  {
  	u16 pcicmd;
  
  	pci_read_config_word(dev, PCI_COMMAND, &pcicmd);
  
  	if ((pcicmd & PCI_COMMAND_MASTER) == 0) {
  		pci_set_master(dev);
  
  		if (pci_read_config_word(dev, PCI_COMMAND, &pcicmd) ||
  		    (pcicmd & PCI_COMMAND_MASTER) == 0) {
28cfd8af5   Bartlomiej Zolnierkiewicz   ide: include PCI ...
159
160
161
  			printk(KERN_ERR "%s %s: error updating PCICMD
  ",
  				name, pci_name(dev));
d54452fbf   Bartlomiej Zolnierkiewicz   ide: factor out s...
162
163
164
165
166
167
  			return -EIO;
  		}
  	}
  
  	return 0;
  }
b123f56e0   Bartlomiej Zolnierkiewicz   ide: do complete ...
168
  EXPORT_SYMBOL_GPL(ide_pci_set_master);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
169
  #endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
856204360   Bartlomiej Zolnierkiewicz   ide: constify str...
170
  void ide_setup_pci_noise(struct pci_dev *dev, const struct ide_port_info *d)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
171
  {
28cfd8af5   Bartlomiej Zolnierkiewicz   ide: include PCI ...
172
173
174
175
  	printk(KERN_INFO "%s %s: IDE controller (0x%04x:0x%04x rev 0x%02x)
  ",
  		d->name, pci_name(dev),
  		dev->vendor, dev->device, dev->revision);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
176
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
177
178
179
180
181
182
  EXPORT_SYMBOL_GPL(ide_setup_pci_noise);
  
  
  /**
   *	ide_pci_enable	-	do PCI enables
   *	@dev: PCI device
a06876a76   Bartlomiej Zolnierkiewicz   ide: pci: free PC...
183
   *	@bars: PCI BARs mask
039788e15   Bartlomiej Zolnierkiewicz   ide: replace ide_...
184
   *	@d: IDE port info
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
185
186
   *
   *	Enable the IDE PCI device. We attempt to enable the device in full
094839164   Benjamin Herrenschmidt   PCI: Remove users...
187
188
189
   *	but if that fails then we only need IO space. The PCI code should
   *	have setup the proper resources for us already for controllers in
   *	legacy mode.
846bb88ae   Paolo Ciarrocchi   IDE: Coding Style...
190
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
191
192
   *	Returns zero on success or an error code
   */
039788e15   Bartlomiej Zolnierkiewicz   ide: replace ide_...
193

a06876a76   Bartlomiej Zolnierkiewicz   ide: pci: free PC...
194
195
  static int ide_pci_enable(struct pci_dev *dev, int bars,
  			  const struct ide_port_info *d)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
196
  {
a06876a76   Bartlomiej Zolnierkiewicz   ide: pci: free PC...
197
  	int ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
198
199
  
  	if (pci_enable_device(dev)) {
094839164   Benjamin Herrenschmidt   PCI: Remove users...
200
  		ret = pci_enable_device_io(dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
201
  		if (ret < 0) {
28cfd8af5   Bartlomiej Zolnierkiewicz   ide: include PCI ...
202
203
204
  			printk(KERN_WARNING "%s %s: couldn't enable device
  ",
  				d->name, pci_name(dev));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
205
206
  			goto out;
  		}
28cfd8af5   Bartlomiej Zolnierkiewicz   ide: include PCI ...
207
208
209
  		printk(KERN_WARNING "%s %s: BIOS configuration fixed
  ",
  			d->name, pci_name(dev));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
210
211
212
  	}
  
  	/*
039788e15   Bartlomiej Zolnierkiewicz   ide: replace ide_...
213
214
215
  	 * assume all devices can do 32-bit DMA for now, we can add
  	 * a DMA mask field to the struct ide_port_info if we need it
  	 * (or let lower level driver set the DMA mask)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
216
  	 */
d681f1166   Quentin Lambert   ide: remove depre...
217
  	ret = dma_set_mask(&dev->dev, DMA_BIT_MASK(32));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
218
  	if (ret < 0) {
28cfd8af5   Bartlomiej Zolnierkiewicz   ide: include PCI ...
219
220
221
  		printk(KERN_ERR "%s %s: can't set DMA mask
  ",
  			d->name, pci_name(dev));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
222
223
  		goto out;
  	}
0d1bad216   Bartlomiej Zolnierkiewicz   ide: manage resou...
224
225
  	ret = pci_request_selected_regions(dev, bars, d->name);
  	if (ret < 0)
28cfd8af5   Bartlomiej Zolnierkiewicz   ide: include PCI ...
226
227
228
  		printk(KERN_ERR "%s %s: can't reserve resources
  ",
  			d->name, pci_name(dev));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
229
230
231
232
233
234
235
  out:
  	return ret;
  }
  
  /**
   *	ide_pci_configure	-	configure an unconfigured device
   *	@dev: PCI device
039788e15   Bartlomiej Zolnierkiewicz   ide: replace ide_...
236
   *	@d: IDE port info
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
237
238
239
240
   *
   *	Enable and configure the PCI device we have been passed.
   *	Returns zero on success or an error code.
   */
039788e15   Bartlomiej Zolnierkiewicz   ide: replace ide_...
241

856204360   Bartlomiej Zolnierkiewicz   ide: constify str...
242
  static int ide_pci_configure(struct pci_dev *dev, const struct ide_port_info *d)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
243
244
245
246
247
248
249
250
251
  {
  	u16 pcicmd = 0;
  	/*
  	 * PnP BIOS was *supposed* to have setup this device, but we
  	 * can do it ourselves, so long as the BIOS has assigned an IRQ
  	 * (or possibly the device is using a "legacy header" for IRQs).
  	 * Maybe the user deliberately *disabled* the device,
  	 * but we'll eventually ignore it again if no drives respond.
  	 */
846bb88ae   Paolo Ciarrocchi   IDE: Coding Style...
252
253
  	if (ide_setup_pci_baseregs(dev, d->name) ||
  	    pci_write_config_word(dev, PCI_COMMAND, pcicmd | PCI_COMMAND_IO)) {
28cfd8af5   Bartlomiej Zolnierkiewicz   ide: include PCI ...
254
255
256
  		printk(KERN_INFO "%s %s: device disabled (BIOS)
  ",
  			d->name, pci_name(dev));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
257
258
259
  		return -ENODEV;
  	}
  	if (pci_read_config_word(dev, PCI_COMMAND, &pcicmd)) {
28cfd8af5   Bartlomiej Zolnierkiewicz   ide: include PCI ...
260
261
262
  		printk(KERN_ERR "%s %s: error accessing PCI regs
  ",
  			d->name, pci_name(dev));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
263
264
265
  		return -EIO;
  	}
  	if (!(pcicmd & PCI_COMMAND_IO)) {
28cfd8af5   Bartlomiej Zolnierkiewicz   ide: include PCI ...
266
267
268
  		printk(KERN_ERR "%s %s: unable to enable IDE controller
  ",
  			d->name, pci_name(dev));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
269
270
271
272
273
274
275
  		return -ENXIO;
  	}
  	return 0;
  }
  
  /**
   *	ide_pci_check_iomem	-	check a register is I/O
039788e15   Bartlomiej Zolnierkiewicz   ide: replace ide_...
276
277
278
   *	@dev: PCI device
   *	@d: IDE port info
   *	@bar: BAR number
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
279
   *
1baccff8a   Sergei Shtylyov   ide: make ide_pci...
280
281
   *	Checks if a BAR is configured and points to MMIO space. If so,
   *	return an error code. Otherwise return 0
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
282
   */
039788e15   Bartlomiej Zolnierkiewicz   ide: replace ide_...
283

1baccff8a   Sergei Shtylyov   ide: make ide_pci...
284
285
  static int ide_pci_check_iomem(struct pci_dev *dev, const struct ide_port_info *d,
  			       int bar)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
286
287
  {
  	ulong flags = pci_resource_flags(dev, bar);
846bb88ae   Paolo Ciarrocchi   IDE: Coding Style...
288

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
289
290
291
  	/* Unconfigured ? */
  	if (!flags || pci_resource_len(dev, bar) == 0)
  		return 0;
1baccff8a   Sergei Shtylyov   ide: make ide_pci...
292
293
  	/* I/O space */
  	if (flags & IORESOURCE_IO)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
294
  		return 0;
846bb88ae   Paolo Ciarrocchi   IDE: Coding Style...
295

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
296
  	/* Bad */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
297
298
299
300
  	return -EINVAL;
  }
  
  /**
9f36d3143   Bartlomiej Zolnierkiewicz   ide: remove hw_re...
301
   *	ide_hw_configure	-	configure a struct ide_hw instance
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
302
   *	@dev: PCI device holding interface
039788e15   Bartlomiej Zolnierkiewicz   ide: replace ide_...
303
   *	@d: IDE port info
1ebf74936   Bartlomiej Zolnierkiewicz   ide: separate PCI...
304
   *	@port: port number
9f36d3143   Bartlomiej Zolnierkiewicz   ide: remove hw_re...
305
   *	@hw: struct ide_hw instance corresponding to this port
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
306
307
308
309
310
   *
   *	Perform the initial set up for the hardware interface structure. This
   *	is done per interface port rather than per PCI device. There may be
   *	more than one port per device.
   *
48c3c1072   Bartlomiej Zolnierkiewicz   ide: add struct i...
311
   *	Returns zero on success or an error code.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
312
   */
039788e15   Bartlomiej Zolnierkiewicz   ide: replace ide_...
313

48c3c1072   Bartlomiej Zolnierkiewicz   ide: add struct i...
314
  static int ide_hw_configure(struct pci_dev *dev, const struct ide_port_info *d,
9f36d3143   Bartlomiej Zolnierkiewicz   ide: remove hw_re...
315
  			    unsigned int port, struct ide_hw *hw)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
316
317
  {
  	unsigned long ctl = 0, base = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
318

a5d8c5c83   Bartlomiej Zolnierkiewicz   ide: add ide_pci_...
319
  	if ((d->host_flags & IDE_HFLAG_ISA_PORTS) == 0) {
1baccff8a   Sergei Shtylyov   ide: make ide_pci...
320
321
  		if (ide_pci_check_iomem(dev, d, 2 * port) ||
  		    ide_pci_check_iomem(dev, d, 2 * port + 1)) {
28cfd8af5   Bartlomiej Zolnierkiewicz   ide: include PCI ...
322
323
324
325
  			printk(KERN_ERR "%s %s: I/O baseregs (BIOS) are "
  				"reported as MEM for port %d!
  ",
  				d->name, pci_name(dev), port);
48c3c1072   Bartlomiej Zolnierkiewicz   ide: add struct i...
326
  			return -EINVAL;
1baccff8a   Sergei Shtylyov   ide: make ide_pci...
327
  		}
846bb88ae   Paolo Ciarrocchi   IDE: Coding Style...
328

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
329
330
  		ctl  = pci_resource_start(dev, 2*port+1);
  		base = pci_resource_start(dev, 2*port);
c1da678b5   Bartlomiej Zolnierkiewicz   ide: tighten chec...
331
  	} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
332
333
334
335
  		/* Use default values */
  		ctl = port ? 0x374 : 0x3f4;
  		base = port ? 0x170 : 0x1f0;
  	}
bad7c825c   Bartlomiej Zolnierkiewicz   ide: cleanup ide_...
336

c1da678b5   Bartlomiej Zolnierkiewicz   ide: tighten chec...
337
  	if (!base || !ctl) {
28cfd8af5   Bartlomiej Zolnierkiewicz   ide: include PCI ...
338
339
340
  		printk(KERN_ERR "%s %s: bad PCI BARs for port %d, skipping
  ",
  			d->name, pci_name(dev), port);
48c3c1072   Bartlomiej Zolnierkiewicz   ide: add struct i...
341
  		return -EINVAL;
c1da678b5   Bartlomiej Zolnierkiewicz   ide: tighten chec...
342
  	}
c97c6aca7   Bartlomiej Zolnierkiewicz   ide: pass hw_regs...
343
  	memset(hw, 0, sizeof(*hw));
c97c6aca7   Bartlomiej Zolnierkiewicz   ide: pass hw_regs...
344
  	hw->dev = &dev->dev;
c97c6aca7   Bartlomiej Zolnierkiewicz   ide: pass hw_regs...
345
  	ide_std_init_ports(hw, base, ctl | 2);
48c3c1072   Bartlomiej Zolnierkiewicz   ide: add struct i...
346
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
347
  }
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
348
  #ifdef CONFIG_BLK_DEV_IDEDMA_PCI
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
349
350
  /**
   *	ide_hwif_setup_dma	-	configure DMA interface
039788e15   Bartlomiej Zolnierkiewicz   ide: replace ide_...
351
   *	@hwif: IDE interface
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
352
   *	@d: IDE port info
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
353
354
355
356
357
   *
   *	Set up the DMA base for the interface. Enable the master bits as
   *	necessary and attempt to bring the device DMA into a ready to use
   *	state
   */
039788e15   Bartlomiej Zolnierkiewicz   ide: replace ide_...
358

b123f56e0   Bartlomiej Zolnierkiewicz   ide: do complete ...
359
  int ide_hwif_setup_dma(ide_hwif_t *hwif, const struct ide_port_info *d)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
360
  {
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
361
  	struct pci_dev *dev = to_pci_dev(hwif->dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
362

47b687882   Bartlomiej Zolnierkiewicz   ide: add IDE_HFLA...
363
  	if ((d->host_flags & IDE_HFLAG_NO_AUTODMA) == 0 ||
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
364
365
  	    ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE &&
  	     (dev->class & 0x80))) {
b123f56e0   Bartlomiej Zolnierkiewicz   ide: do complete ...
366
  		unsigned long base = ide_pci_dma_base(hwif, d);
d54452fbf   Bartlomiej Zolnierkiewicz   ide: factor out s...
367

ebb00fb55   Bartlomiej Zolnierkiewicz   ide: factor out s...
368
369
370
371
  		if (base == 0)
  			return -1;
  
  		hwif->dma_base = base;
592b53152   Sergei Shtylyov   ide: move read_sf...
372
373
  		if (hwif->dma_ops == NULL)
  			hwif->dma_ops = &sff_dma_ops;
ebb00fb55   Bartlomiej Zolnierkiewicz   ide: factor out s...
374
375
376
377
  		if (ide_pci_check_simplex(hwif, d) < 0)
  			return -1;
  
  		if (ide_pci_set_master(dev, d->name) < 0)
b123f56e0   Bartlomiej Zolnierkiewicz   ide: do complete ...
378
  			return -1;
d54452fbf   Bartlomiej Zolnierkiewicz   ide: factor out s...
379

135721446   Bartlomiej Zolnierkiewicz   ide: remove ->mmi...
380
  		if (hwif->host_flags & IDE_HFLAG_MMIO)
63158d5c2   Bartlomiej Zolnierkiewicz   ide: cleanup ide_...
381
382
383
384
385
386
387
388
  			printk(KERN_INFO "    %s: MMIO-DMA
  ", hwif->name);
  		else
  			printk(KERN_INFO "    %s: BM-DMA at 0x%04lx-0x%04lx
  ",
  					 hwif->name, base, base + 7);
  
  		hwif->extra_base = base + (hwif->channel ? 8 : 16);
b123f56e0   Bartlomiej Zolnierkiewicz   ide: do complete ...
389
390
  		if (ide_allocate_dma_engine(hwif))
  			return -1;
b123f56e0   Bartlomiej Zolnierkiewicz   ide: do complete ...
391
  	}
d54452fbf   Bartlomiej Zolnierkiewicz   ide: factor out s...
392

b123f56e0   Bartlomiej Zolnierkiewicz   ide: do complete ...
393
  	return 0;
039788e15   Bartlomiej Zolnierkiewicz   ide: replace ide_...
394
  }
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
395
  #endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
396
397
398
399
  
  /**
   *	ide_setup_pci_controller	-	set up IDE PCI
   *	@dev: PCI device
a06876a76   Bartlomiej Zolnierkiewicz   ide: pci: free PC...
400
   *	@bars: PCI BARs mask
039788e15   Bartlomiej Zolnierkiewicz   ide: replace ide_...
401
   *	@d: IDE port info
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
402
   *	@noisy: verbose flag
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
403
404
405
406
407
   *
   *	Set up the PCI and controller side of the IDE interface. This brings
   *	up the PCI side of the device, checks that the device is enabled
   *	and enables it if need be
   */
039788e15   Bartlomiej Zolnierkiewicz   ide: replace ide_...
408

a06876a76   Bartlomiej Zolnierkiewicz   ide: pci: free PC...
409
  static int ide_setup_pci_controller(struct pci_dev *dev, int bars,
a95925a30   Bartlomiej Zolnierkiewicz   ide: respect dev-...
410
  				    const struct ide_port_info *d, int noisy)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
411
412
  {
  	int ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
413
414
415
416
  	u16 pcicmd;
  
  	if (noisy)
  		ide_setup_pci_noise(dev, d);
a06876a76   Bartlomiej Zolnierkiewicz   ide: pci: free PC...
417
  	ret = ide_pci_enable(dev, bars, d);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
418
419
420
421
422
  	if (ret < 0)
  		goto out;
  
  	ret = pci_read_config_word(dev, PCI_COMMAND, &pcicmd);
  	if (ret < 0) {
28cfd8af5   Bartlomiej Zolnierkiewicz   ide: include PCI ...
423
424
425
  		printk(KERN_ERR "%s %s: error accessing PCI regs
  ",
  			d->name, pci_name(dev));
a06876a76   Bartlomiej Zolnierkiewicz   ide: pci: free PC...
426
  		goto out_free_bars;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
427
428
429
430
  	}
  	if (!(pcicmd & PCI_COMMAND_IO)) {	/* is device disabled? */
  		ret = ide_pci_configure(dev, d);
  		if (ret < 0)
a06876a76   Bartlomiej Zolnierkiewicz   ide: pci: free PC...
431
  			goto out_free_bars;
28cfd8af5   Bartlomiej Zolnierkiewicz   ide: include PCI ...
432
433
434
  		printk(KERN_INFO "%s %s: device enabled (Linux)
  ",
  			d->name, pci_name(dev));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
435
  	}
a06876a76   Bartlomiej Zolnierkiewicz   ide: pci: free PC...
436
437
438
439
  	goto out;
  
  out_free_bars:
  	pci_release_selected_regions(dev, bars);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
440
441
442
443
444
445
446
  out:
  	return ret;
  }
  
  /**
   *	ide_pci_setup_ports	-	configure ports/devices on PCI IDE
   *	@dev: PCI device
039788e15   Bartlomiej Zolnierkiewicz   ide: replace ide_...
447
   *	@d: IDE port info
9f36d3143   Bartlomiej Zolnierkiewicz   ide: remove hw_re...
448
449
   *	@hw: struct ide_hw instances corresponding to this PCI IDE device
   *	@hws: struct ide_hw pointers table to update
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
450
451
452
453
454
455
456
457
458
   *
   *	Scan the interfaces attached to this device and do any
   *	necessary per port setup. Attach the devices and ask the
   *	generic DMA layer to do its work for us.
   *
   *	Normally called automaticall from do_ide_pci_setup_device,
   *	but is also used directly as a helper function by some controllers
   *	where the chipset setup is not the default PCI IDE one.
   */
8447d9d52   Bartlomiej Zolnierkiewicz   ide: add ide_devi...
459

c97c6aca7   Bartlomiej Zolnierkiewicz   ide: pass hw_regs...
460
  void ide_pci_setup_ports(struct pci_dev *dev, const struct ide_port_info *d,
9f36d3143   Bartlomiej Zolnierkiewicz   ide: remove hw_re...
461
  			 struct ide_hw *hw, struct ide_hw **hws)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
462
  {
a5d8c5c83   Bartlomiej Zolnierkiewicz   ide: add ide_pci_...
463
  	int channels = (d->host_flags & IDE_HFLAG_SINGLE) ? 1 : 2, port;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
464
  	u8 tmp;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
465
466
467
  	/*
  	 * Set up the IDE ports
  	 */
cf6e854ef   Bartlomiej Zolnierkiewicz   ide: fix disabled...
468

a5d8c5c83   Bartlomiej Zolnierkiewicz   ide: add ide_pci_...
469
  	for (port = 0; port < channels; ++port) {
c0ae50234   Bartlomiej Zolnierkiewicz   ide: remove ide_p...
470
  		const struct ide_pci_enablebit *e = &d->enablebits[port];
856204360   Bartlomiej Zolnierkiewicz   ide: constify str...
471

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
472
  		if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) ||
cf6e854ef   Bartlomiej Zolnierkiewicz   ide: fix disabled...
473
  		    (tmp & e->mask) != e->val)) {
28cfd8af5   Bartlomiej Zolnierkiewicz   ide: include PCI ...
474
475
476
  			printk(KERN_INFO "%s %s: IDE port disabled
  ",
  				d->name, pci_name(dev));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
477
  			continue;	/* port not enabled */
cf6e854ef   Bartlomiej Zolnierkiewicz   ide: fix disabled...
478
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
479

86ccf37c6   Bartlomiej Zolnierkiewicz   ide: remove pciir...
480
  		if (ide_hw_configure(dev, d, port, hw + port))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
481
  			continue;
c97c6aca7   Bartlomiej Zolnierkiewicz   ide: pass hw_regs...
482
  		*(hws + port) = hw + port;
1ebf74936   Bartlomiej Zolnierkiewicz   ide: separate PCI...
483
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
484
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
485
486
487
488
489
490
491
492
493
  EXPORT_SYMBOL_GPL(ide_pci_setup_ports);
  
  /*
   * ide_setup_pci_device() looks at the primary/secondary interfaces
   * on a PCI IDE device and, if they are enabled, prepares the IDE driver
   * for use with them.  This generic code works for most PCI chipsets.
   *
   * One thing that is not standardized is the location of the
   * primary/secondary interface "enable/disable" bits.  For chipsets that
039788e15   Bartlomiej Zolnierkiewicz   ide: replace ide_...
494
   * we "know" about, this information is in the struct ide_port_info;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
495
496
   * for all other chipsets, we just assume both interfaces are enabled.
   */
039788e15   Bartlomiej Zolnierkiewicz   ide: replace ide_...
497
  static int do_ide_setup_pci_device(struct pci_dev *dev,
856204360   Bartlomiej Zolnierkiewicz   ide: constify str...
498
  				   const struct ide_port_info *d,
51d87ed0a   Bartlomiej Zolnierkiewicz   ide: move ide_pci...
499
  				   u8 noisy)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
500
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
501
  	int pciirq, ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
502
503
504
505
  	/*
  	 * Can we trust the reported IRQ?
  	 */
  	pciirq = dev->irq;
708e5f9eb   Bartlomiej Zolnierkiewicz   ide: always call ...
506
507
508
509
510
511
  	/*
  	 * This allows offboard ide-pci cards the enable a BIOS,
  	 * verify interrupt settings of split-mirror pci-config
  	 * space, place chipset into init-mode, and/or preserve
  	 * an interrupt if the card is not native ide support.
  	 */
a326b02b0   Bartlomiej Zolnierkiewicz   ide: drop 'name' ...
512
  	ret = d->init_chipset ? d->init_chipset(dev) : 0;
708e5f9eb   Bartlomiej Zolnierkiewicz   ide: always call ...
513
514
  	if (ret < 0)
  		goto out;
8c6de94cf   Bartlomiej Zolnierkiewicz   ide: use ide_pci_...
515
  	if (ide_pci_is_in_compatibility_mode(dev)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
516
  		if (noisy)
28cfd8af5   Bartlomiej Zolnierkiewicz   ide: include PCI ...
517
518
519
  			printk(KERN_INFO "%s %s: not 100%% native mode: will "
  				"probe irqs later
  ", d->name, pci_name(dev));
2ed0ef543   Bartlomiej Zolnierkiewicz   ide: fix ->init_c...
520
  		pciirq = 0;
28cfd8af5   Bartlomiej Zolnierkiewicz   ide: include PCI ...
521
522
523
524
525
526
527
528
  	} else if (!pciirq && noisy) {
  		printk(KERN_WARNING "%s %s: bad irq (%d): will probe later
  ",
  			d->name, pci_name(dev), pciirq);
  	} else if (noisy) {
  		printk(KERN_INFO "%s %s: 100%% native mode on irq %d
  ",
  			d->name, pci_name(dev), pciirq);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
529
  	}
51d87ed0a   Bartlomiej Zolnierkiewicz   ide: move ide_pci...
530
  	ret = pciirq;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
531
532
533
  out:
  	return ret;
  }
6cdf6eb35   Bartlomiej Zolnierkiewicz   ide: add ->dev an...
534
535
  int ide_pci_init_two(struct pci_dev *dev1, struct pci_dev *dev2,
  		     const struct ide_port_info *d, void *priv)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
536
537
  {
  	struct pci_dev *pdev[] = { dev1, dev2 };
6cdf6eb35   Bartlomiej Zolnierkiewicz   ide: add ->dev an...
538
  	struct ide_host *host;
a06876a76   Bartlomiej Zolnierkiewicz   ide: pci: free PC...
539
  	int ret, i, n_ports = dev2 ? 4 : 2, bars;
9f36d3143   Bartlomiej Zolnierkiewicz   ide: remove hw_re...
540
  	struct ide_hw hw[4], *hws[] = { NULL, NULL, NULL, NULL };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
541

a06876a76   Bartlomiej Zolnierkiewicz   ide: pci: free PC...
542
543
544
545
546
547
548
549
550
551
552
  	if (d->host_flags & IDE_HFLAG_SINGLE)
  		bars = (1 << 2) - 1;
  	else
  		bars = (1 << 4) - 1;
  
  	if ((d->host_flags & IDE_HFLAG_NO_DMA) == 0) {
  		if (d->host_flags & IDE_HFLAG_CS5520)
  			bars |= (1 << 2);
  		else
  			bars |= (1 << 4);
  	}
ad7c52d09   Bartlomiej Zolnierkiewicz   ide: re-implement...
553
  	for (i = 0; i < n_ports / 2; i++) {
a06876a76   Bartlomiej Zolnierkiewicz   ide: pci: free PC...
554
555
556
557
  		ret = ide_setup_pci_controller(pdev[i], bars, d, !i);
  		if (ret < 0) {
  			if (i == 1)
  				pci_release_selected_regions(pdev[0], bars);
a742d6cf0   Bartlomiej Zolnierkiewicz   ide: move ide_set...
558
  			goto out;
a06876a76   Bartlomiej Zolnierkiewicz   ide: pci: free PC...
559
  		}
a742d6cf0   Bartlomiej Zolnierkiewicz   ide: move ide_set...
560

86ccf37c6   Bartlomiej Zolnierkiewicz   ide: remove pciir...
561
  		ide_pci_setup_ports(pdev[i], d, &hw[i*2], &hws[i*2]);
6cdf6eb35   Bartlomiej Zolnierkiewicz   ide: add ->dev an...
562
  	}
8c2eece50   Bartlomiej Zolnierkiewicz   ide: call ide_pci...
563

ad7c52d09   Bartlomiej Zolnierkiewicz   ide: re-implement...
564
  	host = ide_host_alloc(d, hws, n_ports);
6cdf6eb35   Bartlomiej Zolnierkiewicz   ide: add ->dev an...
565
566
  	if (host == NULL) {
  		ret = -ENOMEM;
a06876a76   Bartlomiej Zolnierkiewicz   ide: pci: free PC...
567
  		goto out_free_bars;
6cdf6eb35   Bartlomiej Zolnierkiewicz   ide: add ->dev an...
568
569
570
  	}
  
  	host->dev[0] = &dev1->dev;
ad7c52d09   Bartlomiej Zolnierkiewicz   ide: re-implement...
571
572
  	if (dev2)
  		host->dev[1] = &dev2->dev;
6cdf6eb35   Bartlomiej Zolnierkiewicz   ide: add ->dev an...
573
574
  
  	host->host_priv = priv;
255115fb3   Bartlomiej Zolnierkiewicz   ide: allow host d...
575
  	host->irq_flags = IRQF_SHARED;
ef0b04276   Bartlomiej Zolnierkiewicz   ide: add ide_pci_...
576
  	pci_set_drvdata(pdev[0], host);
ad7c52d09   Bartlomiej Zolnierkiewicz   ide: re-implement...
577
578
  	if (dev2)
  		pci_set_drvdata(pdev[1], host);
6cdf6eb35   Bartlomiej Zolnierkiewicz   ide: add ->dev an...
579

ad7c52d09   Bartlomiej Zolnierkiewicz   ide: re-implement...
580
  	for (i = 0; i < n_ports / 2; i++) {
51d87ed0a   Bartlomiej Zolnierkiewicz   ide: move ide_pci...
581
  		ret = do_ide_setup_pci_device(pdev[i], d, !i);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
582
583
584
585
586
  		/*
  		 * FIXME: Mom, mom, they stole me the helper function to undo
  		 * do_ide_setup_pci_device() on the first device!
  		 */
  		if (ret < 0)
a06876a76   Bartlomiej Zolnierkiewicz   ide: pci: free PC...
587
  			goto out_free_bars;
51d87ed0a   Bartlomiej Zolnierkiewicz   ide: move ide_pci...
588

8c2eece50   Bartlomiej Zolnierkiewicz   ide: call ide_pci...
589
  		/* fixup IRQ */
f65dedfd7   Bartlomiej Zolnierkiewicz   ide: use ide_pci_...
590
  		if (ide_pci_is_in_compatibility_mode(pdev[i])) {
5bae8bf45   Bartlomiej Zolnierkiewicz   ide: use pci_get_...
591
592
  			hw[i*2].irq = pci_get_legacy_ide_irq(pdev[i], 0);
  			hw[i*2 + 1].irq = pci_get_legacy_ide_irq(pdev[i], 1);
f65dedfd7   Bartlomiej Zolnierkiewicz   ide: use ide_pci_...
593
594
  		} else
  			hw[i*2 + 1].irq = hw[i*2].irq = ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
595
  	}
6cdf6eb35   Bartlomiej Zolnierkiewicz   ide: add ->dev an...
596
597
598
  	ret = ide_host_register(host, d, hws);
  	if (ret)
  		ide_host_free(host);
a06876a76   Bartlomiej Zolnierkiewicz   ide: pci: free PC...
599
600
601
602
603
604
605
  	else
  		goto out;
  
  out_free_bars:
  	i = n_ports / 2;
  	while (i--)
  		pci_release_selected_regions(pdev[i], bars);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
606
607
608
  out:
  	return ret;
  }
6cdf6eb35   Bartlomiej Zolnierkiewicz   ide: add ->dev an...
609
  EXPORT_SYMBOL_GPL(ide_pci_init_two);
ef0b04276   Bartlomiej Zolnierkiewicz   ide: add ide_pci_...
610

ad7c52d09   Bartlomiej Zolnierkiewicz   ide: re-implement...
611
612
613
614
615
616
  int ide_pci_init_one(struct pci_dev *dev, const struct ide_port_info *d,
  		     void *priv)
  {
  	return ide_pci_init_two(dev, NULL, d, priv);
  }
  EXPORT_SYMBOL_GPL(ide_pci_init_one);
ef0b04276   Bartlomiej Zolnierkiewicz   ide: add ide_pci_...
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
  void ide_pci_remove(struct pci_dev *dev)
  {
  	struct ide_host *host = pci_get_drvdata(dev);
  	struct pci_dev *dev2 = host->dev[1] ? to_pci_dev(host->dev[1]) : NULL;
  	int bars;
  
  	if (host->host_flags & IDE_HFLAG_SINGLE)
  		bars = (1 << 2) - 1;
  	else
  		bars = (1 << 4) - 1;
  
  	if ((host->host_flags & IDE_HFLAG_NO_DMA) == 0) {
  		if (host->host_flags & IDE_HFLAG_CS5520)
  			bars |= (1 << 2);
  		else
  			bars |= (1 << 4);
  	}
  
  	ide_host_remove(host);
  
  	if (dev2)
  		pci_release_selected_regions(dev2, bars);
  	pci_release_selected_regions(dev, bars);
  
  	if (dev2)
  		pci_disable_device(dev2);
  	pci_disable_device(dev);
  }
  EXPORT_SYMBOL_GPL(ide_pci_remove);
feb22b7f8   Bartlomiej Zolnierkiewicz   ide: add proper P...
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
  
  #ifdef CONFIG_PM
  int ide_pci_suspend(struct pci_dev *dev, pm_message_t state)
  {
  	pci_save_state(dev);
  	pci_disable_device(dev);
  	pci_set_power_state(dev, pci_choose_state(dev, state));
  
  	return 0;
  }
  EXPORT_SYMBOL_GPL(ide_pci_suspend);
  
  int ide_pci_resume(struct pci_dev *dev)
  {
  	struct ide_host *host = pci_get_drvdata(dev);
  	int rc;
  
  	pci_set_power_state(dev, PCI_D0);
  
  	rc = pci_enable_device(dev);
  	if (rc)
  		return rc;
  
  	pci_restore_state(dev);
  	pci_set_master(dev);
  
  	if (host->init_chipset)
  		host->init_chipset(dev);
  
  	return 0;
  }
  EXPORT_SYMBOL_GPL(ide_pci_resume);
  #endif