ide-disk.c 24 KB
Newer Older
Linus Torvalds's avatar
Linus Torvalds committed
1
/*
2
3
4
5
6
 *  Copyright (C) 1994-1998	   Linus Torvalds & authors (see below)
 *  Copyright (C) 1998-2002	   Linux ATA Development
 *				      Andre Hedrick <andre@linux-ide.org>
 *  Copyright (C) 2003		   Red Hat <alan@redhat.com>
 *  Copyright (C) 2003-2005, 2007  Bartlomiej Zolnierkiewicz
Linus Torvalds's avatar
Linus Torvalds committed
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
 */

/*
 *  Mostly written by Mark Lord <mlord@pobox.com>
 *                and Gadi Oxman <gadio@netvision.net.il>
 *                and Andre Hedrick <andre@linux-ide.org>
 *
 * This is the IDE/ATA disk driver, as evolved from hd.c and ide.c.
 */

#define IDEDISK_VERSION	"1.18"

#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>
31
#include <linux/mutex.h>
32
#include <linux/leds.h>
Linus Torvalds's avatar
Linus Torvalds committed
33
#include <linux/ide.h>
34
#include <linux/hdreg.h>
Linus Torvalds's avatar
Linus Torvalds committed
35
36
37
38
39
40
41

#include <asm/byteorder.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/div64.h>

42
#if !defined(CONFIG_DEBUG_BLOCK_EXT_DEVT)
43
#define IDE_DISK_MINORS		(1 << PARTN_BITS)
44
#else
45
#define IDE_DISK_MINORS		0
46
47
#endif

48
#include "ide-disk.h"
Linus Torvalds's avatar
Linus Torvalds committed
49

50
static DEFINE_MUTEX(idedisk_ref_mutex);
Linus Torvalds's avatar
Linus Torvalds committed
51

52
53
static void ide_disk_release(struct kref *);

Linus Torvalds's avatar
Linus Torvalds committed
54
55
56
57
static struct ide_disk_obj *ide_disk_get(struct gendisk *disk)
{
	struct ide_disk_obj *idkp = NULL;

58
	mutex_lock(&idedisk_ref_mutex);
59
	idkp = ide_drv_g(disk, ide_disk_obj);
60
	if (idkp) {
61
		if (ide_device_get(idkp->drive))
62
			idkp = NULL;
63
64
		else
			kref_get(&idkp->kref);
65
	}
66
	mutex_unlock(&idedisk_ref_mutex);
Linus Torvalds's avatar
Linus Torvalds committed
67
68
69
70
71
	return idkp;
}

static void ide_disk_put(struct ide_disk_obj *idkp)
{
72
73
	ide_drive_t *drive = idkp->drive;

74
	mutex_lock(&idedisk_ref_mutex);
Linus Torvalds's avatar
Linus Torvalds committed
75
	kref_put(&idkp->kref, ide_disk_release);
76
	ide_device_put(drive);
77
	mutex_unlock(&idedisk_ref_mutex);
Linus Torvalds's avatar
Linus Torvalds committed
78
79
}

80
static const u8 ide_rw_cmds[] = {
81
82
83
84
85
86
87
88
89
90
91
92
	ATA_CMD_READ_MULTI,
	ATA_CMD_WRITE_MULTI,
	ATA_CMD_READ_MULTI_EXT,
	ATA_CMD_WRITE_MULTI_EXT,
	ATA_CMD_PIO_READ,
	ATA_CMD_PIO_WRITE,
	ATA_CMD_PIO_READ_EXT,
	ATA_CMD_PIO_WRITE_EXT,
	ATA_CMD_READ,
	ATA_CMD_WRITE,
	ATA_CMD_READ_EXT,
	ATA_CMD_WRITE_EXT,
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
};

static const u8 ide_data_phases[] = {
	TASKFILE_MULTI_IN,
	TASKFILE_MULTI_OUT,
	TASKFILE_IN,
	TASKFILE_OUT,
	TASKFILE_IN_DMA,
	TASKFILE_OUT_DMA,
};

static void ide_tf_set_cmd(ide_drive_t *drive, ide_task_t *task, u8 dma)
{
	u8 index, lba48, write;

	lba48 = (task->tf_flags & IDE_TFLAG_LBA48) ? 2 : 0;
	write = (task->tf_flags & IDE_TFLAG_WRITE) ? 1 : 0;

	if (dma)
112
		index = 8;
113
114
115
116
117
118
119
120
121
122
123
	else
		index = drive->mult_count ? 0 : 4;

	task->tf.command = ide_rw_cmds[index + lba48 + write];

	if (dma)
		index = 8; /* fixup index */

	task->data_phase = ide_data_phases[index / 2 + write];
}

Linus Torvalds's avatar
Linus Torvalds committed
124
125
126
127
/*
 * __ide_do_rw_disk() issues READ and WRITE commands to a disk,
 * using LBA if supported, or CHS otherwise, to address sectors.
 */
128
129
static ide_startstop_t __ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
					sector_t block)
