ide-io.c 23.7 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

#include <asm/byteorder.h>
#include <asm/irq.h>
54
#include <linux/uaccess.h>
Linus Torvalds's avatar
Linus Torvalds committed
55 56
#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
	ide_tf_readback(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 && ata_taskfile_request(rq)) {
106
		struct ide_cmd *orig_cmd = rq->special;
107

108 109 110 111 112
		if (cmd->tf_flags & IDE_TFLAG_DYN)
			kfree(orig_cmd);
		else
			memcpy(orig_cmd, cmd, sizeof(*cmd));
	}
113 114
}

115
int ide_complete_rq(ide_drive_t *drive, int error, unsigned int nr_bytes)
Linus Torvalds's avatar
Linus Torvalds committed
116
{
117 118
	ide_hwif_t *hwif = drive->hwif;
	struct request *rq = hwif->rq;
119
	int rc;
Linus Torvalds's avatar
Linus Torvalds committed
120

121 122 123 124 125
	/*
	 * 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)
126
		nr_bytes = blk_rq_sectors(rq) << 9;
127

128
	rc = ide_end_rq(drive, rq, error, nr_bytes);
129 130
	if (rc == 0)
		hwif->rq = NULL;
131

132
	return rc;
Linus Torvalds's avatar
Linus Torvalds committed
133
}
134
EXPORT_SYMBOL(ide_complete_rq);
Linus Torvalds's avatar
Linus Torvalds committed
135

136
void ide_kill_rq(ide_drive_t *drive, struct request *rq)
Linus Torvalds's avatar
Linus Torvalds committed
137
{
138
	u8 drv_req = ata_misc_request(rq) && rq->rq_disk;
139 140
	u8 media = drive->media;

141 142
	drive->failed_pc = NULL;

143
	if ((media == ide_floppy || media == ide_tape) && drv_req) {
144
		scsi_req(rq)->result = 0;
145 146
	} else {
		if (media == ide_tape)
147 148 149
			scsi_req(rq)->result = IDE_DRV_ERROR_GENERAL;
		else if (blk_rq_is_passthrough(rq) && scsi_req(rq)->result == 0)
			scsi_req(rq)->result = -EIO;
150
	}
151 152

	ide_complete_rq(drive, -EIO, blk_rq_bytes(rq));
Linus Torvalds's avatar
Linus Torvalds committed
153 154
}

155
static void ide_tf_set_specify_cmd(ide_drive_t *drive, struct ide_taskfile *tf)
Linus Torvalds's avatar
Linus Torvalds committed
156
{
157 158 159 160
	tf->nsect   = drive->sect;
	tf->lbal    = drive->sect;
	tf->lbam    = drive->cyl;
	tf->lbah    = drive->cyl >> 8;
161
	tf->device  = (drive->head - 1) | drive->select;
162
	tf->command = ATA_CMD_INIT_DEV_PARAMS;
Linus Torvalds's avatar
Linus Torvalds committed
163 164
}

165
static void ide_tf_set_restore_cmd(ide_drive_t *drive, struct ide_taskfile *tf)
Linus Torvalds's avatar
Linus Torvalds committed
166
{
167
	tf->nsect   = drive->sect;
168
	tf->command = ATA_CMD_RESTORE;
Linus Torvalds's avatar
Linus Torvalds committed
169 170
}

171
static void ide_tf_set_setmult_cmd(ide_drive_t *drive, struct ide_taskfile *tf)
Linus Torvalds's avatar
Linus Torvalds committed
172
{
173
	tf->nsect   = drive->mult_req;
174
	tf->command = ATA_CMD_SET_MULTI;
Linus Torvalds's avatar
Linus Torvalds committed
175 176
}

177 178 179 180 181 182 183 184 185
/**
 *	do_special		-	issue some special commands
 *	@drive: drive the command is for
 *
 *	do_special() is used to issue ATA_CMD_INIT_DEV_PARAMS,
 *	ATA_CMD_RESTORE and ATA_CMD_SET_MULTI commands to a drive.
 */

static ide_startstop_t do_special(ide_drive_t *drive)
Linus Torvalds's avatar
Linus Torvalds committed
186
{
187
	struct ide_cmd cmd;
Linus Torvalds's avatar
Linus Torvalds committed
188

189
#ifdef DEBUG
190 191
	printk(KERN_DEBUG "%s: %s: 0x%02x\n", drive->name, __func__,
		drive->special_flags);
192 193
#endif
	if (drive->media != ide_disk) {
194
		drive->special_flags = 0;
195 196 197 198
		drive->mult_req = 0;
		return ide_stopped;
	}

199
	memset(&cmd, 0, sizeof(cmd));
200
	cmd.protocol = ATA_PROT_NODATA;
Linus Torvalds's avatar
Linus Torvalds committed
201

202 203
	if (drive->special_flags & IDE_SFLAG_SET_GEOMETRY) {
		drive->special_flags &= ~IDE_SFLAG_SET_GEOMETRY;
204
		ide_tf_set_specify_cmd(drive, &cmd.tf);
205 206
	} else if (drive->special_flags & IDE_SFLAG_RECALIBRATE) {
		drive->special_flags &= ~IDE_SFLAG_RECALIBRATE;
207
		ide_tf_set_restore_cmd(drive, &cmd.tf);
208 209
	} else if (drive->special_flags & IDE_SFLAG_SET_MULTMODE) {
		drive->special_flags &= ~IDE_SFLAG_SET_MULTMODE;
210
		ide_tf_set_setmult_cmd(drive, &cmd.tf);
211 212
	} else
		BUG();
Linus Torvalds's avatar
Linus Torvalds committed
213

214 215 216
	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;
217

218
	do_rw_taskfile(drive, &cmd);
Linus Torvalds's avatar
Linus Torvalds committed
219 220 221 222

	return ide_started;
}

223
void ide_map_sg(ide_drive_t *drive, struct ide_cmd *cmd)
Linus Torvalds's avatar
Linus Torvalds committed
224 225 226
{
	ide_hwif_t *hwif = drive->hwif;
	struct scatterlist *sg = hwif->sg_table;
227
	struct request *rq = cmd->rq;
Linus Torvalds's avatar
Linus Torvalds committed
228

229
	cmd->sg_nents = blk_rq_map_sg(drive->queue, rq, sg);
Linus Torvalds's avatar
Linus Torvalds committed
230 231 232
}
EXPORT_SYMBOL_GPL(ide_map_sg);

233
void ide_init_sg_cmd(struct ide_cmd *cmd, unsigned int nr_bytes)
Linus Torvalds's avatar
Linus Torvalds committed
234
{
235
	cmd->nbytes = cmd->nleft = nr_bytes;
236 237
	cmd->cursg_ofs = 0;
	cmd->cursg = NULL;
Linus Torvalds's avatar
Linus Torvalds committed
238 239 240 241 242
}
EXPORT_SYMBOL_GPL(ide_init_sg_cmd);

/**
 *	execute_drive_command	-	issue special drive command
243
 *	@drive: the drive to issue the command on
Linus Torvalds's avatar
Linus Torvalds committed
244 245 246 247 248 249 250 251 252 253 254 255
 *	@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)
{
256
	struct ide_cmd *cmd = rq->special;
Linus Torvalds's avatar
Linus Torvalds committed
257

258
	if (cmd) {
259
		if (cmd->protocol == ATA_PROT_PIO) {
260
			ide_init_sg_cmd(cmd, blk_rq_sectors(rq) << 9);
261
			ide_map_sg(drive, cmd);
Linus Torvalds's avatar
Linus Torvalds committed
262
		}
263

264
		return do_rw_taskfile(drive, cmd);
265 266
	}

Linus Torvalds's avatar
Linus Torvalds committed
267 268 269 270 271 272 273
 	/*
 	 * 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
274
	scsi_req(rq)->result = 0;
275
	ide_complete_rq(drive, 0, blk_rq_bytes(rq));
276

Linus Torvalds's avatar
Linus Torvalds committed
277
 	return ide_stopped;
278 279
}

280 281
static ide_startstop_t ide_special_rq(ide_drive_t *drive, struct request *rq)
{
282
	u8 cmd = scsi_req(rq)->cmd[0];
283 284

	switch (cmd) {
285 286 287
	case REQ_PARK_HEADS:
	case REQ_UNPARK_HEADS:
		return ide_do_park_unpark(drive, rq);
288
	case REQ_DEVSET_EXEC:
289
		return ide_do_devset(drive, rq);
290 291 292
	case REQ_DRIVE_RESET:
		return ide_do_reset(drive);
	default:
293
		BUG();
294 295 296
	}
}

Linus Torvalds's avatar
Linus Torvalds committed
297 298 299 300
/**
 *	start_request	-	start of I/O and command issuing for IDE
 *
 *	start_request() initiates handling of a new I/O request. It
301
 *	accepts commands and I/O (read/write) requests.
Linus Torvalds's avatar
Linus Torvalds committed
302 303 304 305 306 307 308 309
 *
 *	FIXME: this function needs a rename
 */
 
static ide_startstop_t start_request (ide_drive_t *drive, struct request *rq)
{
	ide_startstop_t startstop;

310
	BUG_ON(!(rq->rq_flags & RQF_STARTED));
Linus Torvalds's avatar
Linus Torvalds committed
311 312 313

#ifdef DEBUG
	printk("%s: start_request: current=0x%08lx\n",
314
		drive->hwif->name, (unsigned long) rq);
Linus Torvalds's avatar
Linus Torvalds committed
315 316 317 318
#endif

	/* bail early if we've exceeded max_failures */
	if (drive->max_failures && (drive->failures > drive->max_failures)) {
319
		rq->rq_flags |= RQF_FAILED;
Linus Torvalds's avatar
Linus Torvalds committed
320 321 322
		goto kill_rq;
	}

323
	if (ata_pm_request(rq))
324
		ide_check_pm_state(drive, rq);
Linus Torvalds's avatar
Linus Torvalds committed
325

Sergei Shtylyov's avatar
Sergei Shtylyov committed
326
	drive->hwif->tp_ops->dev_select(drive);
327 328
	if (ide_wait_stat(&startstop, drive, drive->ready_stat,
			  ATA_BUSY | ATA_DRQ, WAIT_READY)) {
Linus Torvalds's avatar
Linus Torvalds committed
329 330 331
		printk(KERN_ERR "%s: drive not ready for command\n", drive->name);
		return startstop;
	}
332 333

	if (drive->special_flags == 0) {
334
		struct ide_driver *drv;
Linus Torvalds's avatar
Linus Torvalds committed
335

336 337 338 339 340 341 342
		/*
		 * 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);

343
		if (ata_taskfile_request(rq))
Linus Torvalds's avatar
Linus Torvalds committed
344
			return execute_drive_cmd(drive, rq);
345 346
		else if (ata_pm_request(rq)) {
			struct ide_pm_state *pm = rq->special;
Linus Torvalds's avatar
Linus Torvalds committed
347 348
#ifdef DEBUG_PM
			printk("%s: start_power_step(step: %d)\n",
349
				drive->name, pm->pm_step);
Linus Torvalds's avatar
Linus Torvalds committed
350 351 352
#endif
			startstop = ide_start_power_step(drive, rq);
			if (startstop == ide_stopped &&
353
			    pm->pm_step == IDE_PM_COMPLETED)
354
				ide_complete_pm_rq(drive, rq);
Linus Torvalds's avatar
Linus Torvalds committed
355
			return startstop;
356
		} else if (!rq->rq_disk && ata_misc_request(rq))
357 358 359 360 361 362 363 364 365
			/*
			 * 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
366

367
		drv = *(struct ide_driver **)rq->rq_disk->private_data;
368

369
		return drv->do_request(drive, rq, blk_rq_pos(rq));
Linus Torvalds's avatar
Linus Torvalds committed
370 371 372 373 374 375 376 377 378 379 380 381 382
	}
	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
383
 *	to the port by sleeping for timeout jiffies.
Linus Torvalds's avatar
Linus Torvalds committed
384 385 386 387 388 389 390
 */
 
void ide_stall_queue (ide_drive_t *drive, unsigned long timeout)
{
	if (timeout > WAIT_WORSTCASE)
		timeout = WAIT_WORSTCASE;
	drive->sleep = timeout + jiffies;
391
	drive->dev_flags |= IDE_DFLAG_SLEEPING;
Linus Torvalds's avatar
Linus Torvalds committed
392 393 394
}
EXPORT_SYMBOL(ide_stall_queue);

395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416
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) {
417 418
			if (host->get_lock)
				host->get_lock(ide_intr, hwif);
419 420 421 422 423 424 425 426
		}
	}
	return rc;
}

