ide-io.c 23.6 KB
Newer Older
Linus Torvalds's avatar
Linus Torvalds committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
/*
 *	IDE I/O functions
 *
 *	Basic PIO and command management functionality.
 *
 * This code was split off from ide.c. See ide.c for history and original
 * copyrights.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2, or (at your option) any
 * later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * For the avoidance of doubt the "preferred form" of this code is one which
 * is in an open non patent encumbered format. Where cryptographic key signing
 * forms part of the process of creating an executable the information
 * including keys needed to generate an equivalently functional executable
 * are deemed to be part of the source code.
 */
 
 
#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/blkpg.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/ide.h>
#include <linux/completion.h>
#include <linux/reboot.h>
#include <linux/cdrom.h>
#include <linux/seq_file.h>
#include <linux/device.h>
#include <linux/kmod.h>
#include <linux/scatterlist.h>
Jiri Slaby's avatar
Jiri Slaby committed
50
#include <linux/bitops.h>
Linus Torvalds's avatar
Linus Torvalds committed
51 52 53 54 55 56

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

57
int ide_end_rq(ide_drive_t *drive, struct request *rq, int error,
58
	       unsigned int nr_bytes)
Linus Torvalds's avatar
Linus Torvalds committed
59 60 61 62 63
{
	/*
	 * decide whether to reenable DMA -- 3 is a random magic for now,
	 * if we DMA timeout more than 3 times, just stay in PIO
	 */
64 65 66
	if ((drive->dev_flags & IDE_DFLAG_DMA_PIO_RETRY) &&
	    drive->retry_pio <= 3) {
		drive->dev_flags &= ~IDE_DFLAG_DMA_PIO_RETRY;
67
		ide_dma_on(drive);
Linus Torvalds's avatar
Linus Torvalds committed
68 69
	}

70
	return blk_end_request(rq, error, nr_bytes);
Linus Torvalds's avatar
Linus Torvalds committed
71
}
72
EXPORT_SYMBOL_GPL(ide_end_rq);
Linus Torvalds's avatar
Linus Torvalds committed
73

74
void ide_complete_cmd(ide_drive_t *drive, struct ide_cmd *cmd, u8 stat, u8 err)
75
{
76
	const struct ide_tp_ops *tp_ops = drive->hwif->tp_ops;
77 78
	struct ide_taskfile *tf = &cmd->tf;
	struct request *rq = cmd->rq;
79
	u8 tf_cmd = tf->command;
80 81 82 83

	tf->error = err;
	tf->status = stat;

84 85 86 87 88
	if (cmd->ftf_flags & IDE_FTFLAG_IN_DATA) {
		u8 data[2];

		tp_ops->input_data(drive, cmd, data, 2);

89 90
		cmd->tf.data  = data[0];
		cmd->hob.data = data[1];
91 92 93
	}

	tp_ops->tf_read(drive, cmd);
94

95 96 97 98 99
	if ((cmd->tf_flags & IDE_TFLAG_CUSTOM_HANDLER) &&
	    tf_cmd == ATA_CMD_IDLEIMMEDIATE) {
		if (tf->lbal != 0xc4) {
			printk(KERN_ERR "%s: head unload failed!\n",
			       drive->name);
100
			ide_tf_dump(drive->name, cmd);
101 102 103 104
		} else
			drive->dev_flags |= IDE_DFLAG_PARKED;
	}

105
	if (rq && rq->cmd_type == REQ_TYPE_ATA_TASKFILE)
106
		memcpy(rq->special, cmd, sizeof(*cmd));
107

108 109
	if (cmd->tf_flags & IDE_TFLAG_DYN)
		kfree(cmd);
110 111
}

112 113 114 115 116 117 118 119 120 121
/* obsolete, blk_rq_bytes() should be used instead */
unsigned int ide_rq_bytes(struct request *rq)
{
	if (blk_pc_request(rq))
		return rq->data_len;
	else
		return rq->hard_cur_sectors << 9;
}
EXPORT_SYMBOL_GPL(ide_rq_bytes);

122
int ide_complete_rq(ide_drive_t *drive, int error, unsigned int nr_bytes)
Linus Torvalds's avatar
Linus Torvalds committed
123
{
124 125
	ide_hwif_t *hwif = drive->hwif;
	struct request *rq = hwif->rq;
126
	int rc;
Linus Torvalds's avatar
Linus Torvalds committed
127

128 129 130 131 132 133 134
	/*
	 * if failfast is set on a request, override number of sectors
	 * and complete the whole request right now
	 */
	if (blk_noretry_request(rq) && error <= 0)
		nr_bytes = rq->hard_nr_sectors << 9;

135
	rc = ide_end_rq(drive, rq, error, nr_bytes);
136 137
	if (rc == 0)
		hwif->rq = NULL;
138

139
	return rc;
Linus Torvalds's avatar
Linus Torvalds committed
140
}
141
EXPORT_SYMBOL(ide_complete_rq);
Linus Torvalds's avatar
Linus Torvalds committed
142

