ide-disk.c 34.3 KB
Newer Older
Martin Dalecki's avatar
Martin Dalecki committed
1
/**** vi:set ts=8 sts=8 sw=8:************************************************
2
 *
Martin Dalecki's avatar
Martin Dalecki committed
3 4 5 6 7 8 9
 *  Copyright (C) 1994-1998,2002  Linus Torvalds and authors:
 *
 *	Mark Lord	<mlord@pobox.com>
 *	Gadi Oxman	<gadio@netvision.net.il>
 *	Andre Hedrick	<andre@linux-ide.org>
 *	Jens Axboe	<axboe@suse.de>
 *	Marcin Dalecki	<martin@dalecki.de>
Linus Torvalds's avatar
Linus Torvalds committed
10
 *
Martin Dalecki's avatar
Martin Dalecki committed
11
 * This is the ATA disk device driver, as evolved from hd.c and ide.c.
Linus Torvalds's avatar
Linus Torvalds committed
12 13
 */

Martin Dalecki's avatar
Martin Dalecki committed
14
#define IDEDISK_VERSION	"1.14"
Linus Torvalds's avatar
Linus Torvalds committed
15 16 17 18 19 20 21 22 23 24 25 26

#include <linux/config.h>
#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>
Linus Torvalds's avatar
Linus Torvalds committed
27
#include <linux/slab.h>
Linus Torvalds's avatar
Linus Torvalds committed
28 29
#include <linux/delay.h>
#include <linux/ide.h>
30
#include <linux/buffer_head.h>		/* for invalidate_bdev() */
Linus Torvalds's avatar
Linus Torvalds committed
31 32 33 34 35 36 37

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

#ifdef CONFIG_BLK_DEV_PDC4030
Martin Dalecki's avatar
Martin Dalecki committed
38
# define IS_PDC4030_DRIVE (drive->channel->chipset == ide_pdc4030)
Linus Torvalds's avatar
Linus Torvalds committed
39
#else
Martin Dalecki's avatar
Martin Dalecki committed
40
# define IS_PDC4030_DRIVE (0)	/* auto-NULLs out pdc4030 code */
Linus Torvalds's avatar
Linus Torvalds committed
41 42 43
#endif

/*
Martin Dalecki's avatar
Martin Dalecki committed
44
 * Perform a sanity check on the claimed "lba_capacity"
Linus Torvalds's avatar
Linus Torvalds committed
45 46 47 48 49 50 51
 * value for this drive (from its reported identification information).
 *
 * Returns:	1 if lba_capacity looks sensible
 *		0 otherwise
 *
 * It is called only once for each drive.
 */
Martin Dalecki's avatar
Martin Dalecki committed
52
static int lba_capacity_is_ok(struct hd_driveid *id)
Linus Torvalds's avatar
Linus Torvalds committed
53 54 55
{
	unsigned long lba_sects, chs_sects, head, tail;

Linus Torvalds's avatar
Linus Torvalds committed
56 57 58 59 60
	if ((id->command_set_2 & 0x0400) && (id->cfs_enable_2 & 0x0400)) {
		printk("48-bit Drive: %llu \n", id->lba_capacity_2);
		return 1;
	}

Linus Torvalds's avatar
Linus Torvalds committed
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
	/*
	 * The ATA spec tells large drives to return
	 * C/H/S = 16383/16/63 independent of their size.
	 * Some drives can be jumpered to use 15 heads instead of 16.
	 * Some drives can be jumpered to use 4092 cyls instead of 16383.
	 */
	if ((id->cyls == 16383
	     || (id->cyls == 4092 && id->cur_cyls == 16383)) &&
	    id->sectors == 63 &&
	    (id->heads == 15 || id->heads == 16) &&
	    id->lba_capacity >= 16383*63*id->heads)
		return 1;

	lba_sects   = id->lba_capacity;
	chs_sects   = id->cyls * id->heads * id->sectors;

	/* perform a rough sanity check on lba_sects:  within 10% is OK */
	if ((lba_sects - chs_sects) < chs_sects/10)
		return 1;

	/* some drives have the word order reversed */
	head = ((lba_sects >> 16) & 0xffff);
	tail = (lba_sects & 0xffff);
	lba_sects = (head | (tail << 16));
	if ((lba_sects - chs_sects) < chs_sects/10) {
		id->lba_capacity = lba_sects;
		return 1;	/* lba_capacity is (now) good */
	}

	return 0;	/* lba_capacity value may be bad */
}

Martin Dalecki's avatar
Martin Dalecki committed
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310
/*
 * Handler for command with PIO data-in phase
 */
static ide_startstop_t task_in_intr(struct ata_device *drive, struct request *rq)
{
	char *buf = NULL;
	unsigned long flags;

	if (!ata_status(drive, DATA_READY, BAD_R_STAT)) {
		if (drive->status & (ERR_STAT|DRQ_STAT))
			return ata_error(drive, rq, __FUNCTION__);

		if (!(drive->status & BUSY_STAT)) {
#if 0
			printk("task_in_intr to Soon wait for next interrupt\n");
#endif
			ide_set_handler(drive, task_in_intr, WAIT_CMD, NULL);

			return ide_started;
		}
	}
	buf = ide_map_rq(rq, &flags);
#if 0
	printk("Read: %p, rq->current_nr_sectors: %d\n", buf, (int) rq->current_nr_sectors);
#endif

	ata_read(drive, buf, SECTOR_WORDS);
	ide_unmap_rq(rq, buf, &flags);

	/* First segment of the request is complete. note that this does not
	 * necessarily mean that the entire request is done!! this is only true
	 * if ide_end_request() returns 0.
	 */

	if (--rq->current_nr_sectors <= 0) {
#if 0
		printk("Request Ended stat: %02x\n", drive->status);
#endif
		if (!ide_end_request(drive, rq, 1))
			return ide_stopped;
	}

	/* still data left to transfer */
	ide_set_handler(drive, task_in_intr,  WAIT_CMD, NULL);

	return ide_started;
}

/*
 * Handler for command with PIO data-out phase
 */
static ide_startstop_t task_out_intr(struct ata_device *drive, struct request *rq)
{
	char *buf = NULL;
	unsigned long flags;

	if (!ata_status(drive, DRIVE_READY, drive->bad_wstat))
		return ata_error(drive, rq, __FUNCTION__);

	if (!rq->current_nr_sectors)
		if (!ide_end_request(drive, rq, 1))
			return ide_stopped;

	if ((rq->nr_sectors == 1) != (drive->status & DRQ_STAT)) {
		buf = ide_map_rq(rq, &flags);
#if 0
		printk("write: %p, rq->current_nr_sectors: %d\n", buf, (int) rq->current_nr_sectors);
#endif

		ata_write(drive, buf, SECTOR_WORDS);
		ide_unmap_rq(rq, buf, &flags);
		rq->errors = 0;
		rq->current_nr_sectors--;
	}

	ide_set_handler(drive, task_out_intr, WAIT_CMD, NULL);

	return ide_started;
}

/*
 * Handler for command with Read Multiple
 */
static ide_startstop_t task_mulin_intr(struct ata_device *drive, struct request *rq)
{
	char *buf = NULL;
	unsigned int msect, nsect;
	unsigned long flags;

	if (!ata_status(drive, DATA_READY, BAD_R_STAT)) {
		if (drive->status & (ERR_STAT|DRQ_STAT))
			return ata_error(drive, rq, __FUNCTION__);

		/* no data yet, so wait for another interrupt */
		ide_set_handler(drive, task_mulin_intr, WAIT_CMD, NULL);
		return ide_started;
	}

	/* (ks/hs): Fixed Multi-Sector transfer */
	msect = drive->mult_count;

	do {
		nsect = rq->current_nr_sectors;
		if (nsect > msect)
			nsect = msect;

		buf = ide_map_rq(rq, &flags);

#if 0
		printk("Multiread: %p, nsect: %d , rq->current_nr_sectors: %d\n",
			buf, nsect, rq->current_nr_sectors);
#endif
		ata_read(drive, buf, nsect * SECTOR_WORDS);
		ide_unmap_rq(rq, buf, &flags);
		rq->errors = 0;
		rq->current_nr_sectors -= nsect;
		msect -= nsect;
		if (!rq->current_nr_sectors) {
			if (!ide_end_request(drive, rq, 1))
				return ide_stopped;
		}
	} while (msect);


	/*
	 * more data left
	 */
	ide_set_handler(drive, task_mulin_intr, WAIT_CMD, NULL);

	return ide_started;
}