static inline void ide_unlock_host(struct ide_host *host)
{
	if (host->host_flags & IDE_HFLAG_SERIALIZE) {
427 428
		if (host->release_lock)
			host->release_lock();
429 430 431 432
		clear_bit_unlock(IDE_HOST_BUSY, &host->host_busy);
	}
}

433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452
static void __ide_requeue_and_plug(struct request_queue *q, struct request *rq)
{
	if (rq)
		blk_requeue_request(q, rq);
	if (rq || blk_peek_request(q)) {
		/* Use 3ms as that was the old plug delay */
		blk_delay_queue(q, 3);
	}
}

void ide_requeue_and_plug(ide_drive_t *drive, struct request *rq)
{
	struct request_queue *q = drive->queue;
	unsigned long flags;

	spin_lock_irqsave(q->queue_lock, flags);
	__ide_requeue_and_plug(q, rq);
	spin_unlock_irqrestore(q->queue_lock, flags);
}

Linus Torvalds's avatar
Linus Torvalds committed
453
/*
454
 * Issue a new request to a device.
Linus Torvalds's avatar
Linus Torvalds committed
455
 */
456
void do_ide_request(struct request_queue *q)
Linus Torvalds's avatar
Linus Torvalds committed
457
{
458 459
	ide_drive_t	*drive = q->queuedata;
	ide_hwif_t	*hwif = drive->hwif;
460 461
	struct ide_host *host = hwif->host;
	struct request	*rq = NULL;
Linus Torvalds's avatar
Linus Torvalds committed
462
	ide_startstop_t	startstop;
463
	unsigned long queue_run_ms = 3; /* old plug delay */
Linus Torvalds's avatar
Linus Torvalds committed
464

465
	spin_unlock_irq(q->queue_lock);
466

467 468 469
	/* HLD do_request() callback might sleep, make sure it's okay */
	might_sleep();

470 471 472
	if (ide_lock_host(host, hwif))
		goto plug_device_2;

473
	spin_lock_irq(&hwif->lock);
474

475
	if (!ide_lock_port(hwif)) {
476
		ide_hwif_t *prev_port;
477 478

		WARN_ON_ONCE(hwif->rq);
479
repeat:
480
		prev_port = hwif->host->cur_port;
481 482
		if (drive->dev_flags & IDE_DFLAG_SLEEPING &&
		    time_after(drive->sleep, jiffies)) {
483 484 485
			unsigned long left = jiffies - drive->sleep;

			queue_run_ms = jiffies_to_msecs(left + 1);
486 487
			ide_unlock_port(hwif);
			goto plug_device;
488
		}
489

490 491
		if ((hwif->host->host_flags & IDE_HFLAG_SERIALIZE) &&
		    hwif != prev_port) {
492 493 494
			ide_drive_t *cur_dev =
				prev_port ? prev_port->cur_dev : NULL;

495
			/*
496
			 * set nIEN for previous port, drives in the
497
			 * quirk list may not like intr setups/cleanups
498
			 */
499 500
			if (cur_dev &&
			    (cur_dev->dev_flags & IDE_DFLAG_NIEN_QUIRK) == 0)
501 502 503
				prev_port->tp_ops->write_devctl(prev_port,
								ATA_NIEN |
								ATA_DEVCTL_OBS);
504 505

			hwif->host->cur_port = hwif;
Linus Torvalds's avatar
Linus Torvalds committed
506
		}
507
		hwif->cur_dev = drive;
508
		drive->dev_flags &= ~(IDE_DFLAG_SLEEPING | IDE_DFLAG_PARKED);
Linus Torvalds's avatar
Linus Torvalds committed
509

510 511 512 513 514 515 516
		spin_unlock_irq(&hwif->lock);
		spin_lock_irq(q->queue_lock);
		/*
		 * we know that the queue isn't empty, but this can happen
		 * if the q->prep_rq_fn() decides to kill a request
		 */
		if (!rq)
517
			rq = blk_fetch_request(drive->queue);
Tejun Heo's avatar
Tejun Heo committed
518

519 520 521 522 523 524
		spin_unlock_irq(q->queue_lock);
		spin_lock_irq(&hwif->lock);

		if (!rq) {
			ide_unlock_port(hwif);
			goto out;
Linus Torvalds's avatar
Linus Torvalds committed
525 526 527 528
		}

		/*
		 * Sanity: don't accept a request that isn't a PM request
529 530 531 532 533 534 535 536 537 538
		 * if we are currently power managed. This is very important as
		 * blk_stop_queue() doesn't prevent the blk_fetch_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.
Linus Torvalds's avatar
Linus Torvalds committed
539
		 */
540
		if ((drive->dev_flags & IDE_DFLAG_BLOCKED) &&
541
		    ata_pm_request(rq) == 0 &&
542
		    (rq->rq_flags & RQF_PREEMPT) == 0) {
543 544 545 546
			/* there should be no pending command at this point */
			ide_unlock_port(hwif);
			goto plug_device;
		}
Linus Torvalds's avatar
Linus Torvalds committed
547

548
		scsi_req(rq)->resid_len = blk_rq_bytes(rq);
549
		hwif->rq = rq;
Linus Torvalds's avatar
Linus Torvalds committed
550

551
		spin_unlock_irq(&hwif->lock);
Linus Torvalds's avatar
Linus Torvalds committed
552
		startstop = start_request(drive, rq);
553
		spin_lock_irq(&hwif->lock);
554

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

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

577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599
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
600 601
/**
 *	ide_timer_expiry	-	handle lack of an IDE interrupt
602
 *	@data: timer callback magic (hwif)
Linus Torvalds's avatar
Linus Torvalds committed
603 604 605 606 607 608 609 610 611 612 613 614 615
 *
 *	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)
{
616
	ide_hwif_t	*hwif = (ide_hwif_t *)data;
617
	ide_drive_t	*uninitialized_var(drive);
Linus Torvalds's avatar
Linus Torvalds committed
618 619
	ide_handler_t	*handler;
	unsigned long	flags;
620
	int		wait = -1;
621
	int		plug_device = 0;
Tejun Heo's avatar
Tejun Heo committed
622
	struct request	*uninitialized_var(rq_in_flight);
Linus Torvalds's avatar
Linus Torvalds committed
623

624 625 626
	spin_lock_irqsave(&hwif->lock, flags);

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

628
	if (handler == NULL || hwif->req_gen != hwif->req_gen_timer) {
Linus Torvalds's avatar
Linus Torvalds committed
629 630 631 632 633 634 635
		/*
		 * 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 {
636 637 638
		ide_expiry_t *expiry = hwif->expiry;
		ide_startstop_t startstop = ide_stopped;

639
		drive = hwif->cur_dev;
640 641 642 643 644 645 646 647 648 649

		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;
650
			}
Linus Torvalds's avatar
Linus Torvalds committed
651
		}
652
		hwif->handler = NULL;
653
		hwif->expiry = NULL;
654 655 656 657 658 659 660 661 662 663 664 665 666 667 668
		/*
		 * 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);
669 670 671
			if (hwif->port_ops && hwif->port_ops->clear_irq)
				hwif->port_ops->clear_irq(drive);

672 673 674 675 676 677 678 679 680 681 682 683
			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);
684
		if (startstop == ide_stopped && hwif->polling == 0) {
Tejun Heo's avatar
Tejun Heo committed
685 686
			rq_in_flight = hwif->rq;
			hwif->rq = NULL;
687 688 689
			ide_unlock_port(hwif);
			plug_device = 1;
		}
Linus Torvalds's avatar
Linus Torvalds committed
690
	}
691
	spin_unlock_irqrestore(&hwif->lock, flags);
692

693 694
	if (plug_device) {
		ide_unlock_host(hwif->host);
Tejun Heo's avatar
Tejun Heo committed
695
		ide_requeue_and_plug(drive, rq_in_flight);
696
	}
Linus Torvalds's avatar
Linus Torvalds committed
697 698 699 700 701
}

/**
 *	unexpected_intr		-	handle an unexpected IDE interrupt
 *	@irq: interrupt line
702
 *	@hwif: port being processed
Linus Torvalds's avatar
Linus Torvalds committed
703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726
 *
 *	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.
 */
727 728

static void unexpected_intr(int irq, ide_hwif_t *hwif)
Linus Torvalds's avatar
Linus Torvalds committed
729
{
730 731 732 733 734 735 736 737 738 739 740 741
	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
742
		}
743
	}
Linus Torvalds's avatar
Linus Torvalds committed
744 745 746 747 748
}

