ide-cd.c 46.4 KB
Newer Older
L
Linus Torvalds 已提交
1
/*
2
 * ATAPI CD-ROM driver.
L
Linus Torvalds 已提交
3
 *
4 5 6
 * Copyright (C) 1994-1996   Scott Snyder <snyder@fnald0.fnal.gov>
 * Copyright (C) 1996-1998   Erik Andersen <andersee@debian.org>
 * Copyright (C) 1998-2000   Jens Axboe <axboe@suse.de>
7
 * Copyright (C) 2005, 2007-2009  Bartlomiej Zolnierkiewicz
L
Linus Torvalds 已提交
8 9 10 11 12 13 14
 *
 * May be copied or modified under the terms of the GNU General Public
 * License.  See linux/COPYING for more information.
 *
 * See Documentation/cdrom/ide-cd for usage information.
 *
 * Suggestions are welcome. Patches that work are more welcome though. ;-)
15 16 17
 *
 * Documentation:
 *	Mt. Fuji (SFF8090 version 4) and ATAPI (SFF-8020i rev 2.6) standards.
L
Linus Torvalds 已提交
18
 *
19 20 21 22
 * For historical changelog please see:
 *	Documentation/ide/ChangeLog.ide-cd.1994-2004
 */

23 24 25
#define DRV_NAME "ide-cd"
#define PFX DRV_NAME ": "

26
#define IDECD_VERSION "5.00"
L
Linus Torvalds 已提交
27 28 29 30 31 32 33 34 35 36 37 38

#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/timer.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/errno.h>
#include <linux/cdrom.h>
#include <linux/ide.h>
#include <linux/completion.h>
39
#include <linux/mutex.h>
40
#include <linux/bcd.h>
L
Linus Torvalds 已提交
41

B
Borislav Petkov 已提交
42 43
/* For SCSI -> ATAPI command conversion */
#include <scsi/scsi.h>
L
Linus Torvalds 已提交
44

B
Borislav Petkov 已提交
45 46
#include <linux/irq.h>
#include <linux/io.h>
L
Linus Torvalds 已提交
47
#include <asm/byteorder.h>
B
Borislav Petkov 已提交
48
#include <linux/uaccess.h>
L
Linus Torvalds 已提交
49 50 51 52
#include <asm/unaligned.h>

#include "ide-cd.h"

53
static DEFINE_MUTEX(idecd_ref_mutex);
L
Linus Torvalds 已提交
54

55
static void ide_cd_release(struct device *);
56

L
Linus Torvalds 已提交
57 58 59 60
static struct cdrom_info *ide_cd_get(struct gendisk *disk)
{
	struct cdrom_info *cd = NULL;

61
	mutex_lock(&idecd_ref_mutex);
B
Borislav Petkov 已提交
62
	cd = ide_drv_g(disk, cdrom_info);
63
	if (cd) {
64
		if (ide_device_get(cd->drive))
65
			cd = NULL;
66
		else
67
			get_device(&cd->dev);
68

69
	}
70
	mutex_unlock(&idecd_ref_mutex);
L
Linus Torvalds 已提交
71 72 73 74 75
	return cd;
}

static void ide_cd_put(struct cdrom_info *cd)
{
76 77
	ide_drive_t *drive = cd->drive;

78
	mutex_lock(&idecd_ref_mutex);
79
	put_device(&cd->dev);
80
	ide_device_put(drive);
81
	mutex_unlock(&idecd_ref_mutex);
L
Linus Torvalds 已提交
82 83
}

B
Borislav Petkov 已提交
84
/*
L
Linus Torvalds 已提交
85 86 87
 * Generic packet command support and error handling routines.
 */

B
Borislav Petkov 已提交
88
/* Mark that we've seen a media change and invalidate our internal buffers. */
89
static void cdrom_saw_media_change(ide_drive_t *drive)
L
Linus Torvalds 已提交
90
{
91
	drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED;
92
	drive->atapi_flags &= ~IDE_AFLAG_TOC_VALID;
L
Linus Torvalds 已提交
93 94 95 96 97 98 99
}

static int cdrom_log_sense(ide_drive_t *drive, struct request *rq,
			   struct request_sense *sense)
{
	int log = 0;

B
Borislav Petkov 已提交
100
	ide_debug_log(IDE_DBG_SENSE, "sense_key: 0x%x", sense->sense_key);
101

102
	if (!sense || !rq || (rq->cmd_flags & REQ_QUIET))
L
Linus Torvalds 已提交
103 104 105
		return 0;

	switch (sense->sense_key) {
106 107 108 109 110
	case NO_SENSE:
	case RECOVERED_ERROR:
		break;
	case NOT_READY:
		/*
B
Borislav Petkov 已提交
111 112
		 * don't care about tray state messages for e.g. capacity
		 * commands or in-progress or becoming ready
113 114
		 */
		if (sense->asc == 0x3a || sense->asc == 0x04)
L
Linus Torvalds 已提交
115
			break;
116 117 118 119
		log = 1;
		break;
	case ILLEGAL_REQUEST:
		/*
B
Borislav Petkov 已提交
120 121
		 * don't log START_STOP unit with LoEj set, since we cannot
		 * reliably check if drive can auto-close
122 123
		 */
		if (rq->cmd[0] == GPCMD_START_STOP_UNIT && sense->asc == 0x24)
L
Linus Torvalds 已提交
124
			break;
125 126 127 128
		log = 1;
		break;
	case UNIT_ATTENTION:
		/*
B
Borislav Petkov 已提交
129 130 131
		 * Make good and sure we've seen this potential media change.
		 * Some drives (i.e. Creative) fail to present the correct sense
		 * key in the error register.
132 133 134 135 136 137
		 */
		cdrom_saw_media_change(drive);
		break;
	default:
		log = 1;
		break;
L
Linus Torvalds 已提交
138 139 140 141
	}
	return log;
}

142
static void cdrom_analyze_sense_data(ide_drive_t *drive,
L
Linus Torvalds 已提交
143 144 145
			      struct request *failed_command,
			      struct request_sense *sense)
{
A
Alan Cox 已提交
146 147 148 149
	unsigned long sector;
	unsigned long bio_sectors;
	struct cdrom_info *info = drive->driver_data;

B
Borislav Petkov 已提交
150 151
	ide_debug_log(IDE_DBG_SENSE, "error_code: 0x%x, sense_key: 0x%x",
				     sense->error_code, sense->sense_key);
152 153

	if (failed_command)
B
Borislav Petkov 已提交
154 155
		ide_debug_log(IDE_DBG_SENSE, "failed cmd: 0x%x",
					     failed_command->cmd[0]);
156

L
Linus Torvalds 已提交
157 158 159 160
	if (!cdrom_log_sense(drive, failed_command, sense))
		return;

	/*
B
Borislav Petkov 已提交
161 162 163
	 * If a read toc is executed for a CD-R or CD-RW medium where the first
	 * toc has not been recorded yet, it will fail with 05/24/00 (which is a
	 * confusing error)
L
Linus Torvalds 已提交
164 165 166 167 168
	 */
	if (failed_command && failed_command->cmd[0] == GPCMD_READ_TOC_PMA_ATIP)
		if (sense->sense_key == 0x05 && sense->asc == 0x24)
			return;

B
Borislav Petkov 已提交
169 170
	/* current error */
	if (sense->error_code == 0x70) {
171
		switch (sense->sense_key) {
A
Alan Cox 已提交
172 173 174 175 176 177 178 179 180 181 182 183 184 185
		case MEDIUM_ERROR:
		case VOLUME_OVERFLOW:
		case ILLEGAL_REQUEST:
			if (!sense->valid)
				break;
			if (failed_command == NULL ||
					!blk_fs_request(failed_command))
				break;
			sector = (sense->information[0] << 24) |
				 (sense->information[1] << 16) |
				 (sense->information[2] <<  8) |
				 (sense->information[3]);

			if (drive->queue->hardsect_size == 2048)
B
Borislav Petkov 已提交
186 187
				/* device sector size is 2K */
				sector <<= 2;
188 189

			bio_sectors = max(bio_sectors(failed_command->bio), 4U);
190
			sector &= ~(bio_sectors - 1);
A
Alan Cox 已提交
191

192 193 194 195 196 197 198 199
			/*
			 * The SCSI specification allows for the value
			 * returned by READ CAPACITY to be up to 75 2K
			 * sectors past the last readable block.
			 * Therefore, if we hit a medium error within the
			 * last 75 2K sectors, we decrease the saved size
			 * value.
			 */
A
Alan Cox 已提交
200
			if (sector < get_capacity(info->disk) &&
201
			    drive->probed_capacity - sector < 4 * 75)
A
Alan Cox 已提交
202
				set_capacity(info->disk, sector);
203 204
		}
	}
L
Linus Torvalds 已提交
205

206
	ide_cd_log_error(drive->name, failed_command, sense);
L
Linus Torvalds 已提交
207 208
}

209 210 211
static void ide_cd_complete_failed_rq(ide_drive_t *drive, struct request *rq)
{
	/*
T
Tejun Heo 已提交
212
	 * For REQ_TYPE_SENSE, "rq->special" points to the original
213 214 215
	 * failed request.  Also, the sense data should be read
	 * directly from rq which might be different from the original
	 * sense buffer if it got copied during mapping.
216
	 */
T
Tejun Heo 已提交
217
	struct request *failed = (struct request *)rq->special;
218
	void *sense = bio_data(rq->bio);
219 220 221

	if (failed) {
		if (failed->sense) {
222 223 224 225 226 227
			/*
			 * Sense is always read into drive->sense_data.
			 * Copy back if the failed request has its
			 * sense pointer set.
			 */
			memcpy(failed->sense, sense, 18);
228 229 230 231 232 233 234 235 236 237 238
			sense = failed->sense;
			failed->sense_len = rq->sense_len;
		}
		cdrom_analyze_sense_data(drive, failed, sense);

		if (ide_end_rq(drive, failed, -EIO, blk_rq_bytes(failed)))
			BUG();
	} else
		cdrom_analyze_sense_data(drive, NULL, sense);
}

239

B
Borislav Petkov 已提交
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
 * Allow the drive 5 seconds to recover; some devices will return NOT_READY
 * while flushing data from cache.
 *
 * returns: 0 failed (write timeout expired)
 *	    1 success
 */
static int ide_cd_breathe(ide_drive_t *drive, struct request *rq)
{

	struct cdrom_info *info = drive->driver_data;

	if (!rq->errors)
		info->write_timeout = jiffies +	ATAPI_WAIT_WRITE_BUSY;

	rq->errors = 1;

	if (time_after(jiffies, info->write_timeout))
		return 0;
	else {
		struct request_queue *q = drive->queue;
		unsigned long flags;

		/*
		 * take a breather relying on the unplug timer to kick us again
		 */

		spin_lock_irqsave(q->queue_lock, flags);
		blk_plug_device(q);
		spin_unlock_irqrestore(q->queue_lock, flags);

		return 1;
	}
}

