Blame view

drivers/ide/ide-probe.c 37.4 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
  /*
59bca8cc9   Bartlomiej Zolnierkiewicz   ide: update/add m...
2
3
   *  Copyright (C) 1994-1998   Linus Torvalds & authors (see below)
   *  Copyright (C) 2005, 2007  Bartlomiej Zolnierkiewicz
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
4
5
6
7
8
9
10
11
12
13
14
   */
  
  /*
   *  Mostly written by Mark Lord <mlord@pobox.com>
   *                and Gadi Oxman <gadio@netvision.net.il>
   *                and Andre Hedrick <andre@linux-ide.org>
   *
   *  See linux/MAINTAINERS for address of current maintainer.
   *
   * This is the IDE probe module, as evolved from hd.c and ide.c.
   *
bbe4d6d86   Bartlomiej Zolnierkiewicz   ide: remove stale...
15
16
   * -- increase WAIT_PIDENTIFY to avoid CD-ROM locking at boot
   *	 by Andrea Arcangeli
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
17
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
  #include <linux/module.h>
  #include <linux/types.h>
  #include <linux/string.h>
  #include <linux/kernel.h>
  #include <linux/timer.h>
  #include <linux/mm.h>
  #include <linux/interrupt.h>
  #include <linux/major.h>
  #include <linux/errno.h>
  #include <linux/genhd.h>
  #include <linux/slab.h>
  #include <linux/delay.h>
  #include <linux/ide.h>
  #include <linux/spinlock.h>
  #include <linux/kmod.h>
  #include <linux/pci.h>
dc81785dd   FUJITA Tomonori   ide: build fix
34
  #include <linux/scatterlist.h>
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
  
  #include <asm/byteorder.h>
  #include <asm/irq.h>
  #include <asm/uaccess.h>
  #include <asm/io.h>
  
  /**
   *	generic_id		-	add a generic drive id
   *	@drive:	drive to make an ID block for
   *	
   *	Add a fake id field to the drive we are passed. This allows
   *	use to skip a ton of NULL checks (which people always miss) 
   *	and make drive properties unconditional outside of this file
   */
   
  static void generic_id(ide_drive_t *drive)
  {
4dde4492d   Bartlomiej Zolnierkiewicz   ide: make drive->...
52
53
54
55
56
  	u16 *id = drive->id;
  
  	id[ATA_ID_CUR_CYLS]	= id[ATA_ID_CYLS]	= drive->cyl;
  	id[ATA_ID_CUR_HEADS]	= id[ATA_ID_HEADS]	= drive->head;
  	id[ATA_ID_CUR_SECTORS]	= id[ATA_ID_SECTORS]	= drive->sect;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
57
58
59
60
  }
  
  static void ide_disk_init_chs(ide_drive_t *drive)
  {
4dde4492d   Bartlomiej Zolnierkiewicz   ide: make drive->...
61
  	u16 *id = drive->id;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
62
63
64
  
  	/* Extract geometry if we did not already have one for the drive */
  	if (!drive->cyl || !drive->head || !drive->sect) {
4dde4492d   Bartlomiej Zolnierkiewicz   ide: make drive->...
65
66
67
  		drive->cyl  = drive->bios_cyl  = id[ATA_ID_CYLS];
  		drive->head = drive->bios_head = id[ATA_ID_HEADS];
  		drive->sect = drive->bios_sect = id[ATA_ID_SECTORS];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
68
69
70
  	}
  
  	/* Handle logical geometry translation by the drive */
dd8f46f64   Bartlomiej Zolnierkiewicz   ide: use ata_id_c...
71
  	if (ata_id_current_chs_valid(id)) {
4dde4492d   Bartlomiej Zolnierkiewicz   ide: make drive->...
72
73
74
  		drive->cyl  = id[ATA_ID_CUR_CYLS];
  		drive->head = id[ATA_ID_CUR_HEADS];
  		drive->sect = id[ATA_ID_CUR_SECTORS];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
75
76
77
  	}
  
  	/* Use physical geometry if what we have still makes no sense */
4dde4492d   Bartlomiej Zolnierkiewicz   ide: make drive->...
78
79
80
81
  	if (drive->head > 16 && id[ATA_ID_HEADS] && id[ATA_ID_HEADS] <= 16) {
  		drive->cyl  = id[ATA_ID_CYLS];
  		drive->head = id[ATA_ID_HEADS];
  		drive->sect = id[ATA_ID_SECTORS];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
82
83
84
85
86
  	}
  }
  
  static void ide_disk_init_mult_count(ide_drive_t *drive)
  {
48fb2688a   Bartlomiej Zolnierkiewicz   ide: remove drive...
87
88
  	u16 *id = drive->id;
  	u8 max_multsect = id[ATA_ID_MAX_MULTSECT] & 0xff;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
89

48fb2688a   Bartlomiej Zolnierkiewicz   ide: remove drive...
90
  	if (max_multsect) {
48fb2688a   Bartlomiej Zolnierkiewicz   ide: remove drive...
91
92
93
94
95
96
  		if ((max_multsect / 2) > 1)
  			id[ATA_ID_MULTSECT] = max_multsect | 0x100;
  		else
  			id[ATA_ID_MULTSECT] &= ~0x1ff;
  
  		drive->mult_req = id[ATA_ID_MULTSECT] & 0xff;
7c51c17e0   Bartlomiej Zolnierkiewicz   ide: remove CONFI...
97
98
  
  		if (drive->mult_req)
ca1b96e00   Bartlomiej Zolnierkiewicz   ide: replace spec...
99
  			drive->special_flags |= IDE_SFLAG_SET_MULTMODE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
100
101
  	}
  }