143
void ide_kill_rq(ide_drive_t *drive, struct request *rq)
Linus Torvalds's avatar
Linus Torvalds committed
144
{
145 146 147
	u8 drv_req = blk_special_request(rq) && rq->rq_disk;
	u8 media = drive->media;

148 149
	drive->failed_pc = NULL;

150 151
	if ((media == ide_floppy || media == ide_tape) && drv_req) {
		rq->errors = 0;
152
		ide_complete_rq(drive, 0, blk_rq_bytes(rq));
153 154 155
	} else {
		if (media == ide_tape)
			rq->errors = IDE_DRV_ERROR_GENERAL;
156 157
		else if (blk_fs_request(rq) == 0 && rq->errors == 0)
			rq->errors = -EIO;
158
		ide_complete_rq(drive, -EIO, ide_rq_bytes(rq));
159
	}
Linus Torvalds's avatar
Linus Torvalds committed
160 161
}

162
static void ide_tf_set_specify_cmd(ide_drive_t *drive, struct ide_taskfile *tf)
Linus Torvalds's avatar
Linus Torvalds committed
163
{
164 165 166 167
	tf->nsect   = drive->sect;
	tf->lbal    = drive->sect;
	tf->lbam    = drive->cyl;
	tf->lbah    = drive->cyl >> 8;
168
	tf->device  = (drive->head - 1) | drive->select;
169
	tf->command = ATA_CMD_INIT_DEV_PARAMS;
Linus Torvalds's avatar
Linus Torvalds committed
170 171
}

172
static void ide_tf_set_restore_cmd(ide_drive_t *drive, struct ide_taskfile *tf)
Linus Torvalds's avatar
Linus Torvalds committed
173
{
174
	tf->nsect   = drive->sect;
175
	tf->command = ATA_CMD_RESTORE;
Linus Torvalds's avatar
Linus Torvalds committed
176 177
}

178
static void ide_tf_set_setmult_cmd(ide_drive_t *drive, struct ide_taskfile *tf)
Linus Torvalds's avatar
Linus Torvalds committed
179
{
180
	tf->nsect   = drive->mult_req;
181
	tf->command = ATA_CMD_SET_MULTI;
Linus Torvalds's avatar
Linus Torvalds committed
182 183 184 185 186
}

static ide_startstop_t ide_disk_special(ide_drive_t *drive)
{
	special_t *s = &drive->special;
187
	struct ide_cmd cmd;
Linus Torvalds's avatar
Linus Torvalds committed
188

189
	memset(&cmd, 0, sizeof(cmd));
190
	cmd.protocol = ATA_PROT_NODATA;
Linus Torvalds's avatar
Linus Torvalds committed
191 192 193

	if (s->b.set_geometry) {
		s->b.set_geometry = 0;
194
		ide_tf_set_specify_cmd(drive, &cmd.tf);
Linus Torvalds's avatar
Linus Torvalds committed
195 196
	} else if (s->b.recalibrate) {
		s->b.recalibrate = 0;
197
		ide_tf_set_restore_cmd(drive, &cmd.tf);
Linus Torvalds's avatar
Linus Torvalds committed
198 199
	} else if (s->b.set_multmode) {
		s->b.set_multmode = 0;
200
		ide_tf_set_setmult_cmd(drive, &cmd.tf);
Linus Torvalds's avatar
Linus Torvalds committed
201 202 203 204 205 206 207
	} else if (s->all) {
		int special = s->all;
		s->all = 0;
		printk(KERN_ERR "%s: bad special flag: 0x%02x\n", drive->name, special);
		return ide_stopped;
	}

208 209 210
	cmd.valid.out.tf = IDE_VALID_OUT_TF | IDE_VALID_DEVICE;
	cmd.valid.in.tf  = IDE_VALID_IN_TF  | IDE_VALID_DEVICE;
	cmd.tf_flags = IDE_TFLAG_CUSTOM_HANDLER;
211

212
	do_rw_taskfile(drive, &cmd);
Linus Torvalds's avatar
Linus Torvalds committed
213 214 215 216 217 218 219 220

	return ide_started;
}

/**
 *	do_special		-	issue some special commands
 *	@drive: drive the command is for
 *
221 222 223 224
 *	do_special() is used to issue ATA_CMD_INIT_DEV_PARAMS,
 *	ATA_CMD_RESTORE and ATA_CMD_SET_MULTI commands to a drive.
 *
 *	It used to do much more, but has been scaled back.
Linus Torvalds's avatar
Linus Torvalds committed
225 226 227 228 229 230 231 232 233
 */

static ide_startstop_t do_special (ide_drive_t *drive)
{
	special_t *s = &drive->special;

#ifdef DEBUG
	printk("%s: do_special: 0x%02x\n", drive->name, s->all);
#endif
234 235
	if (drive->media == ide_disk)
		return ide_disk_special(drive);
Linus Torvalds's avatar
Linus Torvalds committed
236

237 238 239
	s->all = 0;
	drive->mult_req = 0;
	return ide_stopped;
Linus Torvalds's avatar
Linus Torvalds committed
240 241
}