static ide_startstop_t task_mulout_intr(struct ata_device *drive, struct request *rq)
{
	int ok;
	int mcount = drive->mult_count;
	ide_startstop_t startstop;


	/*
	 * FIXME: the drive->status checks here seem to be messy.
	 *
	 * (ks/hs): Handle last IRQ on multi-sector transfer,
	 * occurs after all data was sent in this chunk
	 */

	ok = ata_status(drive, DATA_READY, BAD_R_STAT);

	if (!ok || !rq->nr_sectors) {
		if (drive->status & (ERR_STAT | DRQ_STAT)) {
			startstop = ata_error(drive, rq, __FUNCTION__);

			return startstop;
		}
	}

	if (!rq->nr_sectors) {
		__ide_end_request(drive, rq, 1, rq->hard_nr_sectors);
		rq->bio = NULL;

		return ide_stopped;
	}

	if (!ok) {
		/* no data yet, so wait for another interrupt */
		if (!drive->channel->handler)
			ide_set_handler(drive, task_mulout_intr, WAIT_CMD, NULL);

		return ide_started;
	}

	do {
		char *buffer;
		int nsect = rq->current_nr_sectors;
		unsigned long flags;

		if (nsect > mcount)
			nsect = mcount;
		mcount -= nsect;

		buffer = bio_kmap_irq(rq->bio, &flags) + ide_rq_offset(rq);
		rq->sector += nsect;
		rq->nr_sectors -= nsect;
		rq->current_nr_sectors -= nsect;

		/* Do we move to the next bio after this? */
		if (!rq->current_nr_sectors) {
			/* remember to fix this up /jens */
			struct bio *bio = rq->bio->bi_next;

			/* end early if we ran out of requests */
			if (!bio) {
				mcount = 0;
			} else {
				rq->bio = bio;
				rq->current_nr_sectors = bio_iovec(bio)->bv_len >> 9;
			}
		}

		/*
		 * Ok, we're all setup for the interrupt re-entering us on the
		 * last transfer.
		 */
		ata_write(drive, buffer, nsect * SECTOR_WORDS);
		bio_kunmap_irq(buffer, &flags);
	} while (mcount);

	rq->errors = 0;
	if (!drive->channel->handler)
		ide_set_handler(drive, task_mulout_intr, WAIT_CMD, NULL);

	return ide_started;
}

/*
 * Decode with physical ATA command to use and setup associated data.
 */
static u8 get_command(struct ata_device *drive, struct ata_taskfile *ar, int cmd)
Linus Torvalds's avatar
Linus Torvalds committed
311
{
Linus Torvalds's avatar
Linus Torvalds committed
312
	int lba48bit = (drive->id->cfs_enable_2 & 0x0400) ? 1 : 0;
Linus Torvalds's avatar
Linus Torvalds committed
313

Linus Torvalds's avatar
Linus Torvalds committed
314 315
#if 1
	lba48bit = drive->addressing;
Linus Torvalds's avatar
Linus Torvalds committed
316 317
#endif

Martin Dalecki's avatar
Martin Dalecki committed
318
	if (lba48bit) {
Martin Dalecki's avatar
Martin Dalecki committed
319
		if (cmd == READ) {
Martin Dalecki's avatar
Martin Dalecki committed
320 321
			ar->command_type = IDE_DRIVE_TASK_IN;
			if (drive->using_tcq) {
Martin Dalecki's avatar
Martin Dalecki committed
322
				return WIN_READDMA_QUEUED_EXT;
Martin Dalecki's avatar
Martin Dalecki committed
323
			} else if (drive->using_dma) {
Martin Dalecki's avatar
Martin Dalecki committed
324
				return WIN_READDMA_EXT;
Martin Dalecki's avatar
Martin Dalecki committed
325 326
			} else if (drive->mult_count) {
				ar->handler = task_mulin_intr;
Martin Dalecki's avatar
Martin Dalecki committed
327
				return WIN_MULTREAD_EXT;
Martin Dalecki's avatar
Martin Dalecki committed
328 329
			} else {
				ar->handler = task_in_intr;
Martin Dalecki's avatar
Martin Dalecki committed
330
				return WIN_READ_EXT;
Martin Dalecki's avatar
Martin Dalecki committed
331
			}
Martin Dalecki's avatar
Martin Dalecki committed
332
		} else if (cmd == WRITE) {
Martin Dalecki's avatar
Martin Dalecki committed
333 334
			ar->command_type = IDE_DRIVE_TASK_RAW_WRITE;
			if (drive->using_tcq) {
Martin Dalecki's avatar
Martin Dalecki committed
335
				return WIN_WRITEDMA_QUEUED_EXT;
Martin Dalecki's avatar
Martin Dalecki committed
336
			} else if (drive->using_dma) {
Martin Dalecki's avatar
Martin Dalecki committed
337
				return WIN_WRITEDMA_EXT;
Martin Dalecki's avatar
Martin Dalecki committed
338 339
			} else if (drive->mult_count) {
				ar->handler = task_mulout_intr;
Martin Dalecki's avatar
Martin Dalecki committed
340
				return WIN_MULTWRITE_EXT;
Martin Dalecki's avatar
Martin Dalecki committed
341 342
			} else {
				ar->handler = task_out_intr;
Martin Dalecki's avatar
Martin Dalecki committed
343
				return WIN_WRITE_EXT;
Martin Dalecki's avatar
Martin Dalecki committed
344
			}
Martin Dalecki's avatar
Martin Dalecki committed
345
		}
Jens Axboe's avatar
Jens Axboe committed
346
	} else {
Martin Dalecki's avatar
Martin Dalecki committed
347
		if (cmd == READ) {
Martin Dalecki's avatar
Martin Dalecki committed
348 349
			ar->command_type = IDE_DRIVE_TASK_IN;
			if (drive->using_tcq) {
Martin Dalecki's avatar
Martin Dalecki committed
350
				return WIN_READDMA_QUEUED;
Martin Dalecki's avatar
Martin Dalecki committed
351
			} else if (drive->using_dma) {
Martin Dalecki's avatar
Martin Dalecki committed
352
				return WIN_READDMA;
Martin Dalecki's avatar
Martin Dalecki committed
353 354
			} else if (drive->mult_count) {
				ar->handler = task_in_intr;
Martin Dalecki's avatar
Martin Dalecki committed
355
				return WIN_MULTREAD;
Martin Dalecki's avatar
Martin Dalecki committed
356 357
			} else {
				ar->handler = task_in_intr;
Martin Dalecki's avatar
Martin Dalecki committed
358
				return WIN_READ;
Martin Dalecki's avatar
Martin Dalecki committed
359
			}
Martin Dalecki's avatar
Martin Dalecki committed
360
		} else if (cmd == WRITE) {
Martin Dalecki's avatar
Martin Dalecki committed
361 362
			ar->command_type = IDE_DRIVE_TASK_RAW_WRITE;
			if (drive->using_tcq) {
Martin Dalecki's avatar
Martin Dalecki committed
363
				return WIN_WRITEDMA_QUEUED;
Martin Dalecki's avatar
Martin Dalecki committed
364
			} else if (drive->using_dma) {
Martin Dalecki's avatar
Martin Dalecki committed
365
				return WIN_WRITEDMA;
Martin Dalecki's avatar
Martin Dalecki committed
366 367
			} else if (drive->mult_count) {
				ar->handler = task_mulout_intr;
Martin Dalecki's avatar
Martin Dalecki committed
368
				return WIN_MULTWRITE;
Martin Dalecki's avatar
Martin Dalecki committed
369 370
			} else {
				ar->handler = task_out_intr;
Martin Dalecki's avatar
Martin Dalecki committed
371
				return WIN_WRITE;
Martin Dalecki's avatar
Martin Dalecki committed
372
			}
Martin Dalecki's avatar
Martin Dalecki committed
373
		}
Martin Dalecki's avatar
Martin Dalecki committed
374
	}
Martin Dalecki's avatar
Martin Dalecki committed
375

Martin Dalecki's avatar
Martin Dalecki committed
376
	/* not reached! */
Martin Dalecki's avatar
Martin Dalecki committed
377
	return WIN_NOP;
Linus Torvalds's avatar
Linus Torvalds committed
378
}
Linus Torvalds's avatar
Linus Torvalds committed
379

Martin Dalecki's avatar
Martin Dalecki committed
380
static ide_startstop_t chs_do_request(struct ata_device *drive, struct request *rq, sector_t block)
Linus Torvalds's avatar
Linus Torvalds committed
381
{
Martin Dalecki's avatar
Martin Dalecki committed
382 383
	struct ata_taskfile args;
	int sectors;
Linus Torvalds's avatar
Linus Torvalds committed
384

Martin Dalecki's avatar
Martin Dalecki committed
385 386 387 388
	unsigned int track	= (block / drive->sect);
	unsigned int sect	= (block % drive->sect) + 1;
	unsigned int head	= (track % drive->head);
	unsigned int cyl	= (track / drive->head);
Linus Torvalds's avatar
Linus Torvalds committed
389

Martin Dalecki's avatar
Martin Dalecki committed
390
	sectors = rq->nr_sectors;
Linus Torvalds's avatar
Linus Torvalds committed
391 392 393
	if (sectors == 256)
		sectors = 0;

Martin Dalecki's avatar
Martin Dalecki committed
394 395
	memset(&args, 0, sizeof(args));

Martin Dalecki's avatar
Martin Dalecki committed
396 397 398 399 400
	if (blk_rq_tagged(rq)) {
		args.taskfile.feature = sectors;
		args.taskfile.sector_count = rq->tag << 3;
	} else
		args.taskfile.sector_count = sectors;
Martin Dalecki's avatar
Martin Dalecki committed
401

Martin Dalecki's avatar
Martin Dalecki committed
402 403 404
	args.taskfile.sector_number = sect;
	args.taskfile.low_cylinder = cyl;
	args.taskfile.high_cylinder = (cyl>>8);
Martin Dalecki's avatar
Martin Dalecki committed
405

Martin Dalecki's avatar
Martin Dalecki committed
406 407
	args.taskfile.device_head = head;
	args.taskfile.device_head |= drive->select.all;
Martin Dalecki's avatar
Martin Dalecki committed
408
	args.cmd = get_command(drive, &args, rq_data_dir(rq));
Linus Torvalds's avatar
Linus Torvalds committed
409

Linus Torvalds's avatar
Linus Torvalds committed
410 411 412
#ifdef DEBUG
	printk("%s: %sing: ", drive->name,
		(rq_data_dir(rq)==READ) ? "read" : "writ");
Martin Dalecki's avatar
Martin Dalecki committed
413 414
	if (lba)	printk("LBAsect=%lld, ", block);
	else		printk("CHS=%d/%d/%d, ", cyl, head, sect);
Linus Torvalds's avatar
Linus Torvalds committed
415
	printk("sectors=%ld, ", rq->nr_sectors);
Martin Dalecki's avatar
Martin Dalecki committed
416
	printk("buffer=%p\n", rq->buffer);
Linus Torvalds's avatar
Linus Torvalds committed
417
#endif
Linus Torvalds's avatar
Linus Torvalds committed
418

Martin Dalecki's avatar
Martin Dalecki committed
419
	rq->special = &args;
Linus Torvalds's avatar
Linus Torvalds committed
420

Martin Dalecki's avatar
Martin Dalecki committed
421
	return ata_taskfile(drive, &args, rq);
Linus Torvalds's avatar
Linus Torvalds committed
422 423
}

