Blame view

drivers/ide/ide-probe.c 39.2 KB
457c89965   Thomas Gleixner   treewide: Add SPD...
1
  // SPDX-License-Identifier: GPL-2.0-only
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
  /*
59bca8cc9   Bartlomiej Zolnierkiewicz   ide: update/add m...
3
4
   *  Copyright (C) 1994-1998   Linus Torvalds & authors (see below)
   *  Copyright (C) 2005, 2007  Bartlomiej Zolnierkiewicz
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
5
6
7
8
9
10
11
12
13
14
15
   */
  
  /*
   *  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...
16
17
   * -- increase WAIT_PIDENTIFY to avoid CD-ROM locking at boot
   *	 by Andrea Arcangeli
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
18
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
  #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
35
  #include <linux/scatterlist.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
36
37
38
  
  #include <asm/byteorder.h>
  #include <asm/irq.h>
7c0f6ba68   Linus Torvalds   Replace <asm/uacc...
39
  #include <linux/uaccess.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
40
41
42
43
44
45
46
47
48
49
50
51
52
  #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->...
53
54
55
56
57
  	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
58
59
60
61
  }
  
  static void ide_disk_init_chs(ide_drive_t *drive)
  {
4dde4492d   Bartlomiej Zolnierkiewicz   ide: make drive->...
62
  	u16 *id = drive->id;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
63
64
65
  
  	/* 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->...
66
67
68
  		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
69
70
71
  	}
  
  	/* Handle logical geometry translation by the drive */
dd8f46f64   Bartlomiej Zolnierkiewicz   ide: use ata_id_c...
72
  	if (ata_id_current_chs_valid(id)) {
4dde4492d   Bartlomiej Zolnierkiewicz   ide: make drive->...
73
74
75
  		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
76
77
78
  	}
  
  	/* Use physical geometry if what we have still makes no sense */
4dde4492d   Bartlomiej Zolnierkiewicz   ide: make drive->...
79
80
81
82
  	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
83
84
85
86
87
  	}
  }
  
  static void ide_disk_init_mult_count(ide_drive_t *drive)
  {
48fb2688a   Bartlomiej Zolnierkiewicz   ide: remove drive...
88
89
  	u16 *id = drive->id;
  	u8 max_multsect = id[ATA_ID_MAX_MULTSECT] & 0xff;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
90

48fb2688a   Bartlomiej Zolnierkiewicz   ide: remove drive...
91
  	if (max_multsect) {
48fb2688a   Bartlomiej Zolnierkiewicz   ide: remove drive...
92
93
94
95
96
97
  		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...
98
99
  
  		if (drive->mult_req)
ca1b96e00   Bartlomiej Zolnierkiewicz   ide: replace spec...
100
  			drive->special_flags |= IDE_SFLAG_SET_MULTMODE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
101
102
  	}
  }
24630dc68   Bartlomiej Zolnierkiewicz   ide: factor out d...
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
  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;
a2eed33dc   Gustavo A. R. Silva   ide: mark expecte...
145
  		/* fall through */
24630dc68   Bartlomiej Zolnierkiewicz   ide: factor out d...
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
179
180
  	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
181
  /**
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
182
183
184
   *	do_identify	-	identify a drive
   *	@drive: drive to identify 
   *	@cmd: command used
2ebe1d9ef   Bartlomiej Zolnierkiewicz   ide: use try_to_i...
185
   *	@id: buffer for IDENTIFY data
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
186
187
188
189
190
   *
   *	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...
191

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

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

97100fc81   Bartlomiej Zolnierkiewicz   ide: add device f...
205
  	drive->dev_flags |= IDE_DFLAG_ID_READ;
7b9f25b53   Bartlomiej Zolnierkiewicz   ide: add ide_dump...
206
207
208
209
210
  #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
211
  	ide_fix_driveid(id);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
212
  	/*
aaaade3f0   Bartlomiej Zolnierkiewicz   ide: WIN_* -> ATA...
213
214
  	 *  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
215
  	 */
aaaade3f0   Bartlomiej Zolnierkiewicz   ide: WIN_* -> ATA...
216
  	if (cmd == ATA_CMD_ID_ATAPI) {
4dde4492d   Bartlomiej Zolnierkiewicz   ide: make drive->...
217
218
219
  		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
220
  			/* Vertos drives may still be weird */
4dde4492d   Bartlomiej Zolnierkiewicz   ide: make drive->...
221
  			bswap ^= 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
222
  	}
4dde4492d   Bartlomiej Zolnierkiewicz   ide: make drive->...
223
224
225
226
  
  	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
227

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

4dde4492d   Bartlomiej Zolnierkiewicz   ide: make drive->...
231
  	if (strstr(m, "E X A B Y T E N E S T"))
69197ad70   Bartlomiej Zolnierkiewicz   ide: fix memleak ...
232
233
234
  		drive->dev_flags &= ~IDE_DFLAG_PRESENT;
  	else
  		drive->dev_flags |= IDE_DFLAG_PRESENT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
235
236
237
  }
  
  /**
2ebe1d9ef   Bartlomiej Zolnierkiewicz   ide: use try_to_i...
238
   *	ide_dev_read_id	-	send ATA/ATAPI IDENTIFY command
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
239
240
   *	@drive: drive to identify
   *	@cmd: command to use
2ebe1d9ef   Bartlomiej Zolnierkiewicz   ide: use try_to_i...
241
   *	@id: buffer for IDENTIFY data
fa56d4cb4   Bartlomiej Zolnierkiewicz   ide: allow ide_de...
242
   *	@irq_ctx: flag set when called from the IRQ context
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
243
   *
2ebe1d9ef   Bartlomiej Zolnierkiewicz   ide: use try_to_i...
244
   *	Sends an ATA(PI) IDENTIFY request to a drive and waits for a response.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
245
246
247
248
249
   *
   *	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...
250
  int ide_dev_read_id(ide_drive_t *drive, u8 cmd, u16 *id, int irq_ctx)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
251
  {
898ec223f   Bartlomiej Zolnierkiewicz   ide: remove HWIF(...
252
  	ide_hwif_t *hwif = drive->hwif;
4c3032d8a   Bartlomiej Zolnierkiewicz   ide: add struct i...
253
  	struct ide_io_ports *io_ports = &hwif->io_ports;
374e042c3   Bartlomiej Zolnierkiewicz   ide: add struct i...
254
  	const struct ide_tp_ops *tp_ops = hwif->tp_ops;
c47137a99   Bartlomiej Zolnierkiewicz   ide: add ide_read...
255
  	int use_altstatus = 0, rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
256
257
  	unsigned long timeout;
  	u8 s = 0, a = 0;
a182807a8   Bartlomiej Zolnierkiewicz   ide: remove try_t...
258
259
260
261
262
  	/*
  	 * 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...
263
  		tp_ops->write_devctl(hwif, ATA_NIEN | ATA_DEVCTL_OBS);
a182807a8   Bartlomiej Zolnierkiewicz   ide: remove try_t...
264

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

6636487e8   Bartlomiej Zolnierkiewicz   amd74xx: workarou...
271
272
  	if (io_ports->ctl_addr &&
  	    (hwif->host_flags & IDE_HFLAG_BROKEN_ALTSTATUS) == 0) {
374e042c3   Bartlomiej Zolnierkiewicz   ide: add struct i...
273
274
  		a = tp_ops->read_altstatus(hwif);
  		s = tp_ops->read_status(hwif);
27f00e53a   Hannes Reinecke   ide,ata: Rename A...
275
  		if ((a ^ s) & ~ATA_SENSE)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
276
  			/* ancient Seagate drives, broken interfaces */
c47137a99   Bartlomiej Zolnierkiewicz   ide: add ide_read...
277
278
279
280
281
  			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
282
  			/* use non-intrusive polling */
c47137a99   Bartlomiej Zolnierkiewicz   ide: add ide_read...
283
284
  			use_altstatus = 1;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
285
286
287
288
  
  	/* set features register for atapi
  	 * identify command to be sure of reply
  	 */