242
void ide_map_sg(ide_drive_t *drive, struct ide_cmd *cmd)
Linus Torvalds's avatar
Linus Torvalds committed
243 244 245
{
	ide_hwif_t *hwif = drive->hwif;
	struct scatterlist *sg = hwif->sg_table;
246
	struct request *rq = cmd->rq;
Linus Torvalds's avatar
Linus Torvalds committed
247

248
	if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
Linus Torvalds's avatar
Linus Torvalds committed
249
		sg_init_one(sg, rq->buffer, rq->nr_sectors * SECTOR_SIZE);
250
		cmd->sg_nents = 1;
251 252
	} else if (!rq->bio) {
		sg_init_one(sg, rq->data, rq->data_len);
253 254 255
		cmd->sg_nents = 1;
	} else
		cmd->sg_nents = blk_rq_map_sg(drive->queue, rq, sg);
Linus Torvalds's avatar
Linus Torvalds committed
256 257 258
}
EXPORT_SYMBOL_GPL(ide_map_sg);

259
void ide_init_sg_cmd(struct ide_cmd *cmd, unsigned int nr_bytes)
Linus Torvalds's avatar
Linus Torvalds committed
260
{
261
	cmd->nbytes = cmd->nleft = nr_bytes;
262 263
	cmd->cursg_ofs = 0;
	cmd->cursg = NULL;
Linus Torvalds's avatar
Linus Torvalds committed
264 265 266 267 268
}
EXPORT_SYMBOL_GPL(ide_init_sg_cmd);

/**
 *	execute_drive_command	-	issue special drive command
269
 *	@drive: the drive to issue the command on
Linus Torvalds's avatar
Linus Torvalds committed
270 271 272 273 274 275 276 277 278 279 280 281
 *	@rq: the request structure holding the command
 *
 *	execute_drive_cmd() issues a special drive command,  usually 
 *	initiated by ioctl() from the external hdparm program. The
 *	command can be a drive command, drive task or taskfile 
 *	operation. Weirdly you can call it with NULL to wait for
 *	all commands to finish. Don't do this as that is due to change
 */

static ide_startstop_t execute_drive_cmd (ide_drive_t *drive,
		struct request *rq)
{
282
	struct ide_cmd *cmd = rq->special;
Linus Torvalds's avatar
Linus Torvalds committed
283

284
	if (cmd) {
285
		if (cmd->protocol == ATA_PROT_PIO) {
286
			ide_init_sg_cmd(cmd, rq->nr_sectors << 9);
287
			ide_map_sg(drive, cmd);
Linus Torvalds's avatar
Linus Torvalds committed
288
		}
289

290
		return do_rw_taskfile(drive, cmd);
291 292
	}

Linus Torvalds's avatar
Linus Torvalds committed
293 294 295 296 297 298 299
 	/*
 	 * NULL is actually a valid way of waiting for
 	 * all current requests to be flushed from the queue.
 	 */
#ifdef DEBUG
 	printk("%s: DRIVE_CMD (null)\n", drive->name);
#endif
300
	rq->errors = 0;
301
	ide_complete_rq(drive, 0, blk_rq_bytes(rq));
302

Linus Torvalds's avatar
Linus Torvalds committed
303
 	return ide_stopped;
304 305
}

306 307
static ide_startstop_t ide_special_rq(ide_drive_t *drive, struct request *rq)
{
308 309 310
	u8 cmd = rq->cmd[0];

	switch (cmd) {
311 312 313
	case REQ_PARK_HEADS:
	case REQ_UNPARK_HEADS:
		return ide_do_park_unpark(drive, rq);
314
	case REQ_DEVSET_EXEC:
315
		return ide_do_devset(drive, rq);
316 317 318
	case REQ_DRIVE_RESET:
		return ide_do_reset(drive);
	default:
319
		BUG();
320 321 322
	}
}

Linus Torvalds's avatar
Linus Torvalds committed
323 324 325 326
/**
 *	start_request	-	start of I/O and command issuing for IDE
 *
 *	start_request() initiates handling of a new I/O request. It
327
 *	accepts commands and I/O (read/write) requests.
Linus Torvalds's avatar
Linus Torvalds committed
328 329 330 331 332 333 334 335
 *
 *	FIXME: this function needs a rename
 */
 