Martin Dalecki's avatar
Martin Dalecki committed
424
static ide_startstop_t lba28_do_request(struct ata_device *drive, struct request *rq, sector_t block)
Linus Torvalds's avatar
Linus Torvalds committed
425
{
Martin Dalecki's avatar
Martin Dalecki committed
426 427
	struct ata_taskfile args;
	int sectors;
Linus Torvalds's avatar
Linus Torvalds committed
428

Martin Dalecki's avatar
Martin Dalecki committed
429
	sectors = rq->nr_sectors;
Linus Torvalds's avatar
Linus Torvalds committed
430 431 432
	if (sectors == 256)
		sectors = 0;

Martin Dalecki's avatar
Martin Dalecki committed
433
	memset(&args, 0, sizeof(args));
Linus Torvalds's avatar
Linus Torvalds committed
434

Martin Dalecki's avatar
Martin Dalecki committed
435 436 437 438 439 440
	if (blk_rq_tagged(rq)) {
		args.taskfile.feature = sectors;
		args.taskfile.sector_count = rq->tag << 3;
	} else
		args.taskfile.sector_count = sectors;

Martin Dalecki's avatar
Martin Dalecki committed
441 442
	args.taskfile.sector_number = block;
	args.taskfile.low_cylinder = (block >>= 8);
Martin Dalecki's avatar
Martin Dalecki committed
443

Martin Dalecki's avatar
Martin Dalecki committed
444
	args.taskfile.high_cylinder = (block >>= 8);
Martin Dalecki's avatar
Martin Dalecki committed
445

Martin Dalecki's avatar
Martin Dalecki committed
446 447
	args.taskfile.device_head = ((block >> 8) & 0x0f);
	args.taskfile.device_head |= drive->select.all;
Martin Dalecki's avatar
Martin Dalecki committed
448
	args.cmd = get_command(drive, &args, rq_data_dir(rq));
Linus Torvalds's avatar
Linus Torvalds committed
449

Linus Torvalds's avatar
Linus Torvalds committed
450 451 452
#ifdef DEBUG
	printk("%s: %sing: ", drive->name,
		(rq_data_dir(rq)==READ) ? "read" : "writ");
Martin Dalecki's avatar
Martin Dalecki committed
453 454 455
	if (lba)	printk("LBAsect=%lld, ", block);
	else		printk("CHS=%d/%d/%d, ", cyl, head, sect);
	printk("sectors=%ld, ", rq->nr_sectors);
Martin Dalecki's avatar
Martin Dalecki committed
456
	printk("buffer=%p\n", rq->buffer);
Linus Torvalds's avatar
Linus Torvalds committed
457
#endif
Linus Torvalds's avatar
Linus Torvalds committed
458

Martin Dalecki's avatar
Martin Dalecki committed
459
	rq->special = &args;
Linus Torvalds's avatar
Linus Torvalds committed
460

Martin Dalecki's avatar
Martin Dalecki committed
461
	return ata_taskfile(drive, &args, rq);
Linus Torvalds's avatar
Linus Torvalds committed
462 463 464
}

/*
Linus Torvalds's avatar
Linus Torvalds committed
465 466 467
 * 268435455  == 137439 MB or 28bit limit
 * 320173056  == 163929 MB or 48bit addressing
 * 1073741822 == 549756 MB or 48bit addressing fake drive
Linus Torvalds's avatar
Linus Torvalds committed
468
 */
Martin Dalecki's avatar
Martin Dalecki committed
469

Martin Dalecki's avatar
Martin Dalecki committed
470
static ide_startstop_t lba48_do_request(struct ata_device *drive, struct request *rq, sector_t block)
Linus Torvalds's avatar
Linus Torvalds committed
471
{
Martin Dalecki's avatar
Martin Dalecki committed
472 473
	struct ata_taskfile args;
	int sectors;
Linus Torvalds's avatar
Linus Torvalds committed
474

Martin Dalecki's avatar
Martin Dalecki committed
475
	sectors = rq->nr_sectors;
Jens Axboe's avatar
Jens Axboe committed
476
	if (sectors == 65536)
Linus Torvalds's avatar
Linus Torvalds committed
477 478
		sectors = 0;

Martin Dalecki's avatar
Martin Dalecki committed
479
	memset(&args, 0, sizeof(args));
Martin Dalecki's avatar
Martin Dalecki committed
480

Martin Dalecki's avatar
Martin Dalecki committed
481 482 483 484 485 486 487 488
	if (blk_rq_tagged(rq)) {
		args.taskfile.feature = sectors;
		args.hobfile.feature = sectors >> 8;
		args.taskfile.sector_count = rq->tag << 3;
	} else {
		args.taskfile.sector_count = sectors;
		args.hobfile.sector_count = sectors >> 8;
	}
Linus Torvalds's avatar
Linus Torvalds committed
489

Martin Dalecki's avatar
Martin Dalecki committed
490 491 492
	args.taskfile.sector_number = block;		/* low lba */
	args.taskfile.low_cylinder = (block >>= 8);	/* mid lba */
	args.taskfile.high_cylinder = (block >>= 8);	/* hi  lba */
Martin Dalecki's avatar
Martin Dalecki committed
493
	args.taskfile.device_head = drive->select.all;
Martin Dalecki's avatar
Martin Dalecki committed
494

Martin Dalecki's avatar
Martin Dalecki committed
495 496 497
	args.hobfile.sector_number = (block >>= 8);	/* low lba */
	args.hobfile.low_cylinder = (block >>= 8);	/* mid lba */
	args.hobfile.high_cylinder = (block >>= 8);	/* hi  lba */
Martin Dalecki's avatar
Martin Dalecki committed
498 499
	args.hobfile.device_head = drive->select.all;

Martin Dalecki's avatar
Martin Dalecki committed
500
	args.cmd = get_command(drive, &args, rq_data_dir(rq));
Linus Torvalds's avatar
Linus Torvalds committed
501

Linus Torvalds's avatar
Linus Torvalds committed
502
#ifdef DEBUG
Linus Torvalds's avatar
Linus Torvalds committed
503 504
	printk("%s: %sing: ", drive->name,
		(rq_data_dir(rq)==READ) ? "read" : "writ");
Martin Dalecki's avatar
Martin Dalecki committed
505 506 507
	if (lba)	printk("LBAsect=%lld, ", block);
	else		printk("CHS=%d/%d/%d, ", cyl, head, sect);
	printk("sectors=%ld, ", rq->nr_sectors);
Martin Dalecki's avatar
Martin Dalecki committed
508
	printk("buffer=%p\n",rq->buffer);
Linus Torvalds's avatar
Linus Torvalds committed
509
#endif
Linus Torvalds's avatar
Linus Torvalds committed
510

Martin Dalecki's avatar
Martin Dalecki committed
511
	rq->special = &args;
Linus Torvalds's avatar
Linus Torvalds committed
512

Martin Dalecki's avatar
Martin Dalecki committed
513
	return ata_taskfile(drive, &args, rq);
Martin Dalecki's avatar
Martin Dalecki committed
514 515 516 517 518 519 520
}

/*
 * Issue a READ or WRITE command to a disk, using LBA if supported, or CHS
 * otherwise, to address sectors.  It also takes care of issuing special
 * DRIVE_CMDs.
 */