/**
 *	ide_intr	-	default IDE interrupt handler
 *	@irq: interrupt number
749
 *	@dev_id: hwif
Linus Torvalds's avatar
Linus Torvalds committed
750 751 752 753 754 755
 *	@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
 *
756
 *	hwif is the interface in the group currently performing
757
 *	a command. hwif->cur_dev is the drive and hwif->handler is
Linus Torvalds's avatar
Linus Torvalds committed
758 759 760 761 762 763 764 765 766 767
 *	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
768
 *	on the port and the process begins again.
Linus Torvalds's avatar
Linus Torvalds committed
769
 */
770

771
irqreturn_t ide_intr (int irq, void *dev_id)
Linus Torvalds's avatar
Linus Torvalds committed
772
{
773
	ide_hwif_t *hwif = (ide_hwif_t *)dev_id;
774
	struct ide_host *host = hwif->host;
775
	ide_drive_t *uninitialized_var(drive);
Linus Torvalds's avatar
Linus Torvalds committed
776
	ide_handler_t *handler;
777
	unsigned long flags;
Linus Torvalds's avatar
Linus Torvalds committed
778
	ide_startstop_t startstop;
779
	irqreturn_t irq_ret = IRQ_NONE;
780
	int plug_device = 0;
Tejun Heo's avatar
Tejun Heo committed
781
	struct request *uninitialized_var(rq_in_flight);
Linus Torvalds's avatar
Linus Torvalds committed
782

783 784
	if (host->host_flags & IDE_HFLAG_SERIALIZE) {
		if (hwif != host->cur_port)
785 786
			goto out_early;
	}
787

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

790 791
	if (hwif->port_ops && hwif->port_ops->test_irq &&
	    hwif->port_ops->test_irq(hwif) == 0)
792
		goto out;
Linus Torvalds's avatar
Linus Torvalds committed
793

794 795 796
	handler = hwif->handler;

	if (handler == NULL || hwif->polling) {
Linus Torvalds's avatar
Linus Torvalds committed
797 798 799 800 801 802 803 804 805 806 807 808
		/*
		 * 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.
		 */
809
		if ((host->irq_flags & IRQF_SHARED) == 0) {
Linus Torvalds's avatar
Linus Torvalds committed
810 811 812 813
			/*
			 * Probably not a shared PCI interrupt,
			 * so we can safely try to do something about it:
			 */
814
			unexpected_intr(irq, hwif);
Linus Torvalds's avatar
Linus Torvalds committed
815 816 817 818 819
		} else {
			/*
			 * Whack the status register, just in case
			 * we have a leftover pending IRQ.
			 */
820
			(void)hwif->tp_ops->read_status(hwif);
Linus Torvalds's avatar
Linus Torvalds committed
821
		}
822
		goto out;
Linus Torvalds's avatar
Linus Torvalds committed
823
	}
824

825
	drive = hwif->cur_dev;
826 827

	if (!drive_is_ready(drive))
Linus Torvalds's avatar
Linus Torvalds committed
828 829 830 831 832 833 834
		/*
		 * 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.
		 */
835 836
		goto out;

837
	hwif->handler = NULL;
838
	hwif->expiry = NULL;
839 840 841
	hwif->req_gen++;
	del_timer(&hwif->timer);
	spin_unlock(&hwif->lock);
Linus Torvalds's avatar
Linus Torvalds committed
842

843 844
	if (hwif->port_ops && hwif->port_ops->clear_irq)
		hwif->port_ops->clear_irq(drive);
845

846
	if (drive->dev_flags & IDE_DFLAG_UNMASK)
847
		local_irq_enable_in_hardirq();
848

Linus Torvalds's avatar
Linus Torvalds committed
849 850 851
	/* service this interrupt, may set handler for next interrupt */
	startstop = handler(drive);

852
	spin_lock_irq(&hwif->lock);
Linus Torvalds's avatar
Linus Torvalds committed
853 854 855 856 857 858 859
	/*
	 * 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.
	 */
860
	if (startstop == ide_stopped && hwif->polling == 0) {
861
		BUG_ON(hwif->handler);
Tejun Heo's avatar
Tejun Heo committed
862 863
		rq_in_flight = hwif->rq;
		hwif->rq = NULL;
864 865
		ide_unlock_port(hwif);
		plug_device = 1;
Linus Torvalds's avatar
Linus Torvalds committed
866
	}
867 868
	irq_ret = IRQ_HANDLED;
out:
869
	spin_unlock_irqrestore(&hwif->lock, flags);
870
out_early:
871 872
	if (plug_device) {
		ide_unlock_host(hwif->host);
Tejun Heo's avatar
Tejun Heo committed
873
		ide_requeue_and_plug(drive, rq_in_flight);
874
	}
875

876
	return irq_ret;
Linus Torvalds's avatar
Linus Torvalds committed
877
}
878
EXPORT_SYMBOL_GPL(ide_intr);
Linus Torvalds's avatar
Linus Torvalds committed
879

880 881 882 883 884 885 886
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)
887
			hwif->tp_ops->output_data(drive, NULL, buf, min(4, len));
888
		else
889
			hwif->tp_ops->input_data(drive, NULL, buf, min(4, len));
890 891 892 893
		len -= 4;
	}
}
EXPORT_SYMBOL_GPL(ide_pad_transfer);