static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
{
	ide_startstop_t startstop;

336
	BUG_ON(!blk_rq_started(rq));
Linus Torvalds's avatar
Linus Torvalds committed
337 338 339

#ifdef DEBUG
	printk("%s: start_request: current=0x%08lx\n",
340
		drive->hwif->name, (unsigned long) rq);
Linus Torvalds's avatar
Linus Torvalds committed
341 342 343 344
#endif

	/* bail early if we've exceeded max_failures */
	if (drive->max_failures && (drive->failures > drive->max_failures)) {
345
		rq->cmd_flags |= REQ_FAILED;
Linus Torvalds's avatar
Linus Torvalds committed
346 347 348
		goto kill_rq;
	}

349 350
	if (blk_pm_request(rq))
		ide_check_pm_state(drive, rq);
Linus Torvalds's avatar
Linus Torvalds committed
351

Sergei Shtylyov's avatar
Sergei Shtylyov committed
352
	drive->hwif->tp_ops->dev_select(drive);
353 354
	if (ide_wait_stat(&startstop, drive, drive->ready_stat,
			  ATA_BUSY | ATA_DRQ, WAIT_READY)) {
Linus Torvalds's avatar
Linus Torvalds committed
355 356 357 358
		printk(KERN_ERR "%s: drive not ready for command\n", drive->name);
		return startstop;
	}
	if (!drive->special.all) {
359
		struct ide_driver *drv;
Linus Torvalds's avatar
Linus Torvalds committed
360

361 362 363 364 365 366 367
		/*
		 * We reset the drive so we need to issue a SETFEATURES.
		 * Do it _after_ do_special() restored device parameters.
		 */
		if (drive->current_speed == 0xff)
			ide_config_drive_speed(drive, drive->desired_speed);

368
		if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE)
Linus Torvalds's avatar
Linus Torvalds committed
369 370
			return execute_drive_cmd(drive, rq);
		else if (blk_pm_request(rq)) {
371
			struct request_pm_state *pm = rq->data;
Linus Torvalds's avatar
Linus Torvalds committed
372 373
#ifdef DEBUG_PM
			printk("%s: start_power_step(step: %d)\n",
374
				drive->name, pm->pm_step);
Linus Torvalds's avatar
Linus Torvalds committed
375 376 377
#endif
			startstop = ide_start_power_step(drive, rq);
			if (startstop == ide_stopped &&
378
			    pm->pm_step == IDE_PM_COMPLETED)
379
				ide_complete_pm_rq(drive, rq);
Linus Torvalds's avatar
Linus Torvalds committed
380
			return startstop;
381 382 383 384 385 386 387 388 389 390
		} else if (!rq->rq_disk && blk_special_request(rq))
			/*
			 * TODO: Once all ULDs have been modified to
			 * check for specific op codes rather than
			 * blindly accepting any special request, the
			 * check for ->rq_disk above may be replaced
			 * by a more suitable mechanism or even
			 * dropped entirely.
			 */
			return ide_special_rq(drive, rq);
Linus Torvalds's avatar
Linus Torvalds committed
391

392
		drv = *(struct ide_driver **)rq->rq_disk->private_data;
393 394

		return drv->do_request(drive, rq, rq->sector);
Linus Torvalds's avatar
Linus Torvalds committed
395 396 397 398 399 400 401 402 403 404 405 406 407
	}
	return do_special(drive);
kill_rq:
	ide_kill_rq(drive, rq);
	return ide_stopped;
}

/**
 *	ide_stall_queue		-	pause an IDE device
 *	@drive: drive to stall
 *	@timeout: time to stall for (jiffies)
 *
 *	ide_stall_queue() can be used by a drive to give excess bandwidth back
408
 *	to the port by sleeping for timeout jiffies.
Linus Torvalds's avatar
Linus Torvalds committed
409 410 411 412 413 414 415
 */
 
void ide_stall_queue (ide_drive_t *drive, unsigned long timeout)
{
	if (timeout > WAIT_WORSTCASE)
		timeout = WAIT_WORSTCASE;
	drive->sleep = timeout + jiffies;
416
	drive->dev_flags |= IDE_DFLAG_SLEEPING;
Linus Torvalds's avatar
Linus Torvalds committed
417 418 419
}
EXPORT_SYMBOL(ide_stall_queue);

420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441
static inline int ide_lock_port(ide_hwif_t *hwif)
{
	if (hwif->busy)
		return 1;

	hwif->busy = 1;

	return 0;
}

static inline void ide_unlock_port(ide_hwif_t *hwif)
{
	hwif->busy = 0;
}

static inline int ide_lock_host(struct ide_host *host, ide_hwif_t *hwif)
{
	int rc = 0;

	if (host->host_flags & IDE_HFLAG_SERIALIZE) {
		rc = test_and_set_bit_lock(IDE_HOST_BUSY, &host->host_busy);
		if (rc == 0) {
442 443
			if (host->get_lock)
				host->get_lock(ide_intr, hwif);
444 445 446 447 448 449 450 451
		}
	}
	return rc;
}

static inline void ide_unlock_host(struct ide_host *host)
{
	if (host->host_flags & IDE_HFLAG_SERIALIZE) {
452 453
		if (host->release_lock)
			host->release_lock();
454 455 456 457
		clear_bit_unlock(IDE_HOST_BUSY, &host->host_busy);
	}
}