aaaade3f0   Bartlomiej Zolnierkiewicz   ide: WIN_* -> ATA...
289
  	if (cmd == ATA_CMD_ID_ATAPI) {
c9ff9e7b6   Sergei Shtylyov   ide: refactor tf_...
290
  		struct ide_taskfile tf;
4e65837b2   Bartlomiej Zolnierkiewicz   ide: use ->tf_loa...
291

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

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

3a7d24841   Bartlomiej Zolnierkiewicz   ide: use ATA_* de...
302
  	/* wait for IRQ and ATA_DRQ */
fa56d4cb4   Bartlomiej Zolnierkiewicz   ide: allow ide_de...
303
304
305
306
307
308
309
310
311
312
313
314
  	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...
315

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

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

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

3153c26b5   Sergei Shtylyov   ide: refactor tf_...
352
  	return tf.device;
1f2efb82a   Bartlomiej Zolnierkiewicz   ide: add ide_read...
353
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
  /**
   *	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(...
377
  	ide_hwif_t *hwif = drive->hwif;
374e042c3   Bartlomiej Zolnierkiewicz   ide: add struct i...
378
  	const struct ide_tp_ops *tp_ops = hwif->tp_ops;
2ebe1d9ef   Bartlomiej Zolnierkiewicz   ide: use try_to_i...
379
  	u16 *id = drive->id;
57b552757   Bartlomiej Zolnierkiewicz   ide-probe: remove...
380
  	int rc;
97100fc81   Bartlomiej Zolnierkiewicz   ide: add device f...
381
382
383
384
385
  	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
386

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

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

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

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

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

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

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

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

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
491
  		/* identification failed? */
97100fc81   Bartlomiej Zolnierkiewicz   ide: add device f...
492
  		if ((drive->dev_flags & IDE_DFLAG_ID_READ) == 0) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
493
494
495
496
497
498
499
500
501
502
503
504
  			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...
505
  				drive->dev_flags &= ~IDE_DFLAG_PRESENT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
506
  			}
1bd4c1f4f   Bartlomiej Zolnierkiewicz   ide: classify dev...
507
508
509
510
511
  		} 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
512
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
513
  	}
97100fc81   Bartlomiej Zolnierkiewicz   ide: add device f...
514
515
  
  	if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
5f4417a15   Hugh Dickins   ide: fix PowerMac...
516
  		return 0;
97100fc81   Bartlomiej Zolnierkiewicz   ide: add device f...
517

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

349ae23fe   Randy Dunlap   [PATCH] IDE core:...
545
  	ret = device_register(&hwif->gendev);
f74c91413   Bartlomiej Zolnierkiewicz   ide: add warm-plu...
546
  	if (ret < 0) {
349ae23fe   Randy Dunlap   [PATCH] IDE core:...
547
548
  		printk(KERN_WARNING "IDE: %s: device_register error: %d
  ",
eb63963a5   Harvey Harrison   ide: replace rema...
549
  			__func__, ret);
f74c91413   Bartlomiej Zolnierkiewicz   ide: add warm-plu...
550
551
  		goto out;
  	}
3ee074bf4   Greg Kroah-Hartman   device create: id...
552
  	hwif->portdev = device_create(ide_port_class, &hwif->gendev,
02aa2a376   Kees Cook   drivers: avoid fo...
553
  				      MKDEV(0, 0), hwif, "%s", hwif->name);
f74c91413   Bartlomiej Zolnierkiewicz   ide: add warm-plu...
554
555
556
557
  	if (IS_ERR(hwif->portdev)) {
  		ret = PTR_ERR(hwif->portdev);
  		device_unregister(&hwif->gendev);
  	}
f74c91413   Bartlomiej Zolnierkiewicz   ide: add warm-plu...
558
559
  out:
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
560
  }
c860a8f2d   Bartlomiej Zolnierkiewicz   ide: move wait_hw...
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
586
587
  /**
   *	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
588
  {
fdd88f0af   Sergei Shtylyov   ide: inline SELEC...
589
  	const struct ide_tp_ops *tp_ops = hwif->tp_ops;
2bd24a1cf   Bartlomiej Zolnierkiewicz   ide: add port and...
590
591
  	ide_drive_t *drive;
  	int i, rc;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
  
  	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...
609
  	ide_port_for_each_dev(i, drive, hwif) {
8266105b1   Jonas Stare   ide: skip ide_wai...
610
  		/* Ignore disks that we will not probe for later. */
97100fc81   Bartlomiej Zolnierkiewicz   ide: add device f...
611
612
  		if ((drive->dev_flags & IDE_DFLAG_NOPROBE) == 0 ||
  		    (drive->dev_flags & IDE_DFLAG_PRESENT)) {
fdd88f0af   Sergei Shtylyov   ide: inline SELEC...
613
614
  			tp_ops->dev_select(drive);
  			tp_ops->write_devctl(hwif, ATA_DEVCTL_OBS);
8266105b1   Jonas Stare   ide: skip ide_wai...
615
616
617
618
619
620
621
622
623
624
  			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
625
  	/* Exit function with master reselected (let's be sane) */
2bd24a1cf   Bartlomiej Zolnierkiewicz   ide: add port and...
626
  	if (i)
fdd88f0af   Sergei Shtylyov   ide: inline SELEC...
627
  		tp_ops->dev_select(hwif->devices[0]);
8266105b1   Jonas Stare   ide: skip ide_wai...
628

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
629
630
631
632
633
  	return rc;
  }
  
  /**
   *	ide_undecoded_slave	-	look for bad CF adapters
4dde4492d   Bartlomiej Zolnierkiewicz   ide: make drive->...
634
   *	@dev1: slave device
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
635
636
637
638
639
   *
   *	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->...
640
  void ide_undecoded_slave(ide_drive_t *dev1)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
641
  {
5e7f3a466   Bartlomiej Zolnierkiewicz   ide: dynamic allo...
642
  	ide_drive_t *dev0 = dev1->hwif->devices[0];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
643

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

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

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
680
681
682
683
684
685
686
  	/*
  	 * 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...
687
688
689
  	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
690
691
  
  	/*
f367bed00   Bartlomiej Zolnierkiewicz   Revert "ide: chan...
692
693
  	 * 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
694
  	 */
2bd24a1cf   Bartlomiej Zolnierkiewicz   ide: add port and...
695
  	ide_port_for_each_dev(i, drive, hwif) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
696
  		(void) probe_for_drive(drive);
97100fc81   Bartlomiej Zolnierkiewicz   ide: add device f...
697
  		if (drive->dev_flags & IDE_DFLAG_PRESENT)
a14dc5749   Bartlomiej Zolnierkiewicz   ide: move hwif_re...
698
  			rc = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
699
  	}