/**
B
Borislav Petkov 已提交
276 277
 * Returns:
 * 0: if the request should be continued.
278 279
 * 1: if the request will be going through error recovery.
 * 2: if the request should be ended.
B
Borislav Petkov 已提交
280
 */
281
static int cdrom_decode_status(ide_drive_t *drive, u8 stat)
L
Linus Torvalds 已提交
282
{
283
	ide_hwif_t *hwif = drive->hwif;
284
	struct request *rq = hwif->rq;
285
	int err, sense_key, do_end_request = 0;
286
	u8 quiet = rq->cmd_flags & REQ_QUIET;
L
Linus Torvalds 已提交
287

B
Borislav Petkov 已提交
288
	/* get the IDE error register */
289
	err = ide_read_error(drive);
L
Linus Torvalds 已提交
290 291
	sense_key = err >> 4;

292 293 294
	ide_debug_log(IDE_DBG_RQ, "cmd: 0x%x, rq->cmd_type: 0x%x, err: 0x%x, "
				  "stat 0x%x",
				  rq->cmd[0], rq->cmd_type, err, stat);
295

296
	if (blk_sense_request(rq)) {
B
Borislav Petkov 已提交
297 298 299 300 301
		/*
		 * We got an error trying to get sense info from the drive
		 * (probably while trying to recover from a former error).
		 * Just give up.
		 */
302
		rq->cmd_flags |= REQ_FAILED;
303
		return 2;
304
	}
L
Linus Torvalds 已提交
305

306 307 308
	/* if we have an error, pass CHECK_CONDITION as the SCSI status byte */
	if (blk_pc_request(rq) && !rq->errors)
		rq->errors = SAM_STAT_CHECK_CONDITION;
L
Linus Torvalds 已提交
309

310 311
	if (blk_noretry_request(rq))
		do_end_request = 1;
L
Linus Torvalds 已提交
312

313 314
	switch (sense_key) {
	case NOT_READY:
315 316 317 318
		if (blk_fs_request(rq) && rq_data_dir(rq) == WRITE) {
			if (ide_cd_breathe(drive, rq))
				return 1;
		} else {
319
			cdrom_saw_media_change(drive);
L
Linus Torvalds 已提交
320

321 322 323
			if (blk_fs_request(rq) && !quiet)
				printk(KERN_ERR PFX "%s: tray open\n",
					drive->name);
L
Linus Torvalds 已提交
324
		}
325 326 327 328
		do_end_request = 1;
		break;
	case UNIT_ATTENTION:
		cdrom_saw_media_change(drive);
L
Linus Torvalds 已提交
329

330 331
		if (blk_fs_request(rq) == 0)
			return 0;
332

B
Borislav Petkov 已提交
333
		/*
334 335
		 * Arrange to retry the request but be sure to give up if we've
		 * retried too many times.
B
Borislav Petkov 已提交
336
		 */
337 338 339 340
		if (++rq->errors > ERROR_MAX)
			do_end_request = 1;
		break;
	case ILLEGAL_REQUEST:
341
		/*
342 343 344 345 346
		 * Don't print error message for this condition -- SFF8090i
		 * indicates that 5/24/00 is the correct response to a request
		 * to close the tray if the drive doesn't have that capability.
		 *
		 * cdrom_log_sense() knows this!
347
		 */
348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386
		if (rq->cmd[0] == GPCMD_START_STOP_UNIT)
			break;
		/* fall-through */
	case DATA_PROTECT:
		/*
		 * No point in retrying after an illegal request or data
		 * protect error.
		 */
		if (!quiet)
			ide_dump_status(drive, "command error", stat);
		do_end_request = 1;
		break;
	case MEDIUM_ERROR:
		/*
		 * No point in re-trying a zillion times on a bad sector.
		 * If we got here the error is not correctable.
		 */
		if (!quiet)
			ide_dump_status(drive, "media error "
					"(bad sector)", stat);
		do_end_request = 1;
		break;
	case BLANK_CHECK:
		/* disk appears blank? */
		if (!quiet)
			ide_dump_status(drive, "media error (blank)",
					stat);
		do_end_request = 1;
		break;
	default:
		if (blk_fs_request(rq) == 0)
			break;
		if (err & ~ATA_ABORTED) {
			/* go to the default handler for other errors */
			ide_error(drive, "cdrom_decode_status", stat);
			return 1;
		} else if (++rq->errors > ERROR_MAX)
			/* we've racked up too many retries, abort */
			do_end_request = 1;
L
Linus Torvalds 已提交
387 388
	}

389 390 391 392 393 394 395 396 397 398 399 400 401 402
	if (blk_fs_request(rq) == 0) {
		rq->cmd_flags |= REQ_FAILED;
		do_end_request = 1;
	}

	/*
	 * End a request through request sense analysis when we have sense data.
	 * We need this in order to perform end of media processing.
	 */
	if (do_end_request)
		goto end_request;

	/* if we got a CHECK_CONDITION status, queue a request sense command */
	if (stat & ATA_ERR)
403
		return ide_queue_sense_rq(drive, NULL) ? 2 : 1;
404 405
	return 1;

406
end_request:
407
	if (stat & ATA_ERR) {
408
		struct request_queue *q = drive->queue;
409 410
		unsigned long flags;

411
		spin_lock_irqsave(q->queue_lock, flags);
412
		blkdev_dequeue_request(rq);
413
		spin_unlock_irqrestore(q->queue_lock, flags);
414

415
		hwif->rq = NULL;
416

417
		return ide_queue_sense_rq(drive, rq) ? 2 : 1;
418
	} else
419
		return 2;
L
Linus Torvalds 已提交
420 421 422 423 424 425 426
}

/*
 * Check the contents of the interrupt reason register from the cdrom
 * and attempt to recover if there are problems.  Returns  0 if everything's
 * ok; nonzero if the request has been terminated.
 */
427 428
static int ide_cd_check_ireason(ide_drive_t *drive, struct request *rq,
				int len, int ireason, int rw)
L
Linus Torvalds 已提交
429
{
430 431
	ide_hwif_t *hwif = drive->hwif;

B
Borislav Petkov 已提交
432
	ide_debug_log(IDE_DBG_FUNC, "ireason: 0x%x, rw: 0x%x", ireason, rw);
433

434 435 436 437 438
	/*
	 * ireason == 0: the drive wants to receive data from us
	 * ireason == 2: the drive is expecting to transfer data to us
	 */
	if (ireason == (!rw << 1))
L
Linus Torvalds 已提交
439
		return 0;
440
	else if (ireason == (rw << 1)) {
441

B
Borislav Petkov 已提交
442
		/* whoops... */
443
		printk(KERN_ERR PFX "%s: %s: wrong transfer direction!\n",
444
				drive->name, __func__);
L
Linus Torvalds 已提交
445

446
		ide_pad_transfer(drive, rw, len);
447
	} else  if (rw == 0 && ireason == 1) {
B
Borislav Petkov 已提交
448 449 450
		/*
		 * Some drives (ASUS) seem to tell us that status info is
		 * available.  Just get it and ignore.
L
Linus Torvalds 已提交
451
		 */
452
		(void)hwif->tp_ops->read_status(hwif);
L
Linus Torvalds 已提交
453 454
		return 0;
	} else {
B
Borislav Petkov 已提交
455
		/* drive wants a command packet, or invalid ireason... */
456
		printk(KERN_ERR PFX "%s: %s: bad interrupt reason 0x%02x\n",
457
				drive->name, __func__, ireason);
L
Linus Torvalds 已提交
458 459
	}

460 461 462
	if (rq->cmd_type == REQ_TYPE_ATA_PC)
		rq->cmd_flags |= REQ_FAILED;

L
Linus Torvalds 已提交
463 464 465
	return -1;
}

466
static void ide_cd_request_sense_fixup(ide_drive_t *drive, struct ide_cmd *cmd)
467
{
468 469
	struct request *rq = cmd->rq;

B
Borislav Petkov 已提交
470
	ide_debug_log(IDE_DBG_FUNC, "rq->cmd[0]: 0x%x", rq->cmd[0]);
471

472 473 474 475 476
	/*
	 * Some of the trailing request sense fields are optional,
	 * and some drives don't send them.  Sigh.
	 */
	if (rq->cmd[0] == GPCMD_REQUEST_SENSE &&
477 478
	    cmd->nleft > 0 && cmd->nleft <= 5)
		cmd->nleft = 0;
479 480
}

481 482 483 484
int ide_cd_queue_pc(ide_drive_t *drive, const unsigned char *cmd,
		    int write, void *buffer, unsigned *bufflen,
		    struct request_sense *sense, int timeout,
		    unsigned int cmd_flags)
L
Linus Torvalds 已提交
485
{
486 487
	struct cdrom_info *info = drive->driver_data;
	struct request_sense local_sense;
L
Linus Torvalds 已提交
488
	int retries = 10;
489
	unsigned int flags = 0;
L
Linus Torvalds 已提交
490

491 492
	if (!sense)
		sense = &local_sense;
L
Linus Torvalds 已提交
493

B
Borislav Petkov 已提交
494 495 496
	ide_debug_log(IDE_DBG_PC, "cmd[0]: 0x%x, write: 0x%x, timeout: %d, "
				  "cmd_flags: 0x%x",
				  cmd[0], write, timeout, cmd_flags);
497

B
Borislav Petkov 已提交
498
	/* start of retry loop */
L
Linus Torvalds 已提交
499
	do {
500
		struct request *rq;
L
Linus Torvalds 已提交
501 502
		int error;

503 504 505 506 507 508 509 510
		rq = blk_get_request(drive->queue, write, __GFP_WAIT);

		memcpy(rq->cmd, cmd, BLK_MAX_CDB);
		rq->cmd_type = REQ_TYPE_ATA_PC;
		rq->sense = sense;
		rq->cmd_flags |= cmd_flags;
		rq->timeout = timeout;
		if (buffer) {
511 512 513 514 515 516
			error = blk_rq_map_kern(drive->queue, rq, buffer,
						*bufflen, GFP_NOIO);
			if (error) {
				blk_put_request(rq);
				return error;
			}
517 518 519 520 521 522 523 524 525
		}

		error = blk_execute_rq(drive->queue, info->disk, rq, 0);

		if (buffer)
			*bufflen = rq->data_len;

		flags = rq->cmd_flags;
		blk_put_request(rq);
L
Linus Torvalds 已提交
526

B
Borislav Petkov 已提交
527 528 529 530
		/*
		 * FIXME: we should probably abort/retry or something in case of
		 * failure.
		 */
531
		if (flags & REQ_FAILED) {
B
Borislav Petkov 已提交
532 533 534 535
			/*
			 * The request failed.  Retry if it was due to a unit
			 * attention status (usually means media was changed).
			 */
536
			struct request_sense *reqbuf = sense;
L
Linus Torvalds 已提交
537 538 539 540 541

			if (reqbuf->sense_key == UNIT_ATTENTION)
				cdrom_saw_media_change(drive);
			else if (reqbuf->sense_key == NOT_READY &&
				 reqbuf->asc == 4 && reqbuf->ascq != 4) {
B
Borislav Petkov 已提交
542 543 544 545 546
				/*
				 * The drive is in the process of loading
				 * a disk.  Retry, but wait a little to give
				 * the drive time to complete the load.
				 */
L
Linus Torvalds 已提交
547 548
				ssleep(2);
			} else {
B
Borislav Petkov 已提交
549
				/* otherwise, don't retry */
L
Linus Torvalds 已提交
550 551 552 553 554
				retries = 0;
			}
			--retries;
		}

B
Borislav Petkov 已提交
555
		/* end of retry loop */
556
	} while ((flags & REQ_FAILED) && retries >= 0);
L
Linus Torvalds 已提交
557

B
Borislav Petkov 已提交
558
	/* return an error if the command failed */
559
	return (flags & REQ_FAILED) ? -EIO : 0;
L
Linus Torvalds 已提交
560 561
}