Linus Torvalds's avatar
Linus Torvalds committed
458
/*
459
 * Issue a new request to a device.
Linus Torvalds's avatar
Linus Torvalds committed
460
 */
461
void do_ide_request(struct request_queue *q)
Linus Torvalds's avatar
Linus Torvalds committed
462
{
463 464
	ide_drive_t	*drive = q->queuedata;
	ide_hwif_t	*hwif = drive->hwif;
465 466
	struct ide_host *host = hwif->host;
	struct request	*rq = NULL;
Linus Torvalds's avatar
Linus Torvalds committed
467 468
	ide_startstop_t	startstop;

469 470 471 472 473 474
	/*
	 * drive is doing pre-flush, ordered write, post-flush sequence. even
	 * though that is 3 requests, it must be seen as a single transaction.
	 * we must not preempt this drive until that is complete
	 */
	if (blk_queue_flushing(q))
Linus Torvalds's avatar
Linus Torvalds committed
475
		/*
476 477 478
		 * small race where queue could get replugged during
		 * the 3-request flush cycle, just yank the plug since
		 * we want it to finish asap
Linus Torvalds's avatar
Linus Torvalds committed
479
		 */
480
		blk_remove_plug(q);
Linus Torvalds's avatar
Linus Torvalds committed
481

482
	spin_unlock_irq(q->queue_lock);
483 484 485 486

	if (ide_lock_host(host, hwif))
		goto plug_device_2;

487
	spin_lock_irq(&hwif->lock);
488

489
	if (!ide_lock_port(hwif)) {
490
		ide_hwif_t *prev_port;
491
repeat:
492
		prev_port = hwif->host->cur_port;
493
		hwif->rq = NULL;
494

495 496 497 498
		if (drive->dev_flags & IDE_DFLAG_SLEEPING &&
		    time_after(drive->sleep, jiffies)) {
			ide_unlock_port(hwif);
			goto plug_device;
499
		}
500

501 502
		if ((hwif->host->host_flags & IDE_HFLAG_SERIALIZE) &&
		    hwif != prev_port) {
503
			/*
504
			 * set nIEN for previous port, drives in the
505 506
			 * quirk_list may not like intr setups/cleanups
			 */
507
			if (prev_port && prev_port->cur_dev->quirk_list == 0)
508 509 510
				prev_port->tp_ops->write_devctl(prev_port,
								ATA_NIEN |
								ATA_DEVCTL_OBS);
511 512

			hwif->host->cur_port = hwif;
Linus Torvalds's avatar
Linus Torvalds committed
513
		}
514
		hwif->cur_dev = drive;
515
		drive->dev_flags &= ~(IDE_DFLAG_SLEEPING | IDE_DFLAG_PARKED);
Linus Torvalds's avatar
Linus Torvalds committed
516

517
		spin_unlock_irq(&hwif->lock);
518
		spin_lock_irq(q->queue_lock);
Linus Torvalds's avatar
Linus Torvalds committed
519 520 521 522 523
		/*
		 * we know that the queue isn't empty, but this can happen
		 * if the q->prep_rq_fn() decides to kill a request
		 */
		rq = elv_next_request(drive->queue);
524
		spin_unlock_irq(q->queue_lock);
525
		spin_lock_irq(&hwif->lock);
526

Linus Torvalds's avatar
Linus Torvalds committed
527
		if (!rq) {
528
			ide_unlock_port(hwif);
529
			goto out;
Linus Torvalds's avatar
Linus Torvalds committed
530 531 532 533 534 535 536 537 538 539 540 541 542 543 544
		}

		/*
		 * Sanity: don't accept a request that isn't a PM request
		 * if we are currently power managed. This is very important as
		 * blk_stop_queue() doesn't prevent the elv_next_request()
		 * above to return us whatever is in the queue. Since we call
		 * ide_do_request() ourselves, we end up taking requests while
		 * the queue is blocked...
		 * 
		 * We let requests forced at head of queue with ide-preempt
		 * though. I hope that doesn't happen too much, hopefully not
		 * unless the subdriver triggers such a thing in its own PM
		 * state machine.
		 */
545 546 547
		if ((drive->dev_flags & IDE_DFLAG_BLOCKED) &&
		    blk_pm_request(rq) == 0 &&
		    (rq->cmd_flags & REQ_PREEMPT) == 0) {
548
			/* there should be no pending command at this point */
549
			ide_unlock_port(hwif);
550
			goto plug_device;
Linus Torvalds's avatar
Linus Torvalds committed
551 552
		}

553
		hwif->rq = rq;
Linus Torvalds's avatar
Linus Torvalds committed
554

555
		spin_unlock_irq(&hwif->lock);
Linus Torvalds's avatar
Linus Torvalds committed
556
		startstop = start_request(drive, rq);
557
		spin_lock_irq(&hwif->lock);
558

559 560 561 562 563
		if (startstop == ide_stopped)
			goto repeat;
	} else
		goto plug_device;
out:
564
	spin_unlock_irq(&hwif->lock);
565 566
	if (rq == NULL)
		ide_unlock_host(host);
567
	spin_lock_irq(q->queue_lock);
568
	return;
Linus Torvalds's avatar
Linus Torvalds committed
569

570
plug_device:
571
	spin_unlock_irq(&hwif->lock);
572 573
	ide_unlock_host(host);
plug_device_2:
574 575 576 577
	spin_lock_irq(q->queue_lock);

	if (!elv_queue_empty(q))
		blk_plug_device(q);
Linus Torvalds's avatar
Linus Torvalds committed
578 579
}