24630dc68   Bartlomiej Zolnierkiewicz   ide: factor out d...
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
  static void ide_classify_ata_dev(ide_drive_t *drive)
  {
  	u16 *id = drive->id;
  	char *m = (char *)&id[ATA_ID_PROD];
  	int is_cfa = ata_id_is_cfa(id);
  
  	/* CF devices are *not* removable in Linux definition of the term */
  	if (is_cfa == 0 && (id[ATA_ID_CONFIG] & (1 << 7)))
  		drive->dev_flags |= IDE_DFLAG_REMOVABLE;
  
  	drive->media = ide_disk;
  
  	if (!ata_id_has_unload(drive->id))
  		drive->dev_flags |= IDE_DFLAG_NO_UNLOAD;
  
  	printk(KERN_INFO "%s: %s, %s DISK drive
  ", drive->name, m,
  		is_cfa ? "CFA" : "ATA");
  }
  
  static void ide_classify_atapi_dev(ide_drive_t *drive)
  {
  	u16 *id = drive->id;
  	char *m = (char *)&id[ATA_ID_PROD];
  	u8 type = (id[ATA_ID_CONFIG] >> 8) & 0x1f;
  
  	printk(KERN_INFO "%s: %s, ATAPI ", drive->name, m);
  	switch (type) {
  	case ide_floppy:
  		if (!strstr(m, "CD-ROM")) {
  			if (!strstr(m, "oppy") &&
  			    !strstr(m, "poyp") &&
  			    !strstr(m, "ZIP"))
  				printk(KERN_CONT "cdrom or floppy?, assuming ");
  			if (drive->media != ide_cdrom) {
  				printk(KERN_CONT "FLOPPY");
  				drive->dev_flags |= IDE_DFLAG_REMOVABLE;
  				break;
  			}
  		}
  		/* Early cdrom models used zero */
  		type = ide_cdrom;
  	case ide_cdrom:
  		drive->dev_flags |= IDE_DFLAG_REMOVABLE;
  #ifdef CONFIG_PPC
  		/* kludge for Apple PowerBook internal zip */
  		if (!strstr(m, "CD-ROM") && strstr(m, "ZIP")) {
  			printk(KERN_CONT "FLOPPY");
  			type = ide_floppy;
  			break;
  		}
  #endif
  		printk(KERN_CONT "CD/DVD-ROM");
  		break;
  	case ide_tape:
  		printk(KERN_CONT "TAPE");
  		break;
  	case ide_optical:
  		printk(KERN_CONT "OPTICAL");
  		drive->dev_flags |= IDE_DFLAG_REMOVABLE;
  		break;
  	default:
  		printk(KERN_CONT "UNKNOWN (type %d)", type);
  		break;
  	}
  
  	printk(KERN_CONT " drive
  ");
  	drive->media = type;
  	/* an ATAPI device ignores DRDY */
  	drive->ready_stat = 0;
  	if (ata_id_cdb_intr(id))
  		drive->atapi_flags |= IDE_AFLAG_DRQ_INTERRUPT;
  	drive->dev_flags |= IDE_DFLAG_DOORLOCKING;
  	/* we don't do head unloading on ATAPI devices */
  	drive->dev_flags |= IDE_DFLAG_NO_UNLOAD;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
179
  /**
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
180
181
182
   *	do_identify	-	identify a drive
   *	@drive: drive to identify 
   *	@cmd: command used
2ebe1d9ef   Bartlomiej Zolnierkiewicz   ide: use try_to_i...
183
   *	@id: buffer for IDENTIFY data
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
184
185
186
187
188
   *
   *	Called when we have issued a drive identify command to
   *	read and parse the results. This function is run with
   *	interrupts disabled. 
   */
047140ae2   Bartlomiej Zolnierkiewicz   ide: remove inlin...
189

2ebe1d9ef   Bartlomiej Zolnierkiewicz   ide: use try_to_i...
190
  static void do_identify(ide_drive_t *drive, u8 cmd, u16 *id)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
191
  {
898ec223f   Bartlomiej Zolnierkiewicz   ide: remove HWIF(...
192
  	ide_hwif_t *hwif = drive->hwif;
4dde4492d   Bartlomiej Zolnierkiewicz   ide: make drive->...
193
  	char *m = (char *)&id[ATA_ID_PROD];
94b9efdf5   Bartlomiej Zolnierkiewicz   ide: push local_i...
194
  	unsigned long flags;
24630dc68   Bartlomiej Zolnierkiewicz   ide: factor out d...
195
  	int bswap = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
196

94b9efdf5   Bartlomiej Zolnierkiewicz   ide: push local_i...
197
198
  	/* local CPU only; some systems need this */
  	local_irq_save(flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
199
  	/* read 512 bytes of id info */
374e042c3   Bartlomiej Zolnierkiewicz   ide: add struct i...
200
  	hwif->tp_ops->input_data(drive, NULL, id, SECTOR_SIZE);
94b9efdf5   Bartlomiej Zolnierkiewicz   ide: push local_i...
201
  	local_irq_restore(flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
202

97100fc81   Bartlomiej Zolnierkiewicz   ide: add device f...
203
  	drive->dev_flags |= IDE_DFLAG_ID_READ;
7b9f25b53   Bartlomiej Zolnierkiewicz   ide: add ide_dump...
204
205
206
207
208
  #ifdef DEBUG
  	printk(KERN_INFO "%s: dumping identify data
  ", drive->name);
  	ide_dump_identify((u8 *)id);
  #endif
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
209
  	ide_fix_driveid(id);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
210
  	/*
aaaade3f0   Bartlomiej Zolnierkiewicz   ide: WIN_* -> ATA...
211
212
  	 *  ATA_CMD_ID_ATA returns little-endian info,
  	 *  ATA_CMD_ID_ATAPI *usually* returns little-endian info.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
213
  	 */
aaaade3f0   Bartlomiej Zolnierkiewicz   ide: WIN_* -> ATA...
214
  	if (cmd == ATA_CMD_ID_ATAPI) {
4dde4492d   Bartlomiej Zolnierkiewicz   ide: make drive->...
215
216
217
  		if ((m[0] == 'N' && m[1] == 'E') ||  /* NEC */
  		    (m[0] == 'F' && m[1] == 'X') ||  /* Mitsumi */
  		    (m[0] == 'P' && m[1] == 'i'))    /* Pioneer */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
218
  			/* Vertos drives may still be weird */
4dde4492d   Bartlomiej Zolnierkiewicz   ide: make drive->...
219
  			bswap ^= 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
220
  	}
4dde4492d   Bartlomiej Zolnierkiewicz   ide: make drive->...
221
222
223
224
  
  	ide_fixstring(m, ATA_ID_PROD_LEN, bswap);
  	ide_fixstring((char *)&id[ATA_ID_FW_REV], ATA_ID_FW_REV_LEN, bswap);
  	ide_fixstring((char *)&id[ATA_ID_SERNO], ATA_ID_SERNO_LEN, bswap);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
225

699b052ad   Tejun Heo   ide: do_identify(...
226
  	/* we depend on this a lot! */
4dde4492d   Bartlomiej Zolnierkiewicz   ide: make drive->...
227
  	m[ATA_ID_PROD_LEN - 1] = '\0';
699b052ad   Tejun Heo   ide: do_identify(...
228

4dde4492d   Bartlomiej Zolnierkiewicz   ide: make drive->...
229
  	if (strstr(m, "E X A B Y T E N E S T"))
69197ad70   Bartlomiej Zolnierkiewicz   ide: fix memleak ...
230
231
232
  		drive->dev_flags &= ~IDE_DFLAG_PRESENT;
  	else
  		drive->dev_flags |= IDE_DFLAG_PRESENT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
233
234
235
  }
  
  /**
2ebe1d9ef   Bartlomiej Zolnierkiewicz   ide: use try_to_i...
236
   *	ide_dev_read_id	-	send ATA/ATAPI IDENTIFY command
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
237
238
   *	@drive: drive to identify
   *	@cmd: command to use
2ebe1d9ef   Bartlomiej Zolnierkiewicz   ide: use try_to_i...
239
   *	@id: buffer for IDENTIFY data
fa56d4cb4   Bartlomiej Zolnierkiewicz   ide: allow ide_de...
240
   *	@irq_ctx: flag set when called from the IRQ context
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
241
   *
2ebe1d9ef   Bartlomiej Zolnierkiewicz   ide: use try_to_i...
242
   *	Sends an ATA(PI) IDENTIFY request to a drive and waits for a response.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
243
244
245
246
247
   *
   *	Returns:	0  device was identified
   *			1  device timed-out (no response to identify request)
   *			2  device aborted the command (refused to identify itself)
   */
fa56d4cb4   Bartlomiej Zolnierkiewicz   ide: allow ide_de...
248
  int ide_dev_read_id(ide_drive_t *drive, u8 cmd, u16 *id, int irq_ctx)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
249
  {
898ec223f   Bartlomiej Zolnierkiewicz   ide: remove HWIF(...
250
  	ide_hwif_t *hwif = drive->hwif;
4c3032d8a   Bartlomiej Zolnierkiewicz   ide: add struct i...
251
  	struct ide_io_ports *io_ports = &hwif->io_ports;
374e042c3   Bartlomiej Zolnierkiewicz   ide: add struct i...
252
  	const struct ide_tp_ops *tp_ops = hwif->tp_ops;
c47137a99   Bartlomiej Zolnierkiewicz   ide: add ide_read...
253
  	int use_altstatus = 0, rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
254
255
  	unsigned long timeout;
  	u8 s = 0, a = 0;
a182807a8   Bartlomiej Zolnierkiewicz   ide: remove try_t...
256
257
258
259
260
  	/*
  	 * Disable device IRQ.  Otherwise we'll get spurious interrupts
  	 * during the identify phase that the IRQ handler isn't expecting.
  	 */
  	if (io_ports->ctl_addr)
ecf3a31d2   Sergei Shtylyov   ide: turn set_irq...
261
  		tp_ops->write_devctl(hwif, ATA_NIEN | ATA_DEVCTL_OBS);
a182807a8   Bartlomiej Zolnierkiewicz   ide: remove try_t...
262

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
263
  	/* take a deep breath */
fa56d4cb4   Bartlomiej Zolnierkiewicz   ide: allow ide_de...
264
265
266
267
  	if (irq_ctx)
  		mdelay(50);
  	else
  		msleep(50);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
268

6636487e8   Bartlomiej Zolnierkiewicz   amd74xx: workarou...
269
270
  	if (io_ports->ctl_addr &&
  	    (hwif->host_flags & IDE_HFLAG_BROKEN_ALTSTATUS) == 0) {
374e042c3   Bartlomiej Zolnierkiewicz   ide: add struct i...
271
272
  		a = tp_ops->read_altstatus(hwif);
  		s = tp_ops->read_status(hwif);
3a7d24841   Bartlomiej Zolnierkiewicz   ide: use ATA_* de...
273
  		if ((a ^ s) & ~ATA_IDX)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
274
  			/* ancient Seagate drives, broken interfaces */
c47137a99   Bartlomiej Zolnierkiewicz   ide: add ide_read...
275
276
277
278
279
  			printk(KERN_INFO "%s: probing with STATUS(0x%02x) "
  					 "instead of ALTSTATUS(0x%02x)
  ",
  					 drive->name, s, a);
  		else
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
280
  			/* use non-intrusive polling */
c47137a99   Bartlomiej Zolnierkiewicz   ide: add ide_read...
281
282
  			use_altstatus = 1;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
283
284
285
286
  
  	/* set features register for atapi
  	 * identify command to be sure of reply
  	 */
aaaade3f0   Bartlomiej Zolnierkiewicz   ide: WIN_* -> ATA...
287
  	if (cmd == ATA_CMD_ID_ATAPI) {
c9ff9e7b6   Sergei Shtylyov   ide: refactor tf_...
288
  		struct ide_taskfile tf;
4e65837b2   Bartlomiej Zolnierkiewicz   ide: use ->tf_loa...
289

c9ff9e7b6   Sergei Shtylyov   ide: refactor tf_...
290
  		memset(&tf, 0, sizeof(tf));
4e65837b2   Bartlomiej Zolnierkiewicz   ide: use ->tf_loa...
291
  		/* disable DMA & overlap */
c9ff9e7b6   Sergei Shtylyov   ide: refactor tf_...
292
  		tp_ops->tf_load(drive, &tf, IDE_VALID_FEATURE);
4e65837b2   Bartlomiej Zolnierkiewicz   ide: use ->tf_loa...
293
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
294
295
  
  	/* ask drive for ID */
374e042c3   Bartlomiej Zolnierkiewicz   ide: add struct i...
296
  	tp_ops->exec_command(hwif, cmd);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
297

aaaade3f0   Bartlomiej Zolnierkiewicz   ide: WIN_* -> ATA...
298
  	timeout = ((cmd == ATA_CMD_ID_ATA) ? WAIT_WORSTCASE : WAIT_PIDENTIFY) / 2;
b163f46d5   Bartlomiej Zolnierkiewicz   ide: enhance ide_...
299

3a7d24841   Bartlomiej Zolnierkiewicz   ide: use ATA_* de...
300
  	/* wait for IRQ and ATA_DRQ */
fa56d4cb4   Bartlomiej Zolnierkiewicz   ide: allow ide_de...
301
302
303
304
305
306
307
308
309
310
311
312
  	if (irq_ctx) {
  		rc = __ide_wait_stat(drive, ATA_DRQ, BAD_R_STAT, timeout, &s);
  		if (rc)
  			return 1;
  	} else {
  		rc = ide_busy_sleep(drive, timeout, use_altstatus);
  		if (rc)
  			return 1;
  
  		msleep(50);
  		s = tp_ops->read_status(hwif);
  	}
c47137a99   Bartlomiej Zolnierkiewicz   ide: add ide_read...
313

3a7d24841   Bartlomiej Zolnierkiewicz   ide: use ATA_* de...
314
  	if (OK_STAT(s, ATA_DRQ, BAD_R_STAT)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
315
  		/* drive returned ID */
2ebe1d9ef   Bartlomiej Zolnierkiewicz   ide: use try_to_i...
316
  		do_identify(drive, cmd, id);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
317
318
319
  		/* drive responded with ID */
  		rc = 0;
  		/* clear drive IRQ */
374e042c3   Bartlomiej Zolnierkiewicz   ide: add struct i...
320
  		(void)tp_ops->read_status(hwif);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
321
322
323
324
325
326
  	} else {
  		/* drive refused ID */
  		rc = 2;
  	}
  	return rc;
  }
28ee9bc5c   Bartlomiej Zolnierkiewicz   ide: report timeo...
327
  int ide_busy_sleep(ide_drive_t *drive, unsigned long timeout, int altstatus)
3a5015cc9   Bartlomiej Zolnierkiewicz   ide: add ide_busy...
328
  {
28ee9bc5c   Bartlomiej Zolnierkiewicz   ide: report timeo...
329
  	ide_hwif_t *hwif = drive->hwif;
3a5015cc9   Bartlomiej Zolnierkiewicz   ide: add ide_busy...
330
  	u8 stat;
b163f46d5   Bartlomiej Zolnierkiewicz   ide: enhance ide_...
331
  	timeout += jiffies;
3a5015cc9   Bartlomiej Zolnierkiewicz   ide: add ide_busy...
332
  	do {
b163f46d5   Bartlomiej Zolnierkiewicz   ide: enhance ide_...
333
334
335
  		msleep(50);	/* give drive a breather */
  		stat = altstatus ? hwif->tp_ops->read_altstatus(hwif)
  				 : hwif->tp_ops->read_status(hwif);
3a7d24841   Bartlomiej Zolnierkiewicz   ide: use ATA_* de...
336
  		if ((stat & ATA_BUSY) == 0)
3a5015cc9   Bartlomiej Zolnierkiewicz   ide: add ide_busy...
337
338
  			return 0;
  	} while (time_before(jiffies, timeout));
28ee9bc5c   Bartlomiej Zolnierkiewicz   ide: report timeo...
339
340
  	printk(KERN_ERR "%s: timeout in %s
  ", drive->name, __func__);
b163f46d5   Bartlomiej Zolnierkiewicz   ide: enhance ide_...
341
  	return 1;	/* drive timed-out */
3a5015cc9   Bartlomiej Zolnierkiewicz   ide: add ide_busy...
342
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
343

1f2efb82a   Bartlomiej Zolnierkiewicz   ide: add ide_read...
344
345
  static u8 ide_read_device(ide_drive_t *drive)
  {
3153c26b5   Sergei Shtylyov   ide: refactor tf_...
346
  	struct ide_taskfile tf;
1f2efb82a   Bartlomiej Zolnierkiewicz   ide: add ide_read...
347

3153c26b5   Sergei Shtylyov   ide: refactor tf_...
348
  	drive->hwif->tp_ops->tf_read(drive, &tf, IDE_VALID_DEVICE);
1f2efb82a   Bartlomiej Zolnierkiewicz   ide: add ide_read...
349

3153c26b5   Sergei Shtylyov   ide: refactor tf_...
350
  	return tf.device;
1f2efb82a   Bartlomiej Zolnierkiewicz   ide: add ide_read...
351
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
  /**
   *	do_probe		-	probe an IDE device
   *	@drive: drive to probe
   *	@cmd: command to use
   *
   *	do_probe() has the difficult job of finding a drive if it exists,
   *	without getting hung up if it doesn't exist, without trampling on
   *	ethernet cards, and without leaving any IRQs dangling to haunt us later.
   *
   *	If a drive is "known" to exist (from CMOS or kernel parameters),
   *	but does not respond right away, the probe will "hang in there"
   *	for the maximum wait time (about 30 seconds), otherwise it will
   *	exit much more quickly.
   *
   * Returns:	0  device was identified
   *		1  device timed-out (no response to identify request)
   *		2  device aborted the command (refused to identify itself)
   *		3  bad status from device (possible for ATAPI drives)
   *		4  probe was not attempted because failure was obvious
   */
  
  static int do_probe (ide_drive_t *drive, u8 cmd)
  {
898ec223f   Bartlomiej Zolnierkiewicz   ide: remove HWIF(...
375
  	ide_hwif_t *hwif = drive->hwif;
374e042c3   Bartlomiej Zolnierkiewicz   ide: add struct i...
376
  	const struct ide_tp_ops *tp_ops = hwif->tp_ops;
2ebe1d9ef   Bartlomiej Zolnierkiewicz   ide: use try_to_i...
377
  	u16 *id = drive->id;
57b552757   Bartlomiej Zolnierkiewicz   ide-probe: remove...
378
  	int rc;
97100fc81   Bartlomiej Zolnierkiewicz   ide: add device f...
379
380
381
382
383
  	u8 present = !!(drive->dev_flags & IDE_DFLAG_PRESENT), stat;
  
  	/* avoid waiting for inappropriate probes */
  	if (present && drive->media != ide_disk && cmd == ATA_CMD_ID_ATA)
  		return 4;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
384

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
385
  #ifdef DEBUG
1b8ebad87   Bartlomiej Zolnierkiewicz   ide: use proper p...
386
387
  	printk(KERN_INFO "probing for %s: present=%d, media=%d, probetype=%s
  ",
97100fc81   Bartlomiej Zolnierkiewicz   ide: add device f...
388
  		drive->name, present, drive->media,
aaaade3f0   Bartlomiej Zolnierkiewicz   ide: WIN_* -> ATA...
389
  		(cmd == ATA_CMD_ID_ATA) ? "ATA" : "ATAPI");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
390
391
392
393
394
395
  #endif
  
  	/* needed for some systems
  	 * (e.g. crw9624 as drive0 with disk as slave)
  	 */
  	msleep(50);
fdd88f0af   Sergei Shtylyov   ide: inline SELEC...
396
  	tp_ops->dev_select(drive);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
397
  	msleep(50);
1f2efb82a   Bartlomiej Zolnierkiewicz   ide: add ide_read...
398

7f612f272   Bartlomiej Zolnierkiewicz   ide: remove [ata_...
399
  	if (ide_read_device(drive) != drive->select && present == 0) {
123995b97   Bartlomiej Zolnierkiewicz   ide: use 'drive->...
400
  		if (drive->dn & 1) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
401
  			/* exit with drive0 selected */
fdd88f0af   Sergei Shtylyov   ide: inline SELEC...
402
  			tp_ops->dev_select(hwif->devices[0]);
3a7d24841   Bartlomiej Zolnierkiewicz   ide: use ATA_* de...
403
  			/* allow ATA_BUSY to assert & clear */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
404
405
406
407
408
  			msleep(50);
  		}
  		/* no i/f present: mmm.. this should be a 4 -ml */
  		return 3;
  	}
374e042c3   Bartlomiej Zolnierkiewicz   ide: add struct i...
409
  	stat = tp_ops->read_status(hwif);
c47137a99   Bartlomiej Zolnierkiewicz   ide: add ide_read...
410

3a7d24841   Bartlomiej Zolnierkiewicz   ide: use ATA_* de...
411
  	if (OK_STAT(stat, ATA_DRDY, ATA_BUSY) ||
97100fc81   Bartlomiej Zolnierkiewicz   ide: add device f...
412
  	    present || cmd == ATA_CMD_ID_ATAPI) {
fa56d4cb4   Bartlomiej Zolnierkiewicz   ide: allow ide_de...
413
  		rc = ide_dev_read_id(drive, cmd, id, 0);
2ebe1d9ef   Bartlomiej Zolnierkiewicz   ide: use try_to_i...
414
  		if (rc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
415
  			/* failed: try again */
fa56d4cb4   Bartlomiej Zolnierkiewicz   ide: allow ide_de...
416
  			rc = ide_dev_read_id(drive, cmd, id, 0);
57b552757   Bartlomiej Zolnierkiewicz   ide-probe: remove...
417

374e042c3   Bartlomiej Zolnierkiewicz   ide: add struct i...
418
  		stat = tp_ops->read_status(hwif);
57b552757   Bartlomiej Zolnierkiewicz   ide-probe: remove...
419

3a7d24841   Bartlomiej Zolnierkiewicz   ide: use ATA_* de...
420
  		if (stat == (ATA_BUSY | ATA_DRDY))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
421
  			return 4;
aaaade3f0   Bartlomiej Zolnierkiewicz   ide: WIN_* -> ATA...
422
  		if (rc == 1 && cmd == ATA_CMD_ID_ATAPI) {
57b552757   Bartlomiej Zolnierkiewicz   ide-probe: remove...
423
424
425
  			printk(KERN_ERR "%s: no response (status = 0x%02x), "
  					"resetting drive
  ", drive->name, stat);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
426
  			msleep(50);
fdd88f0af   Sergei Shtylyov   ide: inline SELEC...
427
  			tp_ops->dev_select(drive);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
428
  			msleep(50);
aaaade3f0   Bartlomiej Zolnierkiewicz   ide: WIN_* -> ATA...
429
  			tp_ops->exec_command(hwif, ATA_CMD_DEV_RESET);
28ee9bc5c   Bartlomiej Zolnierkiewicz   ide: report timeo...
430
  			(void)ide_busy_sleep(drive, WAIT_WORSTCASE, 0);
fa56d4cb4   Bartlomiej Zolnierkiewicz   ide: allow ide_de...
431
  			rc = ide_dev_read_id(drive, cmd, id, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
432
  		}
57b552757   Bartlomiej Zolnierkiewicz   ide-probe: remove...
433
434
  
  		/* ensure drive IRQ is clear */
374e042c3   Bartlomiej Zolnierkiewicz   ide: add struct i...
435
  		stat = tp_ops->read_status(hwif);
57b552757   Bartlomiej Zolnierkiewicz   ide-probe: remove...
436

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
437
  		if (rc == 1)
57b552757   Bartlomiej Zolnierkiewicz   ide-probe: remove...
438
439
440
  			printk(KERN_ERR "%s: no response (status = 0x%02x)
  ",
  					drive->name, stat);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
441
442
443
444
  	} else {
  		/* not present or maybe ATAPI */
  		rc = 3;
  	}
123995b97   Bartlomiej Zolnierkiewicz   ide: use 'drive->...
445
  	if (drive->dn & 1) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
446
  		/* exit with drive0 selected */
fdd88f0af   Sergei Shtylyov   ide: inline SELEC...
447
  		tp_ops->dev_select(hwif->devices[0]);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
448
449
  		msleep(50);
  		/* ensure drive irq is clear */
374e042c3   Bartlomiej Zolnierkiewicz   ide: add struct i...
450
  		(void)tp_ops->read_status(hwif);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
451
452
453
  	}
  	return rc;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
454
455
456
457
458
459
460
461
  /**
   *	probe_for_drives	-	upper level drive probe
   *	@drive: drive to probe for
   *
   *	probe_for_drive() tests for existence of a given drive using do_probe()
   *	and presents things to the user as needed.
   *
   *	Returns:	0  no device was found
97100fc81   Bartlomiej Zolnierkiewicz   ide: add device f...
462
463
   *			1  device was found
   *			   (note: IDE_DFLAG_PRESENT might still be not set)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
464
   */
047140ae2   Bartlomiej Zolnierkiewicz   ide: remove inlin...
465
466
  
  static u8 probe_for_drive(ide_drive_t *drive)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
467
  {
4dde4492d   Bartlomiej Zolnierkiewicz   ide: make drive->...
468
  	char *m;
1bd4c1f4f   Bartlomiej Zolnierkiewicz   ide: classify dev...
469
470
  	int rc;
  	u8 cmd;
4dde4492d   Bartlomiej Zolnierkiewicz   ide: make drive->...
471

97100fc81   Bartlomiej Zolnierkiewicz   ide: add device f...
472
  	drive->dev_flags &= ~IDE_DFLAG_ID_READ;
4dde4492d   Bartlomiej Zolnierkiewicz   ide: make drive->...
473
474
  	m = (char *)&drive->id[ATA_ID_PROD];
  	strcpy(m, "UNKNOWN");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
475
  	/* skip probing? */
97100fc81   Bartlomiej Zolnierkiewicz   ide: add device f...
476
  	if ((drive->dev_flags & IDE_DFLAG_NOPROBE) == 0) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
477
  		/* if !(success||timed-out) */
1bd4c1f4f   Bartlomiej Zolnierkiewicz   ide: classify dev...
478
479
480
  		cmd = ATA_CMD_ID_ATA;
  		rc = do_probe(drive, cmd);
  		if (rc >= 2) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
481
  			/* look for ATAPI device */
1bd4c1f4f   Bartlomiej Zolnierkiewicz   ide: classify dev...
482
483
484
  			cmd = ATA_CMD_ID_ATAPI;
  			rc = do_probe(drive, cmd);
  		}
c36a7e988   Bartlomiej Zolnierkiewicz   ide: fix EXABYTEN...
485

97100fc81   Bartlomiej Zolnierkiewicz   ide: add device f...
486
  		if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
5f4417a15   Hugh Dickins   ide: fix PowerMac...
487
  			return 0;
4dde4492d   Bartlomiej Zolnierkiewicz   ide: make drive->...
488

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
489
  		/* identification failed? */
97100fc81   Bartlomiej Zolnierkiewicz   ide: add device f...
490
  		if ((drive->dev_flags & IDE_DFLAG_ID_READ) == 0) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
491
492
493
494
495
496
497
498
499
500
501
502
  			if (drive->media == ide_disk) {
  				printk(KERN_INFO "%s: non-IDE drive, CHS=%d/%d/%d
  ",
  					drive->name, drive->cyl,
  					drive->head, drive->sect);
  			} else if (drive->media == ide_cdrom) {
  				printk(KERN_INFO "%s: ATAPI cdrom (?)
  ", drive->name);
  			} else {
  				/* nuke it */
  				printk(KERN_WARNING "%s: Unknown device on bus refused identification. Ignoring.
  ", drive->name);
97100fc81   Bartlomiej Zolnierkiewicz   ide: add device f...
503
  				drive->dev_flags &= ~IDE_DFLAG_PRESENT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
504
  			}
1bd4c1f4f   Bartlomiej Zolnierkiewicz   ide: classify dev...
505
506
507
508
509
  		} else {
  			if (cmd == ATA_CMD_ID_ATAPI)
  				ide_classify_atapi_dev(drive);
  			else
  				ide_classify_ata_dev(drive);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
510
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
511
  	}
97100fc81   Bartlomiej Zolnierkiewicz   ide: add device f...
512
513
  
  	if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
5f4417a15   Hugh Dickins   ide: fix PowerMac...
514
  		return 0;
97100fc81   Bartlomiej Zolnierkiewicz   ide: add device f...
515

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
516
  	/* The drive wasn't being helpful. Add generic info only */
97100fc81   Bartlomiej Zolnierkiewicz   ide: add device f...
517
  	if ((drive->dev_flags & IDE_DFLAG_ID_READ) == 0) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
518
519
520
521
522
523
524
525
  		generic_id(drive);
  		return 1;
  	}
  
  	if (drive->media == ide_disk) {
  		ide_disk_init_chs(drive);
  		ide_disk_init_mult_count(drive);
  	}
69197ad70   Bartlomiej Zolnierkiewicz   ide: fix memleak ...
526
  	return 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
527
  }
fc410698e   Pavel Machek   ide: small whites...
528
  static void hwif_release_dev(struct device *dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
529
530
  {
  	ide_hwif_t *hwif = container_of(dev, ide_hwif_t, gendev);
f36d4024c   Aleksey Makarov   [PATCH] mutex sub...
531
  	complete(&hwif->gendev_rel_comp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
532
  }
f74c91413   Bartlomiej Zolnierkiewicz   ide: add warm-plu...
533
  static int ide_register_port(ide_hwif_t *hwif)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
534
  {
349ae23fe   Randy Dunlap   [PATCH] IDE core:...
535
  	int ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
536
  	/* register with global device tree */
dc09c7842   Kay Sievers   ide: struct devic...
537
  	dev_set_name(&hwif->gendev, hwif->name);
fcb520772   Greg Kroah-Hartman   ide: remove drive...
538
  	dev_set_drvdata(&hwif->gendev, hwif);
bb54affa6   Andreas Schwab   ide: fix IDE PMAC...
539
540
  	if (hwif->gendev.parent == NULL)
  		hwif->gendev.parent = hwif->dev;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
541
  	hwif->gendev.release = hwif_release_dev;
96d409412   Bartlomiej Zolnierkiewicz   ide: small ide_re...
542

349ae23fe   Randy Dunlap   [PATCH] IDE core:...
543
  	ret = device_register(&hwif->gendev);
f74c91413   Bartlomiej Zolnierkiewicz   ide: add warm-plu...
544
  	if (ret < 0) {
349ae23fe   Randy Dunlap   [PATCH] IDE core:...
545
546
  		printk(KERN_WARNING "IDE: %s: device_register error: %d
  ",
eb63963a5   Harvey Harrison   ide: replace rema...
547
  			__func__, ret);
f74c91413   Bartlomiej Zolnierkiewicz   ide: add warm-plu...
548
549
  		goto out;
  	}
3ee074bf4   Greg Kroah-Hartman   device create: id...
550
551
  	hwif->portdev = device_create(ide_port_class, &hwif->gendev,
  				      MKDEV(0, 0), hwif, hwif->name);
f74c91413   Bartlomiej Zolnierkiewicz   ide: add warm-plu...
552
553
554
555
  	if (IS_ERR(hwif->portdev)) {
  		ret = PTR_ERR(hwif->portdev);
  		device_unregister(&hwif->gendev);
  	}
f74c91413   Bartlomiej Zolnierkiewicz   ide: add warm-plu...
556
557
  out:
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
558
  }
c860a8f2d   Bartlomiej Zolnierkiewicz   ide: move wait_hw...
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
  /**
   *	ide_port_wait_ready	-	wait for port to become ready
   *	@hwif: IDE port
   *
   *	This is needed on some PPCs and a bunch of BIOS-less embedded
   *	platforms.  Typical cases are:
   *
   *	- The firmware hard reset the disk before booting the kernel,
   *	  the drive is still doing it's poweron-reset sequence, that
   *	  can take up to 30 seconds.
   *
   *	- The firmware does nothing (or no firmware), the device is
   *	  still in POST state (same as above actually).
   *
   *	- Some CD/DVD/Writer combo drives tend to drive the bus during
   *	  their reset sequence even when they are non-selected slave
   *	  devices, thus preventing discovery of the main HD.
   *
   *	Doing this wait-for-non-busy should not harm any existing
   *	configuration and fix some issues like the above.
   *
   *	BenH.
   *
   *	Returns 0 on success, error code (< 0) otherwise.
   */
  
  static int ide_port_wait_ready(ide_hwif_t *hwif)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
586
  {
fdd88f0af   Sergei Shtylyov   ide: inline SELEC...
587
  	const struct ide_tp_ops *tp_ops = hwif->tp_ops;
2bd24a1cf   Bartlomiej Zolnierkiewicz   ide: add port and...
588
589
  	ide_drive_t *drive;
  	int i, rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
  
  	printk(KERN_DEBUG "Probing IDE interface %s...
  ", hwif->name);
  
  	/* Let HW settle down a bit from whatever init state we
  	 * come from */
  	mdelay(2);
  
  	/* Wait for BSY bit to go away, spec timeout is 30 seconds,
  	 * I know of at least one disk who takes 31 seconds, I use 35
  	 * here to be safe
  	 */
  	rc = ide_wait_not_busy(hwif, 35000);
  	if (rc)
  		return rc;
  
  	/* Now make sure both master & slave are ready */
2bd24a1cf   Bartlomiej Zolnierkiewicz   ide: add port and...
607
  	ide_port_for_each_dev(i, drive, hwif) {
8266105b1   Jonas Stare   ide: skip ide_wai...
608
  		/* Ignore disks that we will not probe for later. */
97100fc81   Bartlomiej Zolnierkiewicz   ide: add device f...
609
610
  		if ((drive->dev_flags & IDE_DFLAG_NOPROBE) == 0 ||
  		    (drive->dev_flags & IDE_DFLAG_PRESENT)) {
fdd88f0af   Sergei Shtylyov   ide: inline SELEC...
611
612
  			tp_ops->dev_select(drive);
  			tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
8266105b1   Jonas Stare   ide: skip ide_wai...
613
614
615
616
617
618
619
620
621
622
  			mdelay(2);
  			rc = ide_wait_not_busy(hwif, 35000);
  			if (rc)
  				goto out;
  		} else
  			printk(KERN_DEBUG "%s: ide_wait_not_busy() skipped
  ",
  					  drive->name);
  	}
  out:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
623
  	/* Exit function with master reselected (let's be sane) */
2bd24a1cf   Bartlomiej Zolnierkiewicz   ide: add port and...
624
  	if (i)
fdd88f0af   Sergei Shtylyov   ide: inline SELEC...
625
  		tp_ops->dev_select(hwif->devices[0]);
8266105b1   Jonas Stare   ide: skip ide_wai...
626

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
627
628
629
630
631
  	return rc;
  }
  
  /**
   *	ide_undecoded_slave	-	look for bad CF adapters
4dde4492d   Bartlomiej Zolnierkiewicz   ide: make drive->...
632
   *	@dev1: slave device
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
633
634
635
636
637
   *
   *	Analyse the drives on the interface and attempt to decide if we
   *	have the same drive viewed twice. This occurs with crap CF adapters
   *	and PCMCIA sometimes.
   */
4dde4492d   Bartlomiej Zolnierkiewicz   ide: make drive->...
638
  void ide_undecoded_slave(ide_drive_t *dev1)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
639
  {
5e7f3a466   Bartlomiej Zolnierkiewicz   ide: dynamic allo...
640
  	ide_drive_t *dev0 = dev1->hwif->devices[0];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
641

97100fc81   Bartlomiej Zolnierkiewicz   ide: add device f...
642
  	if ((dev1->dn & 1) == 0 || (dev0->dev_flags & IDE_DFLAG_PRESENT) == 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
643
644
645
  		return;
  
  	/* If the models don't match they are not the same product */
4dde4492d   Bartlomiej Zolnierkiewicz   ide: make drive->...
646
647
  	if (strcmp((char *)&dev0->id[ATA_ID_PROD],
  		   (char *)&dev1->id[ATA_ID_PROD]))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
648
649
650
  		return;
  
  	/* Serial numbers do not match */
4dde4492d   Bartlomiej Zolnierkiewicz   ide: make drive->...
651
652
  	if (strncmp((char *)&dev0->id[ATA_ID_SERNO],
  		    (char *)&dev1->id[ATA_ID_SERNO], ATA_ID_SERNO_LEN))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
653
654
655
  		return;
  
  	/* No serial number, thankfully very rare for CF */
4dde4492d   Bartlomiej Zolnierkiewicz   ide: make drive->...
656
  	if (*(char *)&dev0->id[ATA_ID_SERNO] == 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
657
658
659
660
661
  		return;
  
  	/* Appears to be an IDE flash adapter with decode bugs */
  	printk(KERN_WARNING "ide-probe: ignoring undecoded slave
  ");
97100fc81   Bartlomiej Zolnierkiewicz   ide: add device f...
662
  	dev1->dev_flags &= ~IDE_DFLAG_PRESENT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
663
664
665
  }
  
  EXPORT_SYMBOL_GPL(ide_undecoded_slave);
9d501529b   Bartlomiej Zolnierkiewicz   ide: make probe_h...
666
  static int ide_probe_port(ide_hwif_t *hwif)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
667
  {
2bd24a1cf   Bartlomiej Zolnierkiewicz   ide: add port and...
668
  	ide_drive_t *drive;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
669
  	unsigned int irqd;
2bd24a1cf   Bartlomiej Zolnierkiewicz   ide: add port and...
670
  	int i, rc = -ENODEV;
a14dc5749   Bartlomiej Zolnierkiewicz   ide: move hwif_re...
671
672
  
  	BUG_ON(hwif->present);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
673

5e7f3a466   Bartlomiej Zolnierkiewicz   ide: dynamic allo...
674
675
  	if ((hwif->devices[0]->dev_flags & IDE_DFLAG_NOPROBE) &&
  	    (hwif->devices[1]->dev_flags & IDE_DFLAG_NOPROBE))
9d501529b   Bartlomiej Zolnierkiewicz   ide: make probe_h...
676
  		return -EACCES;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
677

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
678
679
680
681
682
683
684
  	/*
  	 * We must always disable IRQ, as probe_for_drive will assert IRQ, but
  	 * we'll install our IRQ driver much later...
  	 */
  	irqd = hwif->irq;
  	if (irqd)
  		disable_irq(hwif->irq);
9ce41aed0   David S. Miller   Revert "ide: skip...
685
686
687
  	if (ide_port_wait_ready(hwif) == -EBUSY)
  		printk(KERN_DEBUG "%s: Wait for ready failed before probe !
  ", hwif->name);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
688
689
  
  	/*
f367bed00   Bartlomiej Zolnierkiewicz   Revert "ide: chan...
690
691
  	 * Second drive should only exist if first drive was found,
  	 * but a lot of cdrom drives are configured as single slaves.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
692
  	 */
2bd24a1cf   Bartlomiej Zolnierkiewicz   ide: add port and...
693
  	ide_port_for_each_dev(i, drive, hwif) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
694
  		(void) probe_for_drive(drive);
97100fc81   Bartlomiej Zolnierkiewicz   ide: add device f...
695
  		if (drive->dev_flags & IDE_DFLAG_PRESENT)
a14dc5749   Bartlomiej Zolnierkiewicz   ide: move hwif_re...
696
  			rc = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
697
  	}
9ce41aed0   David S. Miller   Revert "ide: skip...
698

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
699
700
701
702
703
704
  	/*
  	 * Use cached IRQ number. It might be (and is...) changed by probe
  	 * code above
  	 */
  	if (irqd)
  		enable_irq(irqd);
a14dc5749   Bartlomiej Zolnierkiewicz   ide: move hwif_re...
705
  	return rc;
e84e7ea7c   Bartlomiej Zolnierkiewicz   ide: factor out c...
706
707
708
709
  }
  
  static void ide_port_tune_devices(ide_hwif_t *hwif)
  {
ac95beedf   Bartlomiej Zolnierkiewicz   ide: add struct i...
710
  	const struct ide_port_ops *port_ops = hwif->port_ops;
2bd24a1cf   Bartlomiej Zolnierkiewicz   ide: add port and...
711
712
  	ide_drive_t *drive;
  	int i;
f01393e48   Bartlomiej Zolnierkiewicz   ide: merge ->fixu...
713

7ed5b157d   Bartlomiej Zolnierkiewicz   ide: add ide_for_...
714
  	ide_port_for_each_present_dev(i, drive, hwif) {
8bc1e5aa0   Bartlomiej Zolnierkiewicz   ide: respect quir...
715
  		ide_check_nien_quirk_list(drive);
7ed5b157d   Bartlomiej Zolnierkiewicz   ide: add ide_for_...
716
717
  		if (port_ops && port_ops->quirkproc)
  			port_ops->quirkproc(drive);
f01393e48   Bartlomiej Zolnierkiewicz   ide: merge ->fixu...
718
  	}
0380dad45   Bartlomiej Zolnierkiewicz   it821x: RAID mode...
719

7ed5b157d   Bartlomiej Zolnierkiewicz   ide: add ide_for_...
720
721
  	ide_port_for_each_present_dev(i, drive, hwif) {
  		ide_set_max_pio(drive);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
722

7ed5b157d   Bartlomiej Zolnierkiewicz   ide: add ide_for_...
723
  		drive->dev_flags |= IDE_DFLAG_NICE1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
724

7ed5b157d   Bartlomiej Zolnierkiewicz   ide: add ide_for_...
725
726
  		if (hwif->dma_ops)
  			ide_set_dma(drive);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
727
728
  	}
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
729
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
730
731
732
733
   * init request queue
   */
  static int ide_init_queue(ide_drive_t *drive)
  {
165125e1e   Jens Axboe   [BLOCK] Get rid o...
734
  	struct request_queue *q;
898ec223f   Bartlomiej Zolnierkiewicz   ide: remove HWIF(...
735
  	ide_hwif_t *hwif = drive->hwif;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
736
737
738
739
740
741
742
743
744
745
  	int max_sectors = 256;
  	int max_sg_entries = PRD_ENTRIES;
  
  	/*
  	 *	Our default set up assumes the normal IDE case,
  	 *	that is 64K segmenting, standard PRD setup
  	 *	and LBA28. Some drivers then impose their own
  	 *	limits and LBA48 we could raise it but as yet
  	 *	do not.
  	 */
1946089a1   Christoph Lameter   [PATCH] NUMA awar...
746

201bffa46   Bartlomiej Zolnierkiewicz   ide: use per-devi...
747
  	q = blk_init_queue_node(do_ide_request, NULL, hwif_to_node(hwif));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
748
749
750
751
752
  	if (!q)
  		return 1;
  
  	q->queuedata = drive;
  	blk_queue_segment_boundary(q, 0xffff);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
753
754
  	if (hwif->rqsize < max_sectors)
  		max_sectors = hwif->rqsize;
086fa5ff0   Martin K. Petersen   block: Rename blk...
755
  	blk_queue_max_hw_sectors(q, max_sectors);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
756
757
758
759
760
761
762
763
764
765
766
767
768
769
  
  #ifdef CONFIG_PCI
  	/* When we have an IOMMU, we may have a problem where pci_map_sg()
  	 * creates segments that don't completely match our boundary
  	 * requirements and thus need to be broken up again. Because it
  	 * doesn't align properly either, we may actually have to break up
  	 * to more segments than what was we got in the first place, a max
  	 * worst case is twice as many.
  	 * This will be fixed once we teach pci_map_sg() about our boundary
  	 * requirements, hopefully soon. *FIXME*
  	 */
  	if (!PCI_DMA_BUS_IS_PHYS)
  		max_sg_entries >>= 1;
  #endif /* CONFIG_PCI */
8a78362c4   Martin K. Petersen   block: Consolidat...
770
  	blk_queue_max_segments(q, max_sg_entries);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
771
772
773
774
775
776
  
  	/* assign drive queue */
  	drive->queue = q;
  
  	/* needs drive->queue to be set */
  	ide_toggle_bounce(drive, 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
777
778
  	return 0;
  }
b40d1b88f   Bartlomiej Zolnierkiewicz   ide: move ide_ini...
779
  static DEFINE_MUTEX(ide_cfg_mtx);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
780
  /*
d5bc6592d   Bartlomiej Zolnierkiewicz   ide: factor out d...
781
782
   * For any present drive:
   * - allocate the block device queue
d5bc6592d   Bartlomiej Zolnierkiewicz   ide: factor out d...
783
   */
e415e495f   Elias Oltmanns   ide: Two fixes re...
784
  static int ide_port_setup_devices(ide_hwif_t *hwif)
d5bc6592d   Bartlomiej Zolnierkiewicz   ide: factor out d...
785
  {
2bd24a1cf   Bartlomiej Zolnierkiewicz   ide: add port and...
786
  	ide_drive_t *drive;
e415e495f   Elias Oltmanns   ide: Two fixes re...
787
  	int i, j = 0;
d5bc6592d   Bartlomiej Zolnierkiewicz   ide: factor out d...
788

26042d058   Bartlomiej Zolnierkiewicz   ide: move ide_por...
789
  	mutex_lock(&ide_cfg_mtx);
7ed5b157d   Bartlomiej Zolnierkiewicz   ide: add ide_for_...
790
  	ide_port_for_each_present_dev(i, drive, hwif) {
d5bc6592d   Bartlomiej Zolnierkiewicz   ide: factor out d...
791
792
793
794
  		if (ide_init_queue(drive)) {
  			printk(KERN_ERR "ide: failed to init %s
  ",
  					drive->name);
e415e495f   Elias Oltmanns   ide: Two fixes re...
795
  			drive->dev_flags &= ~IDE_DFLAG_PRESENT;
d5bc6592d   Bartlomiej Zolnierkiewicz   ide: factor out d...
796
797
  			continue;
  		}
e415e495f   Elias Oltmanns   ide: Two fixes re...
798
  		j++;
d5bc6592d   Bartlomiej Zolnierkiewicz   ide: factor out d...
799
  	}
26042d058   Bartlomiej Zolnierkiewicz   ide: move ide_por...
800
  	mutex_unlock(&ide_cfg_mtx);
e415e495f   Elias Oltmanns   ide: Two fixes re...
801
802
  
  	return j;
d5bc6592d   Bartlomiej Zolnierkiewicz   ide: factor out d...
803
  }
ffc36c761   Bartlomiej Zolnierkiewicz   ide: fix handling...
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
  static void ide_host_enable_irqs(struct ide_host *host)
  {
  	ide_hwif_t *hwif;
  	int i;
  
  	ide_host_for_each_port(i, hwif, host) {
  		if (hwif == NULL)
  			continue;
  
  		/* clear any pending IRQs */
  		hwif->tp_ops->read_status(hwif);
  
  		/* unmask IRQs */
  		if (hwif->io_ports.ctl_addr)
  			hwif->tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
  	}
  }
d5bc6592d   Bartlomiej Zolnierkiewicz   ide: factor out d...
821
  /*
b65fac32c   Bartlomiej Zolnierkiewicz   ide: merge ide_hw...
822
   * This routine sets up the IRQ for an IDE interface.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
823
824
825
   */
  static int init_irq (ide_hwif_t *hwif)
  {
4c3032d8a   Bartlomiej Zolnierkiewicz   ide: add struct i...
826
  	struct ide_io_ports *io_ports = &hwif->io_ports;
255115fb3   Bartlomiej Zolnierkiewicz   ide: allow host d...
827
828
829
  	struct ide_host *host = hwif->host;
  	irq_handler_t irq_handler = host->irq_handler;
  	int sa = host->irq_flags;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
830

849d71300   Stanislaw Gruszka   ide: allow to wra...
831
832
  	if (irq_handler == NULL)
  		irq_handler = ide_intr;
849d71300   Stanislaw Gruszka   ide: allow to wra...
833
  	if (request_irq(hwif->irq, irq_handler, sa, hwif->name, hwif))
b65fac32c   Bartlomiej Zolnierkiewicz   ide: merge ide_hw...
834
  		goto out_up;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
835

7b892806b   Adrian Bunk   cleanup after APU...
836
  #if !defined(__mc68000__)
1b8ebad87   Bartlomiej Zolnierkiewicz   ide: use proper p...
837
  	printk(KERN_INFO "%s at 0x%03lx-0x%03lx,0x%03lx on irq %d", hwif->name,
4c3032d8a   Bartlomiej Zolnierkiewicz   ide: add struct i...
838
839
  		io_ports->data_addr, io_ports->status_addr,
  		io_ports->ctl_addr, hwif->irq);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
840
  #else
1b8ebad87   Bartlomiej Zolnierkiewicz   ide: use proper p...
841
  	printk(KERN_INFO "%s at 0x%08lx on irq %d", hwif->name,
4c3032d8a   Bartlomiej Zolnierkiewicz   ide: add struct i...
842
  		io_ports->data_addr, hwif->irq);
7b892806b   Adrian Bunk   cleanup after APU...
843
  #endif /* __mc68000__ */
b65fac32c   Bartlomiej Zolnierkiewicz   ide: merge ide_hw...
844
845
  	if (hwif->host->host_flags & IDE_HFLAG_SERIALIZE)
  		printk(KERN_CONT " (serialized)");
1b8ebad87   Bartlomiej Zolnierkiewicz   ide: use proper p...
846
847
  	printk(KERN_CONT "
  ");
d5bc6592d   Bartlomiej Zolnierkiewicz   ide: factor out d...
848

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
849
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
850
  out_up:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
851
852
853
854
855
856
857
858
859
860
861
862
863
  	return 1;
  }
  
  static int ata_lock(dev_t dev, void *data)
  {
  	/* FIXME: we want to pin hwif down */
  	return 0;
  }
  
  static struct kobject *ata_probe(dev_t dev, int *part, void *data)
  {
  	ide_hwif_t *hwif = data;
  	int unit = *part >> PARTN_BITS;
5e7f3a466   Bartlomiej Zolnierkiewicz   ide: dynamic allo...
864
  	ide_drive_t *drive = hwif->devices[unit];
97100fc81   Bartlomiej Zolnierkiewicz   ide: add device f...
865
866
  
  	if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
867
868
869
870
  		return NULL;
  
  	if (drive->media == ide_disk)
  		request_module("ide-disk");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
871
872
873
874
875
876
877
878
879
880
881
882
883
884
  	if (drive->media == ide_cdrom || drive->media == ide_optical)
  		request_module("ide-cd");
  	if (drive->media == ide_tape)
  		request_module("ide-tape");
  	if (drive->media == ide_floppy)
  		request_module("ide-floppy");
  
  	return NULL;
  }
  
  static struct kobject *exact_match(dev_t dev, int *part, void *data)
  {
  	struct gendisk *p = data;
  	*part &= (1 << PARTN_BITS) - 1;
ed9e19823   Tejun Heo   block: implement ...
885
  	return &disk_to_dev(p)->kobj;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
  }
  
  static int exact_lock(dev_t dev, void *data)
  {
  	struct gendisk *p = data;
  
  	if (!get_disk(p))
  		return -1;
  	return 0;
  }
  
  void ide_register_region(struct gendisk *disk)
  {
  	blk_register_region(MKDEV(disk->major, disk->first_minor),
  			    disk->minors, NULL, exact_match, exact_lock, disk);
  }
  
  EXPORT_SYMBOL_GPL(ide_register_region);
  
  void ide_unregister_region(struct gendisk *disk)
  {
  	blk_unregister_region(MKDEV(disk->major, disk->first_minor),
  			      disk->minors);
  }
  
  EXPORT_SYMBOL_GPL(ide_unregister_region);
  
  void ide_init_disk(struct gendisk *disk, ide_drive_t *drive)
  {
  	ide_hwif_t *hwif = drive->hwif;
7f612f272   Bartlomiej Zolnierkiewicz   ide: remove [ata_...
916
  	unsigned int unit = drive->dn & 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
917
918
919
920
921
922
923
924
925
926
927
928
  
  	disk->major = hwif->major;
  	disk->first_minor = unit << PARTN_BITS;
  	sprintf(disk->disk_name, "hd%c", 'a' + hwif->index * MAX_DRIVES + unit);
  	disk->queue = drive->queue;
  }
  
  EXPORT_SYMBOL_GPL(ide_init_disk);
  
  static void drive_release_dev (struct device *dev)
  {
  	ide_drive_t *drive = container_of(dev, ide_drive_t, gendev);
5b0c4b30a   Bartlomiej Zolnierkiewicz   ide: remove IDE d...
929
  	ide_proc_unregister_device(drive);
b5479167f   Bartlomiej Zolnierkiewicz   ide: fix locking ...
930
931
  	blk_cleanup_queue(drive->queue);
  	drive->queue = NULL;
97100fc81   Bartlomiej Zolnierkiewicz   ide: add device f...
932
  	drive->dev_flags &= ~IDE_DFLAG_PRESENT;
8604affde   Bartlomiej Zolnierkiewicz   [PATCH] convert I...
933

f36d4024c   Aleksey Makarov   [PATCH] mutex sub...
934
  	complete(&drive->gendev_rel_comp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
935
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
936
937
  static int hwif_init(ide_hwif_t *hwif)
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
938
  	if (!hwif->irq) {
8b07ed26f   Bartlomiej Zolnierkiewicz   ide: remove no lo...
939
940
941
  		printk(KERN_ERR "%s: disabled, no IRQ
  ", hwif->name);
  		return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
942
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
943

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
944
945
946
947
948
  	if (register_blkdev(hwif->major, hwif->name))
  		return 0;
  
  	if (!hwif->sg_max_nents)
  		hwif->sg_max_nents = PRD_ENTRIES;
45711f1af   Jens Axboe   [SG] Update drive...
949
  	hwif->sg_table = kmalloc(sizeof(struct scatterlist)*hwif->sg_max_nents,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
950
951
952
953
954
955
  				 GFP_KERNEL);
  	if (!hwif->sg_table) {
  		printk(KERN_ERR "%s: unable to allocate SG table.
  ", hwif->name);
  		goto out;
  	}
45711f1af   Jens Axboe   [SG] Update drive...
956
957
  
  	sg_init_table(hwif->sg_table, hwif->sg_max_nents);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
958
  	
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
959
  	if (init_irq(hwif)) {
8b07ed26f   Bartlomiej Zolnierkiewicz   ide: remove no lo...
960
961
962
  		printk(KERN_ERR "%s: disabled, unable to get IRQ %d
  ",
  			hwif->name, hwif->irq);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
963
964
  		goto out;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
965

3a4e7c96d   Bartlomiej Zolnierkiewicz   ide: move blk_reg...
966
967
  	blk_register_region(MKDEV(hwif->major, 0), MAX_DRIVES << PARTN_BITS,
  			    THIS_MODULE, ata_probe, ata_lock, hwif);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
968
969
970
971
972
973
  	return 1;
  
  out:
  	unregister_blkdev(hwif->major, hwif->name);
  	return 0;
  }
9601a607c   Bartlomiej Zolnierkiewicz   ide: add hwif_reg...
974
975
  static void hwif_register_devices(ide_hwif_t *hwif)
  {
2bd24a1cf   Bartlomiej Zolnierkiewicz   ide: add port and...
976
  	ide_drive_t *drive;
9601a607c   Bartlomiej Zolnierkiewicz   ide: add hwif_reg...
977
  	unsigned int i;
7ed5b157d   Bartlomiej Zolnierkiewicz   ide: add ide_for_...
978
  	ide_port_for_each_present_dev(i, drive, hwif) {
c5d70cc73   Bartlomiej Zolnierkiewicz   ide: merge init_g...
979
980
  		struct device *dev = &drive->gendev;
  		int ret;
9601a607c   Bartlomiej Zolnierkiewicz   ide: add hwif_reg...
981

dc09c7842   Kay Sievers   ide: struct devic...
982
  		dev_set_name(dev, "%u.%u", hwif->index, i);
fcb520772   Greg Kroah-Hartman   ide: remove drive...
983
  		dev_set_drvdata(dev, drive);
c5d70cc73   Bartlomiej Zolnierkiewicz   ide: merge init_g...
984
985
  		dev->parent = &hwif->gendev;
  		dev->bus = &ide_bus_type;
c5d70cc73   Bartlomiej Zolnierkiewicz   ide: merge init_g...
986
987
988
989
990
991
992
  		dev->release = drive_release_dev;
  
  		ret = device_register(dev);
  		if (ret < 0)
  			printk(KERN_WARNING "IDE: %s: device_register error: "
  					    "%d
  ", __func__, ret);
9601a607c   Bartlomiej Zolnierkiewicz   ide: add hwif_reg...
993
994
  	}
  }
7704ca2a3   Bartlomiej Zolnierkiewicz   ide: factor out c...
995
996
  static void ide_port_init_devices(ide_hwif_t *hwif)
  {
ac95beedf   Bartlomiej Zolnierkiewicz   ide: add struct i...
997
  	const struct ide_port_ops *port_ops = hwif->port_ops;
2bd24a1cf   Bartlomiej Zolnierkiewicz   ide: add port and...
998
  	ide_drive_t *drive;
7704ca2a3   Bartlomiej Zolnierkiewicz   ide: factor out c...
999
  	int i;
2bd24a1cf   Bartlomiej Zolnierkiewicz   ide: add port and...
1000
  	ide_port_for_each_dev(i, drive, hwif) {
123995b97   Bartlomiej Zolnierkiewicz   ide: use 'drive->...
1001
  		drive->dn = i + hwif->channel * 2;
7704ca2a3   Bartlomiej Zolnierkiewicz   ide: factor out c...
1002
1003
  		if (hwif->host_flags & IDE_HFLAG_IO_32BIT)
  			drive->io_32bit = 1;
7610c4f5e   Bartlomiej Zolnierkiewicz   ide: fix IDE_DFLA...
1004
1005
  		if (hwif->host_flags & IDE_HFLAG_NO_IO_32BIT)
  			drive->dev_flags |= IDE_DFLAG_NO_IO_32BIT;
7704ca2a3   Bartlomiej Zolnierkiewicz   ide: factor out c...
1006
  		if (hwif->host_flags & IDE_HFLAG_UNMASK_IRQS)
97100fc81   Bartlomiej Zolnierkiewicz   ide: add device f...
1007
  			drive->dev_flags |= IDE_DFLAG_UNMASK;
807b90d0b   Bartlomiej Zolnierkiewicz   ide: add IDE_HFLA...
1008
  		if (hwif->host_flags & IDE_HFLAG_NO_UNMASK_IRQS)
97100fc81   Bartlomiej Zolnierkiewicz   ide: add device f...
1009
  			drive->dev_flags |= IDE_DFLAG_NO_UNMASK;
1f2cf8b00   Bartlomiej Zolnierkiewicz   ide: add ->port_i...
1010

d2d4e780a   Bartlomiej Zolnierkiewicz   ide: add drive->p...
1011
  		drive->pio_mode = XFER_PIO_0;
e6d95bd14   Bartlomiej Zolnierkiewicz   ide: ->port_init_...
1012
1013
1014
  		if (port_ops && port_ops->init_dev)
  			port_ops->init_dev(drive);
  	}
7704ca2a3   Bartlomiej Zolnierkiewicz   ide: factor out c...
1015
  }
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
1016
1017
  static void ide_init_port(ide_hwif_t *hwif, unsigned int port,
  			  const struct ide_port_info *d)
8447d9d52   Bartlomiej Zolnierkiewicz   ide: add ide_devi...
1018
  {
b76916462   Adrian Bunk   ide: remove the i...
1019
  	hwif->channel = port;
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
1020

29e52cf79   Bartlomiej Zolnierkiewicz   ide: remove chips...
1021
  	hwif->chipset = d->chipset ? d->chipset : ide_pci;
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
1022
1023
1024
  
  	if (d->init_iops)
  		d->init_iops(hwif);
23f8e4bf7   Bartlomiej Zolnierkiewicz   ide: fix early se...
1025
1026
  	/* ->host_flags may be set by ->init_iops (or even earlier...) */
  	hwif->host_flags |= d->host_flags;
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
1027
  	hwif->pio_mask = d->pio_mask;
374e042c3   Bartlomiej Zolnierkiewicz   ide: add struct i...
1028
1029
  	if (d->tp_ops)
  		hwif->tp_ops = d->tp_ops;
ac95beedf   Bartlomiej Zolnierkiewicz   ide: add struct i...
1030
  	/* ->set_pio_mode for DTC2278 is currently limited to port 0 */
2787cb8ae   Bartlomiej Zolnierkiewicz   ide: add IDE_HFLA...
1031
  	if ((hwif->host_flags & IDE_HFLAG_DTC2278) == 0 || hwif->channel == 0)
ac95beedf   Bartlomiej Zolnierkiewicz   ide: add struct i...
1032
  		hwif->port_ops = d->port_ops;
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
1033
1034
1035
  	hwif->swdma_mask = d->swdma_mask;
  	hwif->mwdma_mask = d->mwdma_mask;
  	hwif->ultra_mask = d->udma_mask;
b123f56e0   Bartlomiej Zolnierkiewicz   ide: do complete ...
1036
1037
  	if ((d->host_flags & IDE_HFLAG_NO_DMA) == 0) {
  		int rc;
592b53152   Sergei Shtylyov   ide: move read_sf...
1038
  		hwif->dma_ops = d->dma_ops;
b123f56e0   Bartlomiej Zolnierkiewicz   ide: do complete ...
1039
1040
1041
1042
1043
1044
1045
1046
  		if (d->init_dma)
  			rc = d->init_dma(hwif, d);
  		else
  			rc = ide_hwif_setup_dma(hwif, d);
  
  		if (rc < 0) {
  			printk(KERN_INFO "%s: DMA disabled
  ", hwif->name);
592b53152   Sergei Shtylyov   ide: move read_sf...
1047
1048
  
  			hwif->dma_ops = NULL;
ebb00fb55   Bartlomiej Zolnierkiewicz   ide: factor out s...
1049
  			hwif->dma_base = 0;
b123f56e0   Bartlomiej Zolnierkiewicz   ide: do complete ...
1050
1051
1052
  			hwif->swdma_mask = 0;
  			hwif->mwdma_mask = 0;
  			hwif->ultra_mask = 0;
592b53152   Sergei Shtylyov   ide: move read_sf...
1053
  		}
b123f56e0   Bartlomiej Zolnierkiewicz   ide: do complete ...
1054
  	}
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
1055

1024c5f4b   Bartlomiej Zolnierkiewicz   ide: IDE_HFLAG_SE...
1056
  	if ((d->host_flags & IDE_HFLAG_SERIALIZE) ||
702c026be   Bartlomiej Zolnierkiewicz   ide: rework handl...
1057
1058
  	    ((d->host_flags & IDE_HFLAG_SERIALIZE_DMA) && hwif->dma_base))
  		hwif->host->host_flags |= IDE_HFLAG_SERIALIZE;
1024c5f4b   Bartlomiej Zolnierkiewicz   ide: IDE_HFLAG_SE...
1059

6b4924962   Bartlomiej Zolnierkiewicz   ide: add ->max_se...
1060
1061
  	if (d->max_sectors)
  		hwif->rqsize = d->max_sectors;
70775e9c6   Bartlomiej Zolnierkiewicz   ide: move ->rqsiz...
1062
1063
1064
1065
1066
1067
1068
  	else {
  		if ((hwif->host_flags & IDE_HFLAG_NO_LBA48) ||
  		    (hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA))
  			hwif->rqsize = 256;
  		else
  			hwif->rqsize = 65536;
  	}
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
1069
1070
1071
1072
  
  	/* call chipset specific routine for each enabled port */
  	if (d->init_hwif)
  		d->init_hwif(hwif);
c7f6f21aa   Bartlomiej Zolnierkiewicz   ide: factor out c...
1073
  }
bfa14b42a   Bartlomiej Zolnierkiewicz   ide: add ->cable_...
1074

c7f6f21aa   Bartlomiej Zolnierkiewicz   ide: factor out c...
1075
1076
  static void ide_port_cable_detect(ide_hwif_t *hwif)
  {
ac95beedf   Bartlomiej Zolnierkiewicz   ide: add struct i...
1077
1078
1079
  	const struct ide_port_ops *port_ops = hwif->port_ops;
  
  	if (port_ops && port_ops->cable_detect && (hwif->ultra_mask & 0x78)) {
bfa14b42a   Bartlomiej Zolnierkiewicz   ide: add ->cable_...
1080
  		if (hwif->cbl != ATA_CBL_PATA40_SHORT)
ac95beedf   Bartlomiej Zolnierkiewicz   ide: add struct i...
1081
  			hwif->cbl = port_ops->cable_detect(hwif);
bfa14b42a   Bartlomiej Zolnierkiewicz   ide: add ->cable_...
1082
  	}
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
1083
  }
b40d1b88f   Bartlomiej Zolnierkiewicz   ide: move ide_ini...
1084
1085
1086
1087
1088
1089
  static const u8 ide_hwif_to_major[] =
  	{ IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR, IDE4_MAJOR,
  	  IDE5_MAJOR, IDE6_MAJOR, IDE7_MAJOR, IDE8_MAJOR, IDE9_MAJOR };
  
  static void ide_port_init_devices_data(ide_hwif_t *hwif)
  {
2bd24a1cf   Bartlomiej Zolnierkiewicz   ide: add port and...
1090
1091
  	ide_drive_t *drive;
  	int i;
b40d1b88f   Bartlomiej Zolnierkiewicz   ide: move ide_ini...
1092

2bd24a1cf   Bartlomiej Zolnierkiewicz   ide: add port and...
1093
1094
  	ide_port_for_each_dev(i, drive, hwif) {
  		u8 j = (hwif->index * MAX_DRIVES) + i;
5f4417a15   Hugh Dickins   ide: fix PowerMac...
1095
  		u16 *saved_id = drive->id;
b40d1b88f   Bartlomiej Zolnierkiewicz   ide: move ide_ini...
1096
1097
  
  		memset(drive, 0, sizeof(*drive));
5f4417a15   Hugh Dickins   ide: fix PowerMac...
1098
1099
  		memset(saved_id, 0, SECTOR_SIZE);
  		drive->id = saved_id;
b40d1b88f   Bartlomiej Zolnierkiewicz   ide: move ide_ini...
1100
1101
  
  		drive->media			= ide_disk;
2bd24a1cf   Bartlomiej Zolnierkiewicz   ide: add port and...
1102
  		drive->select			= (i << 4) | ATA_DEVICE_OBS;
b40d1b88f   Bartlomiej Zolnierkiewicz   ide: move ide_ini...
1103
1104
1105
  		drive->hwif			= hwif;
  		drive->ready_stat		= ATA_DRDY;
  		drive->bad_wstat		= BAD_W_STAT;
ca1b96e00   Bartlomiej Zolnierkiewicz   ide: replace spec...
1106
1107
  		drive->special_flags		= IDE_SFLAG_RECALIBRATE |
  						  IDE_SFLAG_SET_GEOMETRY;
b40d1b88f   Bartlomiej Zolnierkiewicz   ide: move ide_ini...
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
  		drive->name[0]			= 'h';
  		drive->name[1]			= 'd';
  		drive->name[2]			= 'a' + j;
  		drive->max_failures		= IDE_DEFAULT_MAX_FAILURES;
  
  		INIT_LIST_HEAD(&drive->list);
  		init_completion(&drive->gendev_rel_comp);
  	}
  }
  
  static void ide_init_port_data(ide_hwif_t *hwif, unsigned int index)
  {
b40d1b88f   Bartlomiej Zolnierkiewicz   ide: move ide_ini...
1120
1121
1122
1123
1124
1125
1126
1127
  	/* fill in any non-zero initial values */
  	hwif->index	= index;
  	hwif->major	= ide_hwif_to_major[index];
  
  	hwif->name[0]	= 'i';
  	hwif->name[1]	= 'd';
  	hwif->name[2]	= 'e';
  	hwif->name[3]	= '0' + index;
7362951b4   Bartlomiej Zolnierkiewicz   ide: move ->lock ...
1128
1129
1130
1131
1132
  	spin_lock_init(&hwif->lock);
  
  	init_timer(&hwif->timer);
  	hwif->timer.function = &ide_timer_expiry;
  	hwif->timer.data = (unsigned long)hwif;
b40d1b88f   Bartlomiej Zolnierkiewicz   ide: move ide_ini...
1133
1134
1135
1136
1137
1138
  	init_completion(&hwif->gendev_rel_comp);
  
  	hwif->tp_ops = &default_tp_ops;
  
  	ide_port_init_devices_data(hwif);
  }
9f36d3143   Bartlomiej Zolnierkiewicz   ide: remove hw_re...
1139
  static void ide_init_port_hw(ide_hwif_t *hwif, struct ide_hw *hw)
b40d1b88f   Bartlomiej Zolnierkiewicz   ide: move ide_ini...
1140
1141
1142
  {
  	memcpy(&hwif->io_ports, &hw->io_ports, sizeof(hwif->io_ports));
  	hwif->irq = hw->irq;
b40d1b88f   Bartlomiej Zolnierkiewicz   ide: move ide_ini...
1143
1144
  	hwif->dev = hw->dev;
  	hwif->gendev.parent = hw->parent ? hw->parent : hw->dev;
b40d1b88f   Bartlomiej Zolnierkiewicz   ide: move ide_ini...
1145
1146
  	hwif->config_data = hw->config;
  }
8cdf31002   Bartlomiej Zolnierkiewicz   ide: fix IDE port...
1147
  static unsigned int ide_indexes;
fe80b937c   Bartlomiej Zolnierkiewicz   ide: merge ide_ma...
1148
  /**
8cdf31002   Bartlomiej Zolnierkiewicz   ide: fix IDE port...
1149
   *	ide_find_port_slot	-	find free port slot
fe80b937c   Bartlomiej Zolnierkiewicz   ide: merge ide_ma...
1150
1151
   *	@d: IDE port info
   *
8cdf31002   Bartlomiej Zolnierkiewicz   ide: fix IDE port...
1152
   *	Return the new port slot index or -ENOENT if we are out of free slots.
fe80b937c   Bartlomiej Zolnierkiewicz   ide: merge ide_ma...
1153
   */
8cdf31002   Bartlomiej Zolnierkiewicz   ide: fix IDE port...
1154
  static int ide_find_port_slot(const struct ide_port_info *d)
fe80b937c   Bartlomiej Zolnierkiewicz   ide: merge ide_ma...
1155
  {
8cdf31002   Bartlomiej Zolnierkiewicz   ide: fix IDE port...
1156
  	int idx = -ENOENT;
fe80b937c   Bartlomiej Zolnierkiewicz   ide: merge ide_ma...
1157
  	u8 bootable = (d && (d->host_flags & IDE_HFLAG_NON_BOOTABLE)) ? 0 : 1;
a419aef8b   Joe Perches   trivial: remove u...
1158
  	u8 i = (d && (d->host_flags & IDE_HFLAG_QD_2ND_PORT)) ? 1 : 0;
fe80b937c   Bartlomiej Zolnierkiewicz   ide: merge ide_ma...
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
  
  	/*
  	 * Claim an unassigned slot.
  	 *
  	 * Give preference to claiming other slots before claiming ide0/ide1,
  	 * just in case there's another interface yet-to-be-scanned
  	 * which uses ports 0x1f0/0x170 (the ide0/ide1 defaults).
  	 *
  	 * Unless there is a bootable card that does not use the standard
  	 * ports 0x1f0/0x170 (the ide0/ide1 defaults).
  	 */
8cdf31002   Bartlomiej Zolnierkiewicz   ide: fix IDE port...
1170
  	mutex_lock(&ide_cfg_mtx);
75d21fffd   Bartlomiej Zolnierkiewicz   ide: remove unnec...
1171
1172
1173
  	if (bootable) {
  		if ((ide_indexes | i) != (1 << MAX_HWIFS) - 1)
  			idx = ffz(ide_indexes | i);
fe80b937c   Bartlomiej Zolnierkiewicz   ide: merge ide_ma...
1174
  	} else {
75d21fffd   Bartlomiej Zolnierkiewicz   ide: remove unnec...
1175
1176
1177
1178
  		if ((ide_indexes | 3) != (1 << MAX_HWIFS) - 1)
  			idx = ffz(ide_indexes | 3);
  		else if ((ide_indexes & 3) != 3)
  			idx = ffz(ide_indexes);
fe80b937c   Bartlomiej Zolnierkiewicz   ide: merge ide_ma...
1179
  	}
8cdf31002   Bartlomiej Zolnierkiewicz   ide: fix IDE port...
1180
1181
1182
  	if (idx >= 0)
  		ide_indexes |= (1 << idx);
  	mutex_unlock(&ide_cfg_mtx);
fe80b937c   Bartlomiej Zolnierkiewicz   ide: merge ide_ma...
1183

8cdf31002   Bartlomiej Zolnierkiewicz   ide: fix IDE port...
1184
1185
  	return idx;
  }
256c5f8ee   Bartlomiej Zolnierkiewicz   ide: fix hwif-s i...
1186

8cdf31002   Bartlomiej Zolnierkiewicz   ide: fix IDE port...
1187
1188
1189
1190
1191
  static void ide_free_port_slot(int idx)
  {
  	mutex_lock(&ide_cfg_mtx);
  	ide_indexes &= ~(1 << idx);
  	mutex_unlock(&ide_cfg_mtx);
fe80b937c   Bartlomiej Zolnierkiewicz   ide: merge ide_ma...
1192
  }
fe80b937c   Bartlomiej Zolnierkiewicz   ide: merge ide_ma...
1193

5e7f3a466   Bartlomiej Zolnierkiewicz   ide: dynamic allo...
1194
1195
  static void ide_port_free_devices(ide_hwif_t *hwif)
  {
2bd24a1cf   Bartlomiej Zolnierkiewicz   ide: add port and...
1196
  	ide_drive_t *drive;
5e7f3a466   Bartlomiej Zolnierkiewicz   ide: dynamic allo...
1197
  	int i;
5f4417a15   Hugh Dickins   ide: fix PowerMac...
1198
1199
  	ide_port_for_each_dev(i, drive, hwif) {
  		kfree(drive->id);
2bd24a1cf   Bartlomiej Zolnierkiewicz   ide: add port and...
1200
  		kfree(drive);
5f4417a15   Hugh Dickins   ide: fix PowerMac...
1201
  	}
5e7f3a466   Bartlomiej Zolnierkiewicz   ide: dynamic allo...
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
  }
  
  static int ide_port_alloc_devices(ide_hwif_t *hwif, int node)
  {
  	int i;
  
  	for (i = 0; i < MAX_DRIVES; i++) {
  		ide_drive_t *drive;
  
  		drive = kzalloc_node(sizeof(*drive), GFP_KERNEL, node);
  		if (drive == NULL)
  			goto out_nomem;
5f4417a15   Hugh Dickins   ide: fix PowerMac...
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
  		/*
  		 * In order to keep things simple we have an id
  		 * block for all drives at all times. If the device
  		 * is pre ATA or refuses ATA/ATAPI identify we
  		 * will add faked data to this.
  		 *
  		 * Also note that 0 everywhere means "can't do X"
  		 */
  		drive->id = kzalloc_node(SECTOR_SIZE, GFP_KERNEL, node);
  		if (drive->id == NULL)
  			goto out_nomem;
5e7f3a466   Bartlomiej Zolnierkiewicz   ide: dynamic allo...
1225
1226
1227
1228
1229
1230
1231
1232
  		hwif->devices[i] = drive;
  	}
  	return 0;
  
  out_nomem:
  	ide_port_free_devices(hwif);
  	return -ENOMEM;
  }
9f36d3143   Bartlomiej Zolnierkiewicz   ide: remove hw_re...
1233
1234
  struct ide_host *ide_host_alloc(const struct ide_port_info *d,
  				struct ide_hw **hws, unsigned int n_ports)
48c3c1072   Bartlomiej Zolnierkiewicz   ide: add struct i...
1235
1236
  {
  	struct ide_host *host;
a32296f93   Bartlomiej Zolnierkiewicz   ide: NUMA aware a...
1237
1238
  	struct device *dev = hws[0] ? hws[0]->dev : NULL;
  	int node = dev ? dev_to_node(dev) : -1;
48c3c1072   Bartlomiej Zolnierkiewicz   ide: add struct i...
1239
  	int i;
a32296f93   Bartlomiej Zolnierkiewicz   ide: NUMA aware a...
1240
  	host = kzalloc_node(sizeof(*host), GFP_KERNEL, node);
48c3c1072   Bartlomiej Zolnierkiewicz   ide: add struct i...
1241
1242
  	if (host == NULL)
  		return NULL;
dca398305   Bartlomiej Zolnierkiewicz   ide: pass number ...
1243
  	for (i = 0; i < n_ports; i++) {
48c3c1072   Bartlomiej Zolnierkiewicz   ide: add struct i...
1244
  		ide_hwif_t *hwif;
8cdf31002   Bartlomiej Zolnierkiewicz   ide: fix IDE port...
1245
  		int idx;
48c3c1072   Bartlomiej Zolnierkiewicz   ide: add struct i...
1246
1247
1248
  
  		if (hws[i] == NULL)
  			continue;
a32296f93   Bartlomiej Zolnierkiewicz   ide: NUMA aware a...
1249
  		hwif = kzalloc_node(sizeof(*hwif), GFP_KERNEL, node);
18de10170   Bartlomiej Zolnierkiewicz   ide: allocate ide...
1250
1251
  		if (hwif == NULL)
  			continue;
5e7f3a466   Bartlomiej Zolnierkiewicz   ide: dynamic allo...
1252
1253
1254
1255
  		if (ide_port_alloc_devices(hwif, node) < 0) {
  			kfree(hwif);
  			continue;
  		}
8cdf31002   Bartlomiej Zolnierkiewicz   ide: fix IDE port...
1256
1257
1258
1259
1260
  		idx = ide_find_port_slot(d);
  		if (idx < 0) {
  			printk(KERN_ERR "%s: no free slot for interface
  ",
  					d ? d->name : "ide");
5f4417a15   Hugh Dickins   ide: fix PowerMac...
1261
  			ide_port_free_devices(hwif);
18de10170   Bartlomiej Zolnierkiewicz   ide: allocate ide...
1262
  			kfree(hwif);
8cdf31002   Bartlomiej Zolnierkiewicz   ide: fix IDE port...
1263
  			continue;
48c3c1072   Bartlomiej Zolnierkiewicz   ide: add struct i...
1264
  		}
8cdf31002   Bartlomiej Zolnierkiewicz   ide: fix IDE port...
1265

8cdf31002   Bartlomiej Zolnierkiewicz   ide: fix IDE port...
1266
  		ide_init_port_data(hwif, idx);
08da591e1   Bartlomiej Zolnierkiewicz   ide: add ide_devi...
1267
  		hwif->host = host;
8cdf31002   Bartlomiej Zolnierkiewicz   ide: fix IDE port...
1268
1269
  		host->ports[i] = hwif;
  		host->n_ports++;
48c3c1072   Bartlomiej Zolnierkiewicz   ide: add struct i...
1270
1271
1272
1273
1274
1275
  	}
  
  	if (host->n_ports == 0) {
  		kfree(host);
  		return NULL;
  	}
a32296f93   Bartlomiej Zolnierkiewicz   ide: NUMA aware a...
1276
  	host->dev[0] = dev;
6cdf6eb35   Bartlomiej Zolnierkiewicz   ide: add ->dev an...
1277

feb22b7f8   Bartlomiej Zolnierkiewicz   ide: add proper P...
1278
1279
  	if (d) {
  		host->init_chipset = d->init_chipset;
e354c1d80   Bartlomiej Zolnierkiewicz   ide: remove IDE_A...
1280
1281
  		host->get_lock     = d->get_lock;
  		host->release_lock = d->release_lock;
ef0b04276   Bartlomiej Zolnierkiewicz   ide: add ide_pci_...
1282
  		host->host_flags = d->host_flags;
aa07573b2   Geert Uytterhoeven   ide: Fix host dri...
1283
  		host->irq_flags = d->irq_flags;
feb22b7f8   Bartlomiej Zolnierkiewicz   ide: add proper P...
1284
  	}
ef0b04276   Bartlomiej Zolnierkiewicz   ide: add ide_pci_...
1285

48c3c1072   Bartlomiej Zolnierkiewicz   ide: add struct i...
1286
1287
  	return host;
  }
48c3c1072   Bartlomiej Zolnierkiewicz   ide: add struct i...
1288
  EXPORT_SYMBOL_GPL(ide_host_alloc);
9a100f4b7   Bartlomiej Zolnierkiewicz   ide: fix ide_regi...
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
  static void ide_port_free(ide_hwif_t *hwif)
  {
  	ide_port_free_devices(hwif);
  	ide_free_port_slot(hwif->index);
  	kfree(hwif);
  }
  
  static void ide_disable_port(ide_hwif_t *hwif)
  {
  	struct ide_host *host = hwif->host;
  	int i;
  
  	printk(KERN_INFO "%s: disabling port
  ", hwif->name);
  
  	for (i = 0; i < MAX_HOST_PORTS; i++) {
  		if (host->ports[i] == hwif) {
  			host->ports[i] = NULL;
  			host->n_ports--;
  		}
  	}
  
  	ide_port_free(hwif);
  }
48c3c1072   Bartlomiej Zolnierkiewicz   ide: add struct i...
1313
  int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
9f36d3143   Bartlomiej Zolnierkiewicz   ide: remove hw_re...
1314
  		      struct ide_hw **hws)
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
1315
1316
  {
  	ide_hwif_t *hwif, *mate = NULL;
e0d002078   Bartlomiej Zolnierkiewicz   ide: fix ide_host...
1317
  	int i, j = 0;
8447d9d52   Bartlomiej Zolnierkiewicz   ide: add ide_devi...
1318

2bd24a1cf   Bartlomiej Zolnierkiewicz   ide: add port and...
1319
  	ide_host_for_each_port(i, hwif, host) {
e0d002078   Bartlomiej Zolnierkiewicz   ide: fix ide_host...
1320
  		if (hwif == NULL) {
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
1321
1322
1323
  			mate = NULL;
  			continue;
  		}
c97c6aca7   Bartlomiej Zolnierkiewicz   ide: pass hw_regs...
1324
  		ide_init_port_hw(hwif, hws[i]);
9fd91d959   Bartlomiej Zolnierkiewicz   ide: add "ignore_...
1325
  		ide_port_apply_params(hwif);
0a6e49e9b   Bartlomiej Zolnierkiewicz   ide: remove now s...
1326
1327
1328
  		if ((i & 1) && mate) {
  			hwif->mate = mate;
  			mate->mate = hwif;
123995b97   Bartlomiej Zolnierkiewicz   ide: use 'drive->...
1329
  		}
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
1330

0a6e49e9b   Bartlomiej Zolnierkiewicz   ide: remove now s...
1331
1332
1333
1334
  		mate = (i & 1) ? NULL : hwif;
  
  		ide_init_port(hwif, i & 1, d);
  		ide_port_cable_detect(hwif);
5880b5de7   Bartlomiej Zolnierkiewicz   ide: don't enable...
1335
1336
  
  		hwif->port_flags |= IDE_PFLAG_PROBING;
7704ca2a3   Bartlomiej Zolnierkiewicz   ide: factor out c...
1337
  		ide_port_init_devices(hwif);
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
1338
  	}
2bd24a1cf   Bartlomiej Zolnierkiewicz   ide: add port and...
1339
  	ide_host_for_each_port(i, hwif, host) {
e0d002078   Bartlomiej Zolnierkiewicz   ide: fix ide_host...
1340
1341
  		if (hwif == NULL)
  			continue;
139ddfcab   Bartlomiej Zolnierkiewicz   ide: move handlin...
1342

eb716beb0   Bartlomiej Zolnierkiewicz   ide: register por...
1343
1344
  		if (ide_probe_port(hwif) == 0)
  			hwif->present = 1;
a14dc5749   Bartlomiej Zolnierkiewicz   ide: move hwif_re...
1345

5880b5de7   Bartlomiej Zolnierkiewicz   ide: don't enable...
1346
  		hwif->port_flags &= ~IDE_PFLAG_PROBING;
c094ea077   Bartlomiej Zolnierkiewicz   ide: add IDE_HFLA...
1347
1348
  		if ((hwif->host_flags & IDE_HFLAG_4DRIVES) == 0 ||
  		    hwif->mate == NULL || hwif->mate->present == 0) {
9a100f4b7   Bartlomiej Zolnierkiewicz   ide: fix ide_regi...
1349
1350
1351
1352
1353
  			if (ide_register_port(hwif)) {
  				ide_disable_port(hwif);
  				continue;
  			}
  		}
a14dc5749   Bartlomiej Zolnierkiewicz   ide: move hwif_re...
1354

eb716beb0   Bartlomiej Zolnierkiewicz   ide: register por...
1355
1356
  		if (hwif->present)
  			ide_port_tune_devices(hwif);
2e13093a8   Bartlomiej Zolnierkiewicz   ide: fix probing ...
1357
  	}
ba6560aa4   Bartlomiej Zolnierkiewicz   ide: kill probe_h...
1358

ffc36c761   Bartlomiej Zolnierkiewicz   ide: fix handling...
1359
  	ide_host_enable_irqs(host);
2bd24a1cf   Bartlomiej Zolnierkiewicz   ide: add port and...
1360
  	ide_host_for_each_port(i, hwif, host) {
e0d002078   Bartlomiej Zolnierkiewicz   ide: fix ide_host...
1361
1362
  		if (hwif == NULL)
  			continue;
ba6560aa4   Bartlomiej Zolnierkiewicz   ide: kill probe_h...
1363
1364
1365
1366
1367
  
  		if (hwif_init(hwif) == 0) {
  			printk(KERN_INFO "%s: failed to initialize IDE "
  					 "interface
  ", hwif->name);
51d6ac701   Ian Campbell   IDE: Unregister a...
1368
1369
  			device_unregister(&hwif->gendev);
  			ide_disable_port(hwif);
ba6560aa4   Bartlomiej Zolnierkiewicz   ide: kill probe_h...
1370
1371
  			continue;
  		}
decdc3f0d   Bartlomiej Zolnierkiewicz   ide: move ide_acp...
1372

eb716beb0   Bartlomiej Zolnierkiewicz   ide: register por...
1373
  		if (hwif->present)
e415e495f   Elias Oltmanns   ide: Two fixes re...
1374
1375
1376
1377
1378
1379
  			if (ide_port_setup_devices(hwif) == 0) {
  				hwif->present = 0;
  				continue;
  			}
  
  		j++;
26042d058   Bartlomiej Zolnierkiewicz   ide: move ide_por...
1380

8b803bd18   Bartlomiej Zolnierkiewicz   ide: sanitize ACP...
1381
  		ide_acpi_init_port(hwif);
eb716beb0   Bartlomiej Zolnierkiewicz   ide: register por...
1382
1383
1384
  
  		if (hwif->present)
  			ide_acpi_port_init_devices(hwif);
2e13093a8   Bartlomiej Zolnierkiewicz   ide: fix probing ...
1385
  	}
2bd24a1cf   Bartlomiej Zolnierkiewicz   ide: add port and...
1386
  	ide_host_for_each_port(i, hwif, host) {
e0d002078   Bartlomiej Zolnierkiewicz   ide: fix ide_host...
1387
1388
  		if (hwif == NULL)
  			continue;
ba6560aa4   Bartlomiej Zolnierkiewicz   ide: kill probe_h...
1389

eb716beb0   Bartlomiej Zolnierkiewicz   ide: register por...
1390
1391
  		ide_sysfs_register_port(hwif);
  		ide_proc_register_port(hwif);
dbee03229   Wolfram Sang   ide: Fix ordering...
1392
  		if (hwif->present) {
d9270a3f1   Bartlomiej Zolnierkiewicz   ide: move create_...
1393
  			ide_proc_port_register_devices(hwif);
dbee03229   Wolfram Sang   ide: Fix ordering...
1394
1395
  			hwif_register_devices(hwif);
  		}
8447d9d52   Bartlomiej Zolnierkiewicz   ide: add ide_devi...
1396
  	}
e0d002078   Bartlomiej Zolnierkiewicz   ide: fix ide_host...
1397
  	return j ? 0 : -1;
8447d9d52   Bartlomiej Zolnierkiewicz   ide: add ide_devi...
1398
  }
48c3c1072   Bartlomiej Zolnierkiewicz   ide: add struct i...
1399
  EXPORT_SYMBOL_GPL(ide_host_register);
151575e46   Bartlomiej Zolnierkiewicz   ide: remove idepr...
1400

9f36d3143   Bartlomiej Zolnierkiewicz   ide: remove hw_re...
1401
  int ide_host_add(const struct ide_port_info *d, struct ide_hw **hws,
dca398305   Bartlomiej Zolnierkiewicz   ide: pass number ...
1402
  		 unsigned int n_ports, struct ide_host **hostp)
6f904d015   Bartlomiej Zolnierkiewicz   ide: add ide_host...
1403
1404
  {
  	struct ide_host *host;
8a69580e1   Bartlomiej Zolnierkiewicz   ide: add ide_host...
1405
  	int rc;
6f904d015   Bartlomiej Zolnierkiewicz   ide: add ide_host...
1406

dca398305   Bartlomiej Zolnierkiewicz   ide: pass number ...
1407
  	host = ide_host_alloc(d, hws, n_ports);
6f904d015   Bartlomiej Zolnierkiewicz   ide: add ide_host...
1408
1409
  	if (host == NULL)
  		return -ENOMEM;
8a69580e1   Bartlomiej Zolnierkiewicz   ide: add ide_host...
1410
1411
1412
1413
1414
  	rc = ide_host_register(host, d, hws);
  	if (rc) {
  		ide_host_free(host);
  		return rc;
  	}
6f904d015   Bartlomiej Zolnierkiewicz   ide: add ide_host...
1415
1416
1417
1418
1419
1420
1421
  
  	if (hostp)
  		*hostp = host;
  
  	return 0;
  }
  EXPORT_SYMBOL_GPL(ide_host_add);
b40d1b88f   Bartlomiej Zolnierkiewicz   ide: move ide_ini...
1422
1423
  static void __ide_port_unregister_devices(ide_hwif_t *hwif)
  {
2bd24a1cf   Bartlomiej Zolnierkiewicz   ide: add port and...
1424
  	ide_drive_t *drive;
b40d1b88f   Bartlomiej Zolnierkiewicz   ide: move ide_ini...
1425
  	int i;
7ed5b157d   Bartlomiej Zolnierkiewicz   ide: add ide_for_...
1426
1427
1428
  	ide_port_for_each_present_dev(i, drive, hwif) {
  		device_unregister(&drive->gendev);
  		wait_for_completion(&drive->gendev_rel_comp);
b40d1b88f   Bartlomiej Zolnierkiewicz   ide: move ide_ini...
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
  	}
  }
  
  void ide_port_unregister_devices(ide_hwif_t *hwif)
  {
  	mutex_lock(&ide_cfg_mtx);
  	__ide_port_unregister_devices(hwif);
  	hwif->present = 0;
  	ide_port_init_devices_data(hwif);
  	mutex_unlock(&ide_cfg_mtx);
  }
  EXPORT_SYMBOL_GPL(ide_port_unregister_devices);
  
  /**
   *	ide_unregister		-	free an IDE interface
   *	@hwif: IDE interface
   *
   *	Perform the final unregister of an IDE interface.
   *
   *	Locking:
   *	The caller must not hold the IDE locks.
   *
   *	It is up to the caller to be sure there is no pending I/O here,
   *	and that the interface will not be reopened (present/vanishing
   *	locking isn't yet done BTW).
   */
  
  static void ide_unregister(ide_hwif_t *hwif)
  {
  	BUG_ON(in_interrupt());
  	BUG_ON(irqs_disabled());
  
  	mutex_lock(&ide_cfg_mtx);
  
  	if (hwif->present) {
  		__ide_port_unregister_devices(hwif);
  		hwif->present = 0;
  	}
  
  	ide_proc_unregister_port(hwif);
  
  	free_irq(hwif->irq, hwif);
  
  	device_unregister(hwif->portdev);
  	device_unregister(&hwif->gendev);
  	wait_for_completion(&hwif->gendev_rel_comp);
  
  	/*
  	 * Remove us from the kernel's knowledge
  	 */
  	blk_unregister_region(MKDEV(hwif->major, 0), MAX_DRIVES<<PARTN_BITS);
  	kfree(hwif->sg_table);
  	unregister_blkdev(hwif->major, hwif->name);
  
  	ide_release_dma_engine(hwif);
  
  	mutex_unlock(&ide_cfg_mtx);
  }
8a69580e1   Bartlomiej Zolnierkiewicz   ide: add ide_host...
1487
  void ide_host_free(struct ide_host *host)
151575e46   Bartlomiej Zolnierkiewicz   ide: remove idepr...
1488
  {
8cdf31002   Bartlomiej Zolnierkiewicz   ide: fix IDE port...
1489
  	ide_hwif_t *hwif;
151575e46   Bartlomiej Zolnierkiewicz   ide: remove idepr...
1490
  	int i;
8447d9d52   Bartlomiej Zolnierkiewicz   ide: add ide_devi...
1491

2bd24a1cf   Bartlomiej Zolnierkiewicz   ide: add port and...
1492
  	ide_host_for_each_port(i, hwif, host) {
9a100f4b7   Bartlomiej Zolnierkiewicz   ide: fix ide_regi...
1493
1494
  		if (hwif)
  			ide_port_free(hwif);
c97c6aca7   Bartlomiej Zolnierkiewicz   ide: pass hw_regs...
1495
  	}
151575e46   Bartlomiej Zolnierkiewicz   ide: remove idepr...
1496

48c3c1072   Bartlomiej Zolnierkiewicz   ide: add struct i...
1497
  	kfree(host);
151575e46   Bartlomiej Zolnierkiewicz   ide: remove idepr...
1498
  }
8a69580e1   Bartlomiej Zolnierkiewicz   ide: add ide_host...
1499
1500
1501
1502
  EXPORT_SYMBOL_GPL(ide_host_free);
  
  void ide_host_remove(struct ide_host *host)
  {
2bd24a1cf   Bartlomiej Zolnierkiewicz   ide: add port and...
1503
  	ide_hwif_t *hwif;
8a69580e1   Bartlomiej Zolnierkiewicz   ide: add ide_host...
1504
  	int i;
2bd24a1cf   Bartlomiej Zolnierkiewicz   ide: add port and...
1505
1506
1507
  	ide_host_for_each_port(i, hwif, host) {
  		if (hwif)
  			ide_unregister(hwif);
8a69580e1   Bartlomiej Zolnierkiewicz   ide: add ide_host...
1508
1509
1510
1511
  	}
  
  	ide_host_free(host);
  }
48c3c1072   Bartlomiej Zolnierkiewicz   ide: add struct i...
1512
  EXPORT_SYMBOL_GPL(ide_host_remove);
2dde7861a   Bartlomiej Zolnierkiewicz   ide: rework Power...
1513
1514
1515
  
  void ide_port_scan(ide_hwif_t *hwif)
  {
5880b5de7   Bartlomiej Zolnierkiewicz   ide: don't enable...
1516
  	int rc;
9fd91d959   Bartlomiej Zolnierkiewicz   ide: add "ignore_...
1517
  	ide_port_apply_params(hwif);
2dde7861a   Bartlomiej Zolnierkiewicz   ide: rework Power...
1518
  	ide_port_cable_detect(hwif);
5880b5de7   Bartlomiej Zolnierkiewicz   ide: don't enable...
1519
1520
  
  	hwif->port_flags |= IDE_PFLAG_PROBING;
2dde7861a   Bartlomiej Zolnierkiewicz   ide: rework Power...
1521
  	ide_port_init_devices(hwif);
5880b5de7   Bartlomiej Zolnierkiewicz   ide: don't enable...
1522
1523
1524
1525
1526
  	rc = ide_probe_port(hwif);
  
  	hwif->port_flags &= ~IDE_PFLAG_PROBING;
  
  	if (rc < 0)
2dde7861a   Bartlomiej Zolnierkiewicz   ide: rework Power...
1527
1528
1529
1530
1531
  		return;
  
  	hwif->present = 1;
  
  	ide_port_tune_devices(hwif);
2dde7861a   Bartlomiej Zolnierkiewicz   ide: rework Power...
1532
  	ide_port_setup_devices(hwif);
e630fcbe9   Bartlomiej Zolnierkiewicz   ide: fix ide_port...
1533
  	ide_acpi_port_init_devices(hwif);
2dde7861a   Bartlomiej Zolnierkiewicz   ide: rework Power...
1534
1535
1536
1537
  	hwif_register_devices(hwif);
  	ide_proc_port_register_devices(hwif);
  }
  EXPORT_SYMBOL_GPL(ide_port_scan);