Martin Dalecki's avatar
Martin Dalecki committed
521
static ide_startstop_t idedisk_do_request(struct ata_device *drive, struct request *rq, sector_t block)
Martin Dalecki's avatar
Martin Dalecki committed
522 523 524 525 526 527 528
{
	/*
	 * Wait until all request have bin finished.
	 */

	while (drive->blocked) {
		yield();
Martin Dalecki's avatar
Martin Dalecki committed
529
		printk(KERN_ERR "ide: Request while drive blocked?");
Martin Dalecki's avatar
Martin Dalecki committed
530 531 532 533
	}

	if (!(rq->flags & REQ_CMD)) {
		blk_dump_rq_flags(rq, "idedisk_do_request - bad command");
Martin Dalecki's avatar
Martin Dalecki committed
534
		ide_end_request(drive, rq, 0);
Martin Dalecki's avatar
Martin Dalecki committed
535 536 537 538
		return ide_stopped;
	}

	if (IS_PDC4030_DRIVE) {
Martin Dalecki's avatar
Martin Dalecki committed
539
		extern ide_startstop_t promise_do_request(struct ata_device *, struct request *, sector_t);
Martin Dalecki's avatar
Martin Dalecki committed
540

Martin Dalecki's avatar
Martin Dalecki committed
541
		return promise_do_request(drive, rq, block);
Martin Dalecki's avatar
Martin Dalecki committed
542 543
	}

Martin Dalecki's avatar
Martin Dalecki committed
544 545 546 547 548 549 550
	/*
	 * start a tagged operation
	 */
	if (drive->using_tcq) {
		unsigned long flags;
		int ret;

Martin Dalecki's avatar
Martin Dalecki committed
551
		spin_lock_irqsave(drive->channel->lock, flags);
Martin Dalecki's avatar
Martin Dalecki committed
552 553 554 555 556 557 558 559

		ret = blk_queue_start_tag(&drive->queue, rq);

		if (ata_pending_commands(drive) > drive->max_depth)
			drive->max_depth = ata_pending_commands(drive);
		if (ata_pending_commands(drive) > drive->max_last_depth)
			drive->max_last_depth = ata_pending_commands(drive);

Martin Dalecki's avatar
Martin Dalecki committed
560
		spin_unlock_irqrestore(drive->channel->lock, flags);
Martin Dalecki's avatar
Martin Dalecki committed
561 562 563 564 565 566 567

		if (ret) {
			BUG_ON(!ata_pending_commands(drive));
			return ide_started;
		}
	}

Martin Dalecki's avatar
Martin Dalecki committed
568 569
	/* 48-bit LBA */
	if ((drive->id->cfs_enable_2 & 0x0400) && (drive->addressing))
Martin Dalecki's avatar
Martin Dalecki committed
570
		return lba48_do_request(drive, rq, block);
Martin Dalecki's avatar
Martin Dalecki committed
571 572 573

	/* 28-bit LBA */
	if (drive->select.b.lba)
Martin Dalecki's avatar
Martin Dalecki committed
574
		return lba28_do_request(drive, rq, block);
Martin Dalecki's avatar
Martin Dalecki committed
575 576

	/* 28-bit CHS */
Martin Dalecki's avatar
Martin Dalecki committed
577
	return chs_do_request(drive, rq, block);
Linus Torvalds's avatar
Linus Torvalds committed
578 579
}

Martin Dalecki's avatar
Martin Dalecki committed
580
static int idedisk_open (struct inode *inode, struct file *filp, struct ata_device *drive)
Linus Torvalds's avatar
Linus Torvalds committed
581 582 583 584
{
	MOD_INC_USE_COUNT;
	if (drive->removable && drive->usage == 1) {
		check_disk_change(inode->i_rdev);
Martin Dalecki's avatar
Martin Dalecki committed
585

Linus Torvalds's avatar
Linus Torvalds committed
586
		/*
Martin Dalecki's avatar
Martin Dalecki committed
587
		 * Ignore the return code from door_lock, since the open() has
Martin Dalecki's avatar
Martin Dalecki committed
588 589
		 * already succeeded once, and the door_lock is irrelevant at this
		 * time.
Linus Torvalds's avatar
Linus Torvalds committed
590
		 */
Martin Dalecki's avatar
Martin Dalecki committed
591 592
		if (drive->doorlocking) {
			struct ata_taskfile args;
Martin Dalecki's avatar
Martin Dalecki committed
593

Martin Dalecki's avatar
Martin Dalecki committed
594 595 596 597 598
			memset(&args, 0, sizeof(args));
			args.cmd = WIN_DOORLOCK;
			if (ide_raw_taskfile(drive, &args))
				drive->doorlocking = 0;
		}
Linus Torvalds's avatar
Linus Torvalds committed
599 600 601 602
	}
	return 0;
}

Martin Dalecki's avatar
Martin Dalecki committed
603
static int idedisk_flushcache(struct ata_device *drive)
604
{
Martin Dalecki's avatar
Martin Dalecki committed
605 606 607
	struct ata_taskfile args;

	memset(&args, 0, sizeof(args));
Martin Dalecki's avatar
Martin Dalecki committed
608

Martin Dalecki's avatar
Martin Dalecki committed
609
	if (drive->id->cfs_enable_2 & 0x2400)
Martin Dalecki's avatar
Martin Dalecki committed
610
		args.cmd = WIN_FLUSH_CACHE_EXT;
Martin Dalecki's avatar
Martin Dalecki committed
611
	else
Martin Dalecki's avatar
Martin Dalecki committed
612
		args.cmd = WIN_FLUSH_CACHE;
Martin Dalecki's avatar
Martin Dalecki committed
613
	return ide_raw_taskfile(drive, &args);
614
}
Linus Torvalds's avatar
Linus Torvalds committed
615

Martin Dalecki's avatar
Martin Dalecki committed
616
static void idedisk_release(struct inode *inode, struct file *filp, struct ata_device *drive)
Linus Torvalds's avatar
Linus Torvalds committed
617 618
{
	if (drive->removable && !drive->usage) {
619
		/* XXX I don't think this is up to the lowlevel drivers..  --hch */
Linus Torvalds's avatar
Linus Torvalds committed
620
		invalidate_bdev(inode->i_bdev, 0);
Martin Dalecki's avatar
Martin Dalecki committed
621

Martin Dalecki's avatar
Martin Dalecki committed
622 623
		if (drive->doorlocking) {
			struct ata_taskfile args;
Martin Dalecki's avatar
Martin Dalecki committed
624

Martin Dalecki's avatar
Martin Dalecki committed
625 626 627 628 629
			memset(&args, 0, sizeof(args));
			args.cmd = WIN_DOORUNLOCK;
			if (ide_raw_taskfile(drive, &args))
				drive->doorlocking = 0;
		}
Linus Torvalds's avatar
Linus Torvalds committed
630
	}
Linus Torvalds's avatar
Linus Torvalds committed
631
	if ((drive->id->cfs_enable_2 & 0x3000) && drive->wcache)
632
		if (idedisk_flushcache(drive))
Linus Torvalds's avatar
Linus Torvalds committed
633 634
			printk (KERN_INFO "%s: Write Cache FAILED Flushing!\n",
				drive->name);
Linus Torvalds's avatar
Linus Torvalds committed
635 636 637
	MOD_DEC_USE_COUNT;
}

Martin Dalecki's avatar
Martin Dalecki committed
638
static int idedisk_check_media_change(struct ata_device *drive)
Linus Torvalds's avatar
Linus Torvalds committed
639
{
640 641
	/* if removable, always assume it was changed */
	return drive->removable;
Linus Torvalds's avatar
Linus Torvalds committed
642 643
}

Martin Dalecki's avatar
Martin Dalecki committed
644
static sector_t idedisk_capacity(struct ata_device *drive)
Linus Torvalds's avatar
Linus Torvalds committed
645
{
Martin Dalecki's avatar
Martin Dalecki committed
646
	return drive->capacity - drive->sect0;
Linus Torvalds's avatar
Linus Torvalds committed
647 648
}

Linus Torvalds's avatar
Linus Torvalds committed
649
/*
Martin Dalecki's avatar
Martin Dalecki committed
650
 * This is tightly woven into the driver->special can not touch.
Linus Torvalds's avatar
Linus Torvalds committed
651 652
 * DON'T do it again until a total personality rewrite is committed.
 */
Martin Dalecki's avatar
Martin Dalecki committed
653
static int set_multcount(struct ata_device *drive, int arg)
Linus Torvalds's avatar
Linus Torvalds committed
654
{
Martin Dalecki's avatar
Martin Dalecki committed
655
	struct ata_taskfile args;
Linus Torvalds's avatar
Linus Torvalds committed
656

Martin Dalecki's avatar
Martin Dalecki committed
657 658 659 660 661 662 663 664 665 666 667 668 669
	/* Setting multi mode count on this channel type is not supported/not
	 * handled.
	 */
	if (IS_PDC4030_DRIVE)
		return -EIO;

	/* Hugh, we still didn't detect the devices capabilities.
	 */
	if (!drive->id)
		return -EIO;

	if (arg > drive->id->max_multsect)
		arg = drive->id->max_multsect;
Martin Dalecki's avatar
Martin Dalecki committed
670

Martin Dalecki's avatar
Martin Dalecki committed
671 672
	memset(&args, 0, sizeof(args));
	args.taskfile.sector_count = arg;
Martin Dalecki's avatar
Martin Dalecki committed
673
	args.cmd = WIN_SETMULT;
Martin Dalecki's avatar
Martin Dalecki committed
674 675 676
	if (!ide_raw_taskfile(drive, &args)) {
		/* all went well track this setting as valid */
		drive->mult_count = arg;
Martin Dalecki's avatar
Martin Dalecki committed
677

Martin Dalecki's avatar
Martin Dalecki committed
678 679 680
		return 0;
	} else
		drive->mult_count = 0; /* reset */
Martin Dalecki's avatar
Martin Dalecki committed
681

Martin Dalecki's avatar
Martin Dalecki committed
682
	return -EIO;
Linus Torvalds's avatar
Linus Torvalds committed
683 684
}