Linus Torvalds's avatar
Linus Torvalds committed
130
131
{
	ide_hwif_t *hwif	= HWIF(drive);
132
	u16 nsectors		= (u16)rq->nr_sectors;
133
134
	u8 lba48		= !!(drive->dev_flags & IDE_DFLAG_LBA48);
	u8 dma			= !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
135
136
	ide_task_t		task;
	struct ide_taskfile	*tf = &task.tf;
137
	ide_startstop_t		rc;
Linus Torvalds's avatar
Linus Torvalds committed
138

139
	if ((hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) && lba48 && dma) {
Linus Torvalds's avatar
Linus Torvalds committed
140
141
142
143
144
145
146
147
148
149
150
		if (block + rq->nr_sectors > 1ULL << 28)
			dma = 0;
		else
			lba48 = 0;
	}

	if (!dma) {
		ide_init_sg_cmd(drive, rq);
		ide_map_sg(drive, rq);
	}

151
	memset(&task, 0, sizeof(task));
152
	task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
153

154
	if (drive->dev_flags & IDE_DFLAG_LBA) {
Linus Torvalds's avatar
Linus Torvalds committed
155
		if (lba48) {
156
157
			pr_debug("%s: LBA=0x%012llx\n", drive->name,
					(unsigned long long)block);
Linus Torvalds's avatar
Linus Torvalds committed
158

159
			tf->hob_nsect = (nsectors >> 8) & 0xff;
160
161
162
163
			tf->hob_lbal  = (u8)(block >> 24);
			if (sizeof(block) != 4) {
				tf->hob_lbam = (u8)((u64)block >> 32);
				tf->hob_lbah = (u8)((u64)block >> 40);
Linus Torvalds's avatar
Linus Torvalds committed
164
			}
165

166
			tf->nsect  = nsectors & 0xff;
167
168
169
			tf->lbal   = (u8) block;
			tf->lbam   = (u8)(block >>  8);
			tf->lbah   = (u8)(block >> 16);
170

171
			task.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB);
Linus Torvalds's avatar
Linus Torvalds committed
172
		} else {
173
			tf->nsect  = nsectors & 0xff;
174
175
176
177
			tf->lbal   = block;
			tf->lbam   = block >>= 8;
			tf->lbah   = block >>= 8;
			tf->device = (block >> 8) & 0xf;
Linus Torvalds's avatar
Linus Torvalds committed
178
		}
179
180

		tf->device |= ATA_LBA;
Linus Torvalds's avatar
Linus Torvalds committed
181
	} else {
182
183
		unsigned int sect, head, cyl, track;

Linus Torvalds's avatar
Linus Torvalds committed
184
185
186
187
188
189
190
		track = (int)block / drive->sect;
		sect  = (int)block % drive->sect + 1;
		head  = track % drive->head;
		cyl   = track / drive->head;

		pr_debug("%s: CHS=%u/%u/%u\n", drive->name, cyl, head, sect);

191
		tf->nsect  = nsectors & 0xff;
192
193
194
195
		tf->lbal   = sect;
		tf->lbam   = cyl;
		tf->lbah   = cyl >> 8;
		tf->device = head;
Linus Torvalds's avatar
Linus Torvalds committed
196
197
	}

198
199
200
201
	if (rq_data_dir(rq))
		task.tf_flags |= IDE_TFLAG_WRITE;

	ide_tf_set_cmd(drive, &task, dma);
202
203
204
	if (!dma)
		hwif->data_phase = task.data_phase;
	task.rq = rq;
205

206
	rc = do_rw_taskfile(drive, &task);
207

208
	if (rc == ide_stopped && dma) {
Linus Torvalds's avatar
Linus Torvalds committed
209
		/* fallback to PIO */
210
		task.tf_flags |= IDE_TFLAG_DMA_PIO_FALLBACK;
211
		ide_tf_set_cmd(drive, &task, 0);
212
		hwif->data_phase = task.data_phase;
Linus Torvalds's avatar
Linus Torvalds committed
213
		ide_init_sg_cmd(drive, rq);
214
		rc = do_rw_taskfile(drive, &task);
Linus Torvalds's avatar
Linus Torvalds committed
215
216
	}

217
	return rc;
Linus Torvalds's avatar
Linus Torvalds committed
218
219
220
221
222
223
224
225
}

/*
 * 268435455  == 137439 MB or 28bit limit
 * 320173056  == 163929 MB or 48bit addressing
 * 1073741822 == 549756 MB or 48bit addressing fake drive
 */

226
227
static ide_startstop_t ide_do_rw_disk(ide_drive_t *drive, struct request *rq,
				      sector_t block)
Linus Torvalds's avatar
Linus Torvalds committed
228
229
230
{
	ide_hwif_t *hwif = HWIF(drive);

231
	BUG_ON(drive->dev_flags & IDE_DFLAG_BLOCKED);
Linus Torvalds's avatar
Linus Torvalds committed
232
233
234
235
236
237
238

	if (!blk_fs_request(rq)) {
		blk_dump_rq_flags(rq, "ide_do_rw_disk - bad command");
		ide_end_request(drive, 0, 0);
		return ide_stopped;
	}

239
240
	ledtrig_ide_activity();

Linus Torvalds's avatar
Linus Torvalds committed
241
242
	pr_debug("%s: %sing: block=%llu, sectors=%lu, buffer=0x%08lx\n",
		 drive->name, rq_data_dir(rq) == READ ? "read" : "writ",
243
244
		 (unsigned long long)block, rq->nr_sectors,
		 (unsigned long)rq->buffer);
Linus Torvalds's avatar
Linus Torvalds committed
245
246
247
248
249
250
251
252
253
254
255

	if (hwif->rw_disk)
		hwif->rw_disk(drive, rq);

	return __ide_do_rw_disk(drive, rq, block);
}

/*
 * Queries for true maximum capacity of the drive.
 * Returns maximum LBA address (> 0) of the drive, 0 if failed.
 */
256
static u64 idedisk_read_native_max_address(ide_drive_t *drive, int lba48)
Linus Torvalds's avatar
Linus Torvalds committed
257
258
{
	ide_task_t args;
259
	struct ide_taskfile *tf = &args.tf;
260
	u64 addr = 0;
Linus Torvalds's avatar
Linus Torvalds committed
261
262
263

	/* Create IDE/ATA command request structure */
	memset(&args, 0, sizeof(ide_task_t));
264
	if (lba48)
265
		tf->command = ATA_CMD_READ_NATIVE_MAX_EXT;
266
	else
267
		tf->command = ATA_CMD_READ_NATIVE_MAX;
268
	tf->device  = ATA_LBA;
269
	args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
270
	if (lba48)
271
		args.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB);
