Blame view

drivers/ide/sgiioc4.c 16.9 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
  /*
0271fc2db   Jeremy Higdon   [PATCH] Fix sgiio...
2
   * Copyright (c) 2003-2006 Silicon Graphics, Inc.  All Rights Reserved.
ccae50bcf   Sergei Shtylyov   sgiioc4: coding s...
3
   * Copyright (C) 2008-2009 MontaVista Software, Inc.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4
5
6
7
8
9
10
11
12
13
14
15
16
   *
   * This program is free software; you can redistribute it and/or modify it
   * under the terms of version 2 of the GNU General Public License
   * as published by the Free Software Foundation.
   *
   * This program is distributed in the hope that it would be useful, but
   * WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
   *
   * You should have received a copy of the GNU General Public
   * License along with this program; if not, write the Free Software
   * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
17
18
19
20
21
22
23
24
25
   * For further information regarding this notice, see:
   *
   * http://oss.sgi.com/projects/GenInfo/NoticeExplan
   */
  
  #include <linux/module.h>
  #include <linux/types.h>
  #include <linux/pci.h>
  #include <linux/delay.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
26
27
  #include <linux/init.h>
  #include <linux/kernel.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
28
29
  #include <linux/ioport.h>
  #include <linux/blkdev.h>
55c16a700   Jens Axboe   IDE: sg chaining ...
30
  #include <linux/scatterlist.h>
22329b511   Brent Casavant   [PATCH] ioc4: Cor...
31
  #include <linux/ioc4.h>
ccae50bcf   Sergei Shtylyov   sgiioc4: coding s...
32
  #include <linux/io.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
33
  #include <linux/ide.h>
ca1997c1f   Bartlomiej Zolnierkiewicz   sgiioc4: use ide_...
34
  #define DRV_NAME "SGIIOC4"
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
  /* IOC4 Specific Definitions */
  #define IOC4_CMD_OFFSET		0x100
  #define IOC4_CTRL_OFFSET	0x120
  #define IOC4_DMA_OFFSET		0x140
  #define IOC4_INTR_OFFSET	0x0
  
  #define IOC4_TIMING		0x00
  #define IOC4_DMA_PTR_L		0x01
  #define IOC4_DMA_PTR_H		0x02
  #define IOC4_DMA_ADDR_L		0x03
  #define IOC4_DMA_ADDR_H		0x04
  #define IOC4_BC_DEV		0x05
  #define IOC4_BC_MEM		0x06
  #define	IOC4_DMA_CTRL		0x07
  #define	IOC4_DMA_END_ADDR	0x08
  
  /* Bits in the IOC4 Control/Status Register */
  #define	IOC4_S_DMA_START	0x01
  #define	IOC4_S_DMA_STOP		0x02
  #define	IOC4_S_DMA_DIR		0x04
  #define	IOC4_S_DMA_ACTIVE	0x08
  #define	IOC4_S_DMA_ERROR	0x10
  #define	IOC4_ATA_MEMERR		0x02
  
  /* Read/Write Directions */
  #define	IOC4_DMA_WRITE		0x04
  #define	IOC4_DMA_READ		0x00
  
  /* Interrupt Register Offsets */
  #define IOC4_INTR_REG		0x03
  #define	IOC4_INTR_SET		0x05
  #define	IOC4_INTR_CLEAR		0x07
  
  #define IOC4_IDE_CACHELINE_SIZE	128
  #define IOC4_CMD_CTL_BLK_SIZE	0x20
  #define IOC4_SUPPORTED_FIRMWARE_REV 46