Martin Dalecki's avatar
Martin Dalecki committed
685
static int set_nowerr(struct ata_device *drive, int arg)
Linus Torvalds's avatar
Linus Torvalds committed
686 687 688
{
	drive->nowerr = arg;
	drive->bad_wstat = arg ? BAD_R_STAT : BAD_W_STAT;
Martin Dalecki's avatar
Martin Dalecki committed
689

Linus Torvalds's avatar
Linus Torvalds committed
690 691 692
	return 0;
}

Martin Dalecki's avatar
Martin Dalecki committed
693
static int write_cache(struct ata_device *drive, int arg)
Linus Torvalds's avatar
Linus Torvalds committed
694
{
Martin Dalecki's avatar
Martin Dalecki committed
695
	struct ata_taskfile args;
Linus Torvalds's avatar
Linus Torvalds committed
696 697 698 699

	if (!(drive->id->cfs_enable_2 & 0x3000))
		return 1;

Martin Dalecki's avatar
Martin Dalecki committed
700 701
	memset(&args, 0, sizeof(args));
	args.taskfile.feature	= (arg) ? SETFEATURES_EN_WCACHE : SETFEATURES_DIS_WCACHE;
Martin Dalecki's avatar
Martin Dalecki committed
702
	args.cmd = WIN_SETFEATURES;
Martin Dalecki's avatar
Martin Dalecki committed
703
	ide_raw_taskfile(drive, &args);
Martin Dalecki's avatar
Martin Dalecki committed
704

Linus Torvalds's avatar
Linus Torvalds committed
705
	drive->wcache = arg;
Martin Dalecki's avatar
Martin Dalecki committed
706

Linus Torvalds's avatar
Linus Torvalds committed
707 708 709
	return 0;
}

Martin Dalecki's avatar
Martin Dalecki committed
710
static int idedisk_standby(struct ata_device *drive)
Linus Torvalds's avatar
Linus Torvalds committed
711
{
Martin Dalecki's avatar
Martin Dalecki committed
712 713 714
	struct ata_taskfile args;

	memset(&args, 0, sizeof(args));
Martin Dalecki's avatar
Martin Dalecki committed
715
	args.cmd = WIN_STANDBYNOW1;
Martin Dalecki's avatar
Martin Dalecki committed
716
	return ide_raw_taskfile(drive, &args);
Linus Torvalds's avatar
Linus Torvalds committed
717 718
}

Martin Dalecki's avatar
Martin Dalecki committed
719
static int set_acoustic(struct ata_device *drive, int arg)
Linus Torvalds's avatar
Linus Torvalds committed
720
{
Martin Dalecki's avatar
Martin Dalecki committed
721
	struct ata_taskfile args;
Linus Torvalds's avatar
Linus Torvalds committed
722

Martin Dalecki's avatar
Martin Dalecki committed
723 724 725
	memset(&args, 0, sizeof(args));
	args.taskfile.feature = (arg)?SETFEATURES_EN_AAM:SETFEATURES_DIS_AAM;
	args.taskfile.sector_count = arg;
Martin Dalecki's avatar
Martin Dalecki committed
726
	args.cmd = WIN_SETFEATURES;
Martin Dalecki's avatar
Martin Dalecki committed
727
	ide_raw_taskfile(drive, &args);
Linus Torvalds's avatar
Linus Torvalds committed
728 729

	drive->acoustic = arg;
Martin Dalecki's avatar
Martin Dalecki committed
730

Linus Torvalds's avatar
Linus Torvalds committed
731 732 733
	return 0;
}

Martin Dalecki's avatar
Martin Dalecki committed
734
#ifdef CONFIG_BLK_DEV_IDE_TCQ
Martin Dalecki's avatar
Martin Dalecki committed
735
static int set_using_tcq(struct ata_device *drive, int arg)
Martin Dalecki's avatar
Martin Dalecki committed
736 737 738
{
	if (!drive->driver)
		return -EPERM;
Martin Dalecki's avatar
Martin Dalecki committed
739

Martin Dalecki's avatar
Martin Dalecki committed
740
	if (!drive->channel->udma_setup)
Martin Dalecki's avatar
Martin Dalecki committed
741
		return -EPERM;
Martin Dalecki's avatar
Martin Dalecki committed
742

Martin Dalecki's avatar
Martin Dalecki committed
743 744 745 746 747 748 749 750 751 752 753 754
	if (arg == drive->queue_depth && drive->using_tcq)
		return 0;

	/*
	 * set depth, but check also id for max supported depth
	 */
	drive->queue_depth = arg ? arg : 1;
	if (drive->id) {
		if (drive->queue_depth > drive->id->queue_depth + 1)
			drive->queue_depth = drive->id->queue_depth + 1;
	}

Martin Dalecki's avatar
Martin Dalecki committed
755
	if (udma_tcq_enable(drive, arg))
Martin Dalecki's avatar
Martin Dalecki committed
756 757 758 759 760 761
		return -EIO;

	return 0;
}
#endif

Martin Dalecki's avatar
Martin Dalecki committed
762
static int probe_lba_addressing(struct ata_device *drive, int arg)
Linus Torvalds's avatar
Linus Torvalds committed
763 764 765 766 767 768 769 770 771 772
{
	drive->addressing =  0;

	if (!(drive->id->cfs_enable_2 & 0x0400))
                return -EIO;

	drive->addressing = arg;
	return 0;
}

Martin Dalecki's avatar
Martin Dalecki committed
773
static int set_lba_addressing(struct ata_device *drive, int arg)
Linus Torvalds's avatar
Linus Torvalds committed
774 775 776 777
{
	return (probe_lba_addressing(drive, arg));
}

Martin Dalecki's avatar
Martin Dalecki committed
778 779
static int idedisk_suspend(struct device *dev, u32 state, u32 level)
{
Martin Dalecki's avatar
Martin Dalecki committed
780
	struct ata_device *drive = dev->driver_data;
Martin Dalecki's avatar
Martin Dalecki committed
781

Martin Dalecki's avatar
Martin Dalecki committed
782 783 784 785
	/* I hope that every freeze operations from the upper levels have
	 * already been done...
	 */

Pavel Machek's avatar
Pavel Machek committed
786 787
	BUG_ON(in_interrupt());

Martin Dalecki's avatar
Martin Dalecki committed
788 789 790
	if (level != SUSPEND_SAVE_STATE)
		return 0;

Martin Dalecki's avatar
Martin Dalecki committed
791
	/* wait until all commands are finished */
Martin Dalecki's avatar
Martin Dalecki committed
792 793
	/* FIXME: waiting for spinlocks should be done instead. */
	while (drive->channel->handler)
Martin Dalecki's avatar
Martin Dalecki committed
794 795 796 797 798 799 800 801
		yield();

	/* set the drive to standby */
	printk(KERN_INFO "suspending: %s ", drive->name);
	if (ata_ops(drive)) {
		if (ata_ops(drive)->standby)
			ata_ops(drive)->standby(drive);
	}
Martin Dalecki's avatar
Martin Dalecki committed
802
	drive->blocked = 1;
Martin Dalecki's avatar
Martin Dalecki committed
803 804

	return 0;
Martin Dalecki's avatar
Martin Dalecki committed
805 806 807 808
}

static int idedisk_resume(struct device *dev, u32 level)
{
Martin Dalecki's avatar
Martin Dalecki committed
809
	struct ata_device *drive = dev->driver_data;
Martin Dalecki's avatar
Martin Dalecki committed
810 811 812

	if (level != RESUME_RESTORE_STATE)
		return 0;
Martin Dalecki's avatar
Martin Dalecki committed
813 814
	if (!drive->blocked)
		panic("ide: Resume but not suspended?\n");
Martin Dalecki's avatar
Martin Dalecki committed
815

Martin Dalecki's avatar
Martin Dalecki committed
816
	drive->blocked = 0;
Martin Dalecki's avatar
Martin Dalecki committed
817
	return 0;
Martin Dalecki's avatar
Martin Dalecki committed
818 819 820
}


821 822 823
/* This is just a hook for the overall driver tree.
 */

Martin Dalecki's avatar
Martin Dalecki committed
824 825 826 827
static struct device_driver idedisk_devdrv = {
	suspend: idedisk_suspend,
	resume: idedisk_resume,
};
828

Martin Dalecki's avatar
Martin Dalecki committed
829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844
/*
 * Queries for true maximum capacity of the drive.
 * Returns maximum LBA address (> 0) of the drive, 0 if failed.
 */