Linus Torvalds's avatar
Linus Torvalds committed
272
	/* submit command request */
273
	ide_no_data_taskfile(drive, &args);
Linus Torvalds's avatar
Linus Torvalds committed
274
275

	/* if OK, compute maximum address value */
276
277
	if ((tf->status & 0x01) == 0)
		addr = ide_get_lba_addr(tf, lba48) + 1;
278

Linus Torvalds's avatar
Linus Torvalds committed
279
280
281
282
283
284
285
	return addr;
}

/*
 * Sets maximum virtual LBA address of the drive.
 * Returns new maximum virtual LBA address (> 0) or 0 on failure.
 */
286
static u64 idedisk_set_max_address(ide_drive_t *drive, u64 addr_req, int lba48)
Linus Torvalds's avatar
Linus Torvalds committed
287
288
{
	ide_task_t args;
289
	struct ide_taskfile *tf = &args.tf;
290
	u64 addr_set = 0;
Linus Torvalds's avatar
Linus Torvalds committed
291
292
293
294

	addr_req--;
	/* Create IDE/ATA command request structure */
	memset(&args, 0, sizeof(ide_task_t));
295
296
297
	tf->lbal     = (addr_req >>  0) & 0xff;
	tf->lbam     = (addr_req >>= 8) & 0xff;
	tf->lbah     = (addr_req >>= 8) & 0xff;
298
299
300
301
	if (lba48) {
		tf->hob_lbal = (addr_req >>= 8) & 0xff;
		tf->hob_lbam = (addr_req >>= 8) & 0xff;
		tf->hob_lbah = (addr_req >>= 8) & 0xff;
302
		tf->command  = ATA_CMD_SET_MAX_EXT;
303
304
	} else {
		tf->device   = (addr_req >>= 8) & 0x0f;
305
		tf->command  = ATA_CMD_SET_MAX;
306
307
	}
	tf->device |= ATA_LBA;
308
	args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
309
	if (lba48)
310
		args.tf_flags |= (IDE_TFLAG_LBA48 | IDE_TFLAG_HOB);
Linus Torvalds's avatar
Linus Torvalds committed
311
	/* submit command request */
312
	ide_no_data_taskfile(drive, &args);
Linus Torvalds's avatar
Linus Torvalds committed
313
	/* if OK, compute maximum address value */
314
315
	if ((tf->status & 0x01) == 0)
		addr_set = ide_get_lba_addr(tf, lba48) + 1;
316

Linus Torvalds's avatar
Linus Torvalds committed
317
318
319
320
321
322
323
324
325
326
	return addr_set;
}

static unsigned long long sectors_to_MB(unsigned long long n)
{
	n <<= 9;		/* make it bytes */
	do_div(n, 1000000);	/* make it MB */
	return n;
}

327
328
329
330
331
332
/*
 * Some disks report total number of sectors instead of
 * maximum sector address.  We list them here.
 */
static const struct drive_list_entry hpa_list[] = {
	{ "ST340823A",	NULL },
333
	{ "ST320413A",	NULL },
334
	{ "ST310211A",	NULL },
335
336
337
	{ NULL,		NULL }
};

338
static void idedisk_check_hpa(ide_drive_t *drive)
Linus Torvalds's avatar
Linus Torvalds committed
339
340
{
	unsigned long long capacity, set_max;
341
	int lba48 = ata_id_lba48_enabled(drive->id);
Linus Torvalds's avatar
Linus Torvalds committed
342
343

	capacity = drive->capacity64;
344
345

	set_max = idedisk_read_native_max_address(drive, lba48);
Linus Torvalds's avatar
Linus Torvalds committed
346

347
348
349
350
351
352
353
354
355
	if (ide_in_drive_list(drive->id, hpa_list)) {
		/*
		 * Since we are inclusive wrt to firmware revisions do this
		 * extra check and apply the workaround only when needed.
		 */
		if (set_max == capacity + 1)
			set_max--;
	}

Linus Torvalds's avatar
Linus Torvalds committed
356
357
358
359
360
361
362
363
364
365
	if (set_max <= capacity)
		return;

	printk(KERN_INFO "%s: Host Protected Area detected.\n"
			 "\tcurrent capacity is %llu sectors (%llu MB)\n"
			 "\tnative  capacity is %llu sectors (%llu MB)\n",
			 drive->name,
			 capacity, sectors_to_MB(capacity),
			 set_max, sectors_to_MB(set_max));

366
367
	set_max = idedisk_set_max_address(drive, set_max, lba48);

Linus Torvalds's avatar
Linus Torvalds committed
368
369
370
371
372
373
374
	if (set_max) {
		drive->capacity64 = set_max;
		printk(KERN_INFO "%s: Host Protected Area disabled.\n",
				 drive->name);
	}
}