580 581 582 583 584 585 586 587 588 589 590
static void ide_plug_device(ide_drive_t *drive)
{
	struct request_queue *q = drive->queue;
	unsigned long flags;

	spin_lock_irqsave(q->queue_lock, flags);
	if (!elv_queue_empty(q))
		blk_plug_device(q);
	spin_unlock_irqrestore(q->queue_lock, flags);
}

591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613
static int drive_is_ready(ide_drive_t *drive)
{
	ide_hwif_t *hwif = drive->hwif;
	u8 stat = 0;

	if (drive->waiting_for_dma)
		return hwif->dma_ops->dma_test_irq(drive);

	if (hwif->io_ports.ctl_addr &&
	    (hwif->host_flags & IDE_HFLAG_BROKEN_ALTSTATUS) == 0)
		stat = hwif->tp_ops->read_altstatus(hwif);
	else
		/* Note: this may clear a pending IRQ!! */
		stat = hwif->tp_ops->read_status(hwif);

	if (stat & ATA_BUSY)
		/* drive busy: definitely not interrupting */
		return 0;

	/* drive ready: *might* be interrupting */
	return 1;
}

Linus Torvalds's avatar
Linus Torvalds committed
614 615
/**
 *	ide_timer_expiry	-	handle lack of an IDE interrupt
616
 *	@data: timer callback magic (hwif)
Linus Torvalds's avatar
Linus Torvalds committed
617 618 619 620 621 622 623 624 625 626 627 628 629
 *
 *	An IDE command has timed out before the expected drive return
 *	occurred. At this point we attempt to clean up the current
 *	mess. If the current handler includes an expiry handler then
 *	we invoke the expiry handler, and providing it is happy the
 *	work is done. If that fails we apply generic recovery rules
 *	invoking the handler and checking the drive DMA status. We
 *	have an excessively incestuous relationship with the DMA
 *	logic that wants cleaning up.
 */
 
void ide_timer_expiry (unsigned long data)
{
630
	ide_hwif_t	*hwif = (ide_hwif_t *)data;
631
	ide_drive_t	*uninitialized_var(drive);
Linus Torvalds's avatar
Linus Torvalds committed
632 633
	ide_handler_t	*handler;
	unsigned long	flags;
634
	int		wait = -1;
635
	int		plug_device = 0;
Linus Torvalds's avatar
Linus Torvalds committed
636

637 638 639
	spin_lock_irqsave(&hwif->lock, flags);

	handler = hwif->handler;
Linus Torvalds's avatar
Linus Torvalds committed
640

641
	if (handler == NULL || hwif->req_gen != hwif->req_gen_timer) {
Linus Torvalds's avatar
Linus Torvalds committed
642 643 644 645 646 647 648
		/*
		 * Either a marginal timeout occurred
		 * (got the interrupt just as timer expired),
		 * or we were "sleeping" to give other devices a chance.
		 * Either way, we don't really want to complain about anything.
		 */
	} else {
649 650 651
		ide_expiry_t *expiry = hwif->expiry;
		ide_startstop_t startstop = ide_stopped;

652
		drive = hwif->cur_dev;
653 654 655 656 657 658 659 660 661 662

		if (expiry) {
			wait = expiry(drive);
			if (wait > 0) { /* continue */
				/* reset timer */
				hwif->timer.expires = jiffies + wait;
				hwif->req_gen_timer = hwif->req_gen;
				add_timer(&hwif->timer);
				spin_unlock_irqrestore(&hwif->lock, flags);
				return;
663
			}
Linus Torvalds's avatar
Linus Torvalds committed
664
		}
665
		hwif->handler = NULL;
666
		hwif->expiry = NULL;
667 668 669 670 671 672 673 674 675 676 677 678 679 680 681
		/*
		 * We need to simulate a real interrupt when invoking
		 * the handler() function, which means we need to
		 * globally mask the specific IRQ:
		 */
		spin_unlock(&hwif->lock);
		/* disable_irq_nosync ?? */
		disable_irq(hwif->irq);
		/* local CPU only, as if we were handling an interrupt */
		local_irq_disable();
		if (hwif->polling) {
			startstop = handler(drive);
		} else if (drive_is_ready(drive)) {
			if (drive->waiting_for_dma)
				hwif->dma_ops->dma_lost_irq(drive);
682 683
			if (hwif->ack_intr)
				hwif->ack_intr(hwif);
684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699
			printk(KERN_WARNING "%s: lost interrupt\n",
				drive->name);
			startstop = handler(drive);
		} else {
			if (drive->waiting_for_dma)
				startstop = ide_dma_timeout_retry(drive, wait);
			else
				startstop = ide_error(drive, "irq timeout",
					hwif->tp_ops->read_status(hwif));
		}
		spin_lock_irq(&hwif->lock);
		enable_irq(hwif->irq);
		if (startstop == ide_stopped) {
			ide_unlock_port(hwif);
			plug_device = 1;
		}
Linus Torvalds's avatar
Linus Torvalds committed
700
	}
701
	spin_unlock_irqrestore(&hwif->lock, flags);
702

703 704
	if (plug_device) {
		ide_unlock_host(hwif->host);
705
		ide_plug_device(drive);
706
	}
Linus Torvalds's avatar
Linus Torvalds committed
707 708 709 710 711
}