static unsigned long native_max_address(struct ata_device *drive)
{
	struct ata_taskfile args;
	unsigned long addr = 0;

	if (!(drive->id->command_set_1 & 0x0400) &&
	    !(drive->id->cfs_enable_2 & 0x0100))
		return addr;

	/* Create IDE/ATA command request structure */
	memset(&args, 0, sizeof(args));
	args.taskfile.device_head = 0x40;
Martin Dalecki's avatar
Martin Dalecki committed
845
	args.cmd = WIN_READ_NATIVE_MAX;
Martin Dalecki's avatar
Martin Dalecki committed
846
	ide_raw_taskfile(drive, &args);
Martin Dalecki's avatar
Martin Dalecki committed
847 848

	/* if OK, compute maximum address value */
Martin Dalecki's avatar
Martin Dalecki committed
849
	if (!(drive->status & ERR_STAT)) {
Martin Dalecki's avatar
Martin Dalecki committed
850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869
		addr = ((args.taskfile.device_head & 0x0f) << 24)
		     | (args.taskfile.high_cylinder << 16)
		     | (args.taskfile.low_cylinder <<  8)
		     | args.taskfile.sector_number;
	}

	addr++;	/* since the return value is (maxlba - 1), we add 1 */

	return addr;
}

static u64 native_max_address_ext(struct ata_device *drive)
{
	struct ata_taskfile args;
	u64 addr = 0;

	/* Create IDE/ATA command request structure */
	memset(&args, 0, sizeof(args));

	args.taskfile.device_head = 0x40;
Martin Dalecki's avatar
Martin Dalecki committed
870
	args.cmd = WIN_READ_NATIVE_MAX_EXT;
Martin Dalecki's avatar
Martin Dalecki committed
871
        ide_raw_taskfile(drive, &args);
Martin Dalecki's avatar
Martin Dalecki committed
872 873

	/* if OK, compute maximum address value */
Martin Dalecki's avatar
Martin Dalecki committed
874
	if (!(drive->status & ERR_STAT)) {
Martin Dalecki's avatar
Martin Dalecki committed
875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893
		u32 high = (args.hobfile.high_cylinder << 16) |
			   (args.hobfile.low_cylinder << 8) |
			    args.hobfile.sector_number;
		u32 low  = (args.taskfile.high_cylinder << 16) |
			   (args.taskfile.low_cylinder << 8) |
			    args.taskfile.sector_number;
		addr = ((u64)high << 24) | low;
	}

	addr++;	/* since the return value is (maxlba - 1), we add 1 */

	return addr;
}

#ifdef CONFIG_IDEDISK_STROKE
/*
 * Sets maximum virtual LBA address of the drive.
 * Returns new maximum virtual LBA address (> 0) or 0 on failure.
 */
Martin Dalecki's avatar
Martin Dalecki committed
894
static sector_t set_max_address(struct ata_device *drive, sector_t addr_req)
Martin Dalecki's avatar
Martin Dalecki committed
895 896 897 898 899 900 901 902 903 904 905 906 907
{
	struct ata_taskfile args;
	sector_t addr_set = 0;

	addr_req--;
	/* Create IDE/ATA command request structure */
	memset(&args, 0, sizeof(args));

	args.taskfile.sector_number = (addr_req >> 0);
	args.taskfile.low_cylinder = (addr_req >> 8);
	args.taskfile.high_cylinder = (addr_req >> 16);

	args.taskfile.device_head = ((addr_req >> 24) & 0x0f) | 0x40;
Martin Dalecki's avatar
Martin Dalecki committed
908
	args.cmd = WIN_SET_MAX;
Martin Dalecki's avatar
Martin Dalecki committed
909
	ide_raw_taskfile(drive, &args);
Martin Dalecki's avatar
Martin Dalecki committed
910

Martin Dalecki's avatar
Martin Dalecki committed
911
	/* if OK, read new maximum address value */
Martin Dalecki's avatar
Martin Dalecki committed
912
	if (!(drive->status & ERR_STAT)) {
Martin Dalecki's avatar
Martin Dalecki committed
913 914 915 916 917 918 919 920 921
		addr_set = ((args.taskfile.device_head & 0x0f) << 24)
			 | (args.taskfile.high_cylinder << 16)
			 | (args.taskfile.low_cylinder <<  8)
			 | args.taskfile.sector_number;
	}
	addr_set++;
	return addr_set;
}

Martin Dalecki's avatar
Martin Dalecki committed
922
static u64 set_max_address_ext(struct ata_device *drive, u64 addr_req)
Martin Dalecki's avatar
Martin Dalecki committed
923 924 925 926 927 928 929 930 931 932 933 934
{
	struct ata_taskfile args;
	u64 addr_set = 0;

	addr_req--;
	/* Create IDE/ATA command request structure */
	memset(&args, 0, sizeof(args));

	args.taskfile.sector_number = (addr_req >>  0);
	args.taskfile.low_cylinder = (addr_req >>= 8);
	args.taskfile.high_cylinder = (addr_req >>= 8);
	args.taskfile.device_head = 0x40;
Martin Dalecki's avatar
Martin Dalecki committed
935
	args.cmd = WIN_SET_MAX_EXT;
Martin Dalecki's avatar
Martin Dalecki committed
936 937 938 939 940 941

	args.hobfile.sector_number = (addr_req >>= 8);
	args.hobfile.low_cylinder = (addr_req >>= 8);
	args.hobfile.high_cylinder = (addr_req >>= 8);
	args.hobfile.device_head = 0x40;

Martin Dalecki's avatar
Martin Dalecki committed
942
	ide_raw_taskfile(drive, &args);
Martin Dalecki's avatar
Martin Dalecki committed
943

Martin Dalecki's avatar
Martin Dalecki committed
944
	/* if OK, compute maximum address value */
Martin Dalecki's avatar
Martin Dalecki committed
945
	if (!(drive->status & ERR_STAT)) {
Martin Dalecki's avatar
Martin Dalecki committed
946 947 948 949 950 951 952 953 954 955 956 957 958 959
		u32 high = (args.hobfile.high_cylinder << 16) |
			   (args.hobfile.low_cylinder << 8) |
			    args.hobfile.sector_number;
		u32 low  = (args.taskfile.high_cylinder << 16) |
			   (args.taskfile.low_cylinder << 8) |
			    args.taskfile.sector_number;
		addr_set = ((u64)high << 24) | low;
	}
	return addr_set;
}

#endif