375
static void init_idedisk_capacity(ide_drive_t *drive)
Linus Torvalds's avatar
Linus Torvalds committed
376
{
377
	u16 *id = drive->id;
378
	int lba;
Linus Torvalds's avatar
Linus Torvalds committed
379

380
	if (ata_id_lba48_enabled(id)) {
Linus Torvalds's avatar
Linus Torvalds committed
381
		/* drive speaks 48-bit LBA */
382
		lba = 1;
383
		drive->capacity64 = ata_id_u64(id, ATA_ID_LBA_CAPACITY_2);
384
	} else if (ata_id_has_lba(id) && ata_id_is_lba_capacity_ok(id)) {
Linus Torvalds's avatar
Linus Torvalds committed
385
		/* drive speaks 28-bit LBA */
386
		lba = 1;
387
		drive->capacity64 = ata_id_u32(id, ATA_ID_LBA_CAPACITY);
Linus Torvalds's avatar
Linus Torvalds committed
388
389
	} else {
		/* drive speaks boring old 28-bit CHS */
390
		lba = 0;
Linus Torvalds's avatar
Linus Torvalds committed
391
392
		drive->capacity64 = drive->cyl * drive->head * drive->sect;
	}
393
394
395
396
397
398
399
400
401
402
403

	if (lba) {
		drive->dev_flags |= IDE_DFLAG_LBA;

		/*
		* If this device supports the Host Protected Area feature set,
		* then we may need to change our opinion about its capacity.
		*/
		if (ata_id_hpa_enabled(id))
			idedisk_check_hpa(drive);
	}
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423

	/* limit drive capacity to 137GB if LBA48 cannot be used */
	if ((drive->dev_flags & IDE_DFLAG_LBA48) == 0 &&
	    drive->capacity64 > 1ULL << 28) {
		printk(KERN_WARNING "%s: cannot use LBA48 - full capacity "
		       "%llu sectors (%llu MB)\n",
		       drive->name, (unsigned long long)drive->capacity64,
		       sectors_to_MB(drive->capacity64));
		drive->capacity64 = 1ULL << 28;
	}

	if ((drive->hwif->host_flags & IDE_HFLAG_NO_LBA48_DMA) &&
	    (drive->dev_flags & IDE_DFLAG_LBA48)) {
		if (drive->capacity64 > 1ULL << 28) {
			printk(KERN_INFO "%s: cannot use LBA48 DMA - PIO mode"
					 " will be used for accessing sectors "
					 "> %u\n", drive->name, 1 << 28);
		} else
			drive->dev_flags &= ~IDE_DFLAG_LBA48;
	}
Linus Torvalds's avatar
Linus Torvalds committed
424
425
}

426
sector_t ide_disk_capacity(ide_drive_t *drive)
Linus Torvalds's avatar
Linus Torvalds committed
427
{
428
	return drive->capacity64;
Linus Torvalds's avatar
Linus Torvalds committed
429
430
}

431
static void idedisk_prepare_flush(struct request_queue *q, struct request *rq)
Linus Torvalds's avatar
Linus Torvalds committed
432
433
{
	ide_drive_t *drive = q->queuedata;
434
	ide_task_t *task = kmalloc(sizeof(*task), GFP_ATOMIC);
Linus Torvalds's avatar
Linus Torvalds committed
435

436
437
438
439
	/* FIXME: map struct ide_taskfile on rq->cmd[] */
	BUG_ON(task == NULL);

	memset(task, 0, sizeof(*task));
440
	if (ata_id_flush_ext_enabled(drive->id) &&
Linus Torvalds's avatar
Linus Torvalds committed
441
	    (drive->capacity64 >= (1UL << 28)))
442
		task->tf.command = ATA_CMD_FLUSH_EXT;
Linus Torvalds's avatar
Linus Torvalds committed
443
	else
444
		task->tf.command = ATA_CMD_FLUSH;
445
446
447
	task->tf_flags	 = IDE_TFLAG_OUT_TF | IDE_TFLAG_OUT_DEVICE |
			   IDE_TFLAG_DYN;
	task->data_phase = TASKFILE_NO_DATA;
Linus Torvalds's avatar
Linus Torvalds committed
448

449
	rq->cmd_type = REQ_TYPE_ATA_TASKFILE;
450
	rq->cmd_flags |= REQ_SOFTBARRIER;
451
	rq->special = task;
Linus Torvalds's avatar
Linus Torvalds committed
452
453
}

454
455
ide_devset_get(multcount, mult_count);

Linus Torvalds's avatar
Linus Torvalds committed
456
457
458
459
460
461
/*
 * This is tightly woven into the driver->do_special can not touch.
 * DON'T do it again until a total personality rewrite is committed.
 */
static int set_multcount(ide_drive_t *drive, int arg)
{
462
463
	struct request *rq;
	int error;
Linus Torvalds's avatar
Linus Torvalds committed
464

465
	if (arg < 0 || arg > (drive->id[ATA_ID_MAX_MULTSECT] & 0xff))
466
467
		return -EINVAL;

Linus Torvalds's avatar
Linus Torvalds committed
468
469
	if (drive->special.b.set_multmode)
		return -EBUSY;
470

471
472
	rq = blk_get_request(drive->queue, READ, __GFP_WAIT);
	rq->cmd_type = REQ_TYPE_ATA_TASKFILE;
473

Linus Torvalds's avatar
Linus Torvalds committed
474
475
	drive->mult_req = arg;
	drive->special.b.set_multmode = 1;
476
477
	error = blk_execute_rq(drive->queue, NULL, rq, 0);
	blk_put_request(rq);
478

Linus Torvalds's avatar
Linus Torvalds committed
479
480
481
	return (drive->mult_count == arg) ? 0 : -EIO;
}

482
ide_devset_get_flag(nowerr, IDE_DFLAG_NOWERR);
483

Linus Torvalds's avatar
Linus Torvalds committed
484
485
static int set_nowerr(ide_drive_t *drive, int arg)
{
486
487
488
	if (arg < 0 || arg > 1)
		return -EINVAL;

489
490
491
492
493
	if (arg)
		drive->dev_flags |= IDE_DFLAG_NOWERR;
	else
		drive->dev_flags &= ~IDE_DFLAG_NOWERR;

Linus Torvalds's avatar
Linus Torvalds committed
494
	drive->bad_wstat = arg ? BAD_R_STAT : BAD_W_STAT;
495

Linus Torvalds's avatar
Linus Torvalds committed
496
497
498
	return 0;
}