562 563 564 565 566 567 568 569 570 571 572
static void ide_cd_error_cmd(ide_drive_t *drive, struct ide_cmd *cmd)
{
	unsigned int nr_bytes = cmd->nbytes - cmd->nleft;

	if (cmd->tf_flags & IDE_TFLAG_WRITE)
		nr_bytes -= cmd->last_xfer_len;

	if (nr_bytes > 0)
		ide_complete_rq(drive, 0, nr_bytes);
}

L
Linus Torvalds 已提交
573 574
static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
{
575
	ide_hwif_t *hwif = drive->hwif;
576
	struct ide_cmd *cmd = &hwif->cmd;
577
	struct request *rq = hwif->rq;
578
	ide_expiry_t *expiry = NULL;
579
	int dma_error = 0, dma, thislen, uptodate = 0;
580
	int write = (rq_data_dir(rq) == WRITE) ? 1 : 0, rc = 0, nsectors;
581
	int sense = blk_sense_request(rq);
582
	unsigned int timeout;
583
	u16 len;
584
	u8 ireason, stat;
L
Linus Torvalds 已提交
585

586
	ide_debug_log(IDE_DBG_PC, "cmd: 0x%x, write: 0x%x", rq->cmd[0], write);
587

B
Borislav Petkov 已提交
588
	/* check for errors */
589
	dma = drive->dma;
L
Linus Torvalds 已提交
590
	if (dma) {
591
		drive->dma = 0;
592
		drive->waiting_for_dma = 0;
593
		dma_error = hwif->dma_ops->dma_end(drive);
594
		ide_dma_unmap_sg(drive, cmd);
595
		if (dma_error) {
596
			printk(KERN_ERR PFX "%s: DMA %s error\n", drive->name,
597
					write ? "write" : "read");
598 599
			ide_dma_off(drive);
		}
L
Linus Torvalds 已提交
600 601
	}

602 603 604 605 606 607 608 609 610 611
	/* check status */
	stat = hwif->tp_ops->read_status(hwif);

	if (!OK_STAT(stat, 0, BAD_R_STAT)) {
		rc = cdrom_decode_status(drive, stat);
		if (rc) {
			if (rc == 2)
				goto out_end;
			return ide_stopped;
		}
612
	}
L
Linus Torvalds 已提交
613

B
Borislav Petkov 已提交
614
	/* using dma, transfer is complete now */
L
Linus Torvalds 已提交
615
	if (dma) {
616
		if (dma_error)
L
Linus Torvalds 已提交
617
			return ide_error(drive, "dma error", stat);
618
		uptodate = 1;
619
		goto out_end;
L
Linus Torvalds 已提交
620 621
	}

622
	ide_read_bcount_and_ireason(drive, &len, &ireason);
623

624
	thislen = blk_fs_request(rq) ? len : cmd->nleft;
L
Linus Torvalds 已提交
625 626 627
	if (thislen > len)
		thislen = len;

B
Borislav Petkov 已提交
628 629
	ide_debug_log(IDE_DBG_PC, "DRQ: stat: 0x%x, thislen: %d",
				  stat, thislen);
630

B
Borislav Petkov 已提交
631
	/* If DRQ is clear, the command has completed. */
632
	if ((stat & ATA_DRQ) == 0) {
633 634 635 636 637 638
		if (blk_fs_request(rq)) {
			/*
			 * If we're not done reading/writing, complain.
			 * Otherwise, complete the command normally.
			 */
			uptodate = 1;
639
			if (cmd->nleft > 0) {
640
				printk(KERN_ERR PFX "%s: %s: data underrun "
641 642
					"(%u bytes)\n", drive->name, __func__,
					cmd->nleft);
643 644 645 646 647
				if (!write)
					rq->cmd_flags |= REQ_FAILED;
				uptodate = 0;
			}
		} else if (!blk_pc_request(rq)) {
648
			ide_cd_request_sense_fixup(drive, cmd);
B
Borislav Petkov 已提交
649
			/* complain if we still have data left to transfer */
650
			uptodate = cmd->nleft ? 0 : 1;
651 652
			if (uptodate == 0)
				rq->cmd_flags |= REQ_FAILED;
653
		}
654
		goto out_end;
655
	}
L
Linus Torvalds 已提交
656

B
Borislav Petkov 已提交
657
	/* check which way to transfer data */
658 659 660
	rc = ide_cd_check_ireason(drive, rq, len, ireason, write);
	if (rc)
		goto out_end;
661

662
	cmd->last_xfer_len = 0;
L
Linus Torvalds 已提交
663

B
Borislav Petkov 已提交
664 665 666
	ide_debug_log(IDE_DBG_PC, "data transfer, rq->cmd_type: 0x%x, "
				  "ireason: 0x%x",
				  rq->cmd_type, ireason);
667

B
Borislav Petkov 已提交
668
	/* transfer data */
L
Linus Torvalds 已提交
669
	while (thislen > 0) {
670
		int blen = min_t(int, thislen, cmd->nleft);
L
Linus Torvalds 已提交
671

672
		if (cmd->nleft == 0)
L
Linus Torvalds 已提交
673 674
			break;

675 676
		ide_pio_bytes(drive, cmd, write, blen);
		cmd->last_xfer_len += blen;
L
Linus Torvalds 已提交
677 678 679 680

		thislen -= blen;
		len -= blen;

681
		if (sense && write == 0)
A
Andreas Schwab 已提交
682
			rq->sense_len += blen;
L
Linus Torvalds 已提交
683 684
	}

B
Borislav Petkov 已提交
685
	/* pad, if necessary */
686 687 688 689 690 691 692 693 694
	if (len > 0) {
		if (blk_fs_request(rq) == 0 || write == 0)
			ide_pad_transfer(drive, write, len);
		else {
			printk(KERN_ERR PFX "%s: confused, missing data\n",
				drive->name);
			blk_dump_rq_flags(rq, "cdrom_newpc_intr");
		}
	}
L
Linus Torvalds 已提交
695

696 697 698 699
	if (blk_pc_request(rq)) {
		timeout = rq->timeout;
	} else {
		timeout = ATAPI_WAIT_PC;
700
		if (!blk_fs_request(rq))
701
			expiry = ide_cd_expiry;
702 703
	}

704 705
	hwif->expiry = expiry;
	ide_set_handler(drive, cdrom_newpc_intr, timeout);
L
Linus Torvalds 已提交
706
	return ide_started;
707

708
out_end:
709
	if (blk_pc_request(rq) && rc == 0) {
710 711
		unsigned int dlen = rq->data_len;

712
		rq->data_len = 0;
713

714
		if (blk_end_request(rq, 0, dlen))
715
			BUG();
716

717
		hwif->rq = NULL;
718
	} else {
719 720 721 722
		if (sense && uptodate)
			ide_cd_complete_failed_rq(drive, rq);

		if (blk_fs_request(rq)) {
723
			if (cmd->nleft == 0)
724 725 726 727 728 729
				uptodate = 1;
		} else {
			if (uptodate <= 0 && rq->errors == 0)
				rq->errors = -EIO;
		}

730 731 732
		if (uptodate == 0)
			ide_cd_error_cmd(drive, cmd);

733 734 735 736
		/* make sure it's fully ended */
		if (blk_pc_request(rq))
			nsectors = (rq->data_len + 511) >> 9;
		else
737
			nsectors = rq->hard_nr_sectors;
738 739 740 741

		if (nsectors == 0)
			nsectors = 1;

742 743 744 745 746 747
		if (blk_fs_request(rq) == 0) {
			rq->data_len -= (cmd->nbytes - cmd->nleft);
			if (uptodate == 0 && (cmd->tf_flags & IDE_TFLAG_WRITE))
				rq->data_len += cmd->last_xfer_len;
		}

748 749
		ide_complete_rq(drive, uptodate ? 0 : -EIO, nsectors << 9);

750 751
		if (sense && rc == 2)
			ide_error(drive, "request sense failure", stat);
752 753
	}
	return ide_stopped;
L
Linus Torvalds 已提交
754 755
}

756
static ide_startstop_t cdrom_start_rw(ide_drive_t *drive, struct request *rq)
L
Linus Torvalds 已提交
757
{
758
	struct cdrom_info *cd = drive->driver_data;
759
	struct request_queue *q = drive->queue;
760 761
	int write = rq_data_dir(rq) == WRITE;
	unsigned short sectors_per_frame =
762
		queue_hardsect_size(q) >> SECTOR_BITS;
L
Linus Torvalds 已提交
763

764
	ide_debug_log(IDE_DBG_RQ, "rq->cmd[0]: 0x%x, rq->cmd_flags: 0x%x, "
B
Borislav Petkov 已提交
765
				  "secs_per_frame: %u",
766
				  rq->cmd[0], rq->cmd_flags, sectors_per_frame);
767

768
	if (write) {
B
Borislav Petkov 已提交
769
		/* disk has become write protected */
770
		if (get_disk_ro(cd->disk))
771 772 773 774 775 776
			return ide_stopped;
	} else {
		/*
		 * We may be retrying this request after an error.  Fix up any
		 * weirdness which might be present in the request packet.
		 */
777
		q->prep_rq_fn(q, rq);
L
Linus Torvalds 已提交
778 779
	}

780
	/* fs requests *must* be hardware frame aligned */
781
	if ((rq->nr_sectors & (sectors_per_frame - 1)) ||
782 783 784 785 786
	    (rq->sector & (sectors_per_frame - 1)))
		return ide_stopped;

	/* use DMA, if possible */
	drive->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
L
Linus Torvalds 已提交
787

788 789
	if (write)
		cd->devinfo.media_written = 1;
L
Linus Torvalds 已提交
790

791 792
	rq->timeout = ATAPI_WAIT_PC;

793
	return ide_started;
L
Linus Torvalds 已提交
794 795
}