ccae50bcf   Sergei Shtylyov   sgiioc4: coding s...
71
  struct ioc4_dma_regs {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
72
73
74
75
76
77
78
79
80
  	u32 timing_reg0;
  	u32 timing_reg1;
  	u32 low_mem_ptr;
  	u32 high_mem_ptr;
  	u32 low_mem_addr;
  	u32 high_mem_addr;
  	u32 dev_byte_count;
  	u32 mem_byte_count;
  	u32 status;
ccae50bcf   Sergei Shtylyov   sgiioc4: coding s...
81
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
82
83
84
  
  /* Each Physical Region Descriptor Entry size is 16 bytes (2 * 64 bits) */
  /* IOC4 has only 1 IDE channel */
ccae50bcf   Sergei Shtylyov   sgiioc4: coding s...
85
86
  #define IOC4_PRD_BYTES		16
  #define IOC4_PRD_ENTRIES	(PAGE_SIZE / (4 * IOC4_PRD_BYTES))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
87

ccae50bcf   Sergei Shtylyov   sgiioc4: coding s...
88
89
90
91
  static void sgiioc4_init_hwif_ports(struct ide_hw *hw,
  				    unsigned long data_port,
  				    unsigned long ctrl_port,
  				    unsigned long irq_port)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
92
93
94
95
96
  {
  	unsigned long reg = data_port;
  	int i;
  
  	/* Registers are word (32 bit) aligned */
4c3032d8a   Bartlomiej Zolnierkiewicz   ide: add struct i...
97
98
  	for (i = 0; i <= 7; i++)
  		hw->io_ports_array[i] = reg + i * 4;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
99

8108b8823   Sergei Shtylyov   sgiioc4: kill use...
100
101
  	hw->io_ports.ctl_addr = ctrl_port;
  	hw->io_ports.irq_addr = irq_port;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
102
  }
ccae50bcf   Sergei Shtylyov   sgiioc4: coding s...
103
  static int sgiioc4_checkirq(ide_hwif_t *hwif)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
104
  {
ccae50bcf   Sergei Shtylyov   sgiioc4: coding s...
105
  	unsigned long intr_addr = hwif->io_ports.irq_addr + IOC4_INTR_REG * 4;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
106

ccae50bcf   Sergei Shtylyov   sgiioc4: coding s...
107
  	if (readl((void __iomem *)intr_addr) & 0x03)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
108
109
110
111
  		return 1;
  
  	return 0;
  }
b73c7ee25   Bartlomiej Zolnierkiewicz   ide: add ->read_s...
112
  static u8 sgiioc4_read_status(ide_hwif_t *);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
113

ccae50bcf   Sergei Shtylyov   sgiioc4: coding s...
114
  static int sgiioc4_clearirq(ide_drive_t *drive)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
115
116
  {
  	u32 intr_reg;
898ec223f   Bartlomiej Zolnierkiewicz   ide: remove HWIF(...
117
  	ide_hwif_t *hwif = drive->hwif;
4c3032d8a   Bartlomiej Zolnierkiewicz   ide: add struct i...
118
119
  	struct ide_io_ports *io_ports = &hwif->io_ports;
  	unsigned long other_ir = io_ports->irq_addr + (IOC4_INTR_REG << 2);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
120
121
  
  	/* Code to check for PCI error conditions */
0ecdca26e   Bartlomiej Zolnierkiewicz   ide: use PIO/MMIO...
122
  	intr_reg = readl((void __iomem *)other_ir);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
123
124
  	if (intr_reg & 0x03) { /* Valid IOC4-IDE interrupt */
  		/*
b73c7ee25   Bartlomiej Zolnierkiewicz   ide: add ->read_s...
125
126
  		 * Using sgiioc4_read_status to read the Status register has a
  		 * side effect of clearing the interrupt.  The first read should
23579a2a1   Bartlomiej Zolnierkiewicz   ide: remove IDE_*...
127
128
129
  		 * clear it if it is set.  The second read should return
  		 * a "clear" status if it got cleared.  If not, then spin
  		 * for a bit trying to clear it.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
130
  		 */
b73c7ee25   Bartlomiej Zolnierkiewicz   ide: add ->read_s...
131
  		u8 stat = sgiioc4_read_status(hwif);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
132
  		int count = 0;
b73c7ee25   Bartlomiej Zolnierkiewicz   ide: add ->read_s...
133
134
  
  		stat = sgiioc4_read_status(hwif);
aa95f0e76   Sergei Shtylylov   sgiioc4: sgiioc4_...
135
  		while ((stat & ATA_BUSY) && (count++ < 100)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
136
  			udelay(1);
b73c7ee25   Bartlomiej Zolnierkiewicz   ide: add ->read_s...
137
  			stat = sgiioc4_read_status(hwif);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
138
139
140
  		}
  
  		if (intr_reg & 0x02) {
36501650e   Bartlomiej Zolnierkiewicz   ide: keep pointer...
141
  			struct pci_dev *dev = to_pci_dev(hwif->dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
142
143
144
145
146
  			/* Error when transferring DMA data on PCI bus */
  			u32 pci_err_addr_low, pci_err_addr_high,
  			    pci_stat_cmd_reg;
  
  			pci_err_addr_low =
4c3032d8a   Bartlomiej Zolnierkiewicz   ide: add struct i...
147
  				readl((void __iomem *)io_ports->irq_addr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
148
  			pci_err_addr_high =
4c3032d8a   Bartlomiej Zolnierkiewicz   ide: add struct i...
149
  				readl((void __iomem *)(io_ports->irq_addr + 4));
36501650e   Bartlomiej Zolnierkiewicz   ide: keep pointer...
150
  			pci_read_config_dword(dev, PCI_COMMAND,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
151
  					      &pci_stat_cmd_reg);
ccae50bcf   Sergei Shtylyov   sgiioc4: coding s...
152
153
154
  			printk(KERN_ERR "%s(%s): PCI Bus Error when doing DMA: "
  			       "status-cmd reg is 0x%x
  ",
eb63963a5   Harvey Harrison   ide: replace rema...
155
  			       __func__, drive->name, pci_stat_cmd_reg);
ccae50bcf   Sergei Shtylyov   sgiioc4: coding s...
156
157
  			printk(KERN_ERR "%s(%s): PCI Error Address is 0x%x%x
  ",
eb63963a5   Harvey Harrison   ide: replace rema...
158
  			       __func__, drive->name,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
159
160
  			       pci_err_addr_high, pci_err_addr_low);
  			/* Clear the PCI Error indicator */
36501650e   Bartlomiej Zolnierkiewicz   ide: keep pointer...
161
  			pci_write_config_dword(dev, PCI_COMMAND, 0x00000146);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
162
163
164
  		}
  
  		/* Clear the Interrupt, Error bits on the IOC4 */
0ecdca26e   Bartlomiej Zolnierkiewicz   ide: use PIO/MMIO...
165
  		writel(0x03, (void __iomem *)other_ir);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
166

0ecdca26e   Bartlomiej Zolnierkiewicz   ide: use PIO/MMIO...
167
  		intr_reg = readl((void __iomem *)other_ir);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
168
169
170
171
  	}
  
  	return intr_reg & 3;
  }
5e37bdc08   Bartlomiej Zolnierkiewicz   ide: add struct i...
172
  static void sgiioc4_dma_start(ide_drive_t *drive)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
173
  {
898ec223f   Bartlomiej Zolnierkiewicz   ide: remove HWIF(...
174
  	ide_hwif_t *hwif = drive->hwif;
0ecdca26e   Bartlomiej Zolnierkiewicz   ide: use PIO/MMIO...
175
176
  	unsigned long ioc4_dma_addr = hwif->dma_base + IOC4_DMA_CTRL * 4;
  	unsigned int reg = readl((void __iomem *)ioc4_dma_addr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
177
  	unsigned int temp_reg = reg | IOC4_S_DMA_START;
0ecdca26e   Bartlomiej Zolnierkiewicz   ide: use PIO/MMIO...
178
  	writel(temp_reg, (void __iomem *)ioc4_dma_addr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
179
  }
ccae50bcf   Sergei Shtylyov   sgiioc4: coding s...
180
  static u32 sgiioc4_ide_dma_stop(ide_hwif_t *hwif, u64 dma_base)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
181
  {
0ecdca26e   Bartlomiej Zolnierkiewicz   ide: use PIO/MMIO...
182
  	unsigned long ioc4_dma_addr = dma_base + IOC4_DMA_CTRL * 4;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
183
184
185
186
  	u32	ioc4_dma;
  	int	count;
  
  	count = 0;
0ecdca26e   Bartlomiej Zolnierkiewicz   ide: use PIO/MMIO...
187
  	ioc4_dma = readl((void __iomem *)ioc4_dma_addr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
188
189
  	while ((ioc4_dma & IOC4_S_DMA_STOP) && (count++ < 200)) {
  		udelay(1);
0ecdca26e   Bartlomiej Zolnierkiewicz   ide: use PIO/MMIO...
190
  		ioc4_dma = readl((void __iomem *)ioc4_dma_addr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
191
192
193
194
195
  	}
  	return ioc4_dma;
  }
  
  /* Stops the IOC4 DMA Engine */
5e37bdc08   Bartlomiej Zolnierkiewicz   ide: add struct i...
196
  static int sgiioc4_dma_end(ide_drive_t *drive)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
197
198
  {
  	u32 ioc4_dma, bc_dev, bc_mem, num, valid = 0, cnt = 0;
898ec223f   Bartlomiej Zolnierkiewicz   ide: remove HWIF(...
199
  	ide_hwif_t *hwif = drive->hwif;
0ecdca26e   Bartlomiej Zolnierkiewicz   ide: use PIO/MMIO...
200
  	unsigned long dma_base = hwif->dma_base;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
201
  	int dma_stat = 0;
3f63c5e88   Sergei Shtylyov   [PATCH] ide: remo...
202
  	unsigned long *ending_dma = ide_get_hwifdata(hwif);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
203

0ecdca26e   Bartlomiej Zolnierkiewicz   ide: use PIO/MMIO...
204
  	writel(IOC4_S_DMA_STOP, (void __iomem *)(dma_base + IOC4_DMA_CTRL * 4));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
205
206
207
208
209
210
211
212
  
  	ioc4_dma = sgiioc4_ide_dma_stop(hwif, dma_base);
  
  	if (ioc4_dma & IOC4_S_DMA_STOP) {
  		printk(KERN_ERR
  		       "%s(%s): IOC4 DMA STOP bit is still 1 :"
  		       "ioc4_dma_reg 0x%x
  ",
eb63963a5   Harvey Harrison   ide: replace rema...
213
  		       __func__, drive->name, ioc4_dma);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
214
215
216
217
  		dma_stat = 1;
  	}
  
  	/*
ccae50bcf   Sergei Shtylyov   sgiioc4: coding s...
218
  	 * The IOC4 will DMA 1's to the ending DMA area to indicate that
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
219
220
221
222
223
224
225
226
227
228
229
230
231
  	 * previous data DMA is complete.  This is necessary because of relaxed
  	 * ordering between register reads and DMA writes on the Altix.
  	 */
  	while ((cnt++ < 200) && (!valid)) {
  		for (num = 0; num < 16; num++) {
  			if (ending_dma[num]) {
  				valid = 1;
  				break;
  			}
  		}
  		udelay(1);
  	}
  	if (!valid) {
eb63963a5   Harvey Harrison   ide: replace rema...
232
233
  		printk(KERN_ERR "%s(%s) : DMA incomplete
  ", __func__,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
234
235
236
  		       drive->name);
  		dma_stat = 1;
  	}
0ecdca26e   Bartlomiej Zolnierkiewicz   ide: use PIO/MMIO...
237
238
  	bc_dev = readl((void __iomem *)(dma_base + IOC4_BC_DEV * 4));
  	bc_mem = readl((void __iomem *)(dma_base + IOC4_BC_MEM * 4));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
239
240
241
242
243
244
245
  
  	if ((bc_dev & 0x01FF) || (bc_mem & 0x1FF)) {
  		if (bc_dev > bc_mem + 8) {
  			printk(KERN_ERR
  			       "%s(%s): WARNING!! byte_count_dev %d "
  			       "!= byte_count_mem %d
  ",
eb63963a5   Harvey Harrison   ide: replace rema...
246
  			       __func__, drive->name, bc_dev, bc_mem);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
247
248
  		}
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
249
250
  	return dma_stat;
  }
8776168ca   Bartlomiej Zolnierkiewicz   ide: change ->set...
251
  static void sgiioc4_set_dma_mode(ide_hwif_t *hwif, ide_drive_t *drive)
ca1997c1f   Bartlomiej Zolnierkiewicz   sgiioc4: use ide_...
252
  {
ca1997c1f   Bartlomiej Zolnierkiewicz   sgiioc4: use ide_...
253
  }
ccae50bcf   Sergei Shtylyov   sgiioc4: coding s...
254
  /* Returns 1 if DMA IRQ issued, 0 otherwise */
5e37bdc08   Bartlomiej Zolnierkiewicz   ide: add struct i...
255
  static int sgiioc4_dma_test_irq(ide_drive_t *drive)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
256
  {
898ec223f   Bartlomiej Zolnierkiewicz   ide: remove HWIF(...
257
  	return sgiioc4_checkirq(drive->hwif);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
258
  }
15ce926ad   Bartlomiej Zolnierkiewicz   ide: merge ->dma_...
259
  static void sgiioc4_dma_host_set(ide_drive_t *drive, int on)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
260
  {
15ce926ad   Bartlomiej Zolnierkiewicz   ide: merge ->dma_...
261
262
  	if (!on)
  		sgiioc4_clearirq(drive);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
263
  }
f094d4d83   Bartlomiej Zolnierkiewicz   ide: sanitize ide...
264
  static void sgiioc4_resetproc(ide_drive_t *drive)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
265
  {
f094d4d83   Bartlomiej Zolnierkiewicz   ide: sanitize ide...
266
  	struct ide_cmd *cmd = &drive->hwif->cmd;
5e37bdc08   Bartlomiej Zolnierkiewicz   ide: add struct i...
267
  	sgiioc4_dma_end(drive);
f094d4d83   Bartlomiej Zolnierkiewicz   ide: sanitize ide...
268
  	ide_dma_unmap_sg(drive, cmd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
269
270
  	sgiioc4_clearirq(drive);
  }
ccae50bcf   Sergei Shtylyov   sgiioc4: coding s...
271
  static void sgiioc4_dma_lost_irq(ide_drive_t *drive)
841d2a9bf   Sergei Shtylyov   ide: make void an...
272
273
274
275
276
  {
  	sgiioc4_resetproc(drive);
  
  	ide_dma_lost_irq(drive);
  }
b73c7ee25   Bartlomiej Zolnierkiewicz   ide: add ->read_s...
277
  static u8 sgiioc4_read_status(ide_hwif_t *hwif)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
278
  {
b73c7ee25   Bartlomiej Zolnierkiewicz   ide: add ->read_s...
279
  	unsigned long port = hwif->io_ports.status_addr;
a835fa798   Jeremy Higdon   [PATCH] sgiioc4: ...
280
  	u8 reg = (u8) readb((void __iomem *) port);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
281

8108b8823   Sergei Shtylyov   sgiioc4: kill use...
282
283
284
  	if (!(reg & ATA_BUSY)) {	/* Not busy... check for interrupt */
  		unsigned long other_ir = port - 0x110;
  		unsigned int intr_reg = (u32) readl((void __iomem *) other_ir);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
285

8108b8823   Sergei Shtylyov   sgiioc4: kill use...
286
287
288
289
  		/* Clear the Interrupt, Error bits on the IOC4 */
  		if (intr_reg & 0x03) {
  			writel(0x03, (void __iomem *) other_ir);
  			intr_reg = (u32) readl((void __iomem *) other_ir);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
290
291
292
293
294
  		}
  	}
  
  	return reg;
  }
ccae50bcf   Sergei Shtylyov   sgiioc4: coding s...
295
296
297
  /* Creates a DMA map for the scatter-gather list entries */
  static int __devinit ide_dma_sgiioc4(ide_hwif_t *hwif,
  				     const struct ide_port_info *d)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
298
  {
36501650e   Bartlomiej Zolnierkiewicz   ide: keep pointer...
299
  	struct pci_dev *dev = to_pci_dev(hwif->dev);
04216fa1b   Bartlomiej Zolnierkiewicz   sgiioc4: use ->in...
300
  	unsigned long dma_base = pci_resource_start(dev, 0) + IOC4_DMA_OFFSET;
ccae50bcf   Sergei Shtylyov   sgiioc4: coding s...
301
  	int num_ports = sizeof(struct ioc4_dma_regs);
3f63c5e88   Sergei Shtylyov   [PATCH] ide: remo...
302
  	void *pad;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
303

9b5a18e19   Sergei Shtylylov   sgiioc4: fix mess...
304
305
  	printk(KERN_INFO "    %s: MMIO-DMA
  ", hwif->name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
306

9b5a18e19   Sergei Shtylylov   sgiioc4: fix mess...
307
308
309
310
311
  	if (request_mem_region(dma_base, num_ports, hwif->name) == NULL) {
  		printk(KERN_ERR "%s(%s) -- ERROR: addresses 0x%08lx to 0x%08lx "
  		       "already in use
  ", __func__, hwif->name,
  		       dma_base, dma_base + num_ports - 1);
ca1997c1f   Bartlomiej Zolnierkiewicz   sgiioc4: use ide_...
312
  		return -1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
313
  	}
107111d45   Sergei Shtylyov   sgiioc4: kill dup...
314
315
  	hwif->dma_base = (unsigned long)hwif->io_ports.irq_addr +
  			 IOC4_DMA_OFFSET;
1678df37b   John Keller   [PATCH] sgiioc4: ...
316

2bbd57cad   Bartlomiej Zolnierkiewicz   ide: switch to DM...
317
  	hwif->sg_max_nents = IOC4_PRD_ENTRIES;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
318

2bbd57cad   Bartlomiej Zolnierkiewicz   ide: switch to DM...
319
320
  	hwif->prd_max_nents = IOC4_PRD_ENTRIES;
  	hwif->prd_ent_size = IOC4_PRD_BYTES;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
321

2bbd57cad   Bartlomiej Zolnierkiewicz   ide: switch to DM...
322
323
  	if (ide_allocate_dma_engine(hwif))
  		goto dma_pci_alloc_failure;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
324

36501650e   Bartlomiej Zolnierkiewicz   ide: keep pointer...
325
  	pad = pci_alloc_consistent(dev, IOC4_IDE_CACHELINE_SIZE,
912ef6d94   Bartlomiej Zolnierkiewicz   sgiioc4: use ->ex...
326
  				   (dma_addr_t *)&hwif->extra_base);
3f63c5e88   Sergei Shtylyov   [PATCH] ide: remo...
327
328
  	if (pad) {
  		ide_set_hwifdata(hwif, pad);
ca1997c1f   Bartlomiej Zolnierkiewicz   sgiioc4: use ide_...
329
  		return 0;
3f63c5e88   Sergei Shtylyov   [PATCH] ide: remo...
330
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
331

2bbd57cad   Bartlomiej Zolnierkiewicz   ide: switch to DM...
332
  	ide_release_dma_engine(hwif);
9b5a18e19   Sergei Shtylylov   sgiioc4: fix mess...
333
334
  	printk(KERN_ERR "%s(%s) -- ERROR: Unable to allocate DMA maps
  ",
eb63963a5   Harvey Harrison   ide: replace rema...
335
  	       __func__, hwif->name);
9b5a18e19   Sergei Shtylylov   sgiioc4: fix mess...
336
  	printk(KERN_INFO "%s: changing from DMA to PIO mode", hwif->name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
337

1678df37b   John Keller   [PATCH] sgiioc4: ...
338
  dma_pci_alloc_failure:
1678df37b   John Keller   [PATCH] sgiioc4: ...
339
  	release_mem_region(dma_base, num_ports);
ca1997c1f   Bartlomiej Zolnierkiewicz   sgiioc4: use ide_...
340
  	return -1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
341
342
343
  }
  
  /* Initializes the IOC4 DMA Engine */
ccae50bcf   Sergei Shtylyov   sgiioc4: coding s...
344
  static void sgiioc4_configure_for_dma(int dma_direction, ide_drive_t *drive)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
345
346
  {
  	u32 ioc4_dma;
898ec223f   Bartlomiej Zolnierkiewicz   ide: remove HWIF(...
347
  	ide_hwif_t *hwif = drive->hwif;
0ecdca26e   Bartlomiej Zolnierkiewicz   ide: use PIO/MMIO...
348
349
  	unsigned long dma_base = hwif->dma_base;
  	unsigned long ioc4_dma_addr = dma_base + IOC4_DMA_CTRL * 4;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
350
  	u32 dma_addr, ending_dma_addr;
0ecdca26e   Bartlomiej Zolnierkiewicz   ide: use PIO/MMIO...
351
  	ioc4_dma = readl((void __iomem *)ioc4_dma_addr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
352
353
  
  	if (ioc4_dma & IOC4_S_DMA_ACTIVE) {
ccae50bcf   Sergei Shtylyov   sgiioc4: coding s...
354
355
356
  		printk(KERN_WARNING "%s(%s): Warning!! DMA from previous "
  		       "transfer was still active
  ", __func__, drive->name);
0ecdca26e   Bartlomiej Zolnierkiewicz   ide: use PIO/MMIO...
357
  		writel(IOC4_S_DMA_STOP, (void __iomem *)ioc4_dma_addr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
358
359
360
  		ioc4_dma = sgiioc4_ide_dma_stop(hwif, dma_base);
  
  		if (ioc4_dma & IOC4_S_DMA_STOP)
ccae50bcf   Sergei Shtylyov   sgiioc4: coding s...
361
362
363
  			printk(KERN_ERR "%s(%s): IOC4 DMA STOP bit is "
  			       "still 1
  ", __func__, drive->name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
364
  	}
0ecdca26e   Bartlomiej Zolnierkiewicz   ide: use PIO/MMIO...
365
  	ioc4_dma = readl((void __iomem *)ioc4_dma_addr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
366
  	if (ioc4_dma & IOC4_S_DMA_ERROR) {
ccae50bcf   Sergei Shtylyov   sgiioc4: coding s...
367
368
369
  		printk(KERN_WARNING "%s(%s): Warning!! DMA Error during "
  		       "previous transfer, status 0x%x
  ",
eb63963a5   Harvey Harrison   ide: replace rema...
370
  		       __func__, drive->name, ioc4_dma);
0ecdca26e   Bartlomiej Zolnierkiewicz   ide: use PIO/MMIO...
371
  		writel(IOC4_S_DMA_STOP, (void __iomem *)ioc4_dma_addr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
372
373
374
  		ioc4_dma = sgiioc4_ide_dma_stop(hwif, dma_base);
  
  		if (ioc4_dma & IOC4_S_DMA_STOP)
ccae50bcf   Sergei Shtylyov   sgiioc4: coding s...
375
376
377
  			printk(KERN_ERR "%s(%s): IOC4 DMA STOP bit is "
  			       "still 1
  ", __func__, drive->name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
378
379
380
381
  	}
  
  	/* Address of the Scatter Gather List */
  	dma_addr = cpu_to_le32(hwif->dmatable_dma);
0ecdca26e   Bartlomiej Zolnierkiewicz   ide: use PIO/MMIO...
382
  	writel(dma_addr, (void __iomem *)(dma_base + IOC4_DMA_PTR_L * 4));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
383
384
  
  	/* Address of the Ending DMA */
3f63c5e88   Sergei Shtylyov   [PATCH] ide: remo...
385
  	memset(ide_get_hwifdata(hwif), 0, IOC4_IDE_CACHELINE_SIZE);
912ef6d94   Bartlomiej Zolnierkiewicz   sgiioc4: use ->ex...
386
  	ending_dma_addr = cpu_to_le32(hwif->extra_base);
ccae50bcf   Sergei Shtylyov   sgiioc4: coding s...
387
388
  	writel(ending_dma_addr, (void __iomem *)(dma_base +
  						 IOC4_DMA_END_ADDR * 4));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
389

0ecdca26e   Bartlomiej Zolnierkiewicz   ide: use PIO/MMIO...
390
  	writel(dma_direction, (void __iomem *)ioc4_dma_addr);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
391
  }
ccae50bcf   Sergei Shtylyov   sgiioc4: coding s...
392
  /* IOC4 Scatter Gather list Format					 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
393
394
395
  /* 128 Bit entries to support 64 bit addresses in the future		 */
  /* The Scatter Gather list Entry should be in the BIG-ENDIAN Format	 */
  /* --------------------------------------------------------------------- */
ccae50bcf   Sergei Shtylyov   sgiioc4: coding s...
396
  /* | Upper 32 bits - Zero	    |		Lower 32 bits- address | */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
397
398
399
  /* --------------------------------------------------------------------- */
  /* | Upper 32 bits - Zero	    |EOL| 15 unused     | 16 Bit Length| */
  /* --------------------------------------------------------------------- */
ccae50bcf   Sergei Shtylyov   sgiioc4: coding s...
400
  /* Creates the scatter gather list, DMA Table				 */
229816941   Bartlomiej Zolnierkiewicz   ide: pass command...
401
  static int sgiioc4_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
402
  {
898ec223f   Bartlomiej Zolnierkiewicz   ide: remove HWIF(...
403
  	ide_hwif_t *hwif = drive->hwif;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
404
  	unsigned int *table = hwif->dmatable_cpu;
229816941   Bartlomiej Zolnierkiewicz   ide: pass command...
405
  	unsigned int count = 0, i = cmd->sg_nents;
e6830a86c   Bartlomiej Zolnierkiewicz   ide: call ide_bui...
406
  	struct scatterlist *sg = hwif->sg_table;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
407

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
408
409
410
411
412
413
414
415
416
417
418
419
  	while (i && sg_dma_len(sg)) {
  		dma_addr_t cur_addr;
  		int cur_len;
  		cur_addr = sg_dma_address(sg);
  		cur_len = sg_dma_len(sg);
  
  		while (cur_len) {
  			if (count++ >= IOC4_PRD_ENTRIES) {
  				printk(KERN_WARNING
  				       "%s: DMA table too small
  ",
  				       drive->name);
11998b316   Bartlomiej Zolnierkiewicz   ide: move ide_map...
420
  				return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
421
  			} else {
0271fc2db   Jeremy Higdon   [PATCH] Fix sgiio...
422
  				u32 bcount =
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
423
424
425
426
  				    0x10000 - (cur_addr & 0xffff);
  
  				if (bcount > cur_len)
  					bcount = cur_len;
ccae50bcf   Sergei Shtylyov   sgiioc4: coding s...
427
428
429
430
  				/*
  				 * Put the address, length in
  				 * the IOC4 dma-table format
  				 */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
431
432
433
434
435
436
  				*table = 0x0;
  				table++;
  				*table = cpu_to_be32(cur_addr);
  				table++;
  				*table = 0x0;
  				table++;
0271fc2db   Jeremy Higdon   [PATCH] Fix sgiio...
437
  				*table = cpu_to_be32(bcount);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
438
439
440
441
442
443
  				table++;
  
  				cur_addr += bcount;
  				cur_len -= bcount;
  			}
  		}
55c16a700   Jens Axboe   IDE: sg chaining ...
444
  		sg = sg_next(sg);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
445
446
447
448
449
450
451
452
  		i--;
  	}
  
  	if (count) {
  		table--;
  		*table |= cpu_to_be32(0x80000000);
  		return count;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
453
454
  	return 0;		/* revert to PIO for this request */
  }
229816941   Bartlomiej Zolnierkiewicz   ide: pass command...
455
  static int sgiioc4_dma_setup(ide_drive_t *drive, struct ide_cmd *cmd)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
456
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
457
  	int ddir;
229816941   Bartlomiej Zolnierkiewicz   ide: pass command...
458
  	u8 write = !!(cmd->tf_flags & IDE_TFLAG_WRITE);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
459

11998b316   Bartlomiej Zolnierkiewicz   ide: move ide_map...
460
  	if (sgiioc4_build_dmatable(drive, cmd) == 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
461
  		/* try PIO instead of DMA */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
462
  		return 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
463

229816941   Bartlomiej Zolnierkiewicz   ide: pass command...
464
  	if (write)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
465
466
467
468
469
470
471
472
473
474
  		/* Writes TO the IOC4 FROM Main Memory */
  		ddir = IOC4_DMA_READ;
  	else
  		/* Writes FROM the IOC4 TO Main Memory */
  		ddir = IOC4_DMA_WRITE;
  
  	sgiioc4_configure_for_dma(ddir, drive);
  
  	return 0;
  }
374e042c3   Bartlomiej Zolnierkiewicz   ide: add struct i...
475
476
477
478
  static const struct ide_tp_ops sgiioc4_tp_ops = {
  	.exec_command		= ide_exec_command,
  	.read_status		= sgiioc4_read_status,
  	.read_altstatus		= ide_read_altstatus,
ecf3a31d2   Sergei Shtylyov   ide: turn set_irq...
479
  	.write_devctl		= ide_write_devctl,
374e042c3   Bartlomiej Zolnierkiewicz   ide: add struct i...
480

abb596b25   Sergei Shtylyov   ide: turn selectp...
481
  	.dev_select		= ide_dev_select,
374e042c3   Bartlomiej Zolnierkiewicz   ide: add struct i...
482
483
484
485
486
487
  	.tf_load		= ide_tf_load,
  	.tf_read		= ide_tf_read,
  
  	.input_data		= ide_input_data,
  	.output_data		= ide_output_data,
  };
ac95beedf   Bartlomiej Zolnierkiewicz   ide: add struct i...
488
489
490
491
  static const struct ide_port_ops sgiioc4_port_ops = {
  	.set_dma_mode		= sgiioc4_set_dma_mode,
  	/* reset DMA engine, clear IRQs */
  	.resetproc		= sgiioc4_resetproc,
ac95beedf   Bartlomiej Zolnierkiewicz   ide: add struct i...
492
  };
f37afdaca   Bartlomiej Zolnierkiewicz   ide: constify str...
493
  static const struct ide_dma_ops sgiioc4_dma_ops = {
5e37bdc08   Bartlomiej Zolnierkiewicz   ide: add struct i...
494
495
496
497
498
499
  	.dma_host_set		= sgiioc4_dma_host_set,
  	.dma_setup		= sgiioc4_dma_setup,
  	.dma_start		= sgiioc4_dma_start,
  	.dma_end		= sgiioc4_dma_end,
  	.dma_test_irq		= sgiioc4_dma_test_irq,
  	.dma_lost_irq		= sgiioc4_dma_lost_irq,
5e37bdc08   Bartlomiej Zolnierkiewicz   ide: add struct i...
500
  };
ecdbc6906   Robin Holt   [IA64] Clear up s...
501
  static const struct ide_port_info sgiioc4_port_info __devinitconst = {
eb3aff553   Bartlomiej Zolnierkiewicz   ide: print messag...
502
  	.name			= DRV_NAME,
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
503
  	.chipset		= ide_pci,
04216fa1b   Bartlomiej Zolnierkiewicz   sgiioc4: use ->in...
504
  	.init_dma		= ide_dma_sgiioc4,
374e042c3   Bartlomiej Zolnierkiewicz   ide: add struct i...
505
  	.tp_ops			= &sgiioc4_tp_ops,
ac95beedf   Bartlomiej Zolnierkiewicz   ide: add struct i...
506
  	.port_ops		= &sgiioc4_port_ops,
5e37bdc08   Bartlomiej Zolnierkiewicz   ide: add struct i...
507
  	.dma_ops		= &sgiioc4_dma_ops,
c5dd43ec6   Bartlomiej Zolnierkiewicz   ide: add IDE_HFLA...
508
  	.host_flags		= IDE_HFLAG_MMIO,
255115fb3   Bartlomiej Zolnierkiewicz   ide: allow host d...
509
  	.irq_flags		= IRQF_SHARED,
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
510
511
  	.mwdma_mask		= ATA_MWDMA2_ONLY,
  };
ccae50bcf   Sergei Shtylyov   sgiioc4: coding s...
512
  static int __devinit sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
513
  {
04216fa1b   Bartlomiej Zolnierkiewicz   sgiioc4: use ->in...
514
  	unsigned long cmd_base, irqport;
1678df37b   John Keller   [PATCH] sgiioc4: ...
515
516
  	unsigned long bar0, cmd_phys_base, ctl;
  	void __iomem *virt_base;
9f36d3143   Bartlomiej Zolnierkiewicz   ide: remove hw_re...
517
  	struct ide_hw hw, *hws[] = { &hw };
8a69580e1   Bartlomiej Zolnierkiewicz   ide: add ide_host...
518
  	int rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
519

ccae50bcf   Sergei Shtylyov   sgiioc4: coding s...
520
  	/* Get the CmdBlk and CtrlBlk base registers */
1678df37b   John Keller   [PATCH] sgiioc4: ...
521
  	bar0 = pci_resource_start(dev, 0);
283435621   Arjan van de Ven   pci: use pci_iore...
522
  	virt_base = pci_ioremap_bar(dev, 0);
1678df37b   John Keller   [PATCH] sgiioc4: ...
523
524
525
  	if (virt_base == NULL) {
  		printk(KERN_ERR "%s: Unable to remap BAR 0 address: 0x%lx
  ",
ca1997c1f   Bartlomiej Zolnierkiewicz   sgiioc4: use ide_...
526
  				DRV_NAME, bar0);
1678df37b   John Keller   [PATCH] sgiioc4: ...
527
528
  		return -ENOMEM;
  	}
ccae50bcf   Sergei Shtylyov   sgiioc4: coding s...
529
530
531
  	cmd_base = (unsigned long)virt_base + IOC4_CMD_OFFSET;
  	ctl = (unsigned long)virt_base + IOC4_CTRL_OFFSET;
  	irqport = (unsigned long)virt_base + IOC4_INTR_OFFSET;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
532

1678df37b   John Keller   [PATCH] sgiioc4: ...
533
  	cmd_phys_base = bar0 + IOC4_CMD_OFFSET;
9b5a18e19   Sergei Shtylylov   sgiioc4: fix mess...
534
535
536
537
538
539
  	if (request_mem_region(cmd_phys_base, IOC4_CMD_CTL_BLK_SIZE,
  			       DRV_NAME) == NULL) {
  		printk(KERN_ERR "%s %s -- ERROR: addresses 0x%08lx to 0x%08lx "
  		       "already in use
  ", DRV_NAME, pci_name(dev),
  		       cmd_phys_base, cmd_phys_base + IOC4_CMD_CTL_BLK_SIZE);
3059ef99a   Sergei Shtylyov   sgiioc4: fix erro...
540
541
  		rc = -EBUSY;
  		goto req_mem_rgn_err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
542
  	}
8f8e8483f   Bartlomiej Zolnierkiewicz   sgiioc4: always i...
543
544
545
  	/* Initialize the IO registers */
  	memset(&hw, 0, sizeof(hw));
  	sgiioc4_init_hwif_ports(&hw, cmd_base, ctl, irqport);
57c802e84   Bartlomiej Zolnierkiewicz   ide: add ide_init...
546
  	hw.irq = dev->irq;
57c802e84   Bartlomiej Zolnierkiewicz   ide: add ide_init...
547
  	hw.dev = &dev->dev;
ce30e4015   Bartlomiej Zolnierkiewicz   sgiioc4: call ide...
548

ccae50bcf   Sergei Shtylyov   sgiioc4: coding s...
549
  	/* Initialize chipset IRQ registers */
0ecdca26e   Bartlomiej Zolnierkiewicz   ide: use PIO/MMIO...
550
  	writel(0x03, (void __iomem *)(irqport + IOC4_INTR_SET * 4));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
551

dca398305   Bartlomiej Zolnierkiewicz   ide: pass number ...
552
  	rc = ide_host_add(&sgiioc4_port_info, hws, 1, NULL);
95a84cd19   Sergei Shtylyov   sgiioc4: use ide_...
553
554
  	if (!rc)
  		return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
555

ce30e4015   Bartlomiej Zolnierkiewicz   sgiioc4: call ide...
556
  	release_mem_region(cmd_phys_base, IOC4_CMD_CTL_BLK_SIZE);
3059ef99a   Sergei Shtylyov   sgiioc4: fix erro...
557
  req_mem_rgn_err:
ce30e4015   Bartlomiej Zolnierkiewicz   sgiioc4: call ide...
558
  	iounmap(virt_base);
8a69580e1   Bartlomiej Zolnierkiewicz   ide: add ide_host...
559
  	return rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
560
  }
ccae50bcf   Sergei Shtylyov   sgiioc4: coding s...
561
  static unsigned int __devinit pci_init_sgiioc4(struct pci_dev *dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
562
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
563
  	int ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
564
565
  	printk(KERN_INFO "%s: IDE controller at PCI slot %s, revision %d
  ",
fc212bb1f   Bartlomiej Zolnierkiewicz   ide: use pci_dev-...
566
567
568
  			 DRV_NAME, pci_name(dev), dev->revision);
  
  	if (dev->revision < IOC4_SUPPORTED_FIRMWARE_REV) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
569
  		printk(KERN_ERR "Skipping %s IDE controller in slot %s: "
ca1997c1f   Bartlomiej Zolnierkiewicz   sgiioc4: use ide_...
570
571
572
573
  				"firmware is obsolete - please upgrade to "
  				"revision46 or higher
  ",
  				DRV_NAME, pci_name(dev));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
574
575
576
  		ret = -EAGAIN;
  		goto out;
  	}
ca1997c1f   Bartlomiej Zolnierkiewicz   sgiioc4: use ide_...
577
  	ret = sgiioc4_ide_setup_pci_device(dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
578
579
580
  out:
  	return ret;
  }
ccae50bcf   Sergei Shtylyov   sgiioc4: coding s...
581
  int __devinit ioc4_ide_attach_one(struct ioc4_driver_data *idd)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
582
  {
ccae50bcf   Sergei Shtylyov   sgiioc4: coding s...
583
584
  	/*
  	 * PCI-RT does not bring out IDE connection.
f5befceb5   Brent Casavant   [PATCH] SGI IOC4:...
585
586
587
588
  	 * Do not attach to this particular IOC4.
  	 */
  	if (idd->idd_variant == IOC4_VARIANT_PCI_RT)
  		return 0;
ca1997c1f   Bartlomiej Zolnierkiewicz   sgiioc4: use ide_...
589
  	return pci_init_sgiioc4(idd->idd_pdev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
590
  }
ecdbc6906   Robin Holt   [IA64] Clear up s...
591
  static struct ioc4_submodule __devinitdata ioc4_ide_submodule = {
22329b511   Brent Casavant   [PATCH] ioc4: Cor...
592
593
594
  	.is_name = "IOC4_ide",
  	.is_owner = THIS_MODULE,
  	.is_probe = ioc4_ide_attach_one,
22329b511   Brent Casavant   [PATCH] ioc4: Cor...
595
  };
82ab1eece   Bartlomiej Zolnierkiewicz   ide: add missing ...
596
  static int __init ioc4_ide_init(void)
22329b511   Brent Casavant   [PATCH] ioc4: Cor...
597
598
599
  {
  	return ioc4_register_submodule(&ioc4_ide_submodule);
  }
59f148005   Brent Casavant   [PATCH] ioc4: Ena...
600
  late_initcall(ioc4_ide_init); /* Call only after IDE init is done */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
601

a835fa798   Jeremy Higdon   [PATCH] sgiioc4: ...
602
  MODULE_AUTHOR("Aniket Malatpure/Jeremy Higdon");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
603
604
  MODULE_DESCRIPTION("IDE PCI driver module for SGI IOC4 Base-IO Card");
  MODULE_LICENSE("GPL");