499
500
501
502
503
504
505
506
507
508
509
510
511
static int ide_do_setfeature(ide_drive_t *drive, u8 feature, u8 nsect)
{
	ide_task_t task;

	memset(&task, 0, sizeof(task));
	task.tf.feature = feature;
	task.tf.nsect   = nsect;
	task.tf.command = ATA_CMD_SET_FEATURES;
	task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;

	return ide_no_data_taskfile(drive, &task);
}

512
513
static void update_ordered(ide_drive_t *drive)
{
514
	u16 *id = drive->id;
515
516
517
	unsigned ordered = QUEUE_ORDERED_NONE;
	prepare_flush_fn *prep_fn = NULL;

518
	if (drive->dev_flags & IDE_DFLAG_WCACHE) {
519
520
521
522
523
524
525
526
527
528
		unsigned long long capacity;
		int barrier;
		/*
		 * We must avoid issuing commands a drive does not
		 * understand or we may crash it. We check flush cache
		 * is supported. We also check we have the LBA48 flush
		 * cache if the drive capacity is too large. By this
		 * time we have trimmed the drive capacity if LBA48 is
		 * not available so we don't need to recheck that.
		 */
529
		capacity = ide_disk_capacity(drive);
530
531
532
533
		barrier = ata_id_flush_enabled(id) &&
			(drive->dev_flags & IDE_DFLAG_NOFLUSH) == 0 &&
			((drive->dev_flags & IDE_DFLAG_LBA48) == 0 ||
			 capacity <= (1ULL << 28) ||
534
			 ata_id_flush_ext_enabled(id));
535
536

		printk(KERN_INFO "%s: cache flushes %ssupported\n",
537
		       drive->name, barrier ? "" : "not ");
538
539
540
541
542
543
544
545
546
547
548

		if (barrier) {
			ordered = QUEUE_ORDERED_DRAIN_FLUSH;
			prep_fn = idedisk_prepare_flush;
		}
	} else
		ordered = QUEUE_ORDERED_DRAIN;

	blk_queue_ordered(drive->queue, ordered, prep_fn);
}

549
ide_devset_get_flag(wcache, IDE_DFLAG_WCACHE);
550
551

static int set_wcache(ide_drive_t *drive, int arg)
Linus Torvalds's avatar
Linus Torvalds committed
552
{
553
	int err = 1;
Linus Torvalds's avatar
Linus Torvalds committed
554

555
556
557
	if (arg < 0 || arg > 1)
		return -EINVAL;

558
	if (ata_id_flush_enabled(drive->id)) {
559
560
		err = ide_do_setfeature(drive,
			arg ? SETFEATURES_WC_ON : SETFEATURES_WC_OFF, 0);
561
562
563
564
565
566
		if (err == 0) {
			if (arg)
				drive->dev_flags |= IDE_DFLAG_WCACHE;
			else
				drive->dev_flags &= ~IDE_DFLAG_WCACHE;
		}
567
	}
Linus Torvalds's avatar
Linus Torvalds committed
568

569
	update_ordered(drive);
Linus Torvalds's avatar
Linus Torvalds committed
570

571
	return err;
Linus Torvalds's avatar
Linus Torvalds committed
572
573
}

574
static int do_idedisk_flushcache(ide_drive_t *drive)
Linus Torvalds's avatar
Linus Torvalds committed
575
576
577
578
{
	ide_task_t args;

	memset(&args, 0, sizeof(ide_task_t));
579
	if (ata_id_flush_ext_enabled(drive->id))
580
		args.tf.command = ATA_CMD_FLUSH_EXT;
Linus Torvalds's avatar
Linus Torvalds committed
581
	else
582
		args.tf.command = ATA_CMD_FLUSH;
583
	args.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
584
	return ide_no_data_taskfile(drive, &args);
Linus Torvalds's avatar
Linus Torvalds committed
585
586
}

587
588
ide_devset_get(acoustic, acoustic);

589
static int set_acoustic(ide_drive_t *drive, int arg)
Linus Torvalds's avatar
Linus Torvalds committed
590
{
591
592
593
	if (arg < 0 || arg > 254)
		return -EINVAL;

594
595
596
	ide_do_setfeature(drive,
		arg ? SETFEATURES_AAM_ON : SETFEATURES_AAM_OFF, arg);

Linus Torvalds's avatar
Linus Torvalds committed
597
	drive->acoustic = arg;
598

Linus Torvalds's avatar
Linus Torvalds committed
599
600
601
	return 0;
}

602
ide_devset_get_flag(addressing, IDE_DFLAG_LBA48);
603

Linus Torvalds's avatar
Linus Torvalds committed
604
605
606
607
608
609
/*
 * drive->addressing:
 *	0: 28-bit
 *	1: 48-bit
 *	2: 48-bit capable doing 28-bit
 */
610
static int set_addressing(ide_drive_t *drive, int arg)
Linus Torvalds's avatar
Linus Torvalds committed
611
{
612
613
614
	if (arg < 0 || arg > 2)
		return -EINVAL;

615
616
	if (arg && ((drive->hwif->host_flags & IDE_HFLAG_NO_LBA48) ||
	    ata_id_lba48_enabled(drive->id) == 0))
617
		return -EIO;
618

619
620
621
	if (arg == 2)
		arg = 0;

622
623
624
625
	if (arg)
		drive->dev_flags |= IDE_DFLAG_LBA48;
	else
		drive->dev_flags &= ~IDE_DFLAG_LBA48;
626

Linus Torvalds's avatar
Linus Torvalds committed
627
628
629
	return 0;
}