796
static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
L
Linus Torvalds 已提交
797 798
{

B
Borislav Petkov 已提交
799 800
	ide_debug_log(IDE_DBG_PC, "rq->cmd[0]: 0x%x, rq->cmd_type: 0x%x",
				  rq->cmd[0], rq->cmd_type);
801

802 803 804 805
	if (blk_pc_request(rq))
		rq->cmd_flags |= REQ_QUIET;
	else
		rq->cmd_flags &= ~REQ_FAILED;
L
Linus Torvalds 已提交
806

807
	drive->dma = 0;
L
Linus Torvalds 已提交
808

B
Borislav Petkov 已提交
809
	/* sg request */
810
	if (rq->bio) {
811
		struct request_queue *q = drive->queue;
812
		char *buf = bio_data(rq->bio);
813 814
		unsigned int alignment;

815
		drive->dma = !!(drive->dev_flags & IDE_DFLAG_USING_DMA);
L
Linus Torvalds 已提交
816 817 818

		/*
		 * check if dma is safe
819 820 821
		 *
		 * NOTE! The "len" and "addr" checks should possibly have
		 * separate masks.
L
Linus Torvalds 已提交
822
		 */
823
		alignment = queue_dma_alignment(q) | q->dma_pad_mask;
824 825
		if ((unsigned long)buf & alignment
		    || rq->data_len & q->dma_pad_mask
826
		    || object_is_on_stack(buf))
827
			drive->dma = 0;
L
Linus Torvalds 已提交
828 829 830
	}
}

831
static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq,
832
					sector_t block)
L
Linus Torvalds 已提交
833
{
834
	struct ide_cmd cmd;
835
	int uptodate = 0, nsectors;
836

B
Borislav Petkov 已提交
837 838 839 840 841
	ide_debug_log(IDE_DBG_RQ, "cmd: 0x%x, block: %llu",
				  rq->cmd[0], (unsigned long long)block);

	if (drive->debug_mask & IDE_DBG_RQ)
		blk_dump_rq_flags(rq, "ide_cd_do_request");
842

L
Linus Torvalds 已提交
843
	if (blk_fs_request(rq)) {
844
		if (cdrom_start_rw(drive, rq) == ide_stopped)
845
			goto out_end;
846
	} else if (blk_sense_request(rq) || blk_pc_request(rq) ||
847
		   rq->cmd_type == REQ_TYPE_ATA_PC) {
848 849 850
		if (!rq->timeout)
			rq->timeout = ATAPI_WAIT_PC;

851
		cdrom_do_block_pc(drive, rq);
852
	} else if (blk_special_request(rq)) {
B
Borislav Petkov 已提交
853
		/* right now this can only be a reset... */
854 855
		uptodate = 1;
		goto out_end;
856
	} else {
857
		blk_dump_rq_flags(rq, DRV_NAME " bad flags");
858 859
		if (rq->errors == 0)
			rq->errors = -EIO;
860
		goto out_end;
L
Linus Torvalds 已提交
861
	}
862

863 864 865
	/* prepare sense request for this command */
	ide_prep_sense(drive, rq);

866 867 868 869 870 871 872
	memset(&cmd, 0, sizeof(cmd));

	if (rq_data_dir(rq))
		cmd.tf_flags |= IDE_TFLAG_WRITE;

	cmd.rq = rq;

873 874 875
	if (blk_fs_request(rq) || rq->data_len) {
		ide_init_sg_cmd(&cmd, blk_fs_request(rq) ? (rq->nr_sectors << 9)
							 : rq->data_len);
876 877 878
		ide_map_sg(drive, &cmd);
	}

879
	return ide_issue_pc(drive, &cmd);
880
out_end:
881
	nsectors = rq->hard_nr_sectors;
882 883 884 885 886 887

	if (nsectors == 0)
		nsectors = 1;

	ide_complete_rq(drive, uptodate ? 0 : -EIO, nsectors << 9);

888
	return ide_stopped;
L
Linus Torvalds 已提交
889 890
}

B
Borislav Petkov 已提交
891
/*
L
Linus Torvalds 已提交
892 893
 * Ioctl handling.
 *
B
Borislav Petkov 已提交
894 895 896 897 898
 * Routines which queue packet commands take as a final argument a pointer to a
 * request_sense struct. If execution of the command results in an error with a
 * CHECK CONDITION status, this structure will be filled with the results of the
 * subsequent request sense command. The pointer can also be NULL, in which case
 * no sense information is returned.
L
Linus Torvalds 已提交
899
 */
900
static void msf_from_bcd(struct atapi_msf *msf)
L
Linus Torvalds 已提交
901
{
A
Adrian Bunk 已提交
902 903 904
	msf->minute = bcd2bin(msf->minute);
	msf->second = bcd2bin(msf->second);
	msf->frame  = bcd2bin(msf->frame);
L
Linus Torvalds 已提交
905 906
}

907
int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense)
L
Linus Torvalds 已提交
908 909 910
{
	struct cdrom_info *info = drive->driver_data;
	struct cdrom_device_info *cdi = &info->devinfo;
911
	unsigned char cmd[BLK_MAX_CDB];
L
Linus Torvalds 已提交
912

B
Borislav Petkov 已提交
913
	ide_debug_log(IDE_DBG_FUNC, "enter");
914

915 916
	memset(cmd, 0, BLK_MAX_CDB);
	cmd[0] = GPCMD_TEST_UNIT_READY;
L
Linus Torvalds 已提交
917

918
	/*
B
Borislav Petkov 已提交
919 920
	 * Sanyo 3 CD changer uses byte 7 of TEST_UNIT_READY to switch CDs
	 * instead of supporting the LOAD_UNLOAD opcode.
921
	 */
922
	cmd[7] = cdi->sanyo_slot % 3;
L
Linus Torvalds 已提交
923

924
	return ide_cd_queue_pc(drive, cmd, 0, NULL, NULL, sense, 0, REQ_QUIET);
L
Linus Torvalds 已提交
925 926 927 928 929 930 931
}

static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
			       unsigned long *sectors_per_frame,
			       struct request_sense *sense)
{
	struct {
932 933
		__be32 lba;
		__be32 blocklen;
L
Linus Torvalds 已提交
934 935 936
	} capbuf;

	int stat;
937 938
	unsigned char cmd[BLK_MAX_CDB];
	unsigned len = sizeof(capbuf);
939
	u32 blocklen;
L
Linus Torvalds 已提交
940

B
Borislav Petkov 已提交
941
	ide_debug_log(IDE_DBG_FUNC, "enter");
942

943 944
	memset(cmd, 0, BLK_MAX_CDB);
	cmd[0] = GPCMD_READ_CDVD_CAPACITY;
L
Linus Torvalds 已提交
945

946 947
	stat = ide_cd_queue_pc(drive, cmd, 0, &capbuf, &len, sense, 0,
			       REQ_QUIET);
948 949 950 951 952 953
	if (stat)
		return stat;

	/*
	 * Sanity check the given block size
	 */
954 955 956 957 958 959
	blocklen = be32_to_cpu(capbuf.blocklen);
	switch (blocklen) {
	case 512:
	case 1024:
	case 2048:
	case 4096:
960 961
		break;
	default:
962 963 964 965
		printk(KERN_ERR PFX "%s: weird block size %u\n",
				drive->name, blocklen);
		printk(KERN_ERR PFX "%s: default to 2kb block size\n",
				drive->name);
966
		blocklen = 2048;
967
		break;
L
Linus Torvalds 已提交
968 969
	}

970
	*capacity = 1 + be32_to_cpu(capbuf.lba);
971
	*sectors_per_frame = blocklen >> SECTOR_BITS;
B
Borislav Petkov 已提交
972

B
Borislav Petkov 已提交
973 974
	ide_debug_log(IDE_DBG_PROBE, "cap: %lu, sectors_per_frame: %lu",
				     *capacity, *sectors_per_frame);
B
Borislav Petkov 已提交
975

976
	return 0;
L
Linus Torvalds 已提交
977 978 979 980 981 982
}

static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag,
				int format, char *buf, int buflen,
				struct request_sense *sense)
{
983
	unsigned char cmd[BLK_MAX_CDB];
L
Linus Torvalds 已提交
984

B
Borislav Petkov 已提交
985
	ide_debug_log(IDE_DBG_FUNC, "enter");
986

987
	memset(cmd, 0, BLK_MAX_CDB);
L
Linus Torvalds 已提交
988

989 990 991 992 993
	cmd[0] = GPCMD_READ_TOC_PMA_ATIP;
	cmd[6] = trackno;
	cmd[7] = (buflen >> 8);
	cmd[8] = (buflen & 0xff);
	cmd[9] = (format << 6);
L
Linus Torvalds 已提交
994 995

	if (msf_flag)
996
		cmd[1] = 2;
L
Linus Torvalds 已提交
997

998
	return ide_cd_queue_pc(drive, cmd, 0, buf, &buflen, sense, 0, REQ_QUIET);
L
Linus Torvalds 已提交
999 1000 1001
}