/**
 *	unexpected_intr		-	handle an unexpected IDE interrupt
 *	@irq: interrupt line
712
 *	@hwif: port being processed
Linus Torvalds's avatar
Linus Torvalds committed
713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736
 *
 *	There's nothing really useful we can do with an unexpected interrupt,
 *	other than reading the status register (to clear it), and logging it.
 *	There should be no way that an irq can happen before we're ready for it,
 *	so we needn't worry much about losing an "important" interrupt here.
 *
 *	On laptops (and "green" PCs), an unexpected interrupt occurs whenever
 *	the drive enters "idle", "standby", or "sleep" mode, so if the status
 *	looks "good", we just ignore the interrupt completely.
 *
 *	This routine assumes __cli() is in effect when called.
 *
 *	If an unexpected interrupt happens on irq15 while we are handling irq14
 *	and if the two interfaces are "serialized" (CMD640), then it looks like
 *	we could screw up by interfering with a new request being set up for 
 *	irq15.
 *
 *	In reality, this is a non-issue.  The new command is not sent unless 
 *	the drive is ready to accept one, in which case we know the drive is
 *	not trying to interrupt us.  And ide_set_handler() is always invoked
 *	before completing the issuance of any new drive command, so we will not
 *	be accidentally invoked as a result of any valid command completion
 *	interrupt.
 */
737 738

static void unexpected_intr(int irq, ide_hwif_t *hwif)
Linus Torvalds's avatar
Linus Torvalds committed
739
{
740 741 742 743 744 745 746 747 748 749 750 751
	u8 stat = hwif->tp_ops->read_status(hwif);

	if (!OK_STAT(stat, ATA_DRDY, BAD_STAT)) {
		/* Try to not flood the console with msgs */
		static unsigned long last_msgtime, count;
		++count;

		if (time_after(jiffies, last_msgtime + HZ)) {
			last_msgtime = jiffies;
			printk(KERN_ERR "%s: unexpected interrupt, "
				"status=0x%02x, count=%ld\n",
				hwif->name, stat, count);
Linus Torvalds's avatar
Linus Torvalds committed
752
		}
753
	}
Linus Torvalds's avatar
Linus Torvalds committed
754 755 756 757 758
}

/**
 *	ide_intr	-	default IDE interrupt handler
 *	@irq: interrupt number
759
 *	@dev_id: hwif
Linus Torvalds's avatar
Linus Torvalds committed
760 761 762 763 764 765
 *	@regs: unused weirdness from the kernel irq layer
 *
 *	This is the default IRQ handler for the IDE layer. You should
 *	not need to override it. If you do be aware it is subtle in
 *	places
 *
766
 *	hwif is the interface in the group currently performing
767
 *	a command. hwif->cur_dev is the drive and hwif->handler is
Linus Torvalds's avatar
Linus Torvalds committed
768 769 770 771 772 773 774 775 776 777
 *	the IRQ handler to call. As we issue a command the handlers
 *	step through multiple states, reassigning the handler to the
 *	next step in the process. Unlike a smart SCSI controller IDE
 *	expects the main processor to sequence the various transfer
 *	stages. We also manage a poll timer to catch up with most
 *	timeout situations. There are still a few where the handlers
 *	don't ever decide to give up.
 *
 *	The handler eventually returns ide_stopped to indicate the
 *	request completed. At this point we issue the next request
778
 *	on the port and the process begins again.
Linus Torvalds's avatar
Linus Torvalds committed
779
 */
780