630
631
632
633
ide_ext_devset_rw(acoustic, acoustic);
ide_ext_devset_rw(address, addressing);
ide_ext_devset_rw(multcount, multcount);
ide_ext_devset_rw(wcache, wcache);
634

635
ide_ext_devset_rw_sync(nowerr, nowerr);
636

637
static void idedisk_setup(ide_drive_t *drive)
Linus Torvalds's avatar
Linus Torvalds committed
638
{
639
	struct ide_disk_obj *idkp = drive->driver_data;
640
	ide_hwif_t *hwif = drive->hwif;
641
642
	u16 *id = drive->id;
	char *m = (char *)&id[ATA_ID_PROD];
Linus Torvalds's avatar
Linus Torvalds committed
643
644
	unsigned long long capacity;

645
	ide_proc_register_driver(drive, idkp->driver);
Linus Torvalds's avatar
Linus Torvalds committed
646

647
	if ((drive->dev_flags & IDE_DFLAG_ID_READ) == 0)
Linus Torvalds's avatar
Linus Torvalds committed
648
649
		return;

650
	if (drive->dev_flags & IDE_DFLAG_REMOVABLE) {
Linus Torvalds's avatar
Linus Torvalds committed
651
		/*
652
		 * Removable disks (eg. SYQUEST); ignore 'WD' drives
Linus Torvalds's avatar
Linus Torvalds committed
653
		 */
654
		if (m[0] != 'W' || m[1] != 'D')
655
			drive->dev_flags |= IDE_DFLAG_DOORLOCKING;
Linus Torvalds's avatar
Linus Torvalds committed
656
657
	}

658
	(void)set_addressing(drive, 1);
Linus Torvalds's avatar
Linus Torvalds committed
659

660
	if (drive->dev_flags & IDE_DFLAG_LBA48) {
Linus Torvalds's avatar
Linus Torvalds committed
661
662
663
664
665
666
667
668
		int max_s = 2048;

		if (max_s > hwif->rqsize)
			max_s = hwif->rqsize;

		blk_queue_max_sectors(drive->queue, max_s);
	}

669
670
	printk(KERN_INFO "%s: max request size: %dKiB\n", drive->name,
			 drive->queue->max_sectors / 2);
Linus Torvalds's avatar
Linus Torvalds committed
671
672

	/* calculate drive capacity, and select LBA if possible */
673
	init_idedisk_capacity(drive);
Linus Torvalds's avatar
Linus Torvalds committed
674
675
676
677
678

	/*
	 * if possible, give fdisk access to more of the drive,
	 * by correcting bios_cyls:
	 */
679
	capacity = ide_disk_capacity(drive);
680

681
	if ((drive->dev_flags & IDE_DFLAG_FORCED_GEOM) == 0) {
682
		if (ata_id_lba48_enabled(drive->id)) {
Linus Torvalds's avatar
Linus Torvalds committed
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
			/* compatibility */
			drive->bios_sect = 63;
			drive->bios_head = 255;
		}

		if (drive->bios_sect && drive->bios_head) {
			unsigned int cap0 = capacity; /* truncate to 32 bits */
			unsigned int cylsz, cyl;

			if (cap0 != capacity)
				drive->bios_cyl = 65535;
			else {
				cylsz = drive->bios_sect * drive->bios_head;
				cyl = cap0 / cylsz;
				if (cyl > 65535)
					cyl = 65535;
				if (cyl > drive->bios_cyl)
					drive->bios_cyl = cyl;
			}
		}
	}
	printk(KERN_INFO "%s: %llu sectors (%llu MB)",
			 drive->name, capacity, sectors_to_MB(capacity));

	/* Only print cache size when it was specified */
708
709
	if (id[ATA_ID_BUF_SIZE])
		printk(KERN_CONT " w/%dKiB Cache", id[ATA_ID_BUF_SIZE] / 2);
Linus Torvalds's avatar
Linus Torvalds committed
710

711
712
	printk(KERN_CONT ", CHS=%d/%d/%d\n",
			 drive->bios_cyl, drive->bios_head, drive->bios_sect);
Linus Torvalds's avatar
Linus Torvalds committed
713
714

	/* write cache enabled? */
715
	if ((id[ATA_ID_CSFO] & 1) || ata_id_wcache_enabled(id))
716
		drive->dev_flags |= IDE_DFLAG_WCACHE;
Linus Torvalds's avatar
Linus Torvalds committed
717

718
	set_wcache(drive, 1);
Linus Torvalds's avatar
Linus Torvalds committed
719
720
721
722
}

static void ide_cacheflush_p(ide_drive_t *drive)
{
723
724
	if (ata_id_flush_enabled(drive->id) == 0 ||
	    (drive->dev_flags & IDE_DFLAG_WCACHE) == 0)
Linus Torvalds's avatar
Linus Torvalds committed
725
726
727
728
729
730
		return;

	if (do_idedisk_flushcache(drive))
		printk(KERN_INFO "%s: wcache flush failed!\n", drive->name);
}

731
static void ide_disk_remove(ide_drive_t *drive)
Linus Torvalds's avatar
Linus Torvalds committed
732
733
734
735
{
	struct ide_disk_obj *idkp = drive->driver_data;
	struct gendisk *g = idkp->disk;

736
	ide_proc_unregister_driver(drive, idkp->driver);
737

Linus Torvalds's avatar
Linus Torvalds committed
738
739
	del_gendisk(g);

740
741
	ide_cacheflush_p(drive);

Linus Torvalds's avatar
Linus Torvalds committed
742
743
744
745
746
	ide_disk_put(idkp);
}