/* Try to read the entire TOC for the disk into our internal buffer. */
1002
int ide_cd_read_toc(ide_drive_t *drive, struct request_sense *sense)
L
Linus Torvalds 已提交
1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014
{
	int stat, ntracks, i;
	struct cdrom_info *info = drive->driver_data;
	struct cdrom_device_info *cdi = &info->devinfo;
	struct atapi_toc *toc = info->toc;
	struct {
		struct atapi_toc_header hdr;
		struct atapi_toc_entry  ent;
	} ms_tmp;
	long last_written;
	unsigned long sectors_per_frame = SECTORS_PER_FRAME;

B
Borislav Petkov 已提交
1015
	ide_debug_log(IDE_DBG_FUNC, "enter");
1016

L
Linus Torvalds 已提交
1017
	if (toc == NULL) {
B
Borislav Petkov 已提交
1018
		/* try to allocate space */
J
Jesper Juhl 已提交
1019
		toc = kmalloc(sizeof(struct atapi_toc), GFP_KERNEL);
L
Linus Torvalds 已提交
1020
		if (toc == NULL) {
1021
			printk(KERN_ERR PFX "%s: No cdrom TOC buffer!\n",
1022
					drive->name);
L
Linus Torvalds 已提交
1023 1024
			return -ENOMEM;
		}
J
Jesper Juhl 已提交
1025
		info->toc = toc;
L
Linus Torvalds 已提交
1026 1027
	}

B
Borislav Petkov 已提交
1028 1029 1030 1031
	/*
	 * Check to see if the existing data is still valid. If it is,
	 * just return.
	 */
L
Linus Torvalds 已提交
1032 1033
	(void) cdrom_check_status(drive, sense);

1034
	if (drive->atapi_flags & IDE_AFLAG_TOC_VALID)
L
Linus Torvalds 已提交
1035 1036
		return 0;

B
Borislav Petkov 已提交
1037
	/* try to get the total cdrom capacity and sector size */
L
Linus Torvalds 已提交
1038 1039 1040 1041 1042 1043
	stat = cdrom_read_capacity(drive, &toc->capacity, &sectors_per_frame,
				   sense);
	if (stat)
		toc->capacity = 0x1fffff;

	set_capacity(info->disk, toc->capacity * sectors_per_frame);
B
Borislav Petkov 已提交
1044
	/* save a private copy of the TOC capacity for error handling */
A
Alan Cox 已提交
1045 1046
	drive->probed_capacity = toc->capacity * sectors_per_frame;

L
Linus Torvalds 已提交
1047 1048 1049
	blk_queue_hardsect_size(drive->queue,
				sectors_per_frame << SECTOR_BITS);

B
Borislav Petkov 已提交
1050
	/* first read just the header, so we know how long the TOC is */
L
Linus Torvalds 已提交
1051 1052
	stat = cdrom_read_tocentry(drive, 0, 1, 0, (char *) &toc->hdr,
				    sizeof(struct atapi_toc_header), sense);
J
Jesper Juhl 已提交
1053 1054
	if (stat)
		return stat;
L
Linus Torvalds 已提交
1055

1056
	if (drive->atapi_flags & IDE_AFLAG_TOCTRACKS_AS_BCD) {
A
Adrian Bunk 已提交
1057 1058
		toc->hdr.first_track = bcd2bin(toc->hdr.first_track);
		toc->hdr.last_track  = bcd2bin(toc->hdr.last_track);
L
Linus Torvalds 已提交
1059 1060 1061 1062 1063 1064 1065 1066
	}

	ntracks = toc->hdr.last_track - toc->hdr.first_track + 1;
	if (ntracks <= 0)
		return -EIO;
	if (ntracks > MAX_TRACKS)
		ntracks = MAX_TRACKS;

B
Borislav Petkov 已提交
1067
	/* now read the whole schmeer */
L
Linus Torvalds 已提交
1068 1069 1070 1071 1072 1073 1074
	stat = cdrom_read_tocentry(drive, toc->hdr.first_track, 1, 0,
				  (char *)&toc->hdr,
				   sizeof(struct atapi_toc_header) +
				   (ntracks + 1) *
				   sizeof(struct atapi_toc_entry), sense);

	if (stat && toc->hdr.first_track > 1) {
B
Borislav Petkov 已提交
1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086
		/*
		 * Cds with CDI tracks only don't have any TOC entries, despite
		 * of this the returned values are
		 * first_track == last_track = number of CDI tracks + 1,
		 * so that this case is indistinguishable from the same layout
		 * plus an additional audio track. If we get an error for the
		 * regular case, we assume a CDI without additional audio
		 * tracks. In this case the readable TOC is empty (CDI tracks
		 * are not included) and only holds the Leadout entry.
		 *
		 * Heiko Eißfeldt.
		 */
L
Linus Torvalds 已提交
1087 1088 1089 1090 1091 1092 1093
		ntracks = 0;
		stat = cdrom_read_tocentry(drive, CDROM_LEADOUT, 1, 0,
					   (char *)&toc->hdr,
					   sizeof(struct atapi_toc_header) +
					   (ntracks + 1) *
					   sizeof(struct atapi_toc_entry),
					   sense);
1094
		if (stat)
L
Linus Torvalds 已提交
1095
			return stat;
1096

1097
		if (drive->atapi_flags & IDE_AFLAG_TOCTRACKS_AS_BCD) {
A
Adrian Bunk 已提交
1098 1099
			toc->hdr.first_track = (u8)bin2bcd(CDROM_LEADOUT);
			toc->hdr.last_track = (u8)bin2bcd(CDROM_LEADOUT);
1100
		} else {
L
Linus Torvalds 已提交
1101 1102 1103 1104 1105 1106 1107 1108
			toc->hdr.first_track = CDROM_LEADOUT;
			toc->hdr.last_track = CDROM_LEADOUT;
		}
	}

	if (stat)
		return stat;

1109
	toc->hdr.toc_length = be16_to_cpu(toc->hdr.toc_length);
L
Linus Torvalds 已提交
1110

1111
	if (drive->atapi_flags & IDE_AFLAG_TOCTRACKS_AS_BCD) {
A
Adrian Bunk 已提交
1112 1113
		toc->hdr.first_track = bcd2bin(toc->hdr.first_track);
		toc->hdr.last_track  = bcd2bin(toc->hdr.last_track);
L
Linus Torvalds 已提交
1114 1115
	}

1116
	for (i = 0; i <= ntracks; i++) {
1117 1118
		if (drive->atapi_flags & IDE_AFLAG_TOCADDR_AS_BCD) {
			if (drive->atapi_flags & IDE_AFLAG_TOCTRACKS_AS_BCD)
A
Adrian Bunk 已提交
1119
				toc->ent[i].track = bcd2bin(toc->ent[i].track);
L
Linus Torvalds 已提交
1120 1121
			msf_from_bcd(&toc->ent[i].addr.msf);
		}
1122 1123 1124
		toc->ent[i].addr.lba = msf_to_lba(toc->ent[i].addr.msf.minute,
						  toc->ent[i].addr.msf.second,
						  toc->ent[i].addr.msf.frame);
L
Linus Torvalds 已提交
1125 1126 1127
	}

	if (toc->hdr.first_track != CDROM_LEADOUT) {
B
Borislav Petkov 已提交
1128
		/* read the multisession information */
L
Linus Torvalds 已提交
1129 1130
		stat = cdrom_read_tocentry(drive, 0, 0, 1, (char *)&ms_tmp,
					   sizeof(ms_tmp), sense);
J
Jesper Juhl 已提交
1131 1132
		if (stat)
			return stat;
L
Linus Torvalds 已提交
1133 1134 1135

		toc->last_session_lba = be32_to_cpu(ms_tmp.ent.addr.lba);
	} else {
1136 1137
		ms_tmp.hdr.last_track = CDROM_LEADOUT;
		ms_tmp.hdr.first_track = ms_tmp.hdr.last_track;
L
Linus Torvalds 已提交
1138 1139 1140
		toc->last_session_lba = msf_to_lba(0, 2, 0); /* 0m 2s 0f */
	}

1141
	if (drive->atapi_flags & IDE_AFLAG_TOCADDR_AS_BCD) {
B
Borislav Petkov 已提交
1142
		/* re-read multisession information using MSF format */
L
Linus Torvalds 已提交
1143 1144 1145 1146 1147
		stat = cdrom_read_tocentry(drive, 0, 1, 1, (char *)&ms_tmp,
					   sizeof(ms_tmp), sense);
		if (stat)
			return stat;

1148
		msf_from_bcd(&ms_tmp.ent.addr.msf);
L
Linus Torvalds 已提交
1149
		toc->last_session_lba = msf_to_lba(ms_tmp.ent.addr.msf.minute,
1150
						   ms_tmp.ent.addr.msf.second,
L
Linus Torvalds 已提交
1151 1152 1153 1154 1155
						   ms_tmp.ent.addr.msf.frame);
	}

	toc->xa_flag = (ms_tmp.hdr.first_track != ms_tmp.hdr.last_track);

B
Borislav Petkov 已提交
1156
	/* now try to get the total cdrom capacity */
L
Linus Torvalds 已提交
1157 1158 1159 1160
	stat = cdrom_get_last_written(cdi, &last_written);
	if (!stat && (last_written > toc->capacity)) {
		toc->capacity = last_written;
		set_capacity(info->disk, toc->capacity * sectors_per_frame);
A
Alan Cox 已提交
1161
		drive->probed_capacity = toc->capacity * sectors_per_frame;
L
Linus Torvalds 已提交
1162 1163 1164
	}

	/* Remember that we've read this stuff. */
1165
	drive->atapi_flags |= IDE_AFLAG_TOC_VALID;
L
Linus Torvalds 已提交
1166 1167 1168 1169

	return 0;
}

1170
int ide_cdrom_get_capabilities(ide_drive_t *drive, u8 *buf)
E
Eric Piel 已提交
1171 1172 1173 1174
{
	struct cdrom_info *info = drive->driver_data;
	struct cdrom_device_info *cdi = &info->devinfo;
	struct packet_command cgc;
1175
	int stat, attempts = 3, size = ATAPI_CAPABILITIES_PAGE_SIZE;
E
Eric Piel 已提交
1176

B
Borislav Petkov 已提交
1177
	ide_debug_log(IDE_DBG_FUNC, "enter");
1178

1179
	if ((drive->atapi_flags & IDE_AFLAG_FULL_CAPS_PAGE) == 0)
1180
		size -= ATAPI_CAPABILITIES_PAGE_PAD_SIZE;
E
Eric Piel 已提交
1181

1182
	init_cdrom_command(&cgc, buf, size, CGC_DATA_UNKNOWN);
B
Borislav Petkov 已提交
1183 1184
	do {
		/* we seem to get stat=0x01,err=0x00 the first time (??) */
E
Eric Piel 已提交
1185 1186 1187 1188 1189 1190 1191
		stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CAPABILITIES_PAGE, 0);
		if (!stat)
			break;
	} while (--attempts);
	return stat;
}