static void idedisk_setup(struct ata_device *drive)
Linus Torvalds's avatar
Linus Torvalds committed
960 961
{
	int i;
962

Linus Torvalds's avatar
Linus Torvalds committed
963
	struct hd_driveid *id = drive->id;
Martin Dalecki's avatar
Martin Dalecki committed
964 965
	sector_t capacity;
	sector_t set_max;
966 967
	int drvid = -1;

Linus Torvalds's avatar
Linus Torvalds committed
968 969 970 971 972 973 974 975 976
	if (id == NULL)
		return;

	/*
	 * CompactFlash cards and their brethern look just like hard drives
	 * to us, but they are removable and don't have a doorlock mechanism.
	 */
	if (drive->removable && !drive_is_flashcard(drive)) {
		/*
977
		 * Removable disks (eg. SYQUEST); ignore 'WD' drives.
Linus Torvalds's avatar
Linus Torvalds committed
978 979 980 981 982 983
		 */
		if (id->model[0] != 'W' || id->model[1] != 'D') {
			drive->doorlocking = 1;
		}
	}
	for (i = 0; i < MAX_DRIVES; ++i) {
Martin Dalecki's avatar
Martin Dalecki committed
984
		struct ata_channel *hwif = drive->channel;
Linus Torvalds's avatar
Linus Torvalds committed
985

986 987 988
		if (drive != &hwif->drives[i])
		    continue;
		drvid = i;
Linus Torvalds's avatar
Linus Torvalds committed
989 990 991 992 993 994
		hwif->gd->de_arr[i] = drive->de;
		if (drive->removable)
			hwif->gd->flags[i] |= GENHD_FL_REMOVABLE;
		break;
	}

995 996 997 998
	/* Register us within the device tree.
	 */

	if (drvid != -1) {
Martin Dalecki's avatar
Martin Dalecki committed
999 1000 1001 1002 1003 1004
		sprintf(drive->device.bus_id, "%d", drvid);
		sprintf(drive->device.name, "ide-disk");
		drive->device.driver = &idedisk_devdrv;
		drive->device.parent = &drive->channel->dev;
		drive->device.driver_data = drive;
		device_register(&drive->device);
1005 1006
	}

Linus Torvalds's avatar
Linus Torvalds committed
1007 1008 1009 1010 1011 1012 1013
	/* Extract geometry if we did not already have one for the drive */
	if (!drive->cyl || !drive->head || !drive->sect) {
		drive->cyl     = drive->bios_cyl  = id->cyls;
		drive->head    = drive->bios_head = id->heads;
		drive->sect    = drive->bios_sect = id->sectors;
	}

Martin Dalecki's avatar
Martin Dalecki committed
1014
	/* Handle logical geometry translation by the drive. */
Linus Torvalds's avatar
Linus Torvalds committed
1015 1016 1017 1018 1019 1020 1021
	if ((id->field_valid & 1) && id->cur_cyls &&
	    id->cur_heads && (id->cur_heads <= 16) && id->cur_sectors) {
		drive->cyl  = id->cur_cyls;
		drive->head = id->cur_heads;
		drive->sect = id->cur_sectors;
	}

Martin Dalecki's avatar
Martin Dalecki committed
1022
	/* Use physical geometry if what we have still makes no sense. */
Linus Torvalds's avatar
Linus Torvalds committed
1023 1024 1025 1026 1027 1028
	if (drive->head > 16 && id->heads && id->heads <= 16) {
		drive->cyl  = id->cyls;
		drive->head = id->heads;
		drive->sect = id->sectors;
	}

Martin Dalecki's avatar
Martin Dalecki committed
1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071
	/* Calculate drive capacity, and select LBA if possible.
	 * drive->id != NULL is spected
	 *
	 * To compute capacity, this uses either of
	 *
	 *    1. CHS value set by user       (whatever user sets will be trusted)
	 *    2. LBA value from target drive (require new ATA feature)
	 *    3. LBA value from system BIOS  (new one is OK, old one may break)
	 *    4. CHS value from system BIOS  (traditional style)
	 *
	 * in above order (i.e., if value of higher priority is available,
	 * reset will be ignored).
	 */
	capacity = drive->cyl * drive->head * drive->sect;
	set_max = native_max_address(drive);

	drive->capacity = 0;
	drive->select.b.lba = 0;

	if (id->cfs_enable_2 & 0x0400) {
		u64 set_max_ext;
		u64 capacity_2;
		capacity_2 = capacity;
		capacity_2 = id->lba_capacity_2;

		drive->cyl = (unsigned int) capacity_2 / (drive->head * drive->sect);
		drive->head = drive->bios_head = 255;
		drive->sect = drive->bios_sect = 63;

		drive->select.b.lba = 1;
		set_max_ext = native_max_address_ext(drive);
		if (set_max_ext > capacity_2) {
#ifdef CONFIG_IDEDISK_STROKE
			set_max_ext = native_max_address_ext(drive);
			set_max_ext = set_max_address_ext(drive, set_max_ext);
			if (set_max_ext) {
				drive->capacity = capacity_2 = set_max_ext;
				drive->cyl = (unsigned int) set_max_ext / (drive->head * drive->sect);
				drive->select.b.lba = 1;
				drive->id->lba_capacity_2 = capacity_2;
                        }
#else
			printk("%s: setmax_ext LBA %llu, native  %llu\n",
1072 1073 1074
				drive->name,
			       (long long) set_max_ext,
			       (long long) capacity_2);
Martin Dalecki's avatar
Martin Dalecki committed
1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116
#endif
		}
		drive->bios_cyl	= drive->cyl;
		drive->capacity	= capacity_2;
	} else {

		/*
		 * Determine capacity, and use LBA if the drive properly
		 * supports it.
		 */

		if ((id->capability & 2) && lba_capacity_is_ok(id)) {
			capacity = id->lba_capacity;
			drive->cyl = capacity / (drive->head * drive->sect);
			drive->select.b.lba = 1;
		}

		if (set_max > capacity) {
#ifdef CONFIG_IDEDISK_STROKE
			set_max = native_max_address(drive);
			set_max = set_max_address(drive, set_max);
			if (set_max) {
				drive->capacity = capacity = set_max;
				drive->cyl = set_max / (drive->head * drive->sect);
				drive->select.b.lba = 1;
				drive->id->lba_capacity = capacity;
			}
#else
			printk("%s: setmax LBA %lu, native  %lu\n",
					drive->name, set_max, capacity);
#endif
		}

		drive->capacity = capacity;

		if ((id->command_set_2 & 0x0400) && (id->cfs_enable_2 & 0x0400)) {
			drive->capacity = id->lba_capacity_2;
			drive->head = 255;
			drive->sect = 63;
			drive->cyl = (unsigned long)(drive->capacity) / (drive->head * drive->sect);
		}
	}
Linus Torvalds's avatar
Linus Torvalds committed
1117 1118

	/*
Martin Dalecki's avatar
Martin Dalecki committed
1119
	 * If possible, give fdisk access to more of the drive,
Linus Torvalds's avatar
Linus Torvalds committed
1120 1121
	 * by correcting bios_cyls:
	 */
Martin Dalecki's avatar
Martin Dalecki committed
1122
	capacity = idedisk_capacity(drive);
Linus Torvalds's avatar
Linus Torvalds committed
1123 1124 1125
	if ((capacity >= (drive->bios_cyl * drive->bios_sect * drive->bios_head)) &&
	    (!drive->forced_geom) && drive->bios_sect && drive->bios_head)
		drive->bios_cyl = (capacity / drive->bios_sect) / drive->bios_head;
Martin Dalecki's avatar
Martin Dalecki committed
1126
	printk(KERN_INFO " %s: %ld sectors", drive->name, capacity);
Linus Torvalds's avatar
Linus Torvalds committed
1127

Martin Dalecki's avatar
Martin Dalecki committed
1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138
#if 0

	/* Right now we avoid this calculation, since it can result in the
	 * usage of not supported compiler internal functions on 32 bit hosts.
	 * However since the calculation appears to be an interesting piece of
	 * number theory let's preserve the formula here.
	 */

	/* Give size in megabytes (MB), not mebibytes (MiB).
	 * We compute the exact rounded value, avoiding overflow.
	 */
Martin Dalecki's avatar
Martin Dalecki committed
1139
	printk(" (%ld MB)", (capacity - capacity/625 + 974)/1950);
Martin Dalecki's avatar
Martin Dalecki committed
1140
#endif
Linus Torvalds's avatar
Linus Torvalds committed
1141

Martin Dalecki's avatar
Martin Dalecki committed
1142 1143
	/* Only print cache size when it was specified.
	 */
Linus Torvalds's avatar
Linus Torvalds committed
1144 1145 1146
	if (id->buf_size)
		printk (" w/%dKiB Cache", id->buf_size/2);

Martin Dalecki's avatar
Martin Dalecki committed
1147
	printk(", CHS=%d/%d/%d",
Linus Torvalds's avatar
Linus Torvalds committed
1148 1149 1150
	       drive->bios_cyl, drive->bios_head, drive->bios_sect);
#ifdef CONFIG_BLK_DEV_IDEDMA
	if (drive->using_dma)
Martin Dalecki's avatar
Martin Dalecki committed
1151
		udma_print(drive);
Martin Dalecki's avatar
Martin Dalecki committed
1152
#endif
Linus Torvalds's avatar
Linus Torvalds committed
1153 1154 1155
	printk("\n");

	drive->mult_count = 0;
Martin Dalecki's avatar
Martin Dalecki committed
1156
#if 0
Linus Torvalds's avatar
Linus Torvalds committed
1157
	if (id->max_multsect) {
Martin Dalecki's avatar
Martin Dalecki committed
1158 1159 1160 1161 1162

		/* FIXME: reenable this again after making it to use
		 * the same code path as the ioctl stuff.
		 */

Linus Torvalds's avatar
Linus Torvalds committed
1163 1164 1165 1166
#ifdef CONFIG_IDEDISK_MULTI_MODE
		id->multsect = ((id->max_multsect/2) > 1) ? id->max_multsect : 0;
		id->multsect_valid = id->multsect ? 1 : 0;
		drive->mult_req = id->multsect_valid ? id->max_multsect : INITIAL_MULT_COUNT;
Martin Dalecki's avatar
Martin Dalecki committed
1167 1168
		if (drive->mult_req)
			drive->special_cmd |= ATA_SPECIAL_MMODE;
Martin Dalecki's avatar
Martin Dalecki committed
1169 1170
#else
		/* original, pre IDE-NFG, per request of AC */
Linus Torvalds's avatar
Linus Torvalds committed
1171 1172 1173 1174
		drive->mult_req = INITIAL_MULT_COUNT;
		if (drive->mult_req > id->max_multsect)
			drive->mult_req = id->max_multsect;
		if (drive->mult_req || ((id->multsect_valid & 1) && id->multsect))
Martin Dalecki's avatar
Martin Dalecki committed
1175
			drive->special_cmd |= ATA_SPECIAL_MMODE;
Martin Dalecki's avatar
Martin Dalecki committed
1176
#endif
Linus Torvalds's avatar
Linus Torvalds committed
1177
	}
Martin Dalecki's avatar
Martin Dalecki committed
1178
#endif
Martin Dalecki's avatar
Martin Dalecki committed
1179 1180 1181 1182 1183 1184 1185 1186

	/* FIXME: Nowadays there are many chipsets out there which *require* 32
	 * bit IO. Those will most propably not work properly with drives not
	 * supporting this. But right now we don't do anything about this. We
	 * dont' even *warn* the user!
	 */

	drive->channel->no_io_32bit = id->dword_io ? 1 : 0;
Martin Dalecki's avatar
Martin Dalecki committed
1187

Linus Torvalds's avatar
Linus Torvalds committed
1188 1189
	if (drive->id->cfs_enable_2 & 0x3000)
		write_cache(drive, (id->cfs_enable_2 & 0x3000));
Martin Dalecki's avatar
Martin Dalecki committed
1190

Martin Dalecki's avatar
Martin Dalecki committed
1191
	probe_lba_addressing(drive, 1);
Linus Torvalds's avatar
Linus Torvalds committed
1192 1193
}

Martin Dalecki's avatar
Martin Dalecki committed
1194
static int idedisk_cleanup(struct ata_device *drive)
Linus Torvalds's avatar
Linus Torvalds committed
1195
{
Martin Dalecki's avatar
Martin Dalecki committed
1196 1197 1198
	if (!drive)
	    return 0;

1199
	put_device(&drive->device);
Linus Torvalds's avatar
Linus Torvalds committed
1200
	if ((drive->id->cfs_enable_2 & 0x3000) && drive->wcache)
1201
		if (idedisk_flushcache(drive))
Linus Torvalds's avatar
Linus Torvalds committed
1202 1203
			printk (KERN_INFO "%s: Write Cache FAILED Flushing!\n",
				drive->name);
Linus Torvalds's avatar
Linus Torvalds committed
1204 1205 1206
	return ide_unregister_subdriver(drive);
}