static void ide_disk_release(struct kref *kref)
{
747
	struct ide_disk_obj *idkp = to_ide_drv(kref, ide_disk_obj);
Linus Torvalds's avatar
Linus Torvalds committed
748
749
750
751
752
753
754
755
756
	ide_drive_t *drive = idkp->drive;
	struct gendisk *g = idkp->disk;

	drive->driver_data = NULL;
	g->private_data = NULL;
	put_disk(g);
	kfree(idkp);
}

757
static int ide_disk_probe(ide_drive_t *drive);
Linus Torvalds's avatar
Linus Torvalds committed
758

Lee Trager's avatar
Lee Trager committed
759
760
761
762
763
764
765
/*
 * On HPA drives the capacity needs to be
 * reinitilized on resume otherwise the disk
 * can not be used and a hard reset is required
 */
static void ide_disk_resume(ide_drive_t *drive)
{
766
	if (ata_id_hpa_enabled(drive->id))
Lee Trager's avatar
Lee Trager committed
767
768
769
		init_idedisk_capacity(drive);
}

770
static void ide_device_shutdown(ide_drive_t *drive)
Linus Torvalds's avatar
Linus Torvalds committed
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
{
#ifdef	CONFIG_ALPHA
	/* On Alpha, halt(8) doesn't actually turn the machine off,
	   it puts you into the sort of firmware monitor. Typically,
	   it's used to boot another kernel image, so it's not much
	   different from reboot(8). Therefore, we don't need to
	   spin down the disk in this case, especially since Alpha
	   firmware doesn't handle disks in standby mode properly.
	   On the other hand, it's reasonably safe to turn the power
	   off when the shutdown process reaches the firmware prompt,
	   as the firmware initialization takes rather long time -
	   at least 10 seconds, which should be sufficient for
	   the disk to expire its write cache. */
	if (system_state != SYSTEM_POWER_OFF) {
#else
	if (system_state == SYSTEM_RESTART) {
#endif
		ide_cacheflush_p(drive);
		return;
	}

792
793
	printk(KERN_INFO "Shutdown: %s\n", drive->name);

794
	drive->gendev.bus->suspend(&drive->gendev, PMSG_SUSPEND);
Linus Torvalds's avatar
Linus Torvalds committed
795
796
797
798
}

static ide_driver_t idedisk_driver = {
	.gen_driver = {
799
		.owner		= THIS_MODULE,
800
801
		.name		= "ide-disk",
		.bus		= &ide_bus_type,
Linus Torvalds's avatar
Linus Torvalds committed
802
	},
803
804
	.probe			= ide_disk_probe,
	.remove			= ide_disk_remove,
Lee Trager's avatar
Lee Trager committed
805
	.resume			= ide_disk_resume,
806
	.shutdown		= ide_device_shutdown,
Linus Torvalds's avatar
Linus Torvalds committed
807
808
809
810
	.version		= IDEDISK_VERSION,
	.do_request		= ide_do_rw_disk,
	.end_request		= ide_end_request,
	.error			= __ide_error,
811
#ifdef CONFIG_IDE_PROC_FS
812
813
	.proc			= ide_disk_proc,
	.settings		= ide_disk_settings,
814
#endif
Linus Torvalds's avatar
Linus Torvalds committed
815
816
};

817
818
819
820
821
static int idedisk_set_doorlock(ide_drive_t *drive, int on)
{
	ide_task_t task;

	memset(&task, 0, sizeof(task));
822
	task.tf.command = on ? ATA_CMD_MEDIA_LOCK : ATA_CMD_MEDIA_UNLOCK;
823
	task.tf_flags = IDE_TFLAG_TF | IDE_TFLAG_DEVICE;
824
825
826
827

	return ide_no_data_taskfile(drive, &task);
}

Linus Torvalds's avatar
Linus Torvalds committed
828
829
830
831
832
833
static int idedisk_open(struct inode *inode, struct file *filp)
{
	struct gendisk *disk = inode->i_bdev->bd_disk;
	struct ide_disk_obj *idkp;
	ide_drive_t *drive;

834
835
	idkp = ide_disk_get(disk);
	if (idkp == NULL)
Linus Torvalds's avatar
Linus Torvalds committed
836
837
838
839
		return -ENXIO;

	drive = idkp->drive;

840
841
	idkp->openers++;

842
	if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) {
Linus Torvalds's avatar
Linus Torvalds committed
843
844
845
846
847
		/*
		 * Ignore the return code from door_lock,
		 * since the open() has already succeeded,
		 * and the door_lock is irrelevant at this point.
		 */
848
849
850
		if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) &&
		    idedisk_set_doorlock(drive, 1))
			drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING;
851
		check_disk_change(inode->i_bdev);
Linus Torvalds's avatar
Linus Torvalds committed
852
853
854
855
856
857
858
	}
	return 0;
}

static int idedisk_release(struct inode *inode, struct file *filp)
{
	struct gendisk *disk = inode->i_bdev->bd_disk;
859
	struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
Linus Torvalds's avatar
Linus Torvalds committed
860
861
	ide_drive_t *drive = idkp->drive;

862
	if (idkp->openers == 1)
Linus Torvalds's avatar
Linus Torvalds committed
863
		ide_cacheflush_p(drive);
864

865
866
867
868
	if ((drive->dev_flags & IDE_DFLAG_REMOVABLE) && idkp->openers == 1) {
		if ((drive->dev_flags & IDE_DFLAG_DOORLOCKING) &&
		    idedisk_set_doorlock(drive, 0))
			drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING;
Linus Torvalds's avatar
Linus Torvalds committed
869
	}
870
871

	idkp->openers--;
Linus Torvalds's avatar
Linus Torvalds committed
872
873
874
875
876
877

	ide_disk_put(idkp);

	return 0;
}