1192
void ide_cdrom_update_speed(ide_drive_t *drive, u8 *buf)
E
Eric Piel 已提交
1193
{
1194
	struct cdrom_info *cd = drive->driver_data;
1195 1196
	u16 curspeed, maxspeed;

B
Borislav Petkov 已提交
1197
	ide_debug_log(IDE_DBG_FUNC, "enter");
1198

1199
	if (drive->atapi_flags & IDE_AFLAG_LE_SPEED_FIELDS) {
1200 1201
		curspeed = le16_to_cpup((__le16 *)&buf[8 + 14]);
		maxspeed = le16_to_cpup((__le16 *)&buf[8 + 8]);
E
Eric Piel 已提交
1202
	} else {
1203 1204
		curspeed = be16_to_cpup((__be16 *)&buf[8 + 14]);
		maxspeed = be16_to_cpup((__be16 *)&buf[8 + 8]);
E
Eric Piel 已提交
1205
	}
1206

B
Borislav Petkov 已提交
1207 1208
	ide_debug_log(IDE_DBG_PROBE, "curspeed: %u, maxspeed: %u",
				     curspeed, maxspeed);
B
Borislav Petkov 已提交
1209

1210 1211
	cd->current_speed = (curspeed + (176/2)) / 176;
	cd->max_speed = (maxspeed + (176/2)) / 176;
E
Eric Piel 已提交
1212 1213
}

1214 1215 1216 1217 1218 1219
#define IDE_CD_CAPABILITIES \
	(CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK | CDC_SELECT_SPEED | \
	 CDC_SELECT_DISC | CDC_MULTI_SESSION | CDC_MCN | CDC_MEDIA_CHANGED | \
	 CDC_PLAY_AUDIO | CDC_RESET | CDC_DRIVE_STATUS | CDC_CD_R | \
	 CDC_CD_RW | CDC_DVD | CDC_DVD_R | CDC_DVD_RAM | CDC_GENERIC_PACKET | \
	 CDC_MO_DRIVE | CDC_MRW | CDC_MRW_W | CDC_RAM)
L
Linus Torvalds 已提交
1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232

static struct cdrom_device_ops ide_cdrom_dops = {
	.open			= ide_cdrom_open_real,
	.release		= ide_cdrom_release_real,
	.drive_status		= ide_cdrom_drive_status,
	.media_changed		= ide_cdrom_check_media_change_real,
	.tray_move		= ide_cdrom_tray_move,
	.lock_door		= ide_cdrom_lock_door,
	.select_speed		= ide_cdrom_select_speed,
	.get_last_session	= ide_cdrom_get_last_session,
	.get_mcn		= ide_cdrom_get_mcn,
	.reset			= ide_cdrom_reset,
	.audio_ioctl		= ide_cdrom_audio_ioctl,
1233
	.capability		= IDE_CD_CAPABILITIES,
L
Linus Torvalds 已提交
1234 1235 1236
	.generic_packet		= ide_cdrom_packet,
};

1237
static int ide_cdrom_register(ide_drive_t *drive, int nslots)
L
Linus Torvalds 已提交
1238 1239 1240 1241
{
	struct cdrom_info *info = drive->driver_data;
	struct cdrom_device_info *devinfo = &info->devinfo;

B
Borislav Petkov 已提交
1242
	ide_debug_log(IDE_DBG_PROBE, "nslots: %d", nslots);
1243

L
Linus Torvalds 已提交
1244
	devinfo->ops = &ide_cdrom_dops;
1245
	devinfo->speed = info->current_speed;
L
Linus Torvalds 已提交
1246
	devinfo->capacity = nslots;
J
Jesper Juhl 已提交
1247
	devinfo->handle = drive;
L
Linus Torvalds 已提交
1248 1249
	strcpy(devinfo->name, drive->name);

1250
	if (drive->atapi_flags & IDE_AFLAG_NO_SPEED_SELECT)
1251 1252
		devinfo->mask |= CDC_SELECT_SPEED;

L
Linus Torvalds 已提交
1253 1254 1255 1256
	devinfo->disk = info->disk;
	return register_cdrom(devinfo);
}

1257
static int ide_cdrom_probe_capabilities(ide_drive_t *drive)
L
Linus Torvalds 已提交
1258
{
1259 1260
	struct cdrom_info *cd = drive->driver_data;
	struct cdrom_device_info *cdi = &cd->devinfo;
1261 1262
	u8 buf[ATAPI_CAPABILITIES_PAGE_SIZE];
	mechtype_t mechtype;
L
Linus Torvalds 已提交
1263 1264
	int nslots = 1;

B
Borislav Petkov 已提交
1265 1266
	ide_debug_log(IDE_DBG_PROBE, "media: 0x%x, atapi_flags: 0x%lx",
				     drive->media, drive->atapi_flags);
1267

1268 1269 1270 1271
	cdi->mask = (CDC_CD_R | CDC_CD_RW | CDC_DVD | CDC_DVD_R |
		     CDC_DVD_RAM | CDC_SELECT_DISC | CDC_PLAY_AUDIO |
		     CDC_MO_DRIVE | CDC_RAM);

L
Linus Torvalds 已提交
1272
	if (drive->media == ide_optical) {
1273
		cdi->mask &= ~(CDC_MO_DRIVE | CDC_RAM);
1274
		printk(KERN_ERR PFX "%s: ATAPI magneto-optical drive\n",
1275
				drive->name);
L
Linus Torvalds 已提交
1276 1277 1278
		return nslots;
	}

1279 1280
	if (drive->atapi_flags & IDE_AFLAG_PRE_ATAPI12) {
		drive->atapi_flags &= ~IDE_AFLAG_NO_EJECT;
1281
		cdi->mask &= ~CDC_PLAY_AUDIO;
L
Linus Torvalds 已提交
1282 1283 1284 1285
		return nslots;
	}

	/*
B
Borislav Petkov 已提交
1286 1287 1288 1289
	 * We have to cheat a little here. the packet will eventually be queued
	 * with ide_cdrom_packet(), which extracts the drive from cdi->handle.
	 * Since this device hasn't been registered with the Uniform layer yet,
	 * it can't do this. Same goes for cdi->ops.
L
Linus Torvalds 已提交
1290
	 */
J
Jesper Juhl 已提交
1291
	cdi->handle = drive;
L
Linus Torvalds 已提交
1292 1293
	cdi->ops = &ide_cdrom_dops;

1294
	if (ide_cdrom_get_capabilities(drive, buf))
L
Linus Torvalds 已提交
1295 1296
		return 0;

1297
	if ((buf[8 + 6] & 0x01) == 0)
1298
		drive->dev_flags &= ~IDE_DFLAG_DOORLOCKING;
1299
	if (buf[8 + 6] & 0x08)
1300
		drive->atapi_flags &= ~IDE_AFLAG_NO_EJECT;
1301
	if (buf[8 + 3] & 0x01)
1302
		cdi->mask &= ~CDC_CD_R;
1303
	if (buf[8 + 3] & 0x02)
1304
		cdi->mask &= ~(CDC_CD_RW | CDC_RAM);
1305
	if (buf[8 + 2] & 0x38)
1306
		cdi->mask &= ~CDC_DVD;
1307
	if (buf[8 + 3] & 0x20)
1308
		cdi->mask &= ~(CDC_DVD_RAM | CDC_RAM);
1309
	if (buf[8 + 3] & 0x10)
1310
		cdi->mask &= ~CDC_DVD_R;
1311
	if ((buf[8 + 4] & 0x01) || (drive->atapi_flags & IDE_AFLAG_PLAY_AUDIO_OK))
1312
		cdi->mask &= ~CDC_PLAY_AUDIO;
1313 1314

	mechtype = buf[8 + 6] >> 5;
B
Borislav Petkov 已提交
1315 1316 1317
	if (mechtype == mechtype_caddy ||
	    mechtype == mechtype_popup ||
	    (drive->atapi_flags & IDE_AFLAG_NO_AUTOCLOSE))
1318
		cdi->mask |= CDC_CLOSE_TRAY;
L
Linus Torvalds 已提交
1319 1320

	if (cdi->sanyo_slot > 0) {
1321
		cdi->mask &= ~CDC_SELECT_DISC;
L
Linus Torvalds 已提交
1322
		nslots = 3;
1323 1324
	} else if (mechtype == mechtype_individual_changer ||
		   mechtype == mechtype_cartridge_changer) {
1325 1326
		nslots = cdrom_number_of_slots(cdi);
		if (nslots > 1)
1327
			cdi->mask &= ~CDC_SELECT_DISC;
L
Linus Torvalds 已提交
1328 1329
	}

1330
	ide_cdrom_update_speed(drive, buf);
1331

1332
	printk(KERN_INFO PFX "%s: ATAPI", drive->name);
1333 1334

	/* don't print speed if the drive reported 0 */
1335 1336
	if (cd->max_speed)
		printk(KERN_CONT " %dX", cd->max_speed);
1337

1338
	printk(KERN_CONT " %s", (cdi->mask & CDC_DVD) ? "CD-ROM" : "DVD-ROM");
L
Linus Torvalds 已提交
1339

1340 1341 1342
	if ((cdi->mask & CDC_DVD_R) == 0 || (cdi->mask & CDC_DVD_RAM) == 0)
		printk(KERN_CONT " DVD%s%s",
				 (cdi->mask & CDC_DVD_R) ? "" : "-R",
1343
				 (cdi->mask & CDC_DVD_RAM) ? "" : "/RAM");
L
Linus Torvalds 已提交
1344

1345 1346 1347 1348
	if ((cdi->mask & CDC_CD_R) == 0 || (cdi->mask & CDC_CD_RW) == 0)
		printk(KERN_CONT " CD%s%s",
				 (cdi->mask & CDC_CD_R) ? "" : "-R",
				 (cdi->mask & CDC_CD_RW) ? "" : "/RW");
L
Linus Torvalds 已提交
1349

1350 1351 1352 1353
	if ((cdi->mask & CDC_SELECT_DISC) == 0)
		printk(KERN_CONT " changer w/%d slots", nslots);
	else
		printk(KERN_CONT " drive");
L
Linus Torvalds 已提交
1354

1355 1356
	printk(KERN_CONT ", %dkB Cache\n",
			 be16_to_cpup((__be16 *)&buf[8 + 12]));
L
Linus Torvalds 已提交
1357 1358 1359 1360

	return nslots;
}

B
Borislav Petkov 已提交
1361
/* standard prep_rq_fn that builds 10 byte cmds */
1362
static int ide_cdrom_prep_fs(struct request_queue *q, struct request *rq)
L
Linus Torvalds 已提交
1363 1364 1365 1366 1367
{
	int hard_sect = queue_hardsect_size(q);
	long block = (long)rq->hard_sector / (hard_sect >> 9);
	unsigned long blocks = rq->hard_nr_sectors / (hard_sect >> 9);

1368
	memset(rq->cmd, 0, BLK_MAX_CDB);
L
Linus Torvalds 已提交
1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399

	if (rq_data_dir(rq) == READ)
		rq->cmd[0] = GPCMD_READ_10;
	else
		rq->cmd[0] = GPCMD_WRITE_10;

	/*
	 * fill in lba
	 */
	rq->cmd[2] = (block >> 24) & 0xff;
	rq->cmd[3] = (block >> 16) & 0xff;
	rq->cmd[4] = (block >>  8) & 0xff;
	rq->cmd[5] = block & 0xff;

	/*
	 * and transfer length
	 */
	rq->cmd[7] = (blocks >> 8) & 0xff;
	rq->cmd[8] = blocks & 0xff;
	rq->cmd_len = 10;
	return BLKPREP_OK;
}