9ce41aed0   David S. Miller   Revert "ide: skip...
700

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
701
702
703
704
705
706
  	/*
  	 * 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...
707
  	return rc;
e84e7ea7c   Bartlomiej Zolnierkiewicz   ide: factor out c...
708
709
710
711
  }
  
  static void ide_port_tune_devices(ide_hwif_t *hwif)
  {
ac95beedf   Bartlomiej Zolnierkiewicz   ide: add struct i...
712
  	const struct ide_port_ops *port_ops = hwif->port_ops;
2bd24a1cf   Bartlomiej Zolnierkiewicz   ide: add port and...
713
714
  	ide_drive_t *drive;
  	int i;
f01393e48   Bartlomiej Zolnierkiewicz   ide: merge ->fixu...
715

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

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

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

7ed5b157d   Bartlomiej Zolnierkiewicz   ide: add ide_for_...
727
728
  		if (hwif->dma_ops)
  			ide_set_dma(drive);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
729
730
  	}
  }
ca18d6f76   Bart Van Assche   block: Make most ...
731
  static void ide_initialize_rq(struct request *rq)
82ed4db49   Christoph Hellwig   block: split scsi...
732
733
  {
  	struct ide_request *req = blk_mq_rq_to_pdu(rq);
d16a67667   Jens Axboe   ide: don't clear ...
734
  	req->special = NULL;
c8d9cf22c   Bart Van Assche   block: Change arg...
735
  	scsi_req_init(&req->sreq);
82ed4db49   Christoph Hellwig   block: split scsi...
736
  	req->sreq.sense = req->sense;
82ed4db49   Christoph Hellwig   block: split scsi...
737
  }
600335205   Jens Axboe   ide: convert to b...
738
739
740
741
  static const struct blk_mq_ops ide_mq_ops = {
  	.queue_rq		= ide_queue_rq,
  	.initialize_rq_fn	= ide_initialize_rq,
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
742
  /*
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
743
744
745
746
   * init request queue
   */
  static int ide_init_queue(ide_drive_t *drive)
  {
165125e1e   Jens Axboe   [BLOCK] Get rid o...
747
  	struct request_queue *q;
898ec223f   Bartlomiej Zolnierkiewicz   ide: remove HWIF(...
748
  	ide_hwif_t *hwif = drive->hwif;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
749
750
  	int max_sectors = 256;
  	int max_sg_entries = PRD_ENTRIES;
600335205   Jens Axboe   ide: convert to b...
751
  	struct blk_mq_tag_set *set;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
752
753
754
755
756
757
758
759
  
  	/*
  	 *	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.
  	 */
600335205   Jens Axboe   ide: convert to b...
760
761
762
763
764
765
766
767
768
769
  
  	set = &drive->tag_set;
  	set->ops = &ide_mq_ops;
  	set->nr_hw_queues = 1;
  	set->queue_depth = 32;
  	set->reserved_tags = 1;
  	set->cmd_size = sizeof(struct ide_request);
  	set->numa_node = hwif_to_node(hwif);
  	set->flags = BLK_MQ_F_SHOULD_MERGE | BLK_MQ_F_BLOCKING;
  	if (blk_mq_alloc_tag_set(set))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
770
  		return 1;
600335205   Jens Axboe   ide: convert to b...
771
772
773
  	q = blk_mq_init_queue(set);
  	if (IS_ERR(q)) {
  		blk_mq_free_tag_set(set);
82ed4db49   Christoph Hellwig   block: split scsi...
774
775
  		return 1;
  	}
600335205   Jens Axboe   ide: convert to b...
776
  	blk_queue_flag_set(QUEUE_FLAG_SCSI_PASSTHROUGH, q);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
777
778
  	q->queuedata = drive;
  	blk_queue_segment_boundary(q, 0xffff);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
779
780
  	if (hwif->rqsize < max_sectors)
  		max_sectors = hwif->rqsize;
086fa5ff0   Martin K. Petersen   block: Rename blk...
781
  	blk_queue_max_hw_sectors(q, max_sectors);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
782
783
784
785
786
787
788
789
790
791
792
  
  #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*
  	 */
164c3d091   Christoph Hellwig   ide: remove the P...
793
  	max_sg_entries >>= 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
794
  #endif /* CONFIG_PCI */
8a78362c4   Martin K. Petersen   block: Consolidat...
795
  	blk_queue_max_segments(q, max_sg_entries);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
796
797
798
  
  	/* assign drive queue */
  	drive->queue = q;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
799
800
  	return 0;
  }
b40d1b88f   Bartlomiej Zolnierkiewicz   ide: move ide_ini...
801
  static DEFINE_MUTEX(ide_cfg_mtx);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
802
  /*
d5bc6592d   Bartlomiej Zolnierkiewicz   ide: factor out d...
803
804
   * For any present drive:
   * - allocate the block device queue
d5bc6592d   Bartlomiej Zolnierkiewicz   ide: factor out d...
805
   */
e415e495f   Elias Oltmanns   ide: Two fixes re...
806
  static int ide_port_setup_devices(ide_hwif_t *hwif)
d5bc6592d   Bartlomiej Zolnierkiewicz   ide: factor out d...
807
  {
2bd24a1cf   Bartlomiej Zolnierkiewicz   ide: add port and...
808
  	ide_drive_t *drive;
e415e495f   Elias Oltmanns   ide: Two fixes re...
809
  	int i, j = 0;
d5bc6592d   Bartlomiej Zolnierkiewicz   ide: factor out d...
810

26042d058   Bartlomiej Zolnierkiewicz   ide: move ide_por...
811
  	mutex_lock(&ide_cfg_mtx);
7ed5b157d   Bartlomiej Zolnierkiewicz   ide: add ide_for_...
812
  	ide_port_for_each_present_dev(i, drive, hwif) {
d5bc6592d   Bartlomiej Zolnierkiewicz   ide: factor out d...
813
814
815
816
  		if (ide_init_queue(drive)) {
  			printk(KERN_ERR "ide: failed to init %s
  ",
  					drive->name);
e415e495f   Elias Oltmanns   ide: Two fixes re...
817
  			drive->dev_flags &= ~IDE_DFLAG_PRESENT;
d5bc6592d   Bartlomiej Zolnierkiewicz   ide: factor out d...
818
819
  			continue;
  		}
e415e495f   Elias Oltmanns   ide: Two fixes re...
820
  		j++;
d5bc6592d   Bartlomiej Zolnierkiewicz   ide: factor out d...
821
  	}
26042d058   Bartlomiej Zolnierkiewicz   ide: move ide_por...
822
  	mutex_unlock(&ide_cfg_mtx);
e415e495f   Elias Oltmanns   ide: Two fixes re...
823
824
  
  	return j;
d5bc6592d   Bartlomiej Zolnierkiewicz   ide: factor out d...
825
  }
ffc36c761   Bartlomiej Zolnierkiewicz   ide: fix handling...
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
  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...
843
  /*
b65fac32c   Bartlomiej Zolnierkiewicz   ide: merge ide_hw...
844
   * This routine sets up the IRQ for an IDE interface.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
845
846
847
   */
  static int init_irq (ide_hwif_t *hwif)
  {
4c3032d8a   Bartlomiej Zolnierkiewicz   ide: add struct i...
848
  	struct ide_io_ports *io_ports = &hwif->io_ports;
255115fb3   Bartlomiej Zolnierkiewicz   ide: allow host d...
849
850
851
  	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
852

849d71300   Stanislaw Gruszka   ide: allow to wra...
853
854
  	if (irq_handler == NULL)
  		irq_handler = ide_intr;
a259d5320   Michael Schmitz   m68k/atari - ide:...
855
856
857
  	if (!host->get_lock)
  		if (request_irq(hwif->irq, irq_handler, sa, hwif->name, hwif))
  			goto out_up;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
858

7b892806b   Adrian Bunk   cleanup after APU...
859
  #if !defined(__mc68000__)
1b8ebad87   Bartlomiej Zolnierkiewicz   ide: use proper p...
860
  	printk(KERN_INFO "%s at 0x%03lx-0x%03lx,0x%03lx on irq %d", hwif->name,
4c3032d8a   Bartlomiej Zolnierkiewicz   ide: add struct i...
861
862
  		io_ports->data_addr, io_ports->status_addr,
  		io_ports->ctl_addr, hwif->irq);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
863
  #else
1b8ebad87   Bartlomiej Zolnierkiewicz   ide: use proper p...
864
  	printk(KERN_INFO "%s at 0x%08lx on irq %d", hwif->name,
4c3032d8a   Bartlomiej Zolnierkiewicz   ide: add struct i...
865
  		io_ports->data_addr, hwif->irq);
7b892806b   Adrian Bunk   cleanup after APU...
866
  #endif /* __mc68000__ */
b65fac32c   Bartlomiej Zolnierkiewicz   ide: merge ide_hw...
867
868
  	if (hwif->host->host_flags & IDE_HFLAG_SERIALIZE)
  		printk(KERN_CONT " (serialized)");
1b8ebad87   Bartlomiej Zolnierkiewicz   ide: use proper p...
869
870
  	printk(KERN_CONT "
  ");
d5bc6592d   Bartlomiej Zolnierkiewicz   ide: factor out d...
871

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
872
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
873
  out_up:
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
874
875
876
877
878
879
880
881
882
883
884
885
886
  	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...
887
  	ide_drive_t *drive = hwif->devices[unit];
97100fc81   Bartlomiej Zolnierkiewicz   ide: add device f...
888
889
  
  	if ((drive->dev_flags & IDE_DFLAG_PRESENT) == 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
890
891
892
893
  		return NULL;
  
  	if (drive->media == ide_disk)
  		request_module("ide-disk");
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
894
895
896
897
898
899
900
901
902
903
904
905
906
907
  	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 ...
908
  	return &disk_to_dev(p)->kobj;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
909
910
911
912
913
  }
  
  static int exact_lock(dev_t dev, void *data)
  {
  	struct gendisk *p = data;
3079c22ea   Jan Kara   genhd: Rename get...
914
  	if (!get_disk_and_module(p))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
  		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_...
938
  	unsigned int unit = drive->dn & 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
939
940
941
942
943
944
945
946
947
948
949
950
  
  	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...
951
  	ide_proc_unregister_device(drive);
600335205   Jens Axboe   ide: convert to b...
952
953
  	if (drive->sense_rq)
  		blk_mq_free_request(drive->sense_rq);
b5479167f   Bartlomiej Zolnierkiewicz   ide: fix locking ...
954
955
  	blk_cleanup_queue(drive->queue);
  	drive->queue = NULL;
600335205   Jens Axboe   ide: convert to b...
956
  	blk_mq_free_tag_set(&drive->tag_set);
b5479167f   Bartlomiej Zolnierkiewicz   ide: fix locking ...
957

97100fc81   Bartlomiej Zolnierkiewicz   ide: add device f...
958
  	drive->dev_flags &= ~IDE_DFLAG_PRESENT;
8604affde   Bartlomiej Zolnierkiewicz   [PATCH] convert I...
959

f36d4024c   Aleksey Makarov   [PATCH] mutex sub...
960
  	complete(&drive->gendev_rel_comp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
961
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
962
963
  static int hwif_init(ide_hwif_t *hwif)
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
964
  	if (!hwif->irq) {
8b07ed26f   Bartlomiej Zolnierkiewicz   ide: remove no lo...
965
966
967
  		printk(KERN_ERR "%s: disabled, no IRQ
  ", hwif->name);
  		return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
968
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
969

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
970
971
972
973
974
  	if (register_blkdev(hwif->major, hwif->name))
  		return 0;
  
  	if (!hwif->sg_max_nents)
  		hwif->sg_max_nents = PRD_ENTRIES;
6da2ec560   Kees Cook   treewide: kmalloc...
975
976
977
  	hwif->sg_table = kmalloc_array(hwif->sg_max_nents,
  				       sizeof(struct scatterlist),
  				       GFP_KERNEL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
978
979
980
981
982
  	if (!hwif->sg_table) {
  		printk(KERN_ERR "%s: unable to allocate SG table.
  ", hwif->name);
  		goto out;
  	}
45711f1af   Jens Axboe   [SG] Update drive...
983
984
  
  	sg_init_table(hwif->sg_table, hwif->sg_max_nents);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
985
  	
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
986
  	if (init_irq(hwif)) {
8b07ed26f   Bartlomiej Zolnierkiewicz   ide: remove no lo...
987
988
989
  		printk(KERN_ERR "%s: disabled, unable to get IRQ %d
  ",
  			hwif->name, hwif->irq);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
990
991
  		goto out;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
992

3a4e7c96d   Bartlomiej Zolnierkiewicz   ide: move blk_reg...
993
994
  	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
995
996
997
998
999
1000
  	return 1;
  
  out:
  	unregister_blkdev(hwif->major, hwif->name);
  	return 0;
  }
9601a607c   Bartlomiej Zolnierkiewicz   ide: add hwif_reg...
1001
1002
  static void hwif_register_devices(ide_hwif_t *hwif)
  {
2bd24a1cf   Bartlomiej Zolnierkiewicz   ide: add port and...
1003
  	ide_drive_t *drive;
9601a607c   Bartlomiej Zolnierkiewicz   ide: add hwif_reg...
1004
  	unsigned int i;
7ed5b157d   Bartlomiej Zolnierkiewicz   ide: add ide_for_...
1005
  	ide_port_for_each_present_dev(i, drive, hwif) {
c5d70cc73   Bartlomiej Zolnierkiewicz   ide: merge init_g...
1006
1007
  		struct device *dev = &drive->gendev;
  		int ret;
9601a607c   Bartlomiej Zolnierkiewicz   ide: add hwif_reg...
1008

dc09c7842   Kay Sievers   ide: struct devic...
1009
  		dev_set_name(dev, "%u.%u", hwif->index, i);
fcb520772   Greg Kroah-Hartman   ide: remove drive...
1010
  		dev_set_drvdata(dev, drive);
c5d70cc73   Bartlomiej Zolnierkiewicz   ide: merge init_g...
1011
1012
  		dev->parent = &hwif->gendev;
  		dev->bus = &ide_bus_type;
c5d70cc73   Bartlomiej Zolnierkiewicz   ide: merge init_g...
1013
1014
1015
1016
1017
1018
1019
  		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...
1020
1021
  	}
  }
7704ca2a3   Bartlomiej Zolnierkiewicz   ide: factor out c...
1022
1023
  static void ide_port_init_devices(ide_hwif_t *hwif)
  {
ac95beedf   Bartlomiej Zolnierkiewicz   ide: add struct i...
1024
  	const struct ide_port_ops *port_ops = hwif->port_ops;
2bd24a1cf   Bartlomiej Zolnierkiewicz   ide: add port and...
1025
  	ide_drive_t *drive;
7704ca2a3   Bartlomiej Zolnierkiewicz   ide: factor out c...
1026
  	int i;
2bd24a1cf   Bartlomiej Zolnierkiewicz   ide: add port and...
1027
  	ide_port_for_each_dev(i, drive, hwif) {
123995b97   Bartlomiej Zolnierkiewicz   ide: use 'drive->...
1028
  		drive->dn = i + hwif->channel * 2;
7704ca2a3   Bartlomiej Zolnierkiewicz   ide: factor out c...
1029
1030
  		if (hwif->host_flags & IDE_HFLAG_IO_32BIT)
  			drive->io_32bit = 1;
7610c4f5e   Bartlomiej Zolnierkiewicz   ide: fix IDE_DFLA...
1031
1032
  		if (hwif->host_flags & IDE_HFLAG_NO_IO_32BIT)
  			drive->dev_flags |= IDE_DFLAG_NO_IO_32BIT;
7704ca2a3   Bartlomiej Zolnierkiewicz   ide: factor out c...
1033
  		if (hwif->host_flags & IDE_HFLAG_UNMASK_IRQS)
97100fc81   Bartlomiej Zolnierkiewicz   ide: add device f...
1034
  			drive->dev_flags |= IDE_DFLAG_UNMASK;
807b90d0b   Bartlomiej Zolnierkiewicz   ide: add IDE_HFLA...
1035
  		if (hwif->host_flags & IDE_HFLAG_NO_UNMASK_IRQS)
97100fc81   Bartlomiej Zolnierkiewicz   ide: add device f...
1036
  			drive->dev_flags |= IDE_DFLAG_NO_UNMASK;
1f2cf8b00   Bartlomiej Zolnierkiewicz   ide: add ->port_i...
1037

d2d4e780a   Bartlomiej Zolnierkiewicz   ide: add drive->p...
1038
  		drive->pio_mode = XFER_PIO_0;
e6d95bd14   Bartlomiej Zolnierkiewicz   ide: ->port_init_...
1039
1040
1041
  		if (port_ops && port_ops->init_dev)
  			port_ops->init_dev(drive);
  	}
7704ca2a3   Bartlomiej Zolnierkiewicz   ide: factor out c...
1042
  }
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
1043
1044
  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...
1045
  {
b76916462   Adrian Bunk   ide: remove the i...
1046
  	hwif->channel = port;
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
1047

29e52cf79   Bartlomiej Zolnierkiewicz   ide: remove chips...
1048
  	hwif->chipset = d->chipset ? d->chipset : ide_pci;
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
1049
1050
1051
  
  	if (d->init_iops)
  		d->init_iops(hwif);
23f8e4bf7   Bartlomiej Zolnierkiewicz   ide: fix early se...
1052
1053
  	/* ->host_flags may be set by ->init_iops (or even earlier...) */
  	hwif->host_flags |= d->host_flags;
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
1054
  	hwif->pio_mask = d->pio_mask;
374e042c3   Bartlomiej Zolnierkiewicz   ide: add struct i...
1055
1056
  	if (d->tp_ops)
  		hwif->tp_ops = d->tp_ops;
ac95beedf   Bartlomiej Zolnierkiewicz   ide: add struct i...
1057
  	/* ->set_pio_mode for DTC2278 is currently limited to port 0 */
2787cb8ae   Bartlomiej Zolnierkiewicz   ide: add IDE_HFLA...
1058
  	if ((hwif->host_flags & IDE_HFLAG_DTC2278) == 0 || hwif->channel == 0)
ac95beedf   Bartlomiej Zolnierkiewicz   ide: add struct i...
1059
  		hwif->port_ops = d->port_ops;
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
1060
1061
1062
  	hwif->swdma_mask = d->swdma_mask;
  	hwif->mwdma_mask = d->mwdma_mask;
  	hwif->ultra_mask = d->udma_mask;
b123f56e0   Bartlomiej Zolnierkiewicz   ide: do complete ...
1063
1064
  	if ((d->host_flags & IDE_HFLAG_NO_DMA) == 0) {
  		int rc;
592b53152   Sergei Shtylyov   ide: move read_sf...
1065
  		hwif->dma_ops = d->dma_ops;
b123f56e0   Bartlomiej Zolnierkiewicz   ide: do complete ...
1066
1067
1068
1069
1070
1071
1072
1073
  		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...
1074
1075
  
  			hwif->dma_ops = NULL;
ebb00fb55   Bartlomiej Zolnierkiewicz   ide: factor out s...
1076
  			hwif->dma_base = 0;
b123f56e0   Bartlomiej Zolnierkiewicz   ide: do complete ...
1077
1078
1079
  			hwif->swdma_mask = 0;
  			hwif->mwdma_mask = 0;
  			hwif->ultra_mask = 0;
592b53152   Sergei Shtylyov   ide: move read_sf...
1080
  		}
b123f56e0   Bartlomiej Zolnierkiewicz   ide: do complete ...
1081
  	}
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
1082

1024c5f4b   Bartlomiej Zolnierkiewicz   ide: IDE_HFLAG_SE...
1083
  	if ((d->host_flags & IDE_HFLAG_SERIALIZE) ||
702c026be   Bartlomiej Zolnierkiewicz   ide: rework handl...
1084
1085
  	    ((d->host_flags & IDE_HFLAG_SERIALIZE_DMA) && hwif->dma_base))
  		hwif->host->host_flags |= IDE_HFLAG_SERIALIZE;
1024c5f4b   Bartlomiej Zolnierkiewicz   ide: IDE_HFLAG_SE...
1086

6b4924962   Bartlomiej Zolnierkiewicz   ide: add ->max_se...
1087
1088
  	if (d->max_sectors)
  		hwif->rqsize = d->max_sectors;
70775e9c6   Bartlomiej Zolnierkiewicz   ide: move ->rqsiz...
1089
1090
1091
1092
1093
1094
1095
  	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...
1096
1097
1098
1099
  
  	/* call chipset specific routine for each enabled port */
  	if (d->init_hwif)
  		d->init_hwif(hwif);
c7f6f21aa   Bartlomiej Zolnierkiewicz   ide: factor out c...
1100
  }
bfa14b42a   Bartlomiej Zolnierkiewicz   ide: add ->cable_...
1101

c7f6f21aa   Bartlomiej Zolnierkiewicz   ide: factor out c...
1102
1103
  static void ide_port_cable_detect(ide_hwif_t *hwif)
  {
ac95beedf   Bartlomiej Zolnierkiewicz   ide: add struct i...
1104
1105
1106
  	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_...
1107
  		if (hwif->cbl != ATA_CBL_PATA40_SHORT)
ac95beedf   Bartlomiej Zolnierkiewicz   ide: add struct i...
1108
  			hwif->cbl = port_ops->cable_detect(hwif);
bfa14b42a   Bartlomiej Zolnierkiewicz   ide: add ->cable_...
1109
  	}
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
1110
  }
600335205   Jens Axboe   ide: convert to b...
1111
1112
1113
1114
1115
1116
1117
1118
  /*
   * Deferred request list insertion handler
   */
  static void drive_rq_insert_work(struct work_struct *work)
  {
  	ide_drive_t *drive = container_of(work, ide_drive_t, rq_work);
  	ide_hwif_t *hwif = drive->hwif;
  	struct request *rq;
9a6d54880   Jens Axboe   ide: ensure atapi...
1119
  	blk_status_t ret;
600335205   Jens Axboe   ide: convert to b...
1120
  	LIST_HEAD(list);
9a6d54880   Jens Axboe   ide: ensure atapi...
1121
  	blk_mq_quiesce_queue(drive->queue);
600335205   Jens Axboe   ide: convert to b...
1122

9a6d54880   Jens Axboe   ide: ensure atapi...
1123
1124
1125
1126
  	ret = BLK_STS_OK;
  	spin_lock_irq(&hwif->lock);
  	while (!list_empty(&drive->rq_list)) {
  		rq = list_first_entry(&drive->rq_list, struct request, queuelist);
600335205   Jens Axboe   ide: convert to b...
1127
  		list_del_init(&rq->queuelist);
9a6d54880   Jens Axboe   ide: ensure atapi...
1128
1129
1130
1131
  
  		spin_unlock_irq(&hwif->lock);
  		ret = ide_issue_rq(drive, rq, true);
  		spin_lock_irq(&hwif->lock);
600335205   Jens Axboe   ide: convert to b...
1132
  	}
9a6d54880   Jens Axboe   ide: ensure atapi...
1133
1134
1135
1136
1137
1138
  	spin_unlock_irq(&hwif->lock);
  
  	blk_mq_unquiesce_queue(drive->queue);
  
  	if (ret != BLK_STS_OK)
  		kblockd_schedule_work(&drive->rq_work);
600335205   Jens Axboe   ide: convert to b...
1139
  }
b40d1b88f   Bartlomiej Zolnierkiewicz   ide: move ide_ini...
1140
1141
1142
1143
1144
1145
  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...
1146
1147
  	ide_drive_t *drive;
  	int i;
b40d1b88f   Bartlomiej Zolnierkiewicz   ide: move ide_ini...
1148

2bd24a1cf   Bartlomiej Zolnierkiewicz   ide: add port and...
1149
1150
  	ide_port_for_each_dev(i, drive, hwif) {
  		u8 j = (hwif->index * MAX_DRIVES) + i;
5f4417a15   Hugh Dickins   ide: fix PowerMac...
1151
  		u16 *saved_id = drive->id;
b40d1b88f   Bartlomiej Zolnierkiewicz   ide: move ide_ini...
1152
1153
  
  		memset(drive, 0, sizeof(*drive));
5f4417a15   Hugh Dickins   ide: fix PowerMac...
1154
1155
  		memset(saved_id, 0, SECTOR_SIZE);
  		drive->id = saved_id;
b40d1b88f   Bartlomiej Zolnierkiewicz   ide: move ide_ini...
1156
1157
  
  		drive->media			= ide_disk;
2bd24a1cf   Bartlomiej Zolnierkiewicz   ide: add port and...
1158
  		drive->select			= (i << 4) | ATA_DEVICE_OBS;
b40d1b88f   Bartlomiej Zolnierkiewicz   ide: move ide_ini...
1159
1160
1161
  		drive->hwif			= hwif;
  		drive->ready_stat		= ATA_DRDY;
  		drive->bad_wstat		= BAD_W_STAT;
ca1b96e00   Bartlomiej Zolnierkiewicz   ide: replace spec...
1162
1163
  		drive->special_flags		= IDE_SFLAG_RECALIBRATE |
  						  IDE_SFLAG_SET_GEOMETRY;
b40d1b88f   Bartlomiej Zolnierkiewicz   ide: move ide_ini...
1164
1165
1166
1167
1168
1169
1170
  		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);
600335205   Jens Axboe   ide: convert to b...
1171
1172
1173
  
  		INIT_WORK(&drive->rq_work, drive_rq_insert_work);
  		INIT_LIST_HEAD(&drive->rq_list);
b40d1b88f   Bartlomiej Zolnierkiewicz   ide: move ide_ini...
1174
1175
1176
1177
1178
  	}
  }
  
  static void ide_init_port_data(ide_hwif_t *hwif, unsigned int index)
  {
b40d1b88f   Bartlomiej Zolnierkiewicz   ide: move ide_ini...
1179
1180
1181
1182
1183
1184
1185
1186
  	/* 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 ...
1187
  	spin_lock_init(&hwif->lock);
10738ba8e   Kees Cook   ide: Convert time...
1188
  	timer_setup(&hwif->timer, ide_timer_expiry, 0);
7362951b4   Bartlomiej Zolnierkiewicz   ide: move ->lock ...
1189

b40d1b88f   Bartlomiej Zolnierkiewicz   ide: move ide_ini...
1190
1191
1192
1193
1194
1195
  	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...
1196
  static void ide_init_port_hw(ide_hwif_t *hwif, struct ide_hw *hw)
b40d1b88f   Bartlomiej Zolnierkiewicz   ide: move ide_ini...
1197
1198
1199
  {
  	memcpy(&hwif->io_ports, &hw->io_ports, sizeof(hwif->io_ports));
  	hwif->irq = hw->irq;
b40d1b88f   Bartlomiej Zolnierkiewicz   ide: move ide_ini...
1200
1201
  	hwif->dev = hw->dev;
  	hwif->gendev.parent = hw->parent ? hw->parent : hw->dev;
b40d1b88f   Bartlomiej Zolnierkiewicz   ide: move ide_ini...
1202
1203
  	hwif->config_data = hw->config;
  }
8cdf31002   Bartlomiej Zolnierkiewicz   ide: fix IDE port...
1204
  static unsigned int ide_indexes;
fe80b937c   Bartlomiej Zolnierkiewicz   ide: merge ide_ma...
1205
  /**
8cdf31002   Bartlomiej Zolnierkiewicz   ide: fix IDE port...
1206
   *	ide_find_port_slot	-	find free port slot
fe80b937c   Bartlomiej Zolnierkiewicz   ide: merge ide_ma...
1207
1208
   *	@d: IDE port info
   *
8cdf31002   Bartlomiej Zolnierkiewicz   ide: fix IDE port...
1209
   *	Return the new port slot index or -ENOENT if we are out of free slots.
fe80b937c   Bartlomiej Zolnierkiewicz   ide: merge ide_ma...
1210
   */
8cdf31002   Bartlomiej Zolnierkiewicz   ide: fix IDE port...
1211
  static int ide_find_port_slot(const struct ide_port_info *d)
fe80b937c   Bartlomiej Zolnierkiewicz   ide: merge ide_ma...
1212
  {
8cdf31002   Bartlomiej Zolnierkiewicz   ide: fix IDE port...
1213
  	int idx = -ENOENT;
fe80b937c   Bartlomiej Zolnierkiewicz   ide: merge ide_ma...
1214
  	u8 bootable = (d && (d->host_flags & IDE_HFLAG_NON_BOOTABLE)) ? 0 : 1;
a419aef8b   Joe Perches   trivial: remove u...
1215
  	u8 i = (d && (d->host_flags & IDE_HFLAG_QD_2ND_PORT)) ? 1 : 0;
fe80b937c   Bartlomiej Zolnierkiewicz   ide: merge ide_ma...
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
  
  	/*
  	 * 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...
1227
  	mutex_lock(&ide_cfg_mtx);
75d21fffd   Bartlomiej Zolnierkiewicz   ide: remove unnec...
1228
1229
1230
  	if (bootable) {
  		if ((ide_indexes | i) != (1 << MAX_HWIFS) - 1)
  			idx = ffz(ide_indexes | i);
fe80b937c   Bartlomiej Zolnierkiewicz   ide: merge ide_ma...
1231
  	} else {
75d21fffd   Bartlomiej Zolnierkiewicz   ide: remove unnec...
1232
1233
1234
1235
  		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...
1236
  	}
8cdf31002   Bartlomiej Zolnierkiewicz   ide: fix IDE port...
1237
1238
1239
  	if (idx >= 0)
  		ide_indexes |= (1 << idx);
  	mutex_unlock(&ide_cfg_mtx);
fe80b937c   Bartlomiej Zolnierkiewicz   ide: merge ide_ma...
1240

8cdf31002   Bartlomiej Zolnierkiewicz   ide: fix IDE port...
1241
1242
  	return idx;
  }
256c5f8ee   Bartlomiej Zolnierkiewicz   ide: fix hwif-s i...
1243

8cdf31002   Bartlomiej Zolnierkiewicz   ide: fix IDE port...
1244
1245
1246
1247
1248
  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...
1249
  }
fe80b937c   Bartlomiej Zolnierkiewicz   ide: merge ide_ma...
1250

5e7f3a466   Bartlomiej Zolnierkiewicz   ide: dynamic allo...
1251
1252
  static void ide_port_free_devices(ide_hwif_t *hwif)
  {
2bd24a1cf   Bartlomiej Zolnierkiewicz   ide: add port and...
1253
  	ide_drive_t *drive;
5e7f3a466   Bartlomiej Zolnierkiewicz   ide: dynamic allo...
1254
  	int i;
5f4417a15   Hugh Dickins   ide: fix PowerMac...
1255
1256
  	ide_port_for_each_dev(i, drive, hwif) {
  		kfree(drive->id);
2bd24a1cf   Bartlomiej Zolnierkiewicz   ide: add port and...
1257
  		kfree(drive);
5f4417a15   Hugh Dickins   ide: fix PowerMac...
1258
  	}
5e7f3a466   Bartlomiej Zolnierkiewicz   ide: dynamic allo...
1259
1260
1261
1262
  }
  
  static int ide_port_alloc_devices(ide_hwif_t *hwif, int node)
  {
82ed4db49   Christoph Hellwig   block: split scsi...
1263
  	ide_drive_t *drive;
5e7f3a466   Bartlomiej Zolnierkiewicz   ide: dynamic allo...
1264
1265
1266
  	int i;
  
  	for (i = 0; i < MAX_DRIVES; i++) {
5e7f3a466   Bartlomiej Zolnierkiewicz   ide: dynamic allo...
1267
1268
1269
  		drive = kzalloc_node(sizeof(*drive), GFP_KERNEL, node);
  		if (drive == NULL)
  			goto out_nomem;
5f4417a15   Hugh Dickins   ide: fix PowerMac...
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
  		/*
  		 * 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)
82ed4db49   Christoph Hellwig   block: split scsi...
1280
  			goto out_free_drive;
5e7f3a466   Bartlomiej Zolnierkiewicz   ide: dynamic allo...
1281
1282
1283
  		hwif->devices[i] = drive;
  	}
  	return 0;
82ed4db49   Christoph Hellwig   block: split scsi...
1284
1285
  out_free_drive:
  	kfree(drive);
5e7f3a466   Bartlomiej Zolnierkiewicz   ide: dynamic allo...
1286
1287
1288
1289
  out_nomem:
  	ide_port_free_devices(hwif);
  	return -ENOMEM;
  }
9f36d3143   Bartlomiej Zolnierkiewicz   ide: remove hw_re...
1290
1291
  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...
1292
1293
  {
  	struct ide_host *host;
a32296f93   Bartlomiej Zolnierkiewicz   ide: NUMA aware a...
1294
1295
  	struct device *dev = hws[0] ? hws[0]->dev : NULL;
  	int node = dev ? dev_to_node(dev) : -1;
48c3c1072   Bartlomiej Zolnierkiewicz   ide: add struct i...
1296
  	int i;
a32296f93   Bartlomiej Zolnierkiewicz   ide: NUMA aware a...
1297
  	host = kzalloc_node(sizeof(*host), GFP_KERNEL, node);
48c3c1072   Bartlomiej Zolnierkiewicz   ide: add struct i...
1298
1299
  	if (host == NULL)
  		return NULL;
dca398305   Bartlomiej Zolnierkiewicz   ide: pass number ...
1300
  	for (i = 0; i < n_ports; i++) {
48c3c1072   Bartlomiej Zolnierkiewicz   ide: add struct i...
1301
  		ide_hwif_t *hwif;
8cdf31002   Bartlomiej Zolnierkiewicz   ide: fix IDE port...
1302
  		int idx;
48c3c1072   Bartlomiej Zolnierkiewicz   ide: add struct i...
1303
1304
1305
  
  		if (hws[i] == NULL)
  			continue;
a32296f93   Bartlomiej Zolnierkiewicz   ide: NUMA aware a...
1306
  		hwif = kzalloc_node(sizeof(*hwif), GFP_KERNEL, node);
18de10170   Bartlomiej Zolnierkiewicz   ide: allocate ide...
1307
1308
  		if (hwif == NULL)
  			continue;
5e7f3a466   Bartlomiej Zolnierkiewicz   ide: dynamic allo...
1309
1310
1311
1312
  		if (ide_port_alloc_devices(hwif, node) < 0) {
  			kfree(hwif);
  			continue;
  		}
8cdf31002   Bartlomiej Zolnierkiewicz   ide: fix IDE port...
1313
1314
1315
1316
1317
  		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...
1318
  			ide_port_free_devices(hwif);
18de10170   Bartlomiej Zolnierkiewicz   ide: allocate ide...
1319
  			kfree(hwif);
8cdf31002   Bartlomiej Zolnierkiewicz   ide: fix IDE port...
1320
  			continue;
48c3c1072   Bartlomiej Zolnierkiewicz   ide: add struct i...
1321
  		}
8cdf31002   Bartlomiej Zolnierkiewicz   ide: fix IDE port...
1322

8cdf31002   Bartlomiej Zolnierkiewicz   ide: fix IDE port...
1323
  		ide_init_port_data(hwif, idx);
08da591e1   Bartlomiej Zolnierkiewicz   ide: add ide_devi...
1324
  		hwif->host = host;
8cdf31002   Bartlomiej Zolnierkiewicz   ide: fix IDE port...
1325
1326
  		host->ports[i] = hwif;
  		host->n_ports++;
48c3c1072   Bartlomiej Zolnierkiewicz   ide: add struct i...
1327
1328
1329
1330
1331
1332
  	}
  
  	if (host->n_ports == 0) {
  		kfree(host);
  		return NULL;
  	}
a32296f93   Bartlomiej Zolnierkiewicz   ide: NUMA aware a...
1333
  	host->dev[0] = dev;
6cdf6eb35   Bartlomiej Zolnierkiewicz   ide: add ->dev an...
1334

feb22b7f8   Bartlomiej Zolnierkiewicz   ide: add proper P...
1335
1336
  	if (d) {
  		host->init_chipset = d->init_chipset;
e354c1d80   Bartlomiej Zolnierkiewicz   ide: remove IDE_A...
1337
1338
  		host->get_lock     = d->get_lock;
  		host->release_lock = d->release_lock;
ef0b04276   Bartlomiej Zolnierkiewicz   ide: add ide_pci_...
1339
  		host->host_flags = d->host_flags;
aa07573b2   Geert Uytterhoeven   ide: Fix host dri...
1340
  		host->irq_flags = d->irq_flags;
feb22b7f8   Bartlomiej Zolnierkiewicz   ide: add proper P...
1341
  	}
ef0b04276   Bartlomiej Zolnierkiewicz   ide: add ide_pci_...
1342

48c3c1072   Bartlomiej Zolnierkiewicz   ide: add struct i...
1343
1344
  	return host;
  }
48c3c1072   Bartlomiej Zolnierkiewicz   ide: add struct i...
1345
  EXPORT_SYMBOL_GPL(ide_host_alloc);
9a100f4b7   Bartlomiej Zolnierkiewicz   ide: fix ide_regi...
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
  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...
1370
  int ide_host_register(struct ide_host *host, const struct ide_port_info *d,
9f36d3143   Bartlomiej Zolnierkiewicz   ide: remove hw_re...
1371
  		      struct ide_hw **hws)
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
1372
1373
  {
  	ide_hwif_t *hwif, *mate = NULL;
e0d002078   Bartlomiej Zolnierkiewicz   ide: fix ide_host...
1374
  	int i, j = 0;
8447d9d52   Bartlomiej Zolnierkiewicz   ide: add ide_devi...
1375

7ad19a99a   Christoph Hellwig   ide: officially d...
1376
1377
1378
1379
  	pr_warn("legacy IDE will be removed in 2021, please switch to libata
  "
  		"Report any missing HW support to linux-ide@vger.kernel.org
  ");
2bd24a1cf   Bartlomiej Zolnierkiewicz   ide: add port and...
1380
  	ide_host_for_each_port(i, hwif, host) {
e0d002078   Bartlomiej Zolnierkiewicz   ide: fix ide_host...
1381
  		if (hwif == NULL) {
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
1382
1383
1384
  			mate = NULL;
  			continue;
  		}
c97c6aca7   Bartlomiej Zolnierkiewicz   ide: pass hw_regs...
1385
  		ide_init_port_hw(hwif, hws[i]);
9fd91d959   Bartlomiej Zolnierkiewicz   ide: add "ignore_...
1386
  		ide_port_apply_params(hwif);
0a6e49e9b   Bartlomiej Zolnierkiewicz   ide: remove now s...
1387
1388
1389
  		if ((i & 1) && mate) {
  			hwif->mate = mate;
  			mate->mate = hwif;
123995b97   Bartlomiej Zolnierkiewicz   ide: use 'drive->...
1390
  		}
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
1391

0a6e49e9b   Bartlomiej Zolnierkiewicz   ide: remove now s...
1392
1393
1394
1395
  		mate = (i & 1) ? NULL : hwif;
  
  		ide_init_port(hwif, i & 1, d);
  		ide_port_cable_detect(hwif);
5880b5de7   Bartlomiej Zolnierkiewicz   ide: don't enable...
1396
1397
  
  		hwif->port_flags |= IDE_PFLAG_PROBING;
7704ca2a3   Bartlomiej Zolnierkiewicz   ide: factor out c...
1398
  		ide_port_init_devices(hwif);
c413b9b94   Bartlomiej Zolnierkiewicz   ide: add struct i...
1399
  	}
2bd24a1cf   Bartlomiej Zolnierkiewicz   ide: add port and...
1400
  	ide_host_for_each_port(i, hwif, host) {
e0d002078   Bartlomiej Zolnierkiewicz   ide: fix ide_host...
1401
1402
  		if (hwif == NULL)
  			continue;
139ddfcab   Bartlomiej Zolnierkiewicz   ide: move handlin...
1403

eb716beb0   Bartlomiej Zolnierkiewicz   ide: register por...
1404
1405
  		if (ide_probe_port(hwif) == 0)
  			hwif->present = 1;
a14dc5749   Bartlomiej Zolnierkiewicz   ide: move hwif_re...
1406

5880b5de7   Bartlomiej Zolnierkiewicz   ide: don't enable...
1407
  		hwif->port_flags &= ~IDE_PFLAG_PROBING;
c094ea077   Bartlomiej Zolnierkiewicz   ide: add IDE_HFLA...
1408
1409
  		if ((hwif->host_flags & IDE_HFLAG_4DRIVES) == 0 ||
  		    hwif->mate == NULL || hwif->mate->present == 0) {
9a100f4b7   Bartlomiej Zolnierkiewicz   ide: fix ide_regi...
1410
1411
1412
1413
1414
  			if (ide_register_port(hwif)) {
  				ide_disable_port(hwif);
  				continue;
  			}
  		}
a14dc5749   Bartlomiej Zolnierkiewicz   ide: move hwif_re...
1415

eb716beb0   Bartlomiej Zolnierkiewicz   ide: register por...
1416
1417
  		if (hwif->present)
  			ide_port_tune_devices(hwif);
2e13093a8   Bartlomiej Zolnierkiewicz   ide: fix probing ...
1418
  	}
ba6560aa4   Bartlomiej Zolnierkiewicz   ide: kill probe_h...
1419

ffc36c761   Bartlomiej Zolnierkiewicz   ide: fix handling...
1420
  	ide_host_enable_irqs(host);
2bd24a1cf   Bartlomiej Zolnierkiewicz   ide: add port and...
1421
  	ide_host_for_each_port(i, hwif, host) {
e0d002078   Bartlomiej Zolnierkiewicz   ide: fix ide_host...
1422
1423
  		if (hwif == NULL)
  			continue;
ba6560aa4   Bartlomiej Zolnierkiewicz   ide: kill probe_h...
1424
1425
1426
1427
1428
  
  		if (hwif_init(hwif) == 0) {
  			printk(KERN_INFO "%s: failed to initialize IDE "
  					 "interface
  ", hwif->name);
d410a6417   Bartlomiej Zolnierkiewicz   ide: free hwif->p...
1429
  			device_unregister(hwif->portdev);
51d6ac701   Ian Campbell   IDE: Unregister a...
1430
1431
  			device_unregister(&hwif->gendev);
  			ide_disable_port(hwif);
ba6560aa4   Bartlomiej Zolnierkiewicz   ide: kill probe_h...
1432
1433
  			continue;
  		}
decdc3f0d   Bartlomiej Zolnierkiewicz   ide: move ide_acp...
1434

eb716beb0   Bartlomiej Zolnierkiewicz   ide: register por...
1435
  		if (hwif->present)
e415e495f   Elias Oltmanns   ide: Two fixes re...
1436
1437
1438
1439
1440
1441
  			if (ide_port_setup_devices(hwif) == 0) {
  				hwif->present = 0;
  				continue;
  			}
  
  		j++;
26042d058   Bartlomiej Zolnierkiewicz   ide: move ide_por...
1442

8b803bd18   Bartlomiej Zolnierkiewicz   ide: sanitize ACP...
1443
  		ide_acpi_init_port(hwif);
eb716beb0   Bartlomiej Zolnierkiewicz   ide: register por...
1444
1445
1446
  
  		if (hwif->present)
  			ide_acpi_port_init_devices(hwif);
2e13093a8   Bartlomiej Zolnierkiewicz   ide: fix probing ...
1447
  	}
2bd24a1cf   Bartlomiej Zolnierkiewicz   ide: add port and...
1448
  	ide_host_for_each_port(i, hwif, host) {
e0d002078   Bartlomiej Zolnierkiewicz   ide: fix ide_host...
1449
1450
  		if (hwif == NULL)
  			continue;
ba6560aa4   Bartlomiej Zolnierkiewicz   ide: kill probe_h...
1451

eb716beb0   Bartlomiej Zolnierkiewicz   ide: register por...
1452
1453
  		ide_sysfs_register_port(hwif);
  		ide_proc_register_port(hwif);
dbee03229   Wolfram Sang   ide: Fix ordering...
1454
  		if (hwif->present) {
d9270a3f1   Bartlomiej Zolnierkiewicz   ide: move create_...
1455
  			ide_proc_port_register_devices(hwif);
dbee03229   Wolfram Sang   ide: Fix ordering...
1456
1457
  			hwif_register_devices(hwif);
  		}
8447d9d52   Bartlomiej Zolnierkiewicz   ide: add ide_devi...
1458
  	}
e0d002078   Bartlomiej Zolnierkiewicz   ide: fix ide_host...
1459
  	return j ? 0 : -1;
8447d9d52   Bartlomiej Zolnierkiewicz   ide: add ide_devi...
1460
  }
48c3c1072   Bartlomiej Zolnierkiewicz   ide: add struct i...
1461
  EXPORT_SYMBOL_GPL(ide_host_register);
151575e46   Bartlomiej Zolnierkiewicz   ide: remove idepr...
1462

9f36d3143   Bartlomiej Zolnierkiewicz   ide: remove hw_re...
1463
  int ide_host_add(const struct ide_port_info *d, struct ide_hw **hws,
dca398305   Bartlomiej Zolnierkiewicz   ide: pass number ...
1464
  		 unsigned int n_ports, struct ide_host **hostp)
6f904d015   Bartlomiej Zolnierkiewicz   ide: add ide_host...
1465
1466
  {
  	struct ide_host *host;
8a69580e1   Bartlomiej Zolnierkiewicz   ide: add ide_host...
1467
  	int rc;
6f904d015   Bartlomiej Zolnierkiewicz   ide: add ide_host...
1468

dca398305   Bartlomiej Zolnierkiewicz   ide: pass number ...
1469
  	host = ide_host_alloc(d, hws, n_ports);
6f904d015   Bartlomiej Zolnierkiewicz   ide: add ide_host...
1470
1471
  	if (host == NULL)
  		return -ENOMEM;
8a69580e1   Bartlomiej Zolnierkiewicz   ide: add ide_host...
1472
1473
1474
1475
1476
  	rc = ide_host_register(host, d, hws);
  	if (rc) {
  		ide_host_free(host);
  		return rc;
  	}
6f904d015   Bartlomiej Zolnierkiewicz   ide: add ide_host...
1477
1478
1479
1480
1481
1482
1483
  
  	if (hostp)
  		*hostp = host;
  
  	return 0;
  }
  EXPORT_SYMBOL_GPL(ide_host_add);
b40d1b88f   Bartlomiej Zolnierkiewicz   ide: move ide_ini...
1484
1485
  static void __ide_port_unregister_devices(ide_hwif_t *hwif)
  {
2bd24a1cf   Bartlomiej Zolnierkiewicz   ide: add port and...
1486
  	ide_drive_t *drive;
b40d1b88f   Bartlomiej Zolnierkiewicz   ide: move ide_ini...
1487
  	int i;
7ed5b157d   Bartlomiej Zolnierkiewicz   ide: add ide_for_...
1488
1489
1490
  	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...
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
  	}
  }
  
  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);
a259d5320   Michael Schmitz   m68k/atari - ide:...
1531
1532
  	if (!hwif->host->get_lock)
  		free_irq(hwif->irq, hwif);
b40d1b88f   Bartlomiej Zolnierkiewicz   ide: move ide_ini...
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
  
  	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...
1549
  void ide_host_free(struct ide_host *host)
151575e46   Bartlomiej Zolnierkiewicz   ide: remove idepr...
1550
  {
8cdf31002   Bartlomiej Zolnierkiewicz   ide: fix IDE port...
1551
  	ide_hwif_t *hwif;
151575e46   Bartlomiej Zolnierkiewicz   ide: remove idepr...
1552
  	int i;
8447d9d52   Bartlomiej Zolnierkiewicz   ide: add ide_devi...
1553

2bd24a1cf   Bartlomiej Zolnierkiewicz   ide: add port and...
1554
  	ide_host_for_each_port(i, hwif, host) {
9a100f4b7   Bartlomiej Zolnierkiewicz   ide: fix ide_regi...
1555
1556
  		if (hwif)
  			ide_port_free(hwif);
c97c6aca7   Bartlomiej Zolnierkiewicz   ide: pass hw_regs...
1557
  	}
151575e46   Bartlomiej Zolnierkiewicz   ide: remove idepr...
1558

48c3c1072   Bartlomiej Zolnierkiewicz   ide: add struct i...
1559
  	kfree(host);
151575e46   Bartlomiej Zolnierkiewicz   ide: remove idepr...
1560
  }
8a69580e1   Bartlomiej Zolnierkiewicz   ide: add ide_host...
1561
1562
1563
1564
  EXPORT_SYMBOL_GPL(ide_host_free);
  
  void ide_host_remove(struct ide_host *host)
  {
2bd24a1cf   Bartlomiej Zolnierkiewicz   ide: add port and...
1565
  	ide_hwif_t *hwif;
8a69580e1   Bartlomiej Zolnierkiewicz   ide: add ide_host...
1566
  	int i;
2bd24a1cf   Bartlomiej Zolnierkiewicz   ide: add port and...
1567
1568
1569
  	ide_host_for_each_port(i, hwif, host) {
  		if (hwif)
  			ide_unregister(hwif);
8a69580e1   Bartlomiej Zolnierkiewicz   ide: add ide_host...
1570
1571
1572
1573
  	}
  
  	ide_host_free(host);
  }
48c3c1072   Bartlomiej Zolnierkiewicz   ide: add struct i...
1574
  EXPORT_SYMBOL_GPL(ide_host_remove);
2dde7861a   Bartlomiej Zolnierkiewicz   ide: rework Power...
1575
1576
1577
  
  void ide_port_scan(ide_hwif_t *hwif)
  {
5880b5de7   Bartlomiej Zolnierkiewicz   ide: don't enable...
1578
  	int rc;
9fd91d959   Bartlomiej Zolnierkiewicz   ide: add "ignore_...
1579
  	ide_port_apply_params(hwif);
2dde7861a   Bartlomiej Zolnierkiewicz   ide: rework Power...
1580
  	ide_port_cable_detect(hwif);
5880b5de7   Bartlomiej Zolnierkiewicz   ide: don't enable...
1581
1582
  
  	hwif->port_flags |= IDE_PFLAG_PROBING;
2dde7861a   Bartlomiej Zolnierkiewicz   ide: rework Power...
1583
  	ide_port_init_devices(hwif);
5880b5de7   Bartlomiej Zolnierkiewicz   ide: don't enable...
1584
1585
1586
1587
1588
  	rc = ide_probe_port(hwif);
  
  	hwif->port_flags &= ~IDE_PFLAG_PROBING;
  
  	if (rc < 0)
2dde7861a   Bartlomiej Zolnierkiewicz   ide: rework Power...
1589
1590
1591
1592
1593
  		return;
  
  	hwif->present = 1;
  
  	ide_port_tune_devices(hwif);
2dde7861a   Bartlomiej Zolnierkiewicz   ide: rework Power...
1594
  	ide_port_setup_devices(hwif);
e630fcbe9   Bartlomiej Zolnierkiewicz   ide: fix ide_port...
1595
  	ide_acpi_port_init_devices(hwif);
2dde7861a   Bartlomiej Zolnierkiewicz   ide: rework Power...
1596
1597
1598
1599
  	hwif_register_devices(hwif);
  	ide_proc_port_register_devices(hwif);
  }
  EXPORT_SYMBOL_GPL(ide_port_scan);