878
879
static int idedisk_getgeo(struct block_device *bdev, struct hd_geometry *geo)
{
880
	struct ide_disk_obj *idkp = ide_drv_g(bdev->bd_disk, ide_disk_obj);
881
882
883
884
885
886
887
888
	ide_drive_t *drive = idkp->drive;

	geo->heads = drive->bios_head;
	geo->sectors = drive->bios_sect;
	geo->cylinders = (u16)drive->bios_cyl; /* truncate */
	return 0;
}

Linus Torvalds's avatar
Linus Torvalds committed
889
890
static int idedisk_media_changed(struct gendisk *disk)
{
891
	struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
Linus Torvalds's avatar
Linus Torvalds committed
892
893
894
	ide_drive_t *drive = idkp->drive;

	/* do not scan partitions twice if this is a removable device */
895
896
	if (drive->dev_flags & IDE_DFLAG_ATTACH) {
		drive->dev_flags &= ~IDE_DFLAG_ATTACH;
Linus Torvalds's avatar
Linus Torvalds committed
897
898
		return 0;
	}
899

Linus Torvalds's avatar
Linus Torvalds committed
900
	/* if removable, always assume it was changed */
901
	return !!(drive->dev_flags & IDE_DFLAG_REMOVABLE);
Linus Torvalds's avatar
Linus Torvalds committed
902
903
904
905
}

static int idedisk_revalidate_disk(struct gendisk *disk)
{
906
	struct ide_disk_obj *idkp = ide_drv_g(disk, ide_disk_obj);
907
	set_capacity(disk, ide_disk_capacity(idkp->drive));
Linus Torvalds's avatar
Linus Torvalds committed
908
909
910
911
	return 0;
}

static struct block_device_operations idedisk_ops = {
912
913
914
	.owner			= THIS_MODULE,
	.open			= idedisk_open,
	.release		= idedisk_release,
915
	.ioctl			= ide_disk_ioctl,
916
917
918
	.getgeo			= idedisk_getgeo,
	.media_changed		= idedisk_media_changed,
	.revalidate_disk	= idedisk_revalidate_disk
Linus Torvalds's avatar
Linus Torvalds committed
919
920
921
922
};

MODULE_DESCRIPTION("ATA DISK Driver");

923
static int ide_disk_probe(ide_drive_t *drive)
Linus Torvalds's avatar
Linus Torvalds committed
924
925
926
927
928
929
930
{
	struct ide_disk_obj *idkp;
	struct gendisk *g;

	/* strstr("foo", "") is non-NULL */
	if (!strstr("ide-disk", drive->driver_req))
		goto failed;
931

Linus Torvalds's avatar
Linus Torvalds committed
932
933
934
	if (drive->media != ide_disk)
		goto failed;

935
	idkp = kzalloc(sizeof(*idkp), GFP_KERNEL);
Linus Torvalds's avatar
Linus Torvalds committed
936
937
938
	if (!idkp)
		goto failed;

939
	g = alloc_disk_node(IDE_DISK_MINORS, hwif_to_node(drive->hwif));
Linus Torvalds's avatar
Linus Torvalds committed
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
	if (!g)
		goto out_free_idkp;

	ide_init_disk(g, drive);

	kref_init(&idkp->kref);

	idkp->drive = drive;
	idkp->driver = &idedisk_driver;
	idkp->disk = g;

	g->private_data = &idkp->driver;

	drive->driver_data = idkp;

	idedisk_setup(drive);
956
957
	if ((drive->dev_flags & IDE_DFLAG_LBA) == 0 &&
	    (drive->head == 0 || drive->head > 16)) {
Linus Torvalds's avatar
Linus Torvalds committed
958
959
		printk(KERN_ERR "%s: INVALID GEOMETRY: %d PHYSICAL HEADS?\n",
			drive->name, drive->head);
960
		drive->dev_flags &= ~IDE_DFLAG_ATTACH;
Linus Torvalds's avatar
Linus Torvalds committed
961
	} else
962
		drive->dev_flags |= IDE_DFLAG_ATTACH;
963

964
	g->minors = IDE_DISK_MINORS;
Linus Torvalds's avatar
Linus Torvalds committed
965
	g->driverfs_dev = &drive->gendev;
966
	g->flags |= GENHD_FL_EXT_DEVT;
967
968
	if (drive->dev_flags & IDE_DFLAG_REMOVABLE)
		g->flags = GENHD_FL_REMOVABLE;
969
	set_capacity(g, ide_disk_capacity(drive));
Linus Torvalds's avatar
Linus Torvalds committed
970
971
972
973
974
975
976
	g->fops = &idedisk_ops;
	add_disk(g);
	return 0;

out_free_idkp:
	kfree(idkp);
failed:
977
	return -ENODEV;
Linus Torvalds's avatar
Linus Torvalds committed
978
979
}

980
static void __exit idedisk_exit(void)
Linus Torvalds's avatar
Linus Torvalds committed
981
{
982
	driver_unregister(&idedisk_driver.gen_driver);
Linus Torvalds's avatar
Linus Torvalds committed
983
984
}

985
static int __init idedisk_init(void)
Linus Torvalds's avatar
Linus Torvalds committed
986
{
987
	return driver_register(&idedisk_driver.gen_driver);
Linus Torvalds's avatar
Linus Torvalds committed
988
989
}

990
MODULE_ALIAS("ide:*m-disk*");
991
MODULE_ALIAS("ide-disk");
Linus Torvalds's avatar
Linus Torvalds committed
992
993
994
module_init(idedisk_init);
module_exit(idedisk_exit);
MODULE_LICENSE("GPL");