/*
 * Most of the SCSI commands are supported directly by ATAPI devices.
 * This transform handles the few exceptions.
 */
static int ide_cdrom_prep_pc(struct request *rq)
{
	u8 *c = rq->cmd;

B
Borislav Petkov 已提交
1400
	/* transform 6-byte read/write commands to the 10-byte version */
L
Linus Torvalds 已提交
1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421
	if (c[0] == READ_6 || c[0] == WRITE_6) {
		c[8] = c[4];
		c[5] = c[3];
		c[4] = c[2];
		c[3] = c[1] & 0x1f;
		c[2] = 0;
		c[1] &= 0xe0;
		c[0] += (READ_10 - READ_6);
		rq->cmd_len = 10;
		return BLKPREP_OK;
	}

	/*
	 * it's silly to pretend we understand 6-byte sense commands, just
	 * reject with ILLEGAL_REQUEST and the caller should take the
	 * appropriate action
	 */
	if (c[0] == MODE_SENSE || c[0] == MODE_SELECT) {
		rq->errors = ILLEGAL_REQUEST;
		return BLKPREP_KILL;
	}
1422

L
Linus Torvalds 已提交
1423 1424 1425
	return BLKPREP_OK;
}

1426
static int ide_cdrom_prep_fn(struct request_queue *q, struct request *rq)
L
Linus Torvalds 已提交
1427
{
1428
	if (blk_fs_request(rq))
L
Linus Torvalds 已提交
1429
		return ide_cdrom_prep_fs(q, rq);
1430
	else if (blk_pc_request(rq))
L
Linus Torvalds 已提交
1431 1432 1433 1434 1435
		return ide_cdrom_prep_pc(rq);

	return 0;
}

1436 1437 1438 1439 1440 1441
struct cd_list_entry {
	const char	*id_model;
	const char	*id_firmware;
	unsigned int	cd_flags;
};

1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452
#ifdef CONFIG_IDE_PROC_FS
static sector_t ide_cdrom_capacity(ide_drive_t *drive)
{
	unsigned long capacity, sectors_per_frame;

	if (cdrom_read_capacity(drive, &capacity, &sectors_per_frame, NULL))
		return 0;

	return capacity * sectors_per_frame;
}

1453 1454
static int proc_idecd_read_capacity(char *page, char **start, off_t off,
					int count, int *eof, void *data)
1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467
{
	ide_drive_t *drive = data;
	int len;

	len = sprintf(page, "%llu\n", (long long)ide_cdrom_capacity(drive));
	PROC_IDE_READ_RETURN(page, start, off, count, eof, len);
}

static ide_proc_entry_t idecd_proc[] = {
	{ "capacity", S_IFREG|S_IRUGO, proc_idecd_read_capacity, NULL },
	{ NULL, 0, NULL, NULL }
};

1468 1469 1470 1471 1472 1473 1474
static ide_proc_entry_t *ide_cd_proc_entries(ide_drive_t *drive)
{
	return idecd_proc;
}

static const struct ide_proc_devset *ide_cd_proc_devsets(ide_drive_t *drive)
{
1475
	return NULL;
1476
}
1477 1478
#endif

1479 1480
static const struct cd_list_entry ide_cd_quirks_list[] = {
	/* SCR-3231 doesn't support the SET_CD_SPEED command. */
1481
	{ "SAMSUNG CD-ROM SCR-3231", NULL,   IDE_AFLAG_NO_SPEED_SELECT	     },
1482
	/* Old NEC260 (not R) was released before ATAPI 1.2 spec. */
1483 1484
	{ "NEC CD-ROM DRIVE:260",    "1.01", IDE_AFLAG_TOCADDR_AS_BCD |
					     IDE_AFLAG_PRE_ATAPI12,	     },
1485
	/* Vertos 300, some versions of this drive like to talk BCD. */
1486
	{ "V003S0DS",		     NULL,   IDE_AFLAG_VERTOS_300_SSD,	     },
1487
	/* Vertos 600 ESD. */
1488
	{ "V006E0DS",		     NULL,   IDE_AFLAG_VERTOS_600_ESD,	     },
1489 1490 1491 1492
	/*
	 * Sanyo 3 CD changer uses a non-standard command for CD changing
	 * (by default standard ATAPI support for CD changers is used).
	 */
1493 1494 1495
	{ "CD-ROM CDR-C3 G",	     NULL,   IDE_AFLAG_SANYO_3CD	     },
	{ "CD-ROM CDR-C3G",	     NULL,   IDE_AFLAG_SANYO_3CD	     },
	{ "CD-ROM CDR_C36",	     NULL,   IDE_AFLAG_SANYO_3CD	     },
1496
	/* Stingray 8X CD-ROM. */
1497
	{ "STINGRAY 8422 IDE 8X CD-ROM 7-27-95", NULL, IDE_AFLAG_PRE_ATAPI12 },
1498 1499 1500 1501
	/*
	 * ACER 50X CD-ROM and WPI 32X CD-ROM require the full spec length
	 * mode sense page capabilities size, but older drives break.
	 */
1502 1503
	{ "ATAPI CD ROM DRIVE 50X MAX",	NULL,	IDE_AFLAG_FULL_CAPS_PAGE     },
	{ "WPI CDS-32X",		NULL,	IDE_AFLAG_FULL_CAPS_PAGE     },
1504
	/* ACER/AOpen 24X CD-ROM has the speed fields byte-swapped. */
1505
	{ "",			     "241N", IDE_AFLAG_LE_SPEED_FIELDS       },
1506 1507 1508 1509
	/*
	 * Some drives used by Apple don't advertise audio play
	 * but they do support reading TOC & audio datas.
	 */
1510 1511 1512 1513 1514
	{ "MATSHITADVD-ROM SR-8187", NULL,   IDE_AFLAG_PLAY_AUDIO_OK	     },
	{ "MATSHITADVD-ROM SR-8186", NULL,   IDE_AFLAG_PLAY_AUDIO_OK	     },
	{ "MATSHITADVD-ROM SR-8176", NULL,   IDE_AFLAG_PLAY_AUDIO_OK	     },
	{ "MATSHITADVD-ROM SR-8174", NULL,   IDE_AFLAG_PLAY_AUDIO_OK	     },
	{ "Optiarc DVD RW AD-5200A", NULL,   IDE_AFLAG_PLAY_AUDIO_OK	     },
1515
	{ "Optiarc DVD RW AD-7200A", NULL,   IDE_AFLAG_PLAY_AUDIO_OK	     },
B
Borislav Petkov 已提交
1516
	{ "Optiarc DVD RW AD-7543A", NULL,   IDE_AFLAG_NO_AUTOCLOSE	     },
1517
	{ "TEAC CD-ROM CD-224E",     NULL,   IDE_AFLAG_NO_AUTOCLOSE	     },
1518 1519 1520
	{ NULL, NULL, 0 }
};

1521
static unsigned int ide_cd_flags(u16 *id)
1522 1523 1524 1525
{
	const struct cd_list_entry *cle = ide_cd_quirks_list;

	while (cle->id_model) {
1526
		if (strcmp(cle->id_model, (char *)&id[ATA_ID_PROD]) == 0 &&
1527
		    (cle->id_firmware == NULL ||
1528
		     strstr((char *)&id[ATA_ID_FW_REV], cle->id_firmware)))
1529 1530 1531 1532 1533 1534 1535
			return cle->cd_flags;
		cle++;
	}

	return 0;
}

1536
static int ide_cdrom_setup(ide_drive_t *drive)
L
Linus Torvalds 已提交
1537
{
1538 1539
	struct cdrom_info *cd = drive->driver_data;
	struct cdrom_device_info *cdi = &cd->devinfo;
1540
	struct request_queue *q = drive->queue;
1541 1542
	u16 *id = drive->id;
	char *fw_rev = (char *)&id[ATA_ID_FW_REV];
L
Linus Torvalds 已提交
1543 1544
	int nslots;

B
Borislav Petkov 已提交
1545
	ide_debug_log(IDE_DBG_PROBE, "enter");
1546

1547 1548 1549 1550 1551
	blk_queue_prep_rq(q, ide_cdrom_prep_fn);
	blk_queue_dma_alignment(q, 31);
	blk_queue_update_dma_pad(q, 15);

	q->unplug_delay = max((1 * HZ) / 1000, 1);
L
Linus Torvalds 已提交
1552

1553 1554
	drive->dev_flags |= IDE_DFLAG_MEDIA_CHANGED;
	drive->atapi_flags = IDE_AFLAG_NO_EJECT | ide_cd_flags(id);
L
Linus Torvalds 已提交
1555

1556
	if ((drive->atapi_flags & IDE_AFLAG_VERTOS_300_SSD) &&
1557
	    fw_rev[4] == '1' && fw_rev[6] <= '2')
1558 1559 1560
		drive->atapi_flags |= (IDE_AFLAG_TOCTRACKS_AS_BCD |
				     IDE_AFLAG_TOCADDR_AS_BCD);
	else if ((drive->atapi_flags & IDE_AFLAG_VERTOS_600_ESD) &&
1561
		 fw_rev[4] == '1' && fw_rev[6] <= '2')
1562 1563
		drive->atapi_flags |= IDE_AFLAG_TOCTRACKS_AS_BCD;
	else if (drive->atapi_flags & IDE_AFLAG_SANYO_3CD)
B
Borislav Petkov 已提交
1564 1565
		/* 3 => use CD in slot 0 */
		cdi->sanyo_slot = 3;
L
Linus Torvalds 已提交
1566

1567
	nslots = ide_cdrom_probe_capabilities(drive);
L
Linus Torvalds 已提交
1568

1569
	blk_queue_hardsect_size(q, CD_FRAMESIZE);
L
Linus Torvalds 已提交
1570 1571

	if (ide_cdrom_register(drive, nslots)) {
1572
		printk(KERN_ERR PFX "%s: %s failed to register device with the"
1573
				" cdrom driver.\n", drive->name, __func__);
1574
		cd->devinfo.handle = NULL;
L
Linus Torvalds 已提交
1575 1576
		return 1;
	}
1577 1578

	ide_proc_register_driver(drive, cd->driver);
L
Linus Torvalds 已提交
1579 1580 1581
	return 0;
}