Martin Dalecki's avatar
Martin Dalecki committed
1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229
static int idedisk_ioctl(struct ata_device *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
	struct hd_driveid *id = drive->id;

	switch (cmd) {
		case HDIO_GET_ADDRESS: {
			unsigned long val = drive->addressing;

			if (put_user(val, (unsigned long *) arg))
				return -EFAULT;
			return 0;
		}

		case HDIO_SET_ADDRESS: {
			int val;

			if (arg < 0 || arg > 2)
				return -EINVAL;

			if (ide_spin_wait_hwgroup(drive))
				return -EBUSY;

			val = set_lba_addressing(drive, arg);
Martin Dalecki's avatar
Martin Dalecki committed
1230
			spin_unlock_irq(drive->channel->lock);
Martin Dalecki's avatar
Martin Dalecki committed
1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255

			return val;
		}

		case HDIO_GET_MULTCOUNT: {
			unsigned long val = drive->mult_count & 0xFF;

			if (put_user(val, (unsigned long *) arg))
				return -EFAULT;
			return 0;
		}

		case HDIO_SET_MULTCOUNT: {
			int val;

			if (!id)
				return -EBUSY;

			if (arg < 0 || arg > (id ? id->max_multsect : 0))
				return -EINVAL;

			if (ide_spin_wait_hwgroup(drive))
				return -EBUSY;

			val = set_multcount(drive, arg);
Martin Dalecki's avatar
Martin Dalecki committed
1256
			spin_unlock_irq(drive->channel->lock);
Martin Dalecki's avatar
Martin Dalecki committed
1257 1258 1259 1260 1261 1262 1263 1264 1265

			return val;
		}

		case HDIO_GET_NOWERR: {
			unsigned long val = drive->nowerr;

			if (put_user(val, (unsigned long *) arg))
				return -EFAULT;
Martin Dalecki's avatar
Martin Dalecki committed
1266

Martin Dalecki's avatar
Martin Dalecki committed
1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279
			return 0;
		}

		case HDIO_SET_NOWERR: {
			int val;

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

			if (ide_spin_wait_hwgroup(drive))
				return -EBUSY;

			val = set_nowerr(drive, arg);
Martin Dalecki's avatar
Martin Dalecki committed
1280
			spin_unlock_irq(drive->channel->lock);
Martin Dalecki's avatar
Martin Dalecki committed
1281 1282 1283 1284 1285 1286 1287 1288 1289

			return val;
		}

		case HDIO_GET_WCACHE: {
			unsigned long val = drive->wcache;

			if (put_user(val, (unsigned long *) arg))
				return -EFAULT;
Martin Dalecki's avatar
Martin Dalecki committed
1290

Martin Dalecki's avatar
Martin Dalecki committed
1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303
			return 0;
		}

		case HDIO_SET_WCACHE: {
			int val;

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

			if (ide_spin_wait_hwgroup(drive))
				return -EBUSY;

			val = write_cache(drive, arg);
Martin Dalecki's avatar
Martin Dalecki committed
1304
			spin_unlock_irq(drive->channel->lock);
Martin Dalecki's avatar
Martin Dalecki committed
1305 1306 1307 1308 1309

			return val;
		}

		case HDIO_GET_ACOUSTIC: {
Martin Dalecki's avatar
Martin Dalecki committed
1310
			unsigned long val = drive->acoustic;
Martin Dalecki's avatar
Martin Dalecki committed
1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326

			if (put_user(val, (u8 *) arg))
				return -EFAULT;
			return 0;
		}

		case HDIO_SET_ACOUSTIC: {
			int val;

			if (arg < 0 || arg > 254)
				return -EINVAL;

			if (ide_spin_wait_hwgroup(drive))
				return -EBUSY;

			val = set_acoustic(drive, arg);
Martin Dalecki's avatar
Martin Dalecki committed
1327
			spin_unlock_irq(drive->channel->lock);
Martin Dalecki's avatar
Martin Dalecki committed
1328 1329 1330 1331 1332 1333 1334 1335 1336 1337

			return val;
		}

#ifdef CONFIG_BLK_DEV_IDE_TCQ
		case HDIO_GET_QDMA: {
			u8 val = drive->using_tcq;

			if (put_user(val, (u8 *) arg))
				return -EFAULT;
Martin Dalecki's avatar
Martin Dalecki committed
1338

Martin Dalecki's avatar
Martin Dalecki committed
1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351
			return 0;
		}

		case HDIO_SET_QDMA: {
			int val;

			if (arg < 0 || arg > IDE_MAX_TAG)
				return -EINVAL;

			if (ide_spin_wait_hwgroup(drive))
				return -EBUSY;

			val = set_using_tcq(drive, arg);
Martin Dalecki's avatar
Martin Dalecki committed
1352
			spin_unlock_irq(drive->channel->lock);
Martin Dalecki's avatar
Martin Dalecki committed
1353 1354 1355 1356 1357 1358 1359 1360 1361

			return val;
		}
#endif
		default:
			return -EINVAL;
	}
}

Martin Dalecki's avatar
Martin Dalecki committed
1362
static void idedisk_attach(struct ata_device *drive);
Martin Dalecki's avatar
Martin Dalecki committed
1363

Linus Torvalds's avatar
Linus Torvalds committed
1364
/*
Martin Dalecki's avatar
Martin Dalecki committed
1365
 * Subdriver functions.
Linus Torvalds's avatar
Linus Torvalds committed
1366
 */
1367 1368
static struct ata_operations idedisk_driver = {
	owner:			THIS_MODULE,
Martin Dalecki's avatar
Martin Dalecki committed
1369
	attach:			idedisk_attach,
Linus Torvalds's avatar
Linus Torvalds committed
1370
	cleanup:		idedisk_cleanup,
1371
	standby:		idedisk_standby,
Martin Dalecki's avatar
Martin Dalecki committed
1372
	do_request:		idedisk_do_request,
Linus Torvalds's avatar
Linus Torvalds committed
1373
	end_request:		NULL,
Martin Dalecki's avatar
Martin Dalecki committed
1374
	ioctl:			idedisk_ioctl,
Linus Torvalds's avatar
Linus Torvalds committed
1375 1376
	open:			idedisk_open,
	release:		idedisk_release,
1377 1378
	check_media_change:	idedisk_check_media_change,
	revalidate:		NULL, /* use default method */
Linus Torvalds's avatar
Linus Torvalds committed
1379 1380 1381
	capacity:		idedisk_capacity,
};

Martin Dalecki's avatar
Martin Dalecki committed
1382
static void idedisk_attach(struct ata_device *drive)
Linus Torvalds's avatar
Linus Torvalds committed
1383
{
Martin Dalecki's avatar
Martin Dalecki committed
1384 1385 1386
	char *req;
	struct ata_channel *channel;
	int unit;
Linus Torvalds's avatar
Linus Torvalds committed
1387

Martin Dalecki's avatar
Martin Dalecki committed
1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404
	if (drive->type != ATA_DISK)
		return;

	req = drive->driver_req;
	if (req[0] != '\0' && strcmp(req, "ide-disk"))
		return;

	if (ide_register_subdriver(drive, &idedisk_driver)) {
		printk (KERN_ERR "ide-disk: %s: Failed to register the driver with ide.c\n", drive->name);
		return;
	}

	idedisk_setup(drive);
	if ((!drive->head || drive->head > 16) && !drive->select.b.lba) {
		printk(KERN_ERR "%s: INVALID GEOMETRY: %d PHYSICAL HEADS?\n", drive->name, drive->head);
		idedisk_cleanup(drive);
		return;
Linus Torvalds's avatar
Linus Torvalds committed
1405
	}
Martin Dalecki's avatar
Martin Dalecki committed
1406 1407 1408 1409

	channel = drive->channel;
	unit = drive - channel->drives;

Martin Dalecki's avatar
Martin Dalecki committed
1410
	ata_revalidate(mk_kdev(channel->major, unit << PARTN_BITS));
Linus Torvalds's avatar
Linus Torvalds committed
1411 1412
}

Martin Dalecki's avatar
Martin Dalecki committed
1413
static void __exit idedisk_exit(void)
Linus Torvalds's avatar
Linus Torvalds committed
1414
{
Martin Dalecki's avatar
Martin Dalecki committed
1415 1416
	unregister_ata_driver(&idedisk_driver);
}
Martin Dalecki's avatar
Martin Dalecki committed
1417

Martin Dalecki's avatar
Martin Dalecki committed
1418 1419 1420
int __init idedisk_init(void)
{
	return ata_driver_module(&idedisk_driver);
Linus Torvalds's avatar
Linus Torvalds committed
1421 1422
}

Linus Torvalds's avatar
Linus Torvalds committed
1423 1424
module_init(idedisk_init);
module_exit(idedisk_exit);
Martin Dalecki's avatar
Martin Dalecki committed
1425 1426

MODULE_DESCRIPTION("ATA DISK Driver");
Linus Torvalds's avatar
Linus Torvalds committed
1427
MODULE_LICENSE("GPL");