781
irqreturn_t ide_intr (int irq, void *dev_id)
Linus Torvalds's avatar
Linus Torvalds committed
782
{
783
	ide_hwif_t *hwif = (ide_hwif_t *)dev_id;
784
	struct ide_host *host = hwif->host;
785
	ide_drive_t *uninitialized_var(drive);
Linus Torvalds's avatar
Linus Torvalds committed
786
	ide_handler_t *handler;
787
	unsigned long flags;
Linus Torvalds's avatar
Linus Torvalds committed
788
	ide_startstop_t startstop;
789
	irqreturn_t irq_ret = IRQ_NONE;
790
	int plug_device = 0;
Linus Torvalds's avatar
Linus Torvalds committed
791

792 793
	if (host->host_flags & IDE_HFLAG_SERIALIZE) {
		if (hwif != host->cur_port)
794 795
			goto out_early;
	}
796

797
	spin_lock_irqsave(&hwif->lock, flags);
Linus Torvalds's avatar
Linus Torvalds committed
798

799
	if (hwif->ack_intr && hwif->ack_intr(hwif) == 0)
800
		goto out;
Linus Torvalds's avatar
Linus Torvalds committed
801

802 803 804
	handler = hwif->handler;

	if (handler == NULL || hwif->polling) {
Linus Torvalds's avatar
Linus Torvalds committed
805 806 807 808 809 810 811 812 813 814 815 816
		/*
		 * Not expecting an interrupt from this drive.
		 * That means this could be:
		 *	(1) an interrupt from another PCI device
		 *	sharing the same PCI INT# as us.
		 * or	(2) a drive just entered sleep or standby mode,
		 *	and is interrupting to let us know.
		 * or	(3) a spurious interrupt of unknown origin.
		 *
		 * For PCI, we cannot tell the difference,
		 * so in that case we just ignore it and hope it goes away.
		 */
817
		if ((host->irq_flags & IRQF_SHARED) == 0) {
Linus Torvalds's avatar
Linus Torvalds committed
818 819 820 821
			/*
			 * Probably not a shared PCI interrupt,
			 * so we can safely try to do something about it:
			 */
822
			unexpected_intr(irq, hwif);
Linus Torvalds's avatar
Linus Torvalds committed
823 824 825 826 827
		} else {
			/*
			 * Whack the status register, just in case
			 * we have a leftover pending IRQ.
			 */
828
			(void)hwif->tp_ops->read_status(hwif);
Linus Torvalds's avatar
Linus Torvalds committed
829
		}
830
		goto out;
Linus Torvalds's avatar
Linus Torvalds committed
831
	}
832

833
	drive = hwif->cur_dev;
834 835

	if (!drive_is_ready(drive))
Linus Torvalds's avatar
Linus Torvalds committed
836 837 838 839 840 841 842
		/*
		 * This happens regularly when we share a PCI IRQ with
		 * another device.  Unfortunately, it can also happen
		 * with some buggy drives that trigger the IRQ before
		 * their status register is up to date.  Hopefully we have
		 * enough advance overhead that the latter isn't a problem.
		 */
843 844
		goto out;

845
	hwif->handler = NULL;
846
	hwif->expiry = NULL;
847 848 849
	hwif->req_gen++;
	del_timer(&hwif->timer);
	spin_unlock(&hwif->lock);
Linus Torvalds's avatar
Linus Torvalds committed
850

851 852
	if (hwif->port_ops && hwif->port_ops->clear_irq)
		hwif->port_ops->clear_irq(drive);
853

854
	if (drive->dev_flags & IDE_DFLAG_UNMASK)
855
		local_irq_enable_in_hardirq();
856

Linus Torvalds's avatar
Linus Torvalds committed
857 858 859
	/* service this interrupt, may set handler for next interrupt */
	startstop = handler(drive);

860
	spin_lock_irq(&hwif->lock);
Linus Torvalds's avatar
Linus Torvalds committed
861 862 863 864 865 866 867 868
	/*
	 * Note that handler() may have set things up for another
	 * interrupt to occur soon, but it cannot happen until
	 * we exit from this routine, because it will be the
	 * same irq as is currently being serviced here, and Linux
	 * won't allow another of the same (on any CPU) until we return.
	 */
	if (startstop == ide_stopped) {
869 870 871
		BUG_ON(hwif->handler);
		ide_unlock_port(hwif);
		plug_device = 1;
Linus Torvalds's avatar
Linus Torvalds committed
872
	}
873 874
	irq_ret = IRQ_HANDLED;
out:
875
	spin_unlock_irqrestore(&hwif->lock, flags);
876
out_early:
877 878
	if (plug_device) {
		ide_unlock_host(hwif->host);
879
		ide_plug_device(drive);
880
	}
881

882
	return irq_ret;
Linus Torvalds's avatar
Linus Torvalds committed
883
}
884
EXPORT_SYMBOL_GPL(ide_intr);
Linus Torvalds's avatar
Linus Torvalds committed
885

886 887 888 889 890 891 892
void ide_pad_transfer(ide_drive_t *drive, int write, int len)
{
	ide_hwif_t *hwif = drive->hwif;
	u8 buf[4] = { 0 };

	while (len > 0) {
		if (write)
893
			hwif->tp_ops->output_data(drive, NULL, buf, min(4, len));
894
		else
895
			hwif->tp_ops->input_data(drive, NULL, buf, min(4, len));
896 897 898 899
		len -= 4;
	}
}
EXPORT_SYMBOL_GPL(ide_pad_transfer);