1582
static void ide_cd_remove(ide_drive_t *drive)
L
Linus Torvalds 已提交
1583 1584 1585
{
	struct cdrom_info *info = drive->driver_data;

B
Borislav Petkov 已提交
1586
	ide_debug_log(IDE_DBG_FUNC, "enter");
1587

1588
	ide_proc_unregister_driver(drive, info->driver);
1589
	device_del(&info->dev);
L
Linus Torvalds 已提交
1590 1591
	del_gendisk(info->disk);

1592 1593 1594
	mutex_lock(&idecd_ref_mutex);
	put_device(&info->dev);
	mutex_unlock(&idecd_ref_mutex);
L
Linus Torvalds 已提交
1595 1596
}

1597
static void ide_cd_release(struct device *dev)
L
Linus Torvalds 已提交
1598
{
1599
	struct cdrom_info *info = to_ide_drv(dev, cdrom_info);
L
Linus Torvalds 已提交
1600 1601 1602 1603
	struct cdrom_device_info *devinfo = &info->devinfo;
	ide_drive_t *drive = info->drive;
	struct gendisk *g = info->disk;

B
Borislav Petkov 已提交
1604
	ide_debug_log(IDE_DBG_FUNC, "enter");
1605

1606
	kfree(info->toc);
1607 1608
	if (devinfo->handle == drive)
		unregister_cdrom(devinfo);
L
Linus Torvalds 已提交
1609 1610 1611 1612 1613 1614 1615
	drive->driver_data = NULL;
	blk_queue_prep_rq(drive->queue, NULL);
	g->private_data = NULL;
	put_disk(g);
	kfree(info);
}

1616
static int ide_cd_probe(ide_drive_t *);
L
Linus Torvalds 已提交
1617

1618
static struct ide_driver ide_cdrom_driver = {
1619
	.gen_driver = {
1620
		.owner		= THIS_MODULE,
1621 1622 1623
		.name		= "ide-cdrom",
		.bus		= &ide_bus_type,
	},
1624 1625
	.probe			= ide_cd_probe,
	.remove			= ide_cd_remove,
L
Linus Torvalds 已提交
1626
	.version		= IDECD_VERSION,
1627
	.do_request		= ide_cd_do_request,
1628
#ifdef CONFIG_IDE_PROC_FS
1629 1630
	.proc_entries		= ide_cd_proc_entries,
	.proc_devsets		= ide_cd_proc_devsets,
1631
#endif
L
Linus Torvalds 已提交
1632 1633
};

A
Al Viro 已提交
1634
static int idecd_open(struct block_device *bdev, fmode_t mode)
L
Linus Torvalds 已提交
1635
{
A
Al Viro 已提交
1636
	struct cdrom_info *info = ide_cd_get(bdev->bd_disk);
L
Linus Torvalds 已提交
1637 1638
	int rc = -ENOMEM;

1639
	if (!info)
L
Linus Torvalds 已提交
1640 1641
		return -ENXIO;

A
Al Viro 已提交
1642
	rc = cdrom_open(&info->devinfo, bdev, mode);
L
Linus Torvalds 已提交
1643 1644 1645 1646 1647 1648 1649

	if (rc < 0)
		ide_cd_put(info);

	return rc;
}

A
Al Viro 已提交
1650
static int idecd_release(struct gendisk *disk, fmode_t mode)
L
Linus Torvalds 已提交
1651
{
B
Borislav Petkov 已提交
1652
	struct cdrom_info *info = ide_drv_g(disk, cdrom_info);
L
Linus Torvalds 已提交
1653

A
Al Viro 已提交
1654
	cdrom_release(&info->devinfo, mode);
L
Linus Torvalds 已提交
1655 1656 1657 1658 1659 1660

	ide_cd_put(info);

	return 0;
}

1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685
static int idecd_set_spindown(struct cdrom_device_info *cdi, unsigned long arg)
{
	struct packet_command cgc;
	char buffer[16];
	int stat;
	char spindown;

	if (copy_from_user(&spindown, (void __user *)arg, sizeof(char)))
		return -EFAULT;

	init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_UNKNOWN);

	stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CDROM_PAGE, 0);
	if (stat)
		return stat;

	buffer[11] = (buffer[11] & 0xf0) | (spindown & 0x0f);
	return cdrom_mode_select(cdi, &cgc);
}

static int idecd_get_spindown(struct cdrom_device_info *cdi, unsigned long arg)
{
	struct packet_command cgc;
	char buffer[16];
	int stat;
1686
	char spindown;
1687 1688 1689 1690 1691 1692 1693 1694

	init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_UNKNOWN);

	stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CDROM_PAGE, 0);
	if (stat)
		return stat;

	spindown = buffer[11] & 0x0f;
1695
	if (copy_to_user((void __user *)arg, &spindown, sizeof(char)))
1696 1697 1698 1699
		return -EFAULT;
	return 0;
}

A
Al Viro 已提交
1700
static int idecd_ioctl(struct block_device *bdev, fmode_t mode,
L
Linus Torvalds 已提交
1701 1702
			unsigned int cmd, unsigned long arg)
{
B
Borislav Petkov 已提交
1703
	struct cdrom_info *info = ide_drv_g(bdev->bd_disk, cdrom_info);
L
Linus Torvalds 已提交
1704 1705
	int err;

1706
	switch (cmd) {
1707
	case CDROMSETSPINDOWN:
1708
		return idecd_set_spindown(&info->devinfo, arg);
1709
	case CDROMGETSPINDOWN:
1710 1711 1712
		return idecd_get_spindown(&info->devinfo, arg);
	default:
		break;
1713
	}
1714

1715
	err = generic_ide_ioctl(info->drive, bdev, cmd, arg);
L
Linus Torvalds 已提交
1716
	if (err == -EINVAL)
A
Al Viro 已提交
1717
		err = cdrom_ioctl(&info->devinfo, bdev, mode, cmd, arg);
L
Linus Torvalds 已提交
1718 1719 1720 1721 1722 1723

	return err;
}

static int idecd_media_changed(struct gendisk *disk)
{
B
Borislav Petkov 已提交
1724
	struct cdrom_info *info = ide_drv_g(disk, cdrom_info);
L
Linus Torvalds 已提交
1725 1726 1727 1728 1729
	return cdrom_media_changed(&info->devinfo);
}

static int idecd_revalidate_disk(struct gendisk *disk)
{
B
Borislav Petkov 已提交
1730
	struct cdrom_info *info = ide_drv_g(disk, cdrom_info);
L
Linus Torvalds 已提交
1731
	struct request_sense sense;
1732 1733 1734

	ide_cd_read_toc(info->drive, &sense);

L
Linus Torvalds 已提交
1735 1736 1737 1738
	return  0;
}

static struct block_device_operations idecd_ops = {
1739
	.owner			= THIS_MODULE,
A
Al Viro 已提交
1740 1741 1742
	.open			= idecd_open,
	.release		= idecd_release,
	.locked_ioctl		= idecd_ioctl,
1743 1744
	.media_changed		= idecd_media_changed,
	.revalidate_disk	= idecd_revalidate_disk
L
Linus Torvalds 已提交
1745 1746
};

B
Borislav Petkov 已提交
1747
/* module options */
1748 1749 1750
static unsigned long debug_mask;
module_param(debug_mask, ulong, 0644);

L
Linus Torvalds 已提交
1751 1752
MODULE_DESCRIPTION("ATAPI CD-ROM Driver");

1753
static int ide_cd_probe(ide_drive_t *drive)
L
Linus Torvalds 已提交
1754 1755 1756 1757 1758
{
	struct cdrom_info *info;
	struct gendisk *g;
	struct request_sense sense;

B
Borislav Petkov 已提交
1759 1760
	ide_debug_log(IDE_DBG_PROBE, "driver_req: %s, media: 0x%x",
				     drive->driver_req, drive->media);
1761

L
Linus Torvalds 已提交
1762 1763
	if (!strstr("ide-cdrom", drive->driver_req))
		goto failed;
1764

L
Linus Torvalds 已提交
1765 1766
	if (drive->media != ide_cdrom && drive->media != ide_optical)
		goto failed;
1767

1768
	drive->debug_mask = debug_mask;
1769
	drive->irq_handler = cdrom_newpc_intr;
1770

1771
	info = kzalloc(sizeof(struct cdrom_info), GFP_KERNEL);
L
Linus Torvalds 已提交
1772
	if (info == NULL) {
1773
		printk(KERN_ERR PFX "%s: Can't allocate a cdrom structure\n",
1774
				drive->name);
L
Linus Torvalds 已提交
1775 1776 1777 1778 1779 1780 1781 1782 1783
		goto failed;
	}

	g = alloc_disk(1 << PARTN_BITS);
	if (!g)
		goto out_free_cd;

	ide_init_disk(g, drive);

1784 1785 1786 1787 1788 1789
	info->dev.parent = &drive->gendev;
	info->dev.release = ide_cd_release;
	dev_set_name(&info->dev, dev_name(&drive->gendev));

	if (device_register(&info->dev))
		goto out_free_disk;
L
Linus Torvalds 已提交
1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802

	info->drive = drive;
	info->driver = &ide_cdrom_driver;
	info->disk = g;

	g->private_data = &info->driver;

	drive->driver_data = info;

	g->minors = 1;
	g->driverfs_dev = &drive->gendev;
	g->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE;
	if (ide_cdrom_setup(drive)) {
1803
		put_device(&info->dev);
L
Linus Torvalds 已提交
1804 1805 1806
		goto failed;
	}

1807
	ide_cd_read_toc(drive, &sense);
L
Linus Torvalds 已提交
1808 1809 1810 1811 1812
	g->fops = &idecd_ops;
	g->flags |= GENHD_FL_REMOVABLE;
	add_disk(g);
	return 0;

1813 1814
out_free_disk:
	put_disk(g);
L
Linus Torvalds 已提交
1815 1816 1817
out_free_cd:
	kfree(info);
failed:
1818
	return -ENODEV;
L
Linus Torvalds 已提交
1819 1820 1821 1822
}

static void __exit ide_cdrom_exit(void)
{
1823
	driver_unregister(&ide_cdrom_driver.gen_driver);
L
Linus Torvalds 已提交
1824
}
1825 1826

static int __init ide_cdrom_init(void)
L
Linus Torvalds 已提交
1827
{
1828
	printk(KERN_INFO DRV_NAME " driver " IDECD_VERSION "\n");
1829
	return driver_register(&ide_cdrom_driver.gen_driver);
L
Linus Torvalds 已提交
1830 1831
}

1832
MODULE_ALIAS("ide:*m-cdrom*");
1833
MODULE_ALIAS("ide-cd");
L
Linus Torvalds 已提交
1834 1835 1836
module_init(ide_cdrom_init);
module_exit(ide_cdrom_exit);
MODULE_LICENSE("GPL");