blob: bd552328014a3cf522c6a572b81fe09a09d0543d [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * linux/drivers/ide/ide-cd.c
3 *
4 * Copyright (C) 1994, 1995, 1996 scott snyder <snyder@fnald0.fnal.gov>
5 * Copyright (C) 1996-1998 Erik Andersen <andersee@debian.org>
6 * Copyright (C) 1998-2000 Jens Axboe <axboe@suse.de>
7 *
8 * May be copied or modified under the terms of the GNU General Public
9 * License. See linux/COPYING for more information.
10 *
11 * ATAPI CD-ROM driver. To be used with ide.c.
12 * See Documentation/cdrom/ide-cd for usage information.
13 *
14 * Suggestions are welcome. Patches that work are more welcome though. ;-)
15 * For those wishing to work on this driver, please be sure you download
16 * and comply with the latest Mt. Fuji (SFF8090 version 4) and ATAPI
17 * (SFF-8020i rev 2.6) standards. These documents can be obtained by
18 * anonymous ftp from:
19 * ftp://fission.dt.wdc.com/pub/standards/SFF_atapi/spec/SFF8020-r2.6/PS/8020r26.ps
20 * ftp://ftp.avc-pioneer.com/Mtfuji4/Spec/Fuji4r10.pdf
21 *
22 * Drives that deviate from these standards will be accommodated as much
23 * as possible via compile time or command-line options. Since I only have
24 * a few drives, you generally need to send me patches...
25 *
26 * ----------------------------------
27 * TO DO LIST:
28 * -Make it so that Pioneer CD DR-A24X and friends don't get screwed up on
29 * boot
30 *
Bartlomiej Zolnierkiewicz03553352008-02-01 23:09:18 +010031 * For historical changelog please see:
32 * Documentation/ide/ChangeLog.ide-cd.1994-2004
33 */
34
Linus Torvalds1da177e2005-04-16 15:20:36 -070035#define IDECD_VERSION "4.61"
36
Linus Torvalds1da177e2005-04-16 15:20:36 -070037#include <linux/module.h>
38#include <linux/types.h>
39#include <linux/kernel.h>
40#include <linux/delay.h>
41#include <linux/timer.h>
42#include <linux/slab.h>
43#include <linux/interrupt.h>
44#include <linux/errno.h>
45#include <linux/cdrom.h>
46#include <linux/ide.h>
47#include <linux/completion.h>
Arjan van de Vencf8b8972006-03-23 03:00:45 -080048#include <linux/mutex.h>
Bartlomiej Zolnierkiewicz9a6dc662008-02-01 23:09:22 +010049#include <linux/bcd.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070050
51#include <scsi/scsi.h> /* For SCSI -> ATAPI command conversion */
52
53#include <asm/irq.h>
54#include <asm/io.h>
55#include <asm/byteorder.h>
56#include <asm/uaccess.h>
57#include <asm/unaligned.h>
58
59#include "ide-cd.h"
60
Arjan van de Vencf8b8972006-03-23 03:00:45 -080061static DEFINE_MUTEX(idecd_ref_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -070062
63#define to_ide_cd(obj) container_of(obj, struct cdrom_info, kref)
64
65#define ide_cd_g(disk) \
66 container_of((disk)->private_data, struct cdrom_info, driver)
67
68static struct cdrom_info *ide_cd_get(struct gendisk *disk)
69{
70 struct cdrom_info *cd = NULL;
71
Arjan van de Vencf8b8972006-03-23 03:00:45 -080072 mutex_lock(&idecd_ref_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -070073 cd = ide_cd_g(disk);
74 if (cd)
75 kref_get(&cd->kref);
Arjan van de Vencf8b8972006-03-23 03:00:45 -080076 mutex_unlock(&idecd_ref_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -070077 return cd;
78}
79
80static void ide_cd_release(struct kref *);
81
82static void ide_cd_put(struct cdrom_info *cd)
83{
Arjan van de Vencf8b8972006-03-23 03:00:45 -080084 mutex_lock(&idecd_ref_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -070085 kref_put(&cd->kref, ide_cd_release);
Arjan van de Vencf8b8972006-03-23 03:00:45 -080086 mutex_unlock(&idecd_ref_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -070087}
88
89/****************************************************************************
90 * Generic packet command support and error handling routines.
91 */
92
93/* Mark that we've seen a media change, and invalidate our internal
94 buffers. */
95static void cdrom_saw_media_change (ide_drive_t *drive)
96{
Bartlomiej Zolnierkiewicz0ba11212008-02-01 23:09:21 +010097 struct cdrom_info *cd = drive->driver_data;
98
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +010099 cd->cd_flags |= IDE_CD_FLAG_MEDIA_CHANGED;
100 cd->cd_flags &= ~IDE_CD_FLAG_TOC_VALID;
Bartlomiej Zolnierkiewicz0ba11212008-02-01 23:09:21 +0100101 cd->nsectors_buffered = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102}
103
104static int cdrom_log_sense(ide_drive_t *drive, struct request *rq,
105 struct request_sense *sense)
106{
107 int log = 0;
108
Jens Axboe4aff5e22006-08-10 08:44:47 +0200109 if (!sense || !rq || (rq->cmd_flags & REQ_QUIET))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700110 return 0;
111
112 switch (sense->sense_key) {
113 case NO_SENSE: case RECOVERED_ERROR:
114 break;
115 case NOT_READY:
116 /*
117 * don't care about tray state messages for
118 * e.g. capacity commands or in-progress or
119 * becoming ready
120 */
121 if (sense->asc == 0x3a || sense->asc == 0x04)
122 break;
123 log = 1;
124 break;
125 case ILLEGAL_REQUEST:
126 /*
127 * don't log START_STOP unit with LoEj set, since
128 * we cannot reliably check if drive can auto-close
129 */
130 if (rq->cmd[0] == GPCMD_START_STOP_UNIT && sense->asc == 0x24)
Alan Coxdbe217a2006-06-25 05:47:44 -0700131 break;
132 log = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133 break;
134 case UNIT_ATTENTION:
135 /*
136 * Make good and sure we've seen this potential media
137 * change. Some drives (i.e. Creative) fail to present
138 * the correct sense key in the error register.
139 */
140 cdrom_saw_media_change(drive);
141 break;
142 default:
143 log = 1;
144 break;
145 }
146 return log;
147}
148
149static
150void cdrom_analyze_sense_data(ide_drive_t *drive,
151 struct request *failed_command,
152 struct request_sense *sense)
153{
Alan Coxdbe217a2006-06-25 05:47:44 -0700154 unsigned long sector;
155 unsigned long bio_sectors;
156 unsigned long valid;
157 struct cdrom_info *info = drive->driver_data;
158
Linus Torvalds1da177e2005-04-16 15:20:36 -0700159 if (!cdrom_log_sense(drive, failed_command, sense))
160 return;
161
162 /*
163 * If a read toc is executed for a CD-R or CD-RW medium where
164 * the first toc has not been recorded yet, it will fail with
165 * 05/24/00 (which is a confusing error)
166 */
167 if (failed_command && failed_command->cmd[0] == GPCMD_READ_TOC_PMA_ATIP)
168 if (sense->sense_key == 0x05 && sense->asc == 0x24)
169 return;
170
Alan Coxdbe217a2006-06-25 05:47:44 -0700171 if (sense->error_code == 0x70) { /* Current Error */
172 switch(sense->sense_key) {
173 case MEDIUM_ERROR:
174 case VOLUME_OVERFLOW:
175 case ILLEGAL_REQUEST:
176 if (!sense->valid)
177 break;
178 if (failed_command == NULL ||
179 !blk_fs_request(failed_command))
180 break;
181 sector = (sense->information[0] << 24) |
182 (sense->information[1] << 16) |
183 (sense->information[2] << 8) |
184 (sense->information[3]);
185
186 bio_sectors = bio_sectors(failed_command->bio);
187 if (bio_sectors < 4)
188 bio_sectors = 4;
189 if (drive->queue->hardsect_size == 2048)
190 sector <<= 2; /* Device sector size is 2K */
191 sector &= ~(bio_sectors -1);
192 valid = (sector - failed_command->sector) << 9;
193
194 if (valid < 0)
195 valid = 0;
196 if (sector < get_capacity(info->disk) &&
197 drive->probed_capacity - sector < 4 * 75) {
198 set_capacity(info->disk, sector);
199 }
200 }
201 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700202#if VERBOSE_IDE_CD_ERRORS
203 {
204 int i;
Matt Mackall70d1d472005-07-12 13:58:09 -0700205 const char *s = "bad sense key!";
Linus Torvalds1da177e2005-04-16 15:20:36 -0700206 char buf[80];
207
208 printk ("ATAPI device %s:\n", drive->name);
209 if (sense->error_code==0x70)
210 printk(" Error: ");
211 else if (sense->error_code==0x71)
212 printk(" Deferred Error: ");
213 else if (sense->error_code == 0x7f)
214 printk(" Vendor-specific Error: ");
215 else
216 printk(" Unknown Error Type: ");
217
Robert P. J. Day74c8f972007-07-09 23:17:57 +0200218 if (sense->sense_key < ARRAY_SIZE(sense_key_texts))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700219 s = sense_key_texts[sense->sense_key];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700220
221 printk("%s -- (Sense key=0x%02x)\n", s, sense->sense_key);
222
223 if (sense->asc == 0x40) {
224 sprintf(buf, "Diagnostic failure on component 0x%02x",
225 sense->ascq);
226 s = buf;
227 } else {
Robert P. J. Day74c8f972007-07-09 23:17:57 +0200228 int lo = 0, mid, hi = ARRAY_SIZE(sense_data_texts);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700229 unsigned long key = (sense->sense_key << 16);
230 key |= (sense->asc << 8);
231 if (!(sense->ascq >= 0x80 && sense->ascq <= 0xdd))
232 key |= sense->ascq;
233 s = NULL;
234
235 while (hi > lo) {
236 mid = (lo + hi) / 2;
237 if (sense_data_texts[mid].asc_ascq == key ||
238 sense_data_texts[mid].asc_ascq == (0xff0000|key)) {
239 s = sense_data_texts[mid].text;
240 break;
241 }
242 else if (sense_data_texts[mid].asc_ascq > key)
243 hi = mid;
244 else
245 lo = mid+1;
246 }
247 }
248
249 if (s == NULL) {
250 if (sense->asc > 0x80)
251 s = "(vendor-specific error)";
252 else
253 s = "(reserved error code)";
254 }
255
256 printk(KERN_ERR " %s -- (asc=0x%02x, ascq=0x%02x)\n",
257 s, sense->asc, sense->ascq);
258
259 if (failed_command != NULL) {
260
Robert P. J. Day74c8f972007-07-09 23:17:57 +0200261 int lo=0, mid, hi= ARRAY_SIZE(packet_command_texts);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700262 s = NULL;
263
264 while (hi > lo) {
265 mid = (lo + hi) / 2;
266 if (packet_command_texts[mid].packet_command ==
267 failed_command->cmd[0]) {
268 s = packet_command_texts[mid].text;
269 break;
270 }
271 if (packet_command_texts[mid].packet_command >
272 failed_command->cmd[0])
273 hi = mid;
274 else
275 lo = mid+1;
276 }
277
278 printk (KERN_ERR " The failed \"%s\" packet command was: \n \"", s);
279 for (i=0; i<sizeof (failed_command->cmd); i++)
280 printk ("%02x ", failed_command->cmd[i]);
281 printk ("\"\n");
282 }
283
284 /* The SKSV bit specifies validity of the sense_key_specific
285 * in the next two commands. It is bit 7 of the first byte.
286 * In the case of NOT_READY, if SKSV is set the drive can
287 * give us nice ETA readings.
288 */
289 if (sense->sense_key == NOT_READY && (sense->sks[0] & 0x80)) {
290 int progress = (sense->sks[1] << 8 | sense->sks[2]) * 100;
291 printk(KERN_ERR " Command is %02d%% complete\n", progress / 0xffff);
292
293 }
294
295 if (sense->sense_key == ILLEGAL_REQUEST &&
296 (sense->sks[0] & 0x80) != 0) {
297 printk(KERN_ERR " Error in %s byte %d",
298 (sense->sks[0] & 0x40) != 0 ?
299 "command packet" : "command data",
300 (sense->sks[1] << 8) + sense->sks[2]);
301
302 if ((sense->sks[0] & 0x40) != 0)
303 printk (" bit %d", sense->sks[0] & 0x07);
304
305 printk ("\n");
306 }
307 }
308
309#else /* not VERBOSE_IDE_CD_ERRORS */
310
311 /* Suppress printing unit attention and `in progress of becoming ready'
312 errors when we're not being verbose. */
313
314 if (sense->sense_key == UNIT_ATTENTION ||
315 (sense->sense_key == NOT_READY && (sense->asc == 4 ||
316 sense->asc == 0x3a)))
317 return;
318
319 printk(KERN_ERR "%s: error code: 0x%02x sense_key: 0x%02x asc: 0x%02x ascq: 0x%02x\n",
320 drive->name,
321 sense->error_code, sense->sense_key,
322 sense->asc, sense->ascq);
323#endif /* not VERBOSE_IDE_CD_ERRORS */
324}
325
326/*
327 * Initialize a ide-cd packet command request
328 */
329static void cdrom_prepare_request(ide_drive_t *drive, struct request *rq)
330{
331 struct cdrom_info *cd = drive->driver_data;
332
333 ide_init_drive_cmd(rq);
Jens Axboecea28852006-10-12 15:08:45 +0200334 rq->cmd_type = REQ_TYPE_ATA_PC;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700335 rq->rq_disk = cd->disk;
336}
337
338static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense,
339 struct request *failed_command)
340{
341 struct cdrom_info *info = drive->driver_data;
342 struct request *rq = &info->request_sense_request;
343
344 if (sense == NULL)
345 sense = &info->sense_data;
346
347 /* stuff the sense request in front of our current request */
348 cdrom_prepare_request(drive, rq);
349
350 rq->data = sense;
351 rq->cmd[0] = GPCMD_REQUEST_SENSE;
352 rq->cmd[4] = rq->data_len = 18;
353
Jens Axboe4aff5e22006-08-10 08:44:47 +0200354 rq->cmd_type = REQ_TYPE_SENSE;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700355
356 /* NOTE! Save the failed command in "rq->buffer" */
357 rq->buffer = (void *) failed_command;
358
359 (void) ide_do_drive_cmd(drive, rq, ide_preempt);
360}
361
362static void cdrom_end_request (ide_drive_t *drive, int uptodate)
363{
364 struct request *rq = HWGROUP(drive)->rq;
365 int nsectors = rq->hard_cur_sectors;
366
Jens Axboe4aff5e22006-08-10 08:44:47 +0200367 if (blk_sense_request(rq) && uptodate) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700368 /*
Jens Axboe4aff5e22006-08-10 08:44:47 +0200369 * For REQ_TYPE_SENSE, "rq->buffer" points to the original
370 * failed request
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371 */
372 struct request *failed = (struct request *) rq->buffer;
373 struct cdrom_info *info = drive->driver_data;
374 void *sense = &info->sense_data;
375 unsigned long flags;
376
377 if (failed) {
378 if (failed->sense) {
379 sense = failed->sense;
380 failed->sense_len = rq->sense_len;
381 }
Alan Coxdbe217a2006-06-25 05:47:44 -0700382 cdrom_analyze_sense_data(drive, failed, sense);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383 /*
384 * now end failed request
385 */
Alan Coxdbe217a2006-06-25 05:47:44 -0700386 if (blk_fs_request(failed)) {
387 if (ide_end_dequeued_request(drive, failed, 0,
388 failed->hard_nr_sectors))
389 BUG();
390 } else {
391 spin_lock_irqsave(&ide_lock, flags);
Kiyoshi Ueda5e36bb62008-01-28 10:34:20 +0100392 if (__blk_end_request(failed, -EIO,
393 failed->data_len))
394 BUG();
Alan Coxdbe217a2006-06-25 05:47:44 -0700395 spin_unlock_irqrestore(&ide_lock, flags);
396 }
397 } else
398 cdrom_analyze_sense_data(drive, NULL, sense);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700399 }
400
401 if (!rq->current_nr_sectors && blk_fs_request(rq))
402 uptodate = 1;
403 /* make sure it's fully ended */
404 if (blk_pc_request(rq))
405 nsectors = (rq->data_len + 511) >> 9;
406 if (!nsectors)
407 nsectors = 1;
408
409 ide_end_request(drive, uptodate, nsectors);
410}
411
Alan Coxdbe217a2006-06-25 05:47:44 -0700412static void ide_dump_status_no_sense(ide_drive_t *drive, const char *msg, u8 stat)
413{
414 if (stat & 0x80)
415 return;
416 ide_dump_status(drive, msg, stat);
417}
418
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419/* Returns 0 if the request should be continued.
420 Returns 1 if the request was ended. */
421static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
422{
423 struct request *rq = HWGROUP(drive)->rq;
424 int stat, err, sense_key;
425
426 /* Check for errors. */
427 stat = HWIF(drive)->INB(IDE_STATUS_REG);
428 if (stat_ret)
429 *stat_ret = stat;
430
431 if (OK_STAT(stat, good_stat, BAD_R_STAT))
432 return 0;
433
434 /* Get the IDE error register. */
435 err = HWIF(drive)->INB(IDE_ERROR_REG);
436 sense_key = err >> 4;
437
438 if (rq == NULL) {
439 printk("%s: missing rq in cdrom_decode_status\n", drive->name);
440 return 1;
441 }
442
Jens Axboe4aff5e22006-08-10 08:44:47 +0200443 if (blk_sense_request(rq)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700444 /* We got an error trying to get sense info
445 from the drive (probably while trying
446 to recover from a former error). Just give up. */
447
Jens Axboe4aff5e22006-08-10 08:44:47 +0200448 rq->cmd_flags |= REQ_FAILED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700449 cdrom_end_request(drive, 0);
450 ide_error(drive, "request sense failure", stat);
451 return 1;
452
Jens Axboe8770c012006-10-12 17:24:52 +0200453 } else if (blk_pc_request(rq) || rq->cmd_type == REQ_TYPE_ATA_PC) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700454 /* All other functions, except for READ. */
455 unsigned long flags;
456
457 /*
458 * if we have an error, pass back CHECK_CONDITION as the
459 * scsi status byte
460 */
Jens Axboeb7156732006-11-13 18:05:02 +0100461 if (blk_pc_request(rq) && !rq->errors)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700462 rq->errors = SAM_STAT_CHECK_CONDITION;
463
464 /* Check for tray open. */
465 if (sense_key == NOT_READY) {
466 cdrom_saw_media_change (drive);
467 } else if (sense_key == UNIT_ATTENTION) {
468 /* Check for media change. */
469 cdrom_saw_media_change (drive);
470 /*printk("%s: media changed\n",drive->name);*/
471 return 0;
Stuart Hayes76ca1af2007-04-10 22:38:43 +0200472 } else if ((sense_key == ILLEGAL_REQUEST) &&
473 (rq->cmd[0] == GPCMD_START_STOP_UNIT)) {
474 /*
475 * Don't print error message for this condition--
476 * SFF8090i indicates that 5/24/00 is the correct
477 * response to a request to close the tray if the
478 * drive doesn't have that capability.
479 * cdrom_log_sense() knows this!
480 */
Jens Axboe4aff5e22006-08-10 08:44:47 +0200481 } else if (!(rq->cmd_flags & REQ_QUIET)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700482 /* Otherwise, print an error. */
483 ide_dump_status(drive, "packet command error", stat);
484 }
485
Jens Axboe4aff5e22006-08-10 08:44:47 +0200486 rq->cmd_flags |= REQ_FAILED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700487
488 /*
489 * instead of playing games with moving completions around,
490 * remove failed request completely and end it when the
491 * request sense has completed
492 */
493 if (stat & ERR_STAT) {
494 spin_lock_irqsave(&ide_lock, flags);
495 blkdev_dequeue_request(rq);
496 HWGROUP(drive)->rq = NULL;
497 spin_unlock_irqrestore(&ide_lock, flags);
498
499 cdrom_queue_request_sense(drive, rq->sense, rq);
500 } else
501 cdrom_end_request(drive, 0);
502
503 } else if (blk_fs_request(rq)) {
504 int do_end_request = 0;
505
506 /* Handle errors from READ and WRITE requests. */
507
508 if (blk_noretry_request(rq))
509 do_end_request = 1;
510
511 if (sense_key == NOT_READY) {
512 /* Tray open. */
513 if (rq_data_dir(rq) == READ) {
514 cdrom_saw_media_change (drive);
515
516 /* Fail the request. */
517 printk ("%s: tray open\n", drive->name);
518 do_end_request = 1;
519 } else {
520 struct cdrom_info *info = drive->driver_data;
521
522 /* allow the drive 5 seconds to recover, some
523 * devices will return this error while flushing
524 * data from cache */
525 if (!rq->errors)
526 info->write_timeout = jiffies + ATAPI_WAIT_WRITE_BUSY;
527 rq->errors = 1;
528 if (time_after(jiffies, info->write_timeout))
529 do_end_request = 1;
530 else {
531 unsigned long flags;
532
533 /*
534 * take a breather relying on the
535 * unplug timer to kick us again
536 */
537 spin_lock_irqsave(&ide_lock, flags);
538 blk_plug_device(drive->queue);
539 spin_unlock_irqrestore(&ide_lock,flags);
540 return 1;
541 }
542 }
543 } else if (sense_key == UNIT_ATTENTION) {
544 /* Media change. */
545 cdrom_saw_media_change (drive);
546
547 /* Arrange to retry the request.
548 But be sure to give up if we've retried
549 too many times. */
550 if (++rq->errors > ERROR_MAX)
551 do_end_request = 1;
552 } else if (sense_key == ILLEGAL_REQUEST ||
553 sense_key == DATA_PROTECT) {
554 /* No point in retrying after an illegal
555 request or data protect error.*/
Alan Coxdbe217a2006-06-25 05:47:44 -0700556 ide_dump_status_no_sense (drive, "command error", stat);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700557 do_end_request = 1;
558 } else if (sense_key == MEDIUM_ERROR) {
559 /* No point in re-trying a zillion times on a bad
560 * sector... If we got here the error is not correctable */
Alan Coxdbe217a2006-06-25 05:47:44 -0700561 ide_dump_status_no_sense (drive, "media error (bad sector)", stat);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700562 do_end_request = 1;
563 } else if (sense_key == BLANK_CHECK) {
564 /* Disk appears blank ?? */
Alan Coxdbe217a2006-06-25 05:47:44 -0700565 ide_dump_status_no_sense (drive, "media error (blank)", stat);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700566 do_end_request = 1;
567 } else if ((err & ~ABRT_ERR) != 0) {
568 /* Go to the default handler
569 for other errors. */
570 ide_error(drive, "cdrom_decode_status", stat);
571 return 1;
572 } else if ((++rq->errors > ERROR_MAX)) {
573 /* We've racked up too many retries. Abort. */
574 do_end_request = 1;
575 }
576
Alan Coxdbe217a2006-06-25 05:47:44 -0700577 /* End a request through request sense analysis when we have
578 sense data. We need this in order to perform end of media
579 processing */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700580
Alan Coxdbe217a2006-06-25 05:47:44 -0700581 if (do_end_request) {
582 if (stat & ERR_STAT) {
583 unsigned long flags;
584 spin_lock_irqsave(&ide_lock, flags);
585 blkdev_dequeue_request(rq);
586 HWGROUP(drive)->rq = NULL;
587 spin_unlock_irqrestore(&ide_lock, flags);
588
589 cdrom_queue_request_sense(drive, rq->sense, rq);
590 } else
591 cdrom_end_request(drive, 0);
592 } else {
593 /* If we got a CHECK_CONDITION status,
594 queue a request sense command. */
595 if (stat & ERR_STAT)
596 cdrom_queue_request_sense(drive, NULL, NULL);
597 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700598 } else {
599 blk_dump_rq_flags(rq, "ide-cd: bad rq");
600 cdrom_end_request(drive, 0);
601 }
602
603 /* Retry, or handle the next request. */
604 return 1;
605}
606
607static int cdrom_timer_expiry(ide_drive_t *drive)
608{
609 struct request *rq = HWGROUP(drive)->rq;
610 unsigned long wait = 0;
611
612 /*
613 * Some commands are *slow* and normally take a long time to
614 * complete. Usually we can use the ATAPI "disconnect" to bypass
615 * this, but not all commands/drives support that. Let
616 * ide_timer_expiry keep polling us for these.
617 */
618 switch (rq->cmd[0]) {
619 case GPCMD_BLANK:
620 case GPCMD_FORMAT_UNIT:
621 case GPCMD_RESERVE_RZONE_TRACK:
622 case GPCMD_CLOSE_TRACK:
623 case GPCMD_FLUSH_CACHE:
624 wait = ATAPI_WAIT_PC;
625 break;
626 default:
Jens Axboe4aff5e22006-08-10 08:44:47 +0200627 if (!(rq->cmd_flags & REQ_QUIET))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700628 printk(KERN_INFO "ide-cd: cmd 0x%x timed out\n", rq->cmd[0]);
629 wait = 0;
630 break;
631 }
632 return wait;
633}
634
635/* Set up the device registers for transferring a packet command on DEV,
636 expecting to later transfer XFERLEN bytes. HANDLER is the routine
637 which actually transfers the command to the drive. If this is a
638 drq_interrupt device, this routine will arrange for HANDLER to be
639 called when the interrupt from the drive arrives. Otherwise, HANDLER
640 will be called immediately after the drive is prepared for the transfer. */
641
642static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive,
643 int xferlen,
644 ide_handler_t *handler)
645{
646 ide_startstop_t startstop;
647 struct cdrom_info *info = drive->driver_data;
648 ide_hwif_t *hwif = drive->hwif;
649
650 /* Wait for the controller to be idle. */
651 if (ide_wait_stat(&startstop, drive, 0, BUSY_STAT, WAIT_READY))
652 return startstop;
653
Bartlomiej Zolnierkiewicz3a6a3542008-01-25 22:17:13 +0100654 /* FIXME: for Virtual DMA we must check harder */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700655 if (info->dma)
656 info->dma = !hwif->dma_setup(drive);
657
658 /* Set up the controller registers. */
Bartlomiej Zolnierkiewicz2fc57382008-01-25 22:17:13 +0100659 ide_pktcmd_tf_load(drive, IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL |
660 IDE_TFLAG_NO_SELECT_MASK, xferlen, info->dma);
Bartlomiej Zolnierkiewicz4fe67172008-02-01 23:09:21 +0100661
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +0100662 if (info->cd_flags & IDE_CD_FLAG_DRQ_INTERRUPT) {
Albert Leef0dd8712007-02-17 02:40:21 +0100663 /* waiting for CDB interrupt, not DMA yet. */
664 if (info->dma)
665 drive->waiting_for_dma = 0;
666
Linus Torvalds1da177e2005-04-16 15:20:36 -0700667 /* packet command */
668 ide_execute_command(drive, WIN_PACKETCMD, handler, ATAPI_WAIT_PC, cdrom_timer_expiry);
669 return ide_started;
670 } else {
671 unsigned long flags;
672
673 /* packet command */
674 spin_lock_irqsave(&ide_lock, flags);
675 hwif->OUTBSYNC(drive, WIN_PACKETCMD, IDE_COMMAND_REG);
676 ndelay(400);
677 spin_unlock_irqrestore(&ide_lock, flags);
678
679 return (*handler) (drive);
680 }
681}
682
683/* Send a packet command to DRIVE described by CMD_BUF and CMD_LEN.
684 The device registers must have already been prepared
685 by cdrom_start_packet_command.
686 HANDLER is the interrupt handler to call when the command completes
687 or there's data ready. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700688#define ATAPI_MIN_CDB_BYTES 12
689static ide_startstop_t cdrom_transfer_packet_command (ide_drive_t *drive,
690 struct request *rq,
691 ide_handler_t *handler)
692{
693 ide_hwif_t *hwif = drive->hwif;
694 int cmd_len;
695 struct cdrom_info *info = drive->driver_data;
696 ide_startstop_t startstop;
697
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +0100698 if (info->cd_flags & IDE_CD_FLAG_DRQ_INTERRUPT) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700699 /* Here we should have been called after receiving an interrupt
700 from the device. DRQ should how be set. */
701
702 /* Check for errors. */
703 if (cdrom_decode_status(drive, DRQ_STAT, NULL))
704 return ide_stopped;
Albert Leef0dd8712007-02-17 02:40:21 +0100705
706 /* Ok, next interrupt will be DMA interrupt. */
707 if (info->dma)
708 drive->waiting_for_dma = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700709 } else {
710 /* Otherwise, we must wait for DRQ to get set. */
711 if (ide_wait_stat(&startstop, drive, DRQ_STAT,
712 BUSY_STAT, WAIT_READY))
713 return startstop;
714 }
715
716 /* Arm the interrupt handler. */
717 ide_set_handler(drive, handler, rq->timeout, cdrom_timer_expiry);
718
719 /* ATAPI commands get padded out to 12 bytes minimum */
720 cmd_len = COMMAND_SIZE(rq->cmd[0]);
721 if (cmd_len < ATAPI_MIN_CDB_BYTES)
722 cmd_len = ATAPI_MIN_CDB_BYTES;
723
724 /* Send the command to the device. */
725 HWIF(drive)->atapi_output_bytes(drive, rq->cmd, cmd_len);
726
727 /* Start the DMA if need be */
728 if (info->dma)
729 hwif->dma_start(drive);
730
731 return ide_started;
732}
733
734/****************************************************************************
735 * Block read functions.
736 */
737
Bartlomiej Zolnierkiewicz68661c52008-02-01 23:09:17 +0100738typedef void (xfer_func_t)(ide_drive_t *, void *, u32);
739
Bartlomiej Zolnierkiewicz5a5222d2008-02-01 23:09:17 +0100740static void ide_cd_pad_transfer(ide_drive_t *drive, xfer_func_t *xf, int len)
741{
742 while (len > 0) {
743 int dum = 0;
744 xf(drive, &dum, sizeof(dum));
745 len -= sizeof(dum);
746 }
747}
748
Linus Torvalds1da177e2005-04-16 15:20:36 -0700749/*
750 * Buffer up to SECTORS_TO_TRANSFER sectors from the drive in our sector
751 * buffer. Once the first sector is added, any subsequent sectors are
752 * assumed to be continuous (until the buffer is cleared). For the first
753 * sector added, SECTOR is its sector number. (SECTOR is then ignored until
754 * the buffer is cleared.)
755 */
756static void cdrom_buffer_sectors (ide_drive_t *drive, unsigned long sector,
757 int sectors_to_transfer)
758{
759 struct cdrom_info *info = drive->driver_data;
760
761 /* Number of sectors to read into the buffer. */
762 int sectors_to_buffer = min_t(int, sectors_to_transfer,
763 (SECTOR_BUFFER_SIZE >> SECTOR_BITS) -
764 info->nsectors_buffered);
765
766 char *dest;
767
768 /* If we couldn't get a buffer, don't try to buffer anything... */
769 if (info->buffer == NULL)
770 sectors_to_buffer = 0;
771
772 /* If this is the first sector in the buffer, remember its number. */
773 if (info->nsectors_buffered == 0)
774 info->sector_buffered = sector;
775
776 /* Read the data into the buffer. */
777 dest = info->buffer + info->nsectors_buffered * SECTOR_SIZE;
778 while (sectors_to_buffer > 0) {
779 HWIF(drive)->atapi_input_bytes(drive, dest, SECTOR_SIZE);
780 --sectors_to_buffer;
781 --sectors_to_transfer;
782 ++info->nsectors_buffered;
783 dest += SECTOR_SIZE;
784 }
785
786 /* Throw away any remaining data. */
787 while (sectors_to_transfer > 0) {
788 static char dum[SECTOR_SIZE];
789 HWIF(drive)->atapi_input_bytes(drive, dum, sizeof (dum));
790 --sectors_to_transfer;
791 }
792}
793
794/*
795 * Check the contents of the interrupt reason register from the cdrom
796 * and attempt to recover if there are problems. Returns 0 if everything's
797 * ok; nonzero if the request has been terminated.
798 */
Arjan van de Ven858119e2006-01-14 13:20:43 -0800799static
Linus Torvalds1da177e2005-04-16 15:20:36 -0700800int cdrom_read_check_ireason (ide_drive_t *drive, int len, int ireason)
801{
802 if (ireason == 2)
803 return 0;
804 else if (ireason == 0) {
Bartlomiej Zolnierkiewicz5a5222d2008-02-01 23:09:17 +0100805 ide_hwif_t *hwif = drive->hwif;
806
Linus Torvalds1da177e2005-04-16 15:20:36 -0700807 /* Whoops... The drive is expecting to receive data from us! */
Bartlomiej Zolnierkiewicz35379c02007-12-24 15:23:43 +0100808 printk(KERN_ERR "%s: %s: wrong transfer direction!\n",
809 drive->name, __FUNCTION__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700810
811 /* Throw some data at the drive so it doesn't hang
812 and quit this request. */
Bartlomiej Zolnierkiewicz5a5222d2008-02-01 23:09:17 +0100813 ide_cd_pad_transfer(drive, hwif->atapi_output_bytes, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700814 } else if (ireason == 1) {
815 /* Some drives (ASUS) seem to tell us that status
816 * info is available. just get it and ignore.
817 */
818 (void) HWIF(drive)->INB(IDE_STATUS_REG);
819 return 0;
820 } else {
821 /* Drive wants a command packet, or invalid ireason... */
Bartlomiej Zolnierkiewicz35379c02007-12-24 15:23:43 +0100822 printk(KERN_ERR "%s: %s: bad interrupt reason 0x%02x\n",
823 drive->name, __FUNCTION__, ireason);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700824 }
825
826 cdrom_end_request(drive, 0);
827 return -1;
828}
829
830/*
831 * Interrupt routine. Called when a read request has completed.
832 */
833static ide_startstop_t cdrom_read_intr (ide_drive_t *drive)
834{
835 int stat;
836 int ireason, len, sectors_to_transfer, nskip;
837 struct cdrom_info *info = drive->driver_data;
838 u8 lowcyl = 0, highcyl = 0;
839 int dma = info->dma, dma_error = 0;
840
841 struct request *rq = HWGROUP(drive)->rq;
842
843 /*
844 * handle dma case
845 */
846 if (dma) {
847 info->dma = 0;
Bartlomiej Zolnierkiewicz52ef2ed2007-12-24 15:23:43 +0100848 dma_error = HWIF(drive)->ide_dma_end(drive);
849 if (dma_error) {
850 printk(KERN_ERR "%s: DMA read error\n", drive->name);
Bartlomiej Zolnierkiewicz7469aaf2007-02-17 02:40:26 +0100851 ide_dma_off(drive);
Bartlomiej Zolnierkiewicz52ef2ed2007-12-24 15:23:43 +0100852 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700853 }
854
855 if (cdrom_decode_status(drive, 0, &stat))
856 return ide_stopped;
857
858 if (dma) {
859 if (!dma_error) {
860 ide_end_request(drive, 1, rq->nr_sectors);
861 return ide_stopped;
862 } else
863 return ide_error(drive, "dma error", stat);
864 }
865
866 /* Read the interrupt reason and the transfer length. */
867 ireason = HWIF(drive)->INB(IDE_IREASON_REG) & 0x3;
868 lowcyl = HWIF(drive)->INB(IDE_BCOUNTL_REG);
869 highcyl = HWIF(drive)->INB(IDE_BCOUNTH_REG);
870
871 len = lowcyl + (256 * highcyl);
872
873 /* If DRQ is clear, the command has completed. */
874 if ((stat & DRQ_STAT) == 0) {
875 /* If we're not done filling the current buffer, complain.
876 Otherwise, complete the command normally. */
877 if (rq->current_nr_sectors > 0) {
878 printk (KERN_ERR "%s: cdrom_read_intr: data underrun (%d blocks)\n",
879 drive->name, rq->current_nr_sectors);
Jens Axboe4aff5e22006-08-10 08:44:47 +0200880 rq->cmd_flags |= REQ_FAILED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700881 cdrom_end_request(drive, 0);
882 } else
883 cdrom_end_request(drive, 1);
884 return ide_stopped;
885 }
886
887 /* Check that the drive is expecting to do the same thing we are. */
888 if (cdrom_read_check_ireason (drive, len, ireason))
889 return ide_stopped;
890
891 /* Assume that the drive will always provide data in multiples
892 of at least SECTOR_SIZE, as it gets hairy to keep track
893 of the transfers otherwise. */
894 if ((len % SECTOR_SIZE) != 0) {
895 printk (KERN_ERR "%s: cdrom_read_intr: Bad transfer size %d\n",
896 drive->name, len);
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +0100897 if (info->cd_flags & IDE_CD_FLAG_LIMIT_NFRAMES)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700898 printk (KERN_ERR " This drive is not supported by this version of the driver\n");
899 else {
900 printk (KERN_ERR " Trying to limit transfer sizes\n");
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +0100901 info->cd_flags |= IDE_CD_FLAG_LIMIT_NFRAMES;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700902 }
903 cdrom_end_request(drive, 0);
904 return ide_stopped;
905 }
906
907 /* The number of sectors we need to read from the drive. */
908 sectors_to_transfer = len / SECTOR_SIZE;
909
910 /* First, figure out if we need to bit-bucket
911 any of the leading sectors. */
912 nskip = min_t(int, rq->current_nr_sectors - bio_cur_sectors(rq->bio), sectors_to_transfer);
913
914 while (nskip > 0) {
915 /* We need to throw away a sector. */
916 static char dum[SECTOR_SIZE];
917 HWIF(drive)->atapi_input_bytes(drive, dum, sizeof (dum));
918
919 --rq->current_nr_sectors;
920 --nskip;
921 --sectors_to_transfer;
922 }
923
924 /* Now loop while we still have data to read from the drive. */
925 while (sectors_to_transfer > 0) {
926 int this_transfer;
927
928 /* If we've filled the present buffer but there's another
929 chained buffer after it, move on. */
930 if (rq->current_nr_sectors == 0 && rq->nr_sectors)
931 cdrom_end_request(drive, 1);
932
933 /* If the buffers are full, cache the rest of the data in our
934 internal buffer. */
935 if (rq->current_nr_sectors == 0) {
936 cdrom_buffer_sectors(drive, rq->sector, sectors_to_transfer);
937 sectors_to_transfer = 0;
938 } else {
939 /* Transfer data to the buffers.
940 Figure out how many sectors we can transfer
941 to the current buffer. */
942 this_transfer = min_t(int, sectors_to_transfer,
943 rq->current_nr_sectors);
944
945 /* Read this_transfer sectors
946 into the current buffer. */
947 while (this_transfer > 0) {
948 HWIF(drive)->atapi_input_bytes(drive, rq->buffer, SECTOR_SIZE);
949 rq->buffer += SECTOR_SIZE;
950 --rq->nr_sectors;
951 --rq->current_nr_sectors;
952 ++rq->sector;
953 --this_transfer;
954 --sectors_to_transfer;
955 }
956 }
957 }
958
959 /* Done moving data! Wait for another interrupt. */
960 ide_set_handler(drive, &cdrom_read_intr, ATAPI_WAIT_PC, NULL);
961 return ide_started;
962}
963
964/*
965 * Try to satisfy some of the current read request from our cached data.
966 * Returns nonzero if the request has been completed, zero otherwise.
967 */
968static int cdrom_read_from_buffer (ide_drive_t *drive)
969{
970 struct cdrom_info *info = drive->driver_data;
971 struct request *rq = HWGROUP(drive)->rq;
972 unsigned short sectors_per_frame;
973
974 sectors_per_frame = queue_hardsect_size(drive->queue) >> SECTOR_BITS;
975
976 /* Can't do anything if there's no buffer. */
977 if (info->buffer == NULL) return 0;
978
979 /* Loop while this request needs data and the next block is present
980 in our cache. */
981 while (rq->nr_sectors > 0 &&
982 rq->sector >= info->sector_buffered &&
983 rq->sector < info->sector_buffered + info->nsectors_buffered) {
984 if (rq->current_nr_sectors == 0)
985 cdrom_end_request(drive, 1);
986
987 memcpy (rq->buffer,
988 info->buffer +
989 (rq->sector - info->sector_buffered) * SECTOR_SIZE,
990 SECTOR_SIZE);
991 rq->buffer += SECTOR_SIZE;
992 --rq->current_nr_sectors;
993 --rq->nr_sectors;
994 ++rq->sector;
995 }
996
997 /* If we've satisfied the current request,
998 terminate it successfully. */
999 if (rq->nr_sectors == 0) {
1000 cdrom_end_request(drive, 1);
1001 return -1;
1002 }
1003
1004 /* Move on to the next buffer if needed. */
1005 if (rq->current_nr_sectors == 0)
1006 cdrom_end_request(drive, 1);
1007
1008 /* If this condition does not hold, then the kluge i use to
1009 represent the number of sectors to skip at the start of a transfer
1010 will fail. I think that this will never happen, but let's be
1011 paranoid and check. */
1012 if (rq->current_nr_sectors < bio_cur_sectors(rq->bio) &&
1013 (rq->sector & (sectors_per_frame - 1))) {
1014 printk(KERN_ERR "%s: cdrom_read_from_buffer: buffer botch (%ld)\n",
1015 drive->name, (long)rq->sector);
1016 cdrom_end_request(drive, 0);
1017 return -1;
1018 }
1019
1020 return 0;
1021}
1022
1023/*
1024 * Routine to send a read packet command to the drive.
1025 * This is usually called directly from cdrom_start_read.
1026 * However, for drq_interrupt devices, it is called from an interrupt
1027 * when the drive is ready to accept the command.
1028 */
1029static ide_startstop_t cdrom_start_read_continuation (ide_drive_t *drive)
1030{
1031 struct request *rq = HWGROUP(drive)->rq;
1032 unsigned short sectors_per_frame;
1033 int nskip;
1034
1035 sectors_per_frame = queue_hardsect_size(drive->queue) >> SECTOR_BITS;
1036
1037 /* If the requested sector doesn't start on a cdrom block boundary,
1038 we must adjust the start of the transfer so that it does,
1039 and remember to skip the first few sectors.
1040 If the CURRENT_NR_SECTORS field is larger than the size
1041 of the buffer, it will mean that we're to skip a number
1042 of sectors equal to the amount by which CURRENT_NR_SECTORS
1043 is larger than the buffer size. */
1044 nskip = rq->sector & (sectors_per_frame - 1);
1045 if (nskip > 0) {
1046 /* Sanity check... */
1047 if (rq->current_nr_sectors != bio_cur_sectors(rq->bio) &&
1048 (rq->sector & (sectors_per_frame - 1))) {
1049 printk(KERN_ERR "%s: cdrom_start_read_continuation: buffer botch (%u)\n",
1050 drive->name, rq->current_nr_sectors);
1051 cdrom_end_request(drive, 0);
1052 return ide_stopped;
1053 }
1054 rq->current_nr_sectors += nskip;
1055 }
1056
1057 /* Set up the command */
1058 rq->timeout = ATAPI_WAIT_PC;
1059
1060 /* Send the command to the drive and return. */
1061 return cdrom_transfer_packet_command(drive, rq, &cdrom_read_intr);
1062}
1063
1064
1065#define IDECD_SEEK_THRESHOLD (1000) /* 1000 blocks */
1066#define IDECD_SEEK_TIMER (5 * WAIT_MIN_SLEEP) /* 100 ms */
1067#define IDECD_SEEK_TIMEOUT (2 * WAIT_CMD) /* 20 sec */
1068
1069static ide_startstop_t cdrom_seek_intr (ide_drive_t *drive)
1070{
1071 struct cdrom_info *info = drive->driver_data;
1072 int stat;
1073 static int retry = 10;
1074
1075 if (cdrom_decode_status(drive, 0, &stat))
1076 return ide_stopped;
Bartlomiej Zolnierkiewicz4fe67172008-02-01 23:09:21 +01001077
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01001078 info->cd_flags |= IDE_CD_FLAG_SEEKING;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001079
1080 if (retry && time_after(jiffies, info->start_seek + IDECD_SEEK_TIMER)) {
1081 if (--retry == 0) {
1082 /*
1083 * this condition is far too common, to bother
1084 * users about it
1085 */
1086 /* printk("%s: disabled DSC seek overlap\n", drive->name);*/
1087 drive->dsc_overlap = 0;
1088 }
1089 }
1090 return ide_stopped;
1091}
1092
1093static ide_startstop_t cdrom_start_seek_continuation (ide_drive_t *drive)
1094{
1095 struct request *rq = HWGROUP(drive)->rq;
1096 sector_t frame = rq->sector;
1097
1098 sector_div(frame, queue_hardsect_size(drive->queue) >> SECTOR_BITS);
1099
1100 memset(rq->cmd, 0, sizeof(rq->cmd));
1101 rq->cmd[0] = GPCMD_SEEK;
1102 put_unaligned(cpu_to_be32(frame), (unsigned int *) &rq->cmd[2]);
1103
1104 rq->timeout = ATAPI_WAIT_PC;
1105 return cdrom_transfer_packet_command(drive, rq, &cdrom_seek_intr);
1106}
1107
1108static ide_startstop_t cdrom_start_seek (ide_drive_t *drive, unsigned int block)
1109{
1110 struct cdrom_info *info = drive->driver_data;
1111
1112 info->dma = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001113 info->start_seek = jiffies;
1114 return cdrom_start_packet_command(drive, 0, cdrom_start_seek_continuation);
1115}
1116
1117/* Fix up a possibly partially-processed request so that we can
1118 start it over entirely, or even put it back on the request queue. */
1119static void restore_request (struct request *rq)
1120{
1121 if (rq->buffer != bio_data(rq->bio)) {
1122 sector_t n = (rq->buffer - (char *) bio_data(rq->bio)) / SECTOR_SIZE;
1123
1124 rq->buffer = bio_data(rq->bio);
1125 rq->nr_sectors += n;
1126 rq->sector -= n;
1127 }
1128 rq->hard_cur_sectors = rq->current_nr_sectors = bio_cur_sectors(rq->bio);
1129 rq->hard_nr_sectors = rq->nr_sectors;
1130 rq->hard_sector = rq->sector;
1131 rq->q->prep_rq_fn(rq->q, rq);
1132}
1133
1134/*
1135 * Start a read request from the CD-ROM.
1136 */
1137static ide_startstop_t cdrom_start_read (ide_drive_t *drive, unsigned int block)
1138{
1139 struct cdrom_info *info = drive->driver_data;
1140 struct request *rq = HWGROUP(drive)->rq;
1141 unsigned short sectors_per_frame;
1142
1143 sectors_per_frame = queue_hardsect_size(drive->queue) >> SECTOR_BITS;
1144
1145 /* We may be retrying this request after an error. Fix up
1146 any weirdness which might be present in the request packet. */
1147 restore_request(rq);
1148
1149 /* Satisfy whatever we can of this request from our cached sector. */
1150 if (cdrom_read_from_buffer(drive))
1151 return ide_stopped;
1152
Linus Torvalds1da177e2005-04-16 15:20:36 -07001153 /* Clear the local sector buffer. */
1154 info->nsectors_buffered = 0;
1155
1156 /* use dma, if possible. */
1157 info->dma = drive->using_dma;
1158 if ((rq->sector & (sectors_per_frame - 1)) ||
1159 (rq->nr_sectors & (sectors_per_frame - 1)))
1160 info->dma = 0;
1161
Linus Torvalds1da177e2005-04-16 15:20:36 -07001162 /* Start sending the read request to the drive. */
1163 return cdrom_start_packet_command(drive, 32768, cdrom_start_read_continuation);
1164}
1165
1166/****************************************************************************
1167 * Execute all other packet commands.
1168 */
1169
1170/* Interrupt routine for packet command completion. */
1171static ide_startstop_t cdrom_pc_intr (ide_drive_t *drive)
1172{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001173 struct request *rq = HWGROUP(drive)->rq;
Bartlomiej Zolnierkiewicz68661c52008-02-01 23:09:17 +01001174 xfer_func_t *xferfunc = NULL;
1175 int stat, ireason, len, thislen, write;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001176 u8 lowcyl = 0, highcyl = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001177
1178 /* Check for errors. */
1179 if (cdrom_decode_status(drive, 0, &stat))
1180 return ide_stopped;
1181
1182 /* Read the interrupt reason and the transfer length. */
Bartlomiej Zolnierkiewicz8606ab02007-12-24 15:23:44 +01001183 ireason = HWIF(drive)->INB(IDE_IREASON_REG) & 0x3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001184 lowcyl = HWIF(drive)->INB(IDE_BCOUNTL_REG);
1185 highcyl = HWIF(drive)->INB(IDE_BCOUNTH_REG);
1186
1187 len = lowcyl + (256 * highcyl);
1188
1189 /* If DRQ is clear, the command has completed.
1190 Complain if we still have data left to transfer. */
1191 if ((stat & DRQ_STAT) == 0) {
1192 /* Some of the trailing request sense fields are optional, and
1193 some drives don't send them. Sigh. */
1194 if (rq->cmd[0] == GPCMD_REQUEST_SENSE &&
1195 rq->data_len > 0 &&
1196 rq->data_len <= 5) {
1197 while (rq->data_len > 0) {
1198 *(unsigned char *)rq->data++ = 0;
1199 --rq->data_len;
1200 }
1201 }
1202
1203 if (rq->data_len == 0)
1204 cdrom_end_request(drive, 1);
1205 else {
Jens Axboe4aff5e22006-08-10 08:44:47 +02001206 rq->cmd_flags |= REQ_FAILED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001207 cdrom_end_request(drive, 0);
1208 }
1209 return ide_stopped;
1210 }
1211
1212 /* Figure out how much data to transfer. */
1213 thislen = rq->data_len;
Bartlomiej Zolnierkiewicz68661c52008-02-01 23:09:17 +01001214 if (thislen > len)
1215 thislen = len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001216
Bartlomiej Zolnierkiewicz8606ab02007-12-24 15:23:44 +01001217 if (ireason == 0) {
Bartlomiej Zolnierkiewicz68661c52008-02-01 23:09:17 +01001218 write = 1;
1219 xferfunc = HWIF(drive)->atapi_output_bytes;
1220 } else if (ireason == 2) {
1221 write = 0;
1222 xferfunc = HWIF(drive)->atapi_input_bytes;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001223 }
1224
Bartlomiej Zolnierkiewicz68661c52008-02-01 23:09:17 +01001225 if (xferfunc) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001226 if (!rq->data) {
Bartlomiej Zolnierkiewiczf1071e62008-02-01 23:09:17 +01001227 printk(KERN_ERR "%s: confused, missing data\n",
1228 drive->name);
Bartlomiej Zolnierkiewicz68661c52008-02-01 23:09:17 +01001229 blk_dump_rq_flags(rq, write ? "cdrom_pc_intr, write"
1230 : "cdrom_pc_intr, read");
Bartlomiej Zolnierkiewiczf1071e62008-02-01 23:09:17 +01001231 goto pad;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001232 }
1233 /* Transfer the data. */
Bartlomiej Zolnierkiewicz68661c52008-02-01 23:09:17 +01001234 xferfunc(drive, rq->data, thislen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001235
Linus Torvalds1da177e2005-04-16 15:20:36 -07001236 /* Keep count of how much data we've moved. */
Bartlomiej Zolnierkiewicz5a5222d2008-02-01 23:09:17 +01001237 len -= thislen;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001238 rq->data += thislen;
1239 rq->data_len -= thislen;
1240
Bartlomiej Zolnierkiewicz68661c52008-02-01 23:09:17 +01001241 if (write && blk_sense_request(rq))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001242 rq->sense_len += thislen;
1243 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001244 printk (KERN_ERR "%s: cdrom_pc_intr: The drive "
Rachita Kothiyal1ad55442006-06-23 02:02:56 -07001245 "appears confused (ireason = 0x%02x). "
1246 "Trying to recover by ending request.\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001247 drive->name, ireason);
Jens Axboe4aff5e22006-08-10 08:44:47 +02001248 rq->cmd_flags |= REQ_FAILED;
Rachita Kothiyal1ad55442006-06-23 02:02:56 -07001249 cdrom_end_request(drive, 0);
1250 return ide_stopped;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001251 }
Bartlomiej Zolnierkiewiczf1071e62008-02-01 23:09:17 +01001252pad:
Bartlomiej Zolnierkiewicz5a5222d2008-02-01 23:09:17 +01001253 /*
1254 * If we haven't moved enough data to satisfy the drive,
1255 * add some padding.
1256 */
1257 if (len > 0)
1258 ide_cd_pad_transfer(drive, xferfunc, len);
1259
Linus Torvalds1da177e2005-04-16 15:20:36 -07001260 /* Now we wait for another interrupt. */
1261 ide_set_handler(drive, &cdrom_pc_intr, ATAPI_WAIT_PC, cdrom_timer_expiry);
1262 return ide_started;
1263}
1264
1265static ide_startstop_t cdrom_do_pc_continuation (ide_drive_t *drive)
1266{
1267 struct request *rq = HWGROUP(drive)->rq;
1268
1269 if (!rq->timeout)
1270 rq->timeout = ATAPI_WAIT_PC;
1271
1272 /* Send the command to the drive and return. */
1273 return cdrom_transfer_packet_command(drive, rq, &cdrom_pc_intr);
1274}
1275
1276
1277static ide_startstop_t cdrom_do_packet_command (ide_drive_t *drive)
1278{
1279 int len;
1280 struct request *rq = HWGROUP(drive)->rq;
1281 struct cdrom_info *info = drive->driver_data;
1282
1283 info->dma = 0;
Jens Axboe4aff5e22006-08-10 08:44:47 +02001284 rq->cmd_flags &= ~REQ_FAILED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001285 len = rq->data_len;
1286
1287 /* Start sending the command to the drive. */
1288 return cdrom_start_packet_command(drive, len, cdrom_do_pc_continuation);
1289}
1290
1291
Alan Coxdbe217a2006-06-25 05:47:44 -07001292static int cdrom_queue_packet_command(ide_drive_t *drive, struct request *rq)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001293{
1294 struct request_sense sense;
1295 int retries = 10;
Jens Axboe4aff5e22006-08-10 08:44:47 +02001296 unsigned int flags = rq->cmd_flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001297
1298 if (rq->sense == NULL)
1299 rq->sense = &sense;
1300
1301 /* Start of retry loop. */
1302 do {
1303 int error;
1304 unsigned long time = jiffies;
Jens Axboe4aff5e22006-08-10 08:44:47 +02001305 rq->cmd_flags = flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001306
1307 error = ide_do_drive_cmd(drive, rq, ide_wait);
1308 time = jiffies - time;
1309
1310 /* FIXME: we should probably abort/retry or something
1311 * in case of failure */
Jens Axboe4aff5e22006-08-10 08:44:47 +02001312 if (rq->cmd_flags & REQ_FAILED) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001313 /* The request failed. Retry if it was due to a unit
1314 attention status
1315 (usually means media was changed). */
1316 struct request_sense *reqbuf = rq->sense;
1317
1318 if (reqbuf->sense_key == UNIT_ATTENTION)
1319 cdrom_saw_media_change(drive);
1320 else if (reqbuf->sense_key == NOT_READY &&
1321 reqbuf->asc == 4 && reqbuf->ascq != 4) {
1322 /* The drive is in the process of loading
1323 a disk. Retry, but wait a little to give
1324 the drive time to complete the load. */
1325 ssleep(2);
1326 } else {
1327 /* Otherwise, don't retry. */
1328 retries = 0;
1329 }
1330 --retries;
1331 }
1332
1333 /* End of retry loop. */
Jens Axboe4aff5e22006-08-10 08:44:47 +02001334 } while ((rq->cmd_flags & REQ_FAILED) && retries >= 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001335
1336 /* Return an error if the command failed. */
Jens Axboe4aff5e22006-08-10 08:44:47 +02001337 return (rq->cmd_flags & REQ_FAILED) ? -EIO : 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001338}
1339
1340/*
1341 * Write handling
1342 */
Arjan van de Ven858119e2006-01-14 13:20:43 -08001343static int cdrom_write_check_ireason(ide_drive_t *drive, int len, int ireason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001344{
1345 /* Two notes about IDE interrupt reason here - 0 means that
1346 * the drive wants to receive data from us, 2 means that
1347 * the drive is expecting to transfer data to us.
1348 */
1349 if (ireason == 0)
1350 return 0;
1351 else if (ireason == 2) {
Bartlomiej Zolnierkiewicz5a5222d2008-02-01 23:09:17 +01001352 ide_hwif_t *hwif = drive->hwif;
1353
Linus Torvalds1da177e2005-04-16 15:20:36 -07001354 /* Whoops... The drive wants to send data. */
Bartlomiej Zolnierkiewicz35379c02007-12-24 15:23:43 +01001355 printk(KERN_ERR "%s: %s: wrong transfer direction!\n",
1356 drive->name, __FUNCTION__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001357
Bartlomiej Zolnierkiewicz5a5222d2008-02-01 23:09:17 +01001358 ide_cd_pad_transfer(drive, hwif->atapi_input_bytes, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001359 } else {
1360 /* Drive wants a command packet, or invalid ireason... */
Bartlomiej Zolnierkiewicz35379c02007-12-24 15:23:43 +01001361 printk(KERN_ERR "%s: %s: bad interrupt reason 0x%02x\n",
1362 drive->name, __FUNCTION__, ireason);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001363 }
1364
1365 cdrom_end_request(drive, 0);
1366 return 1;
1367}
1368
Kiyoshi Uedaaaa04c22007-12-11 17:51:23 -05001369/*
1370 * Called from blk_end_request_callback() after the data of the request
1371 * is completed and before the request is completed.
1372 * By returning value '1', blk_end_request_callback() returns immediately
1373 * without completing the request.
1374 */
1375static int cdrom_newpc_intr_dummy_cb(struct request *rq)
1376{
1377 return 1;
1378}
1379
Linus Torvalds1da177e2005-04-16 15:20:36 -07001380/*
1381 * best way to deal with dma that is not sector aligned right now... note
1382 * that in this path we are not using ->data or ->buffer at all. this irs
1383 * can replace cdrom_pc_intr, cdrom_read_intr, and cdrom_write_intr in the
1384 * future.
1385 */
1386static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
1387{
1388 struct cdrom_info *info = drive->driver_data;
1389 struct request *rq = HWGROUP(drive)->rq;
1390 int dma_error, dma, stat, ireason, len, thislen;
1391 u8 lowcyl, highcyl;
1392 xfer_func_t *xferfunc;
1393 unsigned long flags;
1394
1395 /* Check for errors. */
1396 dma_error = 0;
1397 dma = info->dma;
1398 if (dma) {
1399 info->dma = 0;
1400 dma_error = HWIF(drive)->ide_dma_end(drive);
Bartlomiej Zolnierkiewiczeba15fb2008-02-01 23:09:17 +01001401 if (dma_error) {
1402 printk(KERN_ERR "%s: DMA %s error\n", drive->name,
1403 rq_data_dir(rq) ? "write" : "read");
1404 ide_dma_off(drive);
1405 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001406 }
1407
1408 if (cdrom_decode_status(drive, 0, &stat))
1409 return ide_stopped;
1410
1411 /*
1412 * using dma, transfer is complete now
1413 */
1414 if (dma) {
Bartlomiej Zolnierkiewiczeba15fb2008-02-01 23:09:17 +01001415 if (dma_error)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001416 return ide_error(drive, "dma error", stat);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001417
Kiyoshi Uedaaaa04c22007-12-11 17:51:23 -05001418 spin_lock_irqsave(&ide_lock, flags);
1419 if (__blk_end_request(rq, 0, rq->data_len))
1420 BUG();
1421 HWGROUP(drive)->rq = NULL;
1422 spin_unlock_irqrestore(&ide_lock, flags);
1423
1424 return ide_stopped;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001425 }
1426
1427 /*
1428 * ok we fall to pio :/
1429 */
1430 ireason = HWIF(drive)->INB(IDE_IREASON_REG) & 0x3;
1431 lowcyl = HWIF(drive)->INB(IDE_BCOUNTL_REG);
1432 highcyl = HWIF(drive)->INB(IDE_BCOUNTH_REG);
1433
1434 len = lowcyl + (256 * highcyl);
1435 thislen = rq->data_len;
1436 if (thislen > len)
1437 thislen = len;
1438
1439 /*
1440 * If DRQ is clear, the command has completed.
1441 */
Kiyoshi Uedaaaa04c22007-12-11 17:51:23 -05001442 if ((stat & DRQ_STAT) == 0) {
1443 spin_lock_irqsave(&ide_lock, flags);
Jens Axboe4f4f6c252008-01-31 13:57:51 +01001444 if (__blk_end_request(rq, 0, rq->data_len))
Kiyoshi Uedaaaa04c22007-12-11 17:51:23 -05001445 BUG();
1446 HWGROUP(drive)->rq = NULL;
1447 spin_unlock_irqrestore(&ide_lock, flags);
1448
1449 return ide_stopped;
1450 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001451
1452 /*
1453 * check which way to transfer data
1454 */
1455 if (rq_data_dir(rq) == WRITE) {
1456 /*
1457 * write to drive
1458 */
1459 if (cdrom_write_check_ireason(drive, len, ireason))
1460 return ide_stopped;
1461
1462 xferfunc = HWIF(drive)->atapi_output_bytes;
1463 } else {
1464 /*
1465 * read from drive
1466 */
1467 if (cdrom_read_check_ireason(drive, len, ireason))
1468 return ide_stopped;
1469
1470 xferfunc = HWIF(drive)->atapi_input_bytes;
1471 }
1472
1473 /*
1474 * transfer data
1475 */
1476 while (thislen > 0) {
1477 int blen = blen = rq->data_len;
1478 char *ptr = rq->data;
1479
1480 /*
1481 * bio backed?
1482 */
1483 if (rq->bio) {
1484 ptr = bio_data(rq->bio);
1485 blen = bio_iovec(rq->bio)->bv_len;
1486 }
1487
1488 if (!ptr) {
1489 printk(KERN_ERR "%s: confused, missing data\n", drive->name);
1490 break;
1491 }
1492
1493 if (blen > thislen)
1494 blen = thislen;
1495
1496 xferfunc(drive, ptr, blen);
1497
1498 thislen -= blen;
1499 len -= blen;
1500 rq->data_len -= blen;
1501
1502 if (rq->bio)
Kiyoshi Uedaaaa04c22007-12-11 17:51:23 -05001503 /*
1504 * The request can't be completed until DRQ is cleared.
1505 * So complete the data, but don't complete the request
1506 * using the dummy function for the callback feature
1507 * of blk_end_request_callback().
1508 */
1509 blk_end_request_callback(rq, 0, blen,
1510 cdrom_newpc_intr_dummy_cb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001511 else
1512 rq->data += blen;
1513 }
1514
1515 /*
1516 * pad, if necessary
1517 */
Bartlomiej Zolnierkiewicz5a5222d2008-02-01 23:09:17 +01001518 if (len > 0)
1519 ide_cd_pad_transfer(drive, xferfunc, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001520
Eric Sesterhenn125e1872006-06-23 02:06:06 -07001521 BUG_ON(HWGROUP(drive)->handler != NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001522
1523 ide_set_handler(drive, cdrom_newpc_intr, rq->timeout, NULL);
1524 return ide_started;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001525}
1526
1527static ide_startstop_t cdrom_write_intr(ide_drive_t *drive)
1528{
1529 int stat, ireason, len, sectors_to_transfer, uptodate;
1530 struct cdrom_info *info = drive->driver_data;
1531 int dma_error = 0, dma = info->dma;
1532 u8 lowcyl = 0, highcyl = 0;
1533
1534 struct request *rq = HWGROUP(drive)->rq;
1535
1536 /* Check for errors. */
1537 if (dma) {
1538 info->dma = 0;
Bartlomiej Zolnierkiewiczb481b232007-12-24 15:23:43 +01001539 dma_error = HWIF(drive)->ide_dma_end(drive);
1540 if (dma_error) {
1541 printk(KERN_ERR "%s: DMA write error\n", drive->name);
Bartlomiej Zolnierkiewicz7469aaf2007-02-17 02:40:26 +01001542 ide_dma_off(drive);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001543 }
1544 }
1545
1546 if (cdrom_decode_status(drive, 0, &stat))
1547 return ide_stopped;
1548
1549 /*
1550 * using dma, transfer is complete now
1551 */
1552 if (dma) {
1553 if (dma_error)
1554 return ide_error(drive, "dma error", stat);
1555
1556 ide_end_request(drive, 1, rq->nr_sectors);
1557 return ide_stopped;
1558 }
1559
1560 /* Read the interrupt reason and the transfer length. */
Bartlomiej Zolnierkiewicz31a71192007-12-24 15:23:43 +01001561 ireason = HWIF(drive)->INB(IDE_IREASON_REG) & 0x3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001562 lowcyl = HWIF(drive)->INB(IDE_BCOUNTL_REG);
1563 highcyl = HWIF(drive)->INB(IDE_BCOUNTH_REG);
1564
1565 len = lowcyl + (256 * highcyl);
1566
1567 /* If DRQ is clear, the command has completed. */
1568 if ((stat & DRQ_STAT) == 0) {
1569 /* If we're not done writing, complain.
1570 * Otherwise, complete the command normally.
1571 */
1572 uptodate = 1;
1573 if (rq->current_nr_sectors > 0) {
Bartlomiej Zolnierkiewiczb481b232007-12-24 15:23:43 +01001574 printk(KERN_ERR "%s: %s: data underrun (%d blocks)\n",
1575 drive->name, __FUNCTION__,
1576 rq->current_nr_sectors);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001577 uptodate = 0;
1578 }
1579 cdrom_end_request(drive, uptodate);
1580 return ide_stopped;
1581 }
1582
1583 /* Check that the drive is expecting to do the same thing we are. */
1584 if (cdrom_write_check_ireason(drive, len, ireason))
1585 return ide_stopped;
1586
1587 sectors_to_transfer = len / SECTOR_SIZE;
1588
1589 /*
1590 * now loop and write out the data
1591 */
1592 while (sectors_to_transfer > 0) {
1593 int this_transfer;
1594
1595 if (!rq->current_nr_sectors) {
Bartlomiej Zolnierkiewiczb481b232007-12-24 15:23:43 +01001596 printk(KERN_ERR "%s: %s: confused, missing data\n",
1597 drive->name, __FUNCTION__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001598 break;
1599 }
1600
1601 /*
1602 * Figure out how many sectors we can transfer
1603 */
1604 this_transfer = min_t(int, sectors_to_transfer, rq->current_nr_sectors);
1605
1606 while (this_transfer > 0) {
1607 HWIF(drive)->atapi_output_bytes(drive, rq->buffer, SECTOR_SIZE);
1608 rq->buffer += SECTOR_SIZE;
1609 --rq->nr_sectors;
1610 --rq->current_nr_sectors;
1611 ++rq->sector;
1612 --this_transfer;
1613 --sectors_to_transfer;
1614 }
1615
1616 /*
1617 * current buffer complete, move on
1618 */
1619 if (rq->current_nr_sectors == 0 && rq->nr_sectors)
1620 cdrom_end_request(drive, 1);
1621 }
1622
1623 /* re-arm handler */
1624 ide_set_handler(drive, &cdrom_write_intr, ATAPI_WAIT_PC, NULL);
1625 return ide_started;
1626}
1627
1628static ide_startstop_t cdrom_start_write_cont(ide_drive_t *drive)
1629{
1630 struct request *rq = HWGROUP(drive)->rq;
1631
1632#if 0 /* the immediate bit */
1633 rq->cmd[1] = 1 << 3;
1634#endif
1635 rq->timeout = ATAPI_WAIT_PC;
1636
1637 return cdrom_transfer_packet_command(drive, rq, cdrom_write_intr);
1638}
1639
1640static ide_startstop_t cdrom_start_write(ide_drive_t *drive, struct request *rq)
1641{
1642 struct cdrom_info *info = drive->driver_data;
1643 struct gendisk *g = info->disk;
1644 unsigned short sectors_per_frame = queue_hardsect_size(drive->queue) >> SECTOR_BITS;
1645
1646 /*
1647 * writes *must* be hardware frame aligned
1648 */
1649 if ((rq->nr_sectors & (sectors_per_frame - 1)) ||
1650 (rq->sector & (sectors_per_frame - 1))) {
1651 cdrom_end_request(drive, 0);
1652 return ide_stopped;
1653 }
1654
1655 /*
1656 * disk has become write protected
1657 */
1658 if (g->policy) {
1659 cdrom_end_request(drive, 0);
1660 return ide_stopped;
1661 }
1662
Linus Torvalds1da177e2005-04-16 15:20:36 -07001663 info->nsectors_buffered = 0;
1664
1665 /* use dma, if possible. we don't need to check more, since we
1666 * know that the transfer is always (at least!) frame aligned */
1667 info->dma = drive->using_dma ? 1 : 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001668
1669 info->devinfo.media_written = 1;
1670
1671 /* Start sending the write request to the drive. */
1672 return cdrom_start_packet_command(drive, 32768, cdrom_start_write_cont);
1673}
1674
1675static ide_startstop_t cdrom_do_newpc_cont(ide_drive_t *drive)
1676{
1677 struct request *rq = HWGROUP(drive)->rq;
1678
1679 if (!rq->timeout)
1680 rq->timeout = ATAPI_WAIT_PC;
1681
1682 return cdrom_transfer_packet_command(drive, rq, cdrom_newpc_intr);
1683}
1684
1685static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
1686{
1687 struct cdrom_info *info = drive->driver_data;
1688
Jens Axboe4aff5e22006-08-10 08:44:47 +02001689 rq->cmd_flags |= REQ_QUIET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001690
1691 info->dma = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001692
1693 /*
1694 * sg request
1695 */
1696 if (rq->bio) {
1697 int mask = drive->queue->dma_alignment;
1698 unsigned long addr = (unsigned long) page_address(bio_page(rq->bio));
1699
Linus Torvalds1da177e2005-04-16 15:20:36 -07001700 info->dma = drive->using_dma;
1701
1702 /*
1703 * check if dma is safe
Linus Torvalds5d9e4ea2005-05-27 07:36:17 -07001704 *
1705 * NOTE! The "len" and "addr" checks should possibly have
1706 * separate masks.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001707 */
Jens Axboe4e7c6812005-05-31 17:47:36 +02001708 if ((rq->data_len & 15) || (addr & mask))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001709 info->dma = 0;
1710 }
1711
1712 /* Start sending the command to the drive. */
1713 return cdrom_start_packet_command(drive, rq->data_len, cdrom_do_newpc_cont);
1714}
1715
1716/****************************************************************************
1717 * cdrom driver request routine.
1718 */
1719static ide_startstop_t
1720ide_do_rw_cdrom (ide_drive_t *drive, struct request *rq, sector_t block)
1721{
1722 ide_startstop_t action;
1723 struct cdrom_info *info = drive->driver_data;
1724
1725 if (blk_fs_request(rq)) {
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01001726 if (info->cd_flags & IDE_CD_FLAG_SEEKING) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001727 unsigned long elapsed = jiffies - info->start_seek;
1728 int stat = HWIF(drive)->INB(IDE_STATUS_REG);
1729
1730 if ((stat & SEEK_STAT) != SEEK_STAT) {
1731 if (elapsed < IDECD_SEEK_TIMEOUT) {
1732 ide_stall_queue(drive, IDECD_SEEK_TIMER);
1733 return ide_stopped;
1734 }
1735 printk (KERN_ERR "%s: DSC timeout\n", drive->name);
1736 }
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01001737 info->cd_flags &= ~IDE_CD_FLAG_SEEKING;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001738 }
1739 if ((rq_data_dir(rq) == READ) && IDE_LARGE_SEEK(info->last_block, block, IDECD_SEEK_THRESHOLD) && drive->dsc_overlap) {
1740 action = cdrom_start_seek(drive, block);
1741 } else {
1742 if (rq_data_dir(rq) == READ)
1743 action = cdrom_start_read(drive, block);
1744 else
1745 action = cdrom_start_write(drive, rq);
1746 }
1747 info->last_block = block;
1748 return action;
Jens Axboecea28852006-10-12 15:08:45 +02001749 } else if (rq->cmd_type == REQ_TYPE_SENSE ||
1750 rq->cmd_type == REQ_TYPE_ATA_PC) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001751 return cdrom_do_packet_command(drive);
Jens Axboe4aff5e22006-08-10 08:44:47 +02001752 } else if (blk_pc_request(rq)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001753 return cdrom_do_block_pc(drive, rq);
Jens Axboe4aff5e22006-08-10 08:44:47 +02001754 } else if (blk_special_request(rq)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001755 /*
1756 * right now this can only be a reset...
1757 */
1758 cdrom_end_request(drive, 1);
1759 return ide_stopped;
1760 }
1761
1762 blk_dump_rq_flags(rq, "ide-cd bad flags");
1763 cdrom_end_request(drive, 0);
1764 return ide_stopped;
1765}
1766
1767
1768
1769/****************************************************************************
1770 * Ioctl handling.
1771 *
1772 * Routines which queue packet commands take as a final argument a pointer
1773 * to a request_sense struct. If execution of the command results
1774 * in an error with a CHECK CONDITION status, this structure will be filled
1775 * with the results of the subsequent request sense command. The pointer
1776 * can also be NULL, in which case no sense information is returned.
1777 */
1778
Linus Torvalds1da177e2005-04-16 15:20:36 -07001779static
1780void msf_from_bcd (struct atapi_msf *msf)
1781{
Bartlomiej Zolnierkiewicz9a6dc662008-02-01 23:09:22 +01001782 msf->minute = BCD2BIN(msf->minute);
1783 msf->second = BCD2BIN(msf->second);
1784 msf->frame = BCD2BIN(msf->frame);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001785}
1786
Linus Torvalds1da177e2005-04-16 15:20:36 -07001787static inline
1788void lba_to_msf (int lba, byte *m, byte *s, byte *f)
1789{
1790 lba += CD_MSF_OFFSET;
1791 lba &= 0xffffff; /* negative lbas use only 24 bits */
1792 *m = lba / (CD_SECS * CD_FRAMES);
1793 lba %= (CD_SECS * CD_FRAMES);
1794 *s = lba / CD_FRAMES;
1795 *f = lba % CD_FRAMES;
1796}
1797
1798
1799static inline
1800int msf_to_lba (byte m, byte s, byte f)
1801{
1802 return (((m * CD_SECS) + s) * CD_FRAMES + f) - CD_MSF_OFFSET;
1803}
1804
1805static int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense)
1806{
1807 struct request req;
1808 struct cdrom_info *info = drive->driver_data;
1809 struct cdrom_device_info *cdi = &info->devinfo;
1810
1811 cdrom_prepare_request(drive, &req);
1812
1813 req.sense = sense;
1814 req.cmd[0] = GPCMD_TEST_UNIT_READY;
Jens Axboe4aff5e22006-08-10 08:44:47 +02001815 req.cmd_flags |= REQ_QUIET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001816
Bartlomiej Zolnierkiewiczcdf60002008-02-01 23:09:22 +01001817 /*
1818 * Sanyo 3 CD changer uses byte 7 of TEST_UNIT_READY to
1819 * switch CDs instead of supporting the LOAD_UNLOAD opcode.
1820 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001821 req.cmd[7] = cdi->sanyo_slot % 3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001822
1823 return cdrom_queue_packet_command(drive, &req);
1824}
1825
1826
1827/* Lock the door if LOCKFLAG is nonzero; unlock it otherwise. */
1828static int
1829cdrom_lockdoor(ide_drive_t *drive, int lockflag, struct request_sense *sense)
1830{
Bartlomiej Zolnierkiewicz4fe67172008-02-01 23:09:21 +01001831 struct cdrom_info *cd = drive->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001832 struct request_sense my_sense;
1833 struct request req;
1834 int stat;
1835
1836 if (sense == NULL)
1837 sense = &my_sense;
1838
1839 /* If the drive cannot lock the door, just pretend. */
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01001840 if (cd->cd_flags & IDE_CD_FLAG_NO_DOORLOCK) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001841 stat = 0;
1842 } else {
1843 cdrom_prepare_request(drive, &req);
1844 req.sense = sense;
1845 req.cmd[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL;
1846 req.cmd[4] = lockflag ? 1 : 0;
1847 stat = cdrom_queue_packet_command(drive, &req);
1848 }
1849
1850 /* If we got an illegal field error, the drive
1851 probably cannot lock the door. */
1852 if (stat != 0 &&
1853 sense->sense_key == ILLEGAL_REQUEST &&
1854 (sense->asc == 0x24 || sense->asc == 0x20)) {
1855 printk (KERN_ERR "%s: door locking not supported\n",
1856 drive->name);
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01001857 cd->cd_flags |= IDE_CD_FLAG_NO_DOORLOCK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001858 stat = 0;
1859 }
1860
1861 /* no medium, that's alright. */
1862 if (stat != 0 && sense->sense_key == NOT_READY && sense->asc == 0x3a)
1863 stat = 0;
1864
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01001865 if (stat == 0) {
1866 if (lockflag)
1867 cd->cd_flags |= IDE_CD_FLAG_DOOR_LOCKED;
1868 else
1869 cd->cd_flags &= ~IDE_CD_FLAG_DOOR_LOCKED;
1870 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001871
1872 return stat;
1873}
1874
1875
1876/* Eject the disk if EJECTFLAG is 0.
1877 If EJECTFLAG is 1, try to reload the disk. */
1878static int cdrom_eject(ide_drive_t *drive, int ejectflag,
1879 struct request_sense *sense)
1880{
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01001881 struct cdrom_info *cd = drive->driver_data;
1882 struct cdrom_device_info *cdi = &cd->devinfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001883 struct request req;
1884 char loej = 0x02;
1885
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01001886 if ((cd->cd_flags & IDE_CD_FLAG_NO_EJECT) && !ejectflag)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001887 return -EDRIVE_CANT_DO_THIS;
Bartlomiej Zolnierkiewicz4fe67172008-02-01 23:09:21 +01001888
Linus Torvalds1da177e2005-04-16 15:20:36 -07001889 /* reload fails on some drives, if the tray is locked */
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01001890 if ((cd->cd_flags & IDE_CD_FLAG_DOOR_LOCKED) && ejectflag)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001891 return 0;
1892
1893 cdrom_prepare_request(drive, &req);
1894
1895 /* only tell drive to close tray if open, if it can do that */
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01001896 if (ejectflag && (cdi->mask & CDC_CLOSE_TRAY))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001897 loej = 0;
1898
1899 req.sense = sense;
1900 req.cmd[0] = GPCMD_START_STOP_UNIT;
1901 req.cmd[4] = loej | (ejectflag != 0);
1902 return cdrom_queue_packet_command(drive, &req);
1903}
1904
1905static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
1906 unsigned long *sectors_per_frame,
1907 struct request_sense *sense)
1908{
1909 struct {
1910 __u32 lba;
1911 __u32 blocklen;
1912 } capbuf;
1913
1914 int stat;
1915 struct request req;
1916
1917 cdrom_prepare_request(drive, &req);
1918
1919 req.sense = sense;
1920 req.cmd[0] = GPCMD_READ_CDVD_CAPACITY;
1921 req.data = (char *)&capbuf;
1922 req.data_len = sizeof(capbuf);
Jens Axboe4aff5e22006-08-10 08:44:47 +02001923 req.cmd_flags |= REQ_QUIET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001924
1925 stat = cdrom_queue_packet_command(drive, &req);
1926 if (stat == 0) {
1927 *capacity = 1 + be32_to_cpu(capbuf.lba);
1928 *sectors_per_frame =
1929 be32_to_cpu(capbuf.blocklen) >> SECTOR_BITS;
1930 }
1931
1932 return stat;
1933}
1934
1935static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag,
1936 int format, char *buf, int buflen,
1937 struct request_sense *sense)
1938{
1939 struct request req;
1940
1941 cdrom_prepare_request(drive, &req);
1942
1943 req.sense = sense;
1944 req.data = buf;
1945 req.data_len = buflen;
Jens Axboe4aff5e22006-08-10 08:44:47 +02001946 req.cmd_flags |= REQ_QUIET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001947 req.cmd[0] = GPCMD_READ_TOC_PMA_ATIP;
1948 req.cmd[6] = trackno;
1949 req.cmd[7] = (buflen >> 8);
1950 req.cmd[8] = (buflen & 0xff);
1951 req.cmd[9] = (format << 6);
1952
1953 if (msf_flag)
1954 req.cmd[1] = 2;
1955
1956 return cdrom_queue_packet_command(drive, &req);
1957}
1958
1959
1960/* Try to read the entire TOC for the disk into our internal buffer. */
1961static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense)
1962{
1963 int stat, ntracks, i;
1964 struct cdrom_info *info = drive->driver_data;
1965 struct cdrom_device_info *cdi = &info->devinfo;
1966 struct atapi_toc *toc = info->toc;
1967 struct {
1968 struct atapi_toc_header hdr;
1969 struct atapi_toc_entry ent;
1970 } ms_tmp;
1971 long last_written;
1972 unsigned long sectors_per_frame = SECTORS_PER_FRAME;
1973
1974 if (toc == NULL) {
1975 /* Try to allocate space. */
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08001976 toc = kmalloc(sizeof(struct atapi_toc), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001977 if (toc == NULL) {
1978 printk (KERN_ERR "%s: No cdrom TOC buffer!\n", drive->name);
1979 return -ENOMEM;
1980 }
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08001981 info->toc = toc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001982 }
1983
1984 /* Check to see if the existing data is still valid.
1985 If it is, just return. */
1986 (void) cdrom_check_status(drive, sense);
1987
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01001988 if (info->cd_flags & IDE_CD_FLAG_TOC_VALID)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001989 return 0;
1990
1991 /* Try to get the total cdrom capacity and sector size. */
1992 stat = cdrom_read_capacity(drive, &toc->capacity, &sectors_per_frame,
1993 sense);
1994 if (stat)
1995 toc->capacity = 0x1fffff;
1996
1997 set_capacity(info->disk, toc->capacity * sectors_per_frame);
Alan Coxdbe217a2006-06-25 05:47:44 -07001998 /* Save a private copy of te TOC capacity for error handling */
1999 drive->probed_capacity = toc->capacity * sectors_per_frame;
2000
Linus Torvalds1da177e2005-04-16 15:20:36 -07002001 blk_queue_hardsect_size(drive->queue,
2002 sectors_per_frame << SECTOR_BITS);
2003
2004 /* First read just the header, so we know how long the TOC is. */
2005 stat = cdrom_read_tocentry(drive, 0, 1, 0, (char *) &toc->hdr,
2006 sizeof(struct atapi_toc_header), sense);
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002007 if (stat)
2008 return stat;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002009
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002010 if (info->cd_flags & IDE_CD_FLAG_TOCTRACKS_AS_BCD) {
Bartlomiej Zolnierkiewicz9a6dc662008-02-01 23:09:22 +01002011 toc->hdr.first_track = BCD2BIN(toc->hdr.first_track);
2012 toc->hdr.last_track = BCD2BIN(toc->hdr.last_track);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002013 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002014
2015 ntracks = toc->hdr.last_track - toc->hdr.first_track + 1;
2016 if (ntracks <= 0)
2017 return -EIO;
2018 if (ntracks > MAX_TRACKS)
2019 ntracks = MAX_TRACKS;
2020
2021 /* Now read the whole schmeer. */
2022 stat = cdrom_read_tocentry(drive, toc->hdr.first_track, 1, 0,
2023 (char *)&toc->hdr,
2024 sizeof(struct atapi_toc_header) +
2025 (ntracks + 1) *
2026 sizeof(struct atapi_toc_entry), sense);
2027
2028 if (stat && toc->hdr.first_track > 1) {
2029 /* Cds with CDI tracks only don't have any TOC entries,
2030 despite of this the returned values are
2031 first_track == last_track = number of CDI tracks + 1,
2032 so that this case is indistinguishable from the same
2033 layout plus an additional audio track.
2034 If we get an error for the regular case, we assume
2035 a CDI without additional audio tracks. In this case
2036 the readable TOC is empty (CDI tracks are not included)
Jan Engelhardt96de0e22007-10-19 23:21:04 +02002037 and only holds the Leadout entry. Heiko Eißfeldt */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002038 ntracks = 0;
2039 stat = cdrom_read_tocentry(drive, CDROM_LEADOUT, 1, 0,
2040 (char *)&toc->hdr,
2041 sizeof(struct atapi_toc_header) +
2042 (ntracks + 1) *
2043 sizeof(struct atapi_toc_entry),
2044 sense);
Bartlomiej Zolnierkiewiczcdf60002008-02-01 23:09:22 +01002045 if (stat)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002046 return stat;
Bartlomiej Zolnierkiewiczcdf60002008-02-01 23:09:22 +01002047
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002048 if (info->cd_flags & IDE_CD_FLAG_TOCTRACKS_AS_BCD) {
Bartlomiej Zolnierkiewicz9a6dc662008-02-01 23:09:22 +01002049 toc->hdr.first_track = (u8)BIN2BCD(CDROM_LEADOUT);
2050 toc->hdr.last_track = (u8)BIN2BCD(CDROM_LEADOUT);
Bartlomiej Zolnierkiewiczcdf60002008-02-01 23:09:22 +01002051 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002052 toc->hdr.first_track = CDROM_LEADOUT;
2053 toc->hdr.last_track = CDROM_LEADOUT;
2054 }
2055 }
2056
2057 if (stat)
2058 return stat;
2059
2060 toc->hdr.toc_length = ntohs (toc->hdr.toc_length);
2061
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002062 if (info->cd_flags & IDE_CD_FLAG_TOCTRACKS_AS_BCD) {
Bartlomiej Zolnierkiewicz9a6dc662008-02-01 23:09:22 +01002063 toc->hdr.first_track = BCD2BIN(toc->hdr.first_track);
2064 toc->hdr.last_track = BCD2BIN(toc->hdr.last_track);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002065 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002066
Bartlomiej Zolnierkiewiczcdf60002008-02-01 23:09:22 +01002067 for (i = 0; i <= ntracks; i++) {
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002068 if (info->cd_flags & IDE_CD_FLAG_TOCADDR_AS_BCD) {
2069 if (info->cd_flags & IDE_CD_FLAG_TOCTRACKS_AS_BCD)
Bartlomiej Zolnierkiewicz9a6dc662008-02-01 23:09:22 +01002070 toc->ent[i].track = BCD2BIN(toc->ent[i].track);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002071 msf_from_bcd(&toc->ent[i].addr.msf);
2072 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002073 toc->ent[i].addr.lba = msf_to_lba (toc->ent[i].addr.msf.minute,
2074 toc->ent[i].addr.msf.second,
2075 toc->ent[i].addr.msf.frame);
2076 }
2077
2078 /* Read the multisession information. */
2079 if (toc->hdr.first_track != CDROM_LEADOUT) {
2080 /* Read the multisession information. */
2081 stat = cdrom_read_tocentry(drive, 0, 0, 1, (char *)&ms_tmp,
2082 sizeof(ms_tmp), sense);
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002083 if (stat)
2084 return stat;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002085
2086 toc->last_session_lba = be32_to_cpu(ms_tmp.ent.addr.lba);
2087 } else {
2088 ms_tmp.hdr.first_track = ms_tmp.hdr.last_track = CDROM_LEADOUT;
2089 toc->last_session_lba = msf_to_lba(0, 2, 0); /* 0m 2s 0f */
2090 }
2091
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002092 if (info->cd_flags & IDE_CD_FLAG_TOCADDR_AS_BCD) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002093 /* Re-read multisession information using MSF format */
2094 stat = cdrom_read_tocentry(drive, 0, 1, 1, (char *)&ms_tmp,
2095 sizeof(ms_tmp), sense);
2096 if (stat)
2097 return stat;
2098
2099 msf_from_bcd (&ms_tmp.ent.addr.msf);
2100 toc->last_session_lba = msf_to_lba(ms_tmp.ent.addr.msf.minute,
2101 ms_tmp.ent.addr.msf.second,
2102 ms_tmp.ent.addr.msf.frame);
2103 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002104
2105 toc->xa_flag = (ms_tmp.hdr.first_track != ms_tmp.hdr.last_track);
2106
2107 /* Now try to get the total cdrom capacity. */
2108 stat = cdrom_get_last_written(cdi, &last_written);
2109 if (!stat && (last_written > toc->capacity)) {
2110 toc->capacity = last_written;
2111 set_capacity(info->disk, toc->capacity * sectors_per_frame);
Alan Coxdbe217a2006-06-25 05:47:44 -07002112 drive->probed_capacity = toc->capacity * sectors_per_frame;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002113 }
2114
2115 /* Remember that we've read this stuff. */
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002116 info->cd_flags |= IDE_CD_FLAG_TOC_VALID;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002117
2118 return 0;
2119}
2120
2121
2122static int cdrom_read_subchannel(ide_drive_t *drive, int format, char *buf,
2123 int buflen, struct request_sense *sense)
2124{
2125 struct request req;
2126
2127 cdrom_prepare_request(drive, &req);
2128
2129 req.sense = sense;
2130 req.data = buf;
2131 req.data_len = buflen;
2132 req.cmd[0] = GPCMD_READ_SUBCHANNEL;
2133 req.cmd[1] = 2; /* MSF addressing */
2134 req.cmd[2] = 0x40; /* request subQ data */
2135 req.cmd[3] = format;
2136 req.cmd[7] = (buflen >> 8);
2137 req.cmd[8] = (buflen & 0xff);
2138 return cdrom_queue_packet_command(drive, &req);
2139}
2140
2141/* ATAPI cdrom drives are free to select the speed you request or any slower
2142 rate :-( Requesting too fast a speed will _not_ produce an error. */
2143static int cdrom_select_speed(ide_drive_t *drive, int speed,
2144 struct request_sense *sense)
2145{
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002146 struct cdrom_info *cd = drive->driver_data;
2147 struct cdrom_device_info *cdi = &cd->devinfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002148 struct request req;
2149 cdrom_prepare_request(drive, &req);
2150
2151 req.sense = sense;
2152 if (speed == 0)
2153 speed = 0xffff; /* set to max */
2154 else
2155 speed *= 177; /* Nx to kbytes/s */
2156
2157 req.cmd[0] = GPCMD_SET_SPEED;
2158 /* Read Drive speed in kbytes/second MSB */
2159 req.cmd[2] = (speed >> 8) & 0xff;
2160 /* Read Drive speed in kbytes/second LSB */
2161 req.cmd[3] = speed & 0xff;
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002162 if ((cdi->mask & (CDC_CD_R | CDC_CD_RW | CDC_DVD_R)) !=
2163 (CDC_CD_R | CDC_CD_RW | CDC_DVD_R)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002164 /* Write Drive speed in kbytes/second MSB */
2165 req.cmd[4] = (speed >> 8) & 0xff;
2166 /* Write Drive speed in kbytes/second LSB */
2167 req.cmd[5] = speed & 0xff;
2168 }
2169
2170 return cdrom_queue_packet_command(drive, &req);
2171}
2172
2173static int cdrom_play_audio(ide_drive_t *drive, int lba_start, int lba_end)
2174{
2175 struct request_sense sense;
2176 struct request req;
2177
2178 cdrom_prepare_request(drive, &req);
2179
2180 req.sense = &sense;
2181 req.cmd[0] = GPCMD_PLAY_AUDIO_MSF;
2182 lba_to_msf(lba_start, &req.cmd[3], &req.cmd[4], &req.cmd[5]);
2183 lba_to_msf(lba_end-1, &req.cmd[6], &req.cmd[7], &req.cmd[8]);
2184
2185 return cdrom_queue_packet_command(drive, &req);
2186}
2187
2188static int cdrom_get_toc_entry(ide_drive_t *drive, int track,
2189 struct atapi_toc_entry **ent)
2190{
2191 struct cdrom_info *info = drive->driver_data;
2192 struct atapi_toc *toc = info->toc;
2193 int ntracks;
2194
2195 /*
2196 * don't serve cached data, if the toc isn't valid
2197 */
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002198 if ((info->cd_flags & IDE_CD_FLAG_TOC_VALID) == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002199 return -EINVAL;
2200
2201 /* Check validity of requested track number. */
2202 ntracks = toc->hdr.last_track - toc->hdr.first_track + 1;
2203 if (toc->hdr.first_track == CDROM_LEADOUT) ntracks = 0;
2204 if (track == CDROM_LEADOUT)
2205 *ent = &toc->ent[ntracks];
2206 else if (track < toc->hdr.first_track ||
2207 track > toc->hdr.last_track)
2208 return -EINVAL;
2209 else
2210 *ent = &toc->ent[track - toc->hdr.first_track];
2211
2212 return 0;
2213}
2214
2215/* the generic packet interface to cdrom.c */
2216static int ide_cdrom_packet(struct cdrom_device_info *cdi,
2217 struct packet_command *cgc)
2218{
2219 struct request req;
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002220 ide_drive_t *drive = cdi->handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002221
2222 if (cgc->timeout <= 0)
2223 cgc->timeout = ATAPI_WAIT_PC;
2224
2225 /* here we queue the commands from the uniform CD-ROM
2226 layer. the packet must be complete, as we do not
2227 touch it at all. */
2228 cdrom_prepare_request(drive, &req);
2229 memcpy(req.cmd, cgc->cmd, CDROM_PACKET_SIZE);
2230 if (cgc->sense)
2231 memset(cgc->sense, 0, sizeof(struct request_sense));
2232 req.data = cgc->buffer;
2233 req.data_len = cgc->buflen;
2234 req.timeout = cgc->timeout;
2235
2236 if (cgc->quiet)
Jens Axboe4aff5e22006-08-10 08:44:47 +02002237 req.cmd_flags |= REQ_QUIET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002238
2239 req.sense = cgc->sense;
2240 cgc->stat = cdrom_queue_packet_command(drive, &req);
2241 if (!cgc->stat)
2242 cgc->buflen -= req.data_len;
2243 return cgc->stat;
2244}
2245
2246static
Linus Torvalds1da177e2005-04-16 15:20:36 -07002247int ide_cdrom_audio_ioctl (struct cdrom_device_info *cdi,
2248 unsigned int cmd, void *arg)
2249
2250{
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002251 ide_drive_t *drive = cdi->handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002252 struct cdrom_info *info = drive->driver_data;
2253 int stat;
2254
2255 switch (cmd) {
2256 /*
2257 * emulate PLAY_AUDIO_TI command with PLAY_AUDIO_10, since
2258 * atapi doesn't support it
2259 */
2260 case CDROMPLAYTRKIND: {
2261 unsigned long lba_start, lba_end;
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002262 struct cdrom_ti *ti = arg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002263 struct atapi_toc_entry *first_toc, *last_toc;
2264
2265 stat = cdrom_get_toc_entry(drive, ti->cdti_trk0, &first_toc);
2266 if (stat)
2267 return stat;
2268
2269 stat = cdrom_get_toc_entry(drive, ti->cdti_trk1, &last_toc);
2270 if (stat)
2271 return stat;
2272
2273 if (ti->cdti_trk1 != CDROM_LEADOUT)
2274 ++last_toc;
2275 lba_start = first_toc->addr.lba;
2276 lba_end = last_toc->addr.lba;
2277
2278 if (lba_end <= lba_start)
2279 return -EINVAL;
2280
2281 return cdrom_play_audio(drive, lba_start, lba_end);
2282 }
2283
2284 case CDROMREADTOCHDR: {
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002285 struct cdrom_tochdr *tochdr = arg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002286 struct atapi_toc *toc;
2287
2288 /* Make sure our saved TOC is valid. */
2289 stat = cdrom_read_toc(drive, NULL);
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002290 if (stat)
2291 return stat;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002292
2293 toc = info->toc;
2294 tochdr->cdth_trk0 = toc->hdr.first_track;
2295 tochdr->cdth_trk1 = toc->hdr.last_track;
2296
2297 return 0;
2298 }
2299
2300 case CDROMREADTOCENTRY: {
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002301 struct cdrom_tocentry *tocentry = arg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002302 struct atapi_toc_entry *toce;
2303
2304 stat = cdrom_get_toc_entry(drive, tocentry->cdte_track, &toce);
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002305 if (stat)
2306 return stat;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002307
2308 tocentry->cdte_ctrl = toce->control;
2309 tocentry->cdte_adr = toce->adr;
2310 if (tocentry->cdte_format == CDROM_MSF) {
2311 lba_to_msf (toce->addr.lba,
2312 &tocentry->cdte_addr.msf.minute,
2313 &tocentry->cdte_addr.msf.second,
2314 &tocentry->cdte_addr.msf.frame);
2315 } else
2316 tocentry->cdte_addr.lba = toce->addr.lba;
2317
2318 return 0;
2319 }
2320
2321 default:
2322 return -EINVAL;
2323 }
2324}
2325
2326static
2327int ide_cdrom_reset (struct cdrom_device_info *cdi)
2328{
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002329 ide_drive_t *drive = cdi->handle;
Bartlomiej Zolnierkiewicz0ba11212008-02-01 23:09:21 +01002330 struct cdrom_info *cd = drive->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002331 struct request_sense sense;
2332 struct request req;
2333 int ret;
2334
2335 cdrom_prepare_request(drive, &req);
Jens Axboe4aff5e22006-08-10 08:44:47 +02002336 req.cmd_type = REQ_TYPE_SPECIAL;
2337 req.cmd_flags = REQ_QUIET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002338 ret = ide_do_drive_cmd(drive, &req, ide_wait);
2339
2340 /*
2341 * A reset will unlock the door. If it was previously locked,
2342 * lock it again.
2343 */
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002344 if (cd->cd_flags & IDE_CD_FLAG_DOOR_LOCKED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002345 (void) cdrom_lockdoor(drive, 1, &sense);
2346
2347 return ret;
2348}
2349
2350
2351static
2352int ide_cdrom_tray_move (struct cdrom_device_info *cdi, int position)
2353{
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002354 ide_drive_t *drive = cdi->handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002355 struct request_sense sense;
2356
2357 if (position) {
2358 int stat = cdrom_lockdoor(drive, 0, &sense);
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002359 if (stat)
2360 return stat;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002361 }
2362
2363 return cdrom_eject(drive, !position, &sense);
2364}
2365
2366static
2367int ide_cdrom_lock_door (struct cdrom_device_info *cdi, int lock)
2368{
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002369 ide_drive_t *drive = cdi->handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002370 return cdrom_lockdoor(drive, lock, NULL);
2371}
2372
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002373static int ide_cdrom_get_capabilities(ide_drive_t *drive, u8 *buf)
Eric Piel9235e682005-06-23 00:10:29 -07002374{
2375 struct cdrom_info *info = drive->driver_data;
2376 struct cdrom_device_info *cdi = &info->devinfo;
2377 struct packet_command cgc;
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002378 int stat, attempts = 3, size = ATAPI_CAPABILITIES_PAGE_SIZE;
Eric Piel9235e682005-06-23 00:10:29 -07002379
Bartlomiej Zolnierkiewicze59724c2008-02-01 23:09:22 +01002380 if ((info->cd_flags & IDE_CD_FLAG_FULL_CAPS_PAGE) == 0)
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002381 size -= ATAPI_CAPABILITIES_PAGE_PAD_SIZE;
Eric Piel9235e682005-06-23 00:10:29 -07002382
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002383 init_cdrom_command(&cgc, buf, size, CGC_DATA_UNKNOWN);
Eric Piel9235e682005-06-23 00:10:29 -07002384 do { /* we seem to get stat=0x01,err=0x00 the first time (??) */
2385 stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CAPABILITIES_PAGE, 0);
2386 if (!stat)
2387 break;
2388 } while (--attempts);
2389 return stat;
2390}
2391
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002392static void ide_cdrom_update_speed(ide_drive_t *drive, u8 *buf)
Eric Piel9235e682005-06-23 00:10:29 -07002393{
Bartlomiej Zolnierkiewicz4fe67172008-02-01 23:09:21 +01002394 struct cdrom_info *cd = drive->driver_data;
Bartlomiej Zolnierkiewicz481c8c62008-02-01 23:09:20 +01002395 u16 curspeed, maxspeed;
2396
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002397 curspeed = *(u16 *)&buf[8 + 14];
2398 maxspeed = *(u16 *)&buf[8 + 8];
2399
Bartlomiej Zolnierkiewicze59724c2008-02-01 23:09:22 +01002400 if (cd->cd_flags & IDE_CD_FLAG_LE_SPEED_FIELDS) {
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002401 curspeed = le16_to_cpu(curspeed);
2402 maxspeed = le16_to_cpu(maxspeed);
Eric Piel9235e682005-06-23 00:10:29 -07002403 } else {
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002404 curspeed = be16_to_cpu(curspeed);
2405 maxspeed = be16_to_cpu(maxspeed);
Eric Piel9235e682005-06-23 00:10:29 -07002406 }
Bartlomiej Zolnierkiewicz481c8c62008-02-01 23:09:20 +01002407
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002408 cd->current_speed = (curspeed + (176/2)) / 176;
2409 cd->max_speed = (maxspeed + (176/2)) / 176;
Eric Piel9235e682005-06-23 00:10:29 -07002410}
2411
2412static
Linus Torvalds1da177e2005-04-16 15:20:36 -07002413int ide_cdrom_select_speed (struct cdrom_device_info *cdi, int speed)
2414{
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002415 ide_drive_t *drive = cdi->handle;
Bartlomiej Zolnierkiewicz0ba11212008-02-01 23:09:21 +01002416 struct cdrom_info *cd = drive->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002417 struct request_sense sense;
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002418 u8 buf[ATAPI_CAPABILITIES_PAGE_SIZE];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002419 int stat;
2420
2421 if ((stat = cdrom_select_speed(drive, speed, &sense)) < 0)
2422 return stat;
2423
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002424 if (!ide_cdrom_get_capabilities(drive, buf)) {
2425 ide_cdrom_update_speed(drive, buf);
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002426 cdi->speed = cd->current_speed;
Eric Piel9235e682005-06-23 00:10:29 -07002427 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002428 return 0;
2429}
2430
2431/*
2432 * add logic to try GET_EVENT command first to check for media and tray
2433 * status. this should be supported by newer cd-r/w and all DVD etc
2434 * drives
2435 */
2436static
2437int ide_cdrom_drive_status (struct cdrom_device_info *cdi, int slot_nr)
2438{
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002439 ide_drive_t *drive = cdi->handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002440 struct media_event_desc med;
2441 struct request_sense sense;
2442 int stat;
2443
2444 if (slot_nr != CDSL_CURRENT)
2445 return -EINVAL;
2446
2447 stat = cdrom_check_status(drive, &sense);
2448 if (!stat || sense.sense_key == UNIT_ATTENTION)
2449 return CDS_DISC_OK;
2450
2451 if (!cdrom_get_media_event(cdi, &med)) {
2452 if (med.media_present)
2453 return CDS_DISC_OK;
2454 else if (med.door_open)
2455 return CDS_TRAY_OPEN;
2456 else
2457 return CDS_NO_DISC;
2458 }
2459
2460 if (sense.sense_key == NOT_READY && sense.asc == 0x04 && sense.ascq == 0x04)
2461 return CDS_DISC_OK;
2462
2463 /*
2464 * If not using Mt Fuji extended media tray reports,
2465 * just return TRAY_OPEN since ATAPI doesn't provide
2466 * any other way to detect this...
2467 */
2468 if (sense.sense_key == NOT_READY) {
Alan Coxdbe217a2006-06-25 05:47:44 -07002469 if (sense.asc == 0x3a && sense.ascq == 1)
2470 return CDS_NO_DISC;
2471 else
2472 return CDS_TRAY_OPEN;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002473 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002474 return CDS_DRIVE_NOT_READY;
2475}
2476
2477static
2478int ide_cdrom_get_last_session (struct cdrom_device_info *cdi,
2479 struct cdrom_multisession *ms_info)
2480{
2481 struct atapi_toc *toc;
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002482 ide_drive_t *drive = cdi->handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002483 struct cdrom_info *info = drive->driver_data;
2484 struct request_sense sense;
2485 int ret;
2486
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002487 if ((info->cd_flags & IDE_CD_FLAG_TOC_VALID) == 0 || info->toc == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002488 if ((ret = cdrom_read_toc(drive, &sense)))
2489 return ret;
2490
2491 toc = info->toc;
2492 ms_info->addr.lba = toc->last_session_lba;
2493 ms_info->xa_flag = toc->xa_flag;
2494
2495 return 0;
2496}
2497
2498static
2499int ide_cdrom_get_mcn (struct cdrom_device_info *cdi,
2500 struct cdrom_mcn *mcn_info)
2501{
2502 int stat;
2503 char mcnbuf[24];
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002504 ide_drive_t *drive = cdi->handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002505
2506/* get MCN */
2507 if ((stat = cdrom_read_subchannel(drive, 2, mcnbuf, sizeof (mcnbuf), NULL)))
2508 return stat;
2509
2510 memcpy (mcn_info->medium_catalog_number, mcnbuf+9,
2511 sizeof (mcn_info->medium_catalog_number)-1);
2512 mcn_info->medium_catalog_number[sizeof (mcn_info->medium_catalog_number)-1]
2513 = '\0';
2514
2515 return 0;
2516}
2517
2518
2519
2520/****************************************************************************
2521 * Other driver requests (open, close, check media change).
2522 */
2523
2524static
2525int ide_cdrom_check_media_change_real (struct cdrom_device_info *cdi,
2526 int slot_nr)
2527{
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002528 ide_drive_t *drive = cdi->handle;
Bartlomiej Zolnierkiewicz0ba11212008-02-01 23:09:21 +01002529 struct cdrom_info *cd = drive->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002530 int retval;
Bartlomiej Zolnierkiewicz0ba11212008-02-01 23:09:21 +01002531
Linus Torvalds1da177e2005-04-16 15:20:36 -07002532 if (slot_nr == CDSL_CURRENT) {
2533 (void) cdrom_check_status(drive, NULL);
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002534 retval = (cd->cd_flags & IDE_CD_FLAG_MEDIA_CHANGED) ? 1 : 0;
2535 cd->cd_flags &= ~IDE_CD_FLAG_MEDIA_CHANGED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002536 return retval;
2537 } else {
2538 return -EINVAL;
2539 }
2540}
2541
2542
2543static
2544int ide_cdrom_open_real (struct cdrom_device_info *cdi, int purpose)
2545{
2546 return 0;
2547}
2548
2549/*
2550 * Close down the device. Invalidate all cached blocks.
2551 */
2552
2553static
2554void ide_cdrom_release_real (struct cdrom_device_info *cdi)
2555{
2556 ide_drive_t *drive = cdi->handle;
Bartlomiej Zolnierkiewicz0ba11212008-02-01 23:09:21 +01002557 struct cdrom_info *cd = drive->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002558
2559 if (!cdi->use_count)
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002560 cd->cd_flags &= ~IDE_CD_FLAG_TOC_VALID;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002561}
2562
Bartlomiej Zolnierkiewicz20e7f7e2008-02-01 23:09:20 +01002563#define IDE_CD_CAPABILITIES \
2564 (CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK | CDC_SELECT_SPEED | \
2565 CDC_SELECT_DISC | CDC_MULTI_SESSION | CDC_MCN | CDC_MEDIA_CHANGED | \
2566 CDC_PLAY_AUDIO | CDC_RESET | CDC_DRIVE_STATUS | CDC_CD_R | \
2567 CDC_CD_RW | CDC_DVD | CDC_DVD_R | CDC_DVD_RAM | CDC_GENERIC_PACKET | \
2568 CDC_MO_DRIVE | CDC_MRW | CDC_MRW_W | CDC_RAM)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002569
Linus Torvalds1da177e2005-04-16 15:20:36 -07002570static struct cdrom_device_ops ide_cdrom_dops = {
2571 .open = ide_cdrom_open_real,
2572 .release = ide_cdrom_release_real,
2573 .drive_status = ide_cdrom_drive_status,
2574 .media_changed = ide_cdrom_check_media_change_real,
2575 .tray_move = ide_cdrom_tray_move,
2576 .lock_door = ide_cdrom_lock_door,
2577 .select_speed = ide_cdrom_select_speed,
2578 .get_last_session = ide_cdrom_get_last_session,
2579 .get_mcn = ide_cdrom_get_mcn,
2580 .reset = ide_cdrom_reset,
2581 .audio_ioctl = ide_cdrom_audio_ioctl,
Bartlomiej Zolnierkiewicz20e7f7e2008-02-01 23:09:20 +01002582 .capability = IDE_CD_CAPABILITIES,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002583 .generic_packet = ide_cdrom_packet,
2584};
2585
2586static int ide_cdrom_register (ide_drive_t *drive, int nslots)
2587{
2588 struct cdrom_info *info = drive->driver_data;
2589 struct cdrom_device_info *devinfo = &info->devinfo;
2590
2591 devinfo->ops = &ide_cdrom_dops;
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002592 devinfo->speed = info->current_speed;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002593 devinfo->capacity = nslots;
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002594 devinfo->handle = drive;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002595 strcpy(devinfo->name, drive->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002596
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002597 if (info->cd_flags & IDE_CD_FLAG_NO_SPEED_SELECT)
Bartlomiej Zolnierkiewicz3cbd8142007-12-24 15:23:43 +01002598 devinfo->mask |= CDC_SELECT_SPEED;
2599
Linus Torvalds1da177e2005-04-16 15:20:36 -07002600 devinfo->disk = info->disk;
2601 return register_cdrom(devinfo);
2602}
2603
2604static
Linus Torvalds1da177e2005-04-16 15:20:36 -07002605int ide_cdrom_probe_capabilities (ide_drive_t *drive)
2606{
Bartlomiej Zolnierkiewicz4fe67172008-02-01 23:09:21 +01002607 struct cdrom_info *cd = drive->driver_data;
2608 struct cdrom_device_info *cdi = &cd->devinfo;
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002609 u8 buf[ATAPI_CAPABILITIES_PAGE_SIZE];
2610 mechtype_t mechtype;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002611 int nslots = 1;
2612
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002613 cdi->mask = (CDC_CD_R | CDC_CD_RW | CDC_DVD | CDC_DVD_R |
2614 CDC_DVD_RAM | CDC_SELECT_DISC | CDC_PLAY_AUDIO |
2615 CDC_MO_DRIVE | CDC_RAM);
2616
Linus Torvalds1da177e2005-04-16 15:20:36 -07002617 if (drive->media == ide_optical) {
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002618 cdi->mask &= ~(CDC_MO_DRIVE | CDC_RAM);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002619 printk(KERN_ERR "%s: ATAPI magneto-optical drive\n", drive->name);
2620 return nslots;
2621 }
2622
Bartlomiej Zolnierkiewicze59724c2008-02-01 23:09:22 +01002623 if (cd->cd_flags & IDE_CD_FLAG_PRE_ATAPI12) {
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002624 cd->cd_flags &= ~IDE_CD_FLAG_NO_EJECT;
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002625 cdi->mask &= ~CDC_PLAY_AUDIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002626 return nslots;
2627 }
2628
2629 /*
2630 * we have to cheat a little here. the packet will eventually
2631 * be queued with ide_cdrom_packet(), which extracts the
2632 * drive from cdi->handle. Since this device hasn't been
2633 * registered with the Uniform layer yet, it can't do this.
2634 * Same goes for cdi->ops.
2635 */
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002636 cdi->handle = drive;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002637 cdi->ops = &ide_cdrom_dops;
2638
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002639 if (ide_cdrom_get_capabilities(drive, buf))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002640 return 0;
2641
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002642 if ((buf[8 + 6] & 0x01) == 0)
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002643 cd->cd_flags |= IDE_CD_FLAG_NO_DOORLOCK;
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002644 if (buf[8 + 6] & 0x08)
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002645 cd->cd_flags &= ~IDE_CD_FLAG_NO_EJECT;
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002646 if (buf[8 + 3] & 0x01)
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002647 cdi->mask &= ~CDC_CD_R;
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002648 if (buf[8 + 3] & 0x02)
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002649 cdi->mask &= ~(CDC_CD_RW | CDC_RAM);
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002650 if (buf[8 + 2] & 0x38)
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002651 cdi->mask &= ~CDC_DVD;
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002652 if (buf[8 + 3] & 0x20)
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002653 cdi->mask &= ~(CDC_DVD_RAM | CDC_RAM);
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002654 if (buf[8 + 3] & 0x10)
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002655 cdi->mask &= ~CDC_DVD_R;
Bartlomiej Zolnierkiewicze59724c2008-02-01 23:09:22 +01002656 if ((buf[8 + 4] & 0x01) || (cd->cd_flags & IDE_CD_FLAG_PLAY_AUDIO_OK))
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002657 cdi->mask &= ~CDC_PLAY_AUDIO;
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002658
2659 mechtype = buf[8 + 6] >> 5;
2660 if (mechtype == mechtype_caddy || mechtype == mechtype_popup)
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002661 cdi->mask |= CDC_CLOSE_TRAY;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002662
Linus Torvalds1da177e2005-04-16 15:20:36 -07002663 if (cdi->sanyo_slot > 0) {
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002664 cdi->mask &= ~CDC_SELECT_DISC;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002665 nslots = 3;
Bartlomiej Zolnierkiewiczcdf60002008-02-01 23:09:22 +01002666 } else if (mechtype == mechtype_individual_changer ||
2667 mechtype == mechtype_cartridge_changer) {
Bartlomiej Zolnierkiewicz2609d062008-02-01 23:09:19 +01002668 nslots = cdrom_number_of_slots(cdi);
2669 if (nslots > 1)
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002670 cdi->mask &= ~CDC_SELECT_DISC;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002671 }
2672
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002673 ide_cdrom_update_speed(drive, buf);
Bartlomiej Zolnierkiewicz4fe67172008-02-01 23:09:21 +01002674
Linus Torvalds1da177e2005-04-16 15:20:36 -07002675 printk(KERN_INFO "%s: ATAPI", drive->name);
Bartlomiej Zolnierkiewicz4fe67172008-02-01 23:09:21 +01002676
2677 /* don't print speed if the drive reported 0 */
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002678 if (cd->max_speed)
2679 printk(KERN_CONT " %dX", cd->max_speed);
Bartlomiej Zolnierkiewicz4fe67172008-02-01 23:09:21 +01002680
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002681 printk(KERN_CONT " %s", (cdi->mask & CDC_DVD) ? "CD-ROM" : "DVD-ROM");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002682
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002683 if ((cdi->mask & CDC_DVD_R) == 0 || (cdi->mask & CDC_DVD_RAM) == 0)
2684 printk(KERN_CONT " DVD%s%s",
2685 (cdi->mask & CDC_DVD_R) ? "" : "-R",
2686 (cdi->mask & CDC_DVD_RAM) ? "" : "-RAM");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002687
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002688 if ((cdi->mask & CDC_CD_R) == 0 || (cdi->mask & CDC_CD_RW) == 0)
2689 printk(KERN_CONT " CD%s%s",
2690 (cdi->mask & CDC_CD_R) ? "" : "-R",
2691 (cdi->mask & CDC_CD_RW) ? "" : "/RW");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002692
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002693 if ((cdi->mask & CDC_SELECT_DISC) == 0)
2694 printk(KERN_CONT " changer w/%d slots", nslots);
2695 else
2696 printk(KERN_CONT " drive");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002697
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002698 printk(KERN_CONT ", %dkB Cache\n", be16_to_cpu(*(u16 *)&buf[8 + 12]));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002699
2700 return nslots;
2701}
2702
Bartlomiej Zolnierkiewicz7662d042007-05-10 00:01:10 +02002703#ifdef CONFIG_IDE_PROC_FS
Linus Torvalds1da177e2005-04-16 15:20:36 -07002704static void ide_cdrom_add_settings(ide_drive_t *drive)
2705{
Bartlomiej Zolnierkiewicz14979432007-05-10 00:01:10 +02002706 ide_add_setting(drive, "dsc_overlap", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1, &drive->dsc_overlap, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002707}
Bartlomiej Zolnierkiewicz7662d042007-05-10 00:01:10 +02002708#else
2709static inline void ide_cdrom_add_settings(ide_drive_t *drive) { ; }
2710#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07002711
2712/*
2713 * standard prep_rq_fn that builds 10 byte cmds
2714 */
Jens Axboe165125e2007-07-24 09:28:11 +02002715static int ide_cdrom_prep_fs(struct request_queue *q, struct request *rq)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002716{
2717 int hard_sect = queue_hardsect_size(q);
2718 long block = (long)rq->hard_sector / (hard_sect >> 9);
2719 unsigned long blocks = rq->hard_nr_sectors / (hard_sect >> 9);
2720
2721 memset(rq->cmd, 0, sizeof(rq->cmd));
2722
2723 if (rq_data_dir(rq) == READ)
2724 rq->cmd[0] = GPCMD_READ_10;
2725 else
2726 rq->cmd[0] = GPCMD_WRITE_10;
2727
2728 /*
2729 * fill in lba
2730 */
2731 rq->cmd[2] = (block >> 24) & 0xff;
2732 rq->cmd[3] = (block >> 16) & 0xff;
2733 rq->cmd[4] = (block >> 8) & 0xff;
2734 rq->cmd[5] = block & 0xff;
2735
2736 /*
2737 * and transfer length
2738 */
2739 rq->cmd[7] = (blocks >> 8) & 0xff;
2740 rq->cmd[8] = blocks & 0xff;
2741 rq->cmd_len = 10;
2742 return BLKPREP_OK;
2743}
2744
2745/*
2746 * Most of the SCSI commands are supported directly by ATAPI devices.
2747 * This transform handles the few exceptions.
2748 */
2749static int ide_cdrom_prep_pc(struct request *rq)
2750{
2751 u8 *c = rq->cmd;
2752
2753 /*
2754 * Transform 6-byte read/write commands to the 10-byte version
2755 */
2756 if (c[0] == READ_6 || c[0] == WRITE_6) {
2757 c[8] = c[4];
2758 c[5] = c[3];
2759 c[4] = c[2];
2760 c[3] = c[1] & 0x1f;
2761 c[2] = 0;
2762 c[1] &= 0xe0;
2763 c[0] += (READ_10 - READ_6);
2764 rq->cmd_len = 10;
2765 return BLKPREP_OK;
2766 }
2767
2768 /*
2769 * it's silly to pretend we understand 6-byte sense commands, just
2770 * reject with ILLEGAL_REQUEST and the caller should take the
2771 * appropriate action
2772 */
2773 if (c[0] == MODE_SENSE || c[0] == MODE_SELECT) {
2774 rq->errors = ILLEGAL_REQUEST;
2775 return BLKPREP_KILL;
2776 }
2777
2778 return BLKPREP_OK;
2779}
2780
Jens Axboe165125e2007-07-24 09:28:11 +02002781static int ide_cdrom_prep_fn(struct request_queue *q, struct request *rq)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002782{
Jens Axboe4aff5e22006-08-10 08:44:47 +02002783 if (blk_fs_request(rq))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002784 return ide_cdrom_prep_fs(q, rq);
Jens Axboe4aff5e22006-08-10 08:44:47 +02002785 else if (blk_pc_request(rq))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002786 return ide_cdrom_prep_pc(rq);
2787
2788 return 0;
2789}
2790
Bartlomiej Zolnierkiewicze59724c2008-02-01 23:09:22 +01002791struct cd_list_entry {
2792 const char *id_model;
2793 const char *id_firmware;
2794 unsigned int cd_flags;
2795};
2796
2797static const struct cd_list_entry ide_cd_quirks_list[] = {
2798 /* Limit transfer size per interrupt. */
2799 { "SAMSUNG CD-ROM SCR-2430", NULL, IDE_CD_FLAG_LIMIT_NFRAMES },
2800 { "SAMSUNG CD-ROM SCR-2432", NULL, IDE_CD_FLAG_LIMIT_NFRAMES },
2801 /* SCR-3231 doesn't support the SET_CD_SPEED command. */
2802 { "SAMSUNG CD-ROM SCR-3231", NULL, IDE_CD_FLAG_NO_SPEED_SELECT },
2803 /* Old NEC260 (not R) was released before ATAPI 1.2 spec. */
2804 { "NEC CD-ROM DRIVE:260", "1.01", IDE_CD_FLAG_TOCADDR_AS_BCD |
2805 IDE_CD_FLAG_PRE_ATAPI12, },
2806 /* Vertos 300, some versions of this drive like to talk BCD. */
2807 { "V003S0DS", NULL, IDE_CD_FLAG_VERTOS_300_SSD, },
2808 /* Vertos 600 ESD. */
2809 { "V006E0DS", NULL, IDE_CD_FLAG_VERTOS_600_ESD, },
2810 /*
2811 * Sanyo 3 CD changer uses a non-standard command for CD changing
2812 * (by default standard ATAPI support for CD changers is used).
2813 */
2814 { "CD-ROM CDR-C3 G", NULL, IDE_CD_FLAG_SANYO_3CD },
2815 { "CD-ROM CDR-C3G", NULL, IDE_CD_FLAG_SANYO_3CD },
2816 { "CD-ROM CDR_C36", NULL, IDE_CD_FLAG_SANYO_3CD },
2817 /* Stingray 8X CD-ROM. */
2818 { "STINGRAY 8422 IDE 8X CD-ROM 7-27-95", NULL, IDE_CD_FLAG_PRE_ATAPI12},
2819 /*
2820 * ACER 50X CD-ROM and WPI 32X CD-ROM require the full spec length
2821 * mode sense page capabilities size, but older drives break.
2822 */
2823 { "ATAPI CD ROM DRIVE 50X MAX", NULL, IDE_CD_FLAG_FULL_CAPS_PAGE },
2824 { "WPI CDS-32X", NULL, IDE_CD_FLAG_FULL_CAPS_PAGE },
2825 /* ACER/AOpen 24X CD-ROM has the speed fields byte-swapped. */
2826 { "", "241N", IDE_CD_FLAG_LE_SPEED_FIELDS },
2827 /*
2828 * Some drives used by Apple don't advertise audio play
2829 * but they do support reading TOC & audio datas.
2830 */
2831 { "MATSHITADVD-ROM SR-8187", NULL, IDE_CD_FLAG_PLAY_AUDIO_OK },
2832 { "MATSHITADVD-ROM SR-8186", NULL, IDE_CD_FLAG_PLAY_AUDIO_OK },
2833 { "MATSHITADVD-ROM SR-8176", NULL, IDE_CD_FLAG_PLAY_AUDIO_OK },
2834 { "MATSHITADVD-ROM SR-8174", NULL, IDE_CD_FLAG_PLAY_AUDIO_OK },
2835 { NULL, NULL, 0 }
2836};
2837
2838static unsigned int ide_cd_flags(struct hd_driveid *id)
2839{
2840 const struct cd_list_entry *cle = ide_cd_quirks_list;
2841
2842 while (cle->id_model) {
2843 if (strcmp(cle->id_model, id->model) == 0 &&
2844 (cle->id_firmware == NULL ||
2845 strstr(id->fw_rev, cle->id_firmware)))
2846 return cle->cd_flags;
2847 cle++;
2848 }
2849
2850 return 0;
2851}
2852
Linus Torvalds1da177e2005-04-16 15:20:36 -07002853static
2854int ide_cdrom_setup (ide_drive_t *drive)
2855{
Bartlomiej Zolnierkiewicz4fe67172008-02-01 23:09:21 +01002856 struct cdrom_info *cd = drive->driver_data;
2857 struct cdrom_device_info *cdi = &cd->devinfo;
Bartlomiej Zolnierkiewicze59724c2008-02-01 23:09:22 +01002858 struct hd_driveid *id = drive->id;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002859 int nslots;
2860
2861 blk_queue_prep_rq(drive->queue, ide_cdrom_prep_fn);
2862 blk_queue_dma_alignment(drive->queue, 31);
2863 drive->queue->unplug_delay = (1 * HZ) / 1000;
2864 if (!drive->queue->unplug_delay)
2865 drive->queue->unplug_delay = 1;
2866
2867 drive->special.all = 0;
2868
Bartlomiej Zolnierkiewicze59724c2008-02-01 23:09:22 +01002869 cd->cd_flags = IDE_CD_FLAG_MEDIA_CHANGED | IDE_CD_FLAG_NO_EJECT |
2870 ide_cd_flags(id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002871
Bartlomiej Zolnierkiewicze59724c2008-02-01 23:09:22 +01002872 if ((id->config & 0x0060) == 0x20)
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002873 cd->cd_flags |= IDE_CD_FLAG_DRQ_INTERRUPT;
Bartlomiej Zolnierkiewiczb8d25de2008-02-01 23:09:19 +01002874
Bartlomiej Zolnierkiewicze59724c2008-02-01 23:09:22 +01002875 if ((cd->cd_flags & IDE_CD_FLAG_VERTOS_300_SSD) &&
2876 id->fw_rev[4] == '1' && id->fw_rev[6] <= '2')
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002877 cd->cd_flags |= (IDE_CD_FLAG_TOCTRACKS_AS_BCD |
2878 IDE_CD_FLAG_TOCADDR_AS_BCD);
Bartlomiej Zolnierkiewicze59724c2008-02-01 23:09:22 +01002879 else if ((cd->cd_flags & IDE_CD_FLAG_VERTOS_600_ESD) &&
2880 id->fw_rev[4] == '1' && id->fw_rev[6] <= '2')
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002881 cd->cd_flags |= IDE_CD_FLAG_TOCTRACKS_AS_BCD;
Bartlomiej Zolnierkiewicze59724c2008-02-01 23:09:22 +01002882 else if (cd->cd_flags & IDE_CD_FLAG_SANYO_3CD)
2883 cdi->sanyo_slot = 3; /* 3 => use CD in slot 0 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002884
Linus Torvalds1da177e2005-04-16 15:20:36 -07002885 nslots = ide_cdrom_probe_capabilities (drive);
2886
2887 /*
2888 * set correct block size
2889 */
2890 blk_queue_hardsect_size(drive->queue, CD_FRAMESIZE);
2891
2892 if (drive->autotune == IDE_TUNE_DEFAULT ||
2893 drive->autotune == IDE_TUNE_AUTO)
2894 drive->dsc_overlap = (drive->next != drive);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002895
2896 if (ide_cdrom_register(drive, nslots)) {
2897 printk (KERN_ERR "%s: ide_cdrom_setup failed to register device with the cdrom driver.\n", drive->name);
Bartlomiej Zolnierkiewicz4fe67172008-02-01 23:09:21 +01002898 cd->devinfo.handle = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002899 return 1;
2900 }
2901 ide_cdrom_add_settings(drive);
2902 return 0;
2903}
2904
Bartlomiej Zolnierkiewiczecfd80e2007-05-10 00:01:09 +02002905#ifdef CONFIG_IDE_PROC_FS
Linus Torvalds1da177e2005-04-16 15:20:36 -07002906static
2907sector_t ide_cdrom_capacity (ide_drive_t *drive)
2908{
2909 unsigned long capacity, sectors_per_frame;
2910
2911 if (cdrom_read_capacity(drive, &capacity, &sectors_per_frame, NULL))
2912 return 0;
2913
2914 return capacity * sectors_per_frame;
2915}
Amos Waterlandd97b32142005-10-30 15:02:10 -08002916#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07002917
Russell King4031bbe2006-01-06 11:41:00 +00002918static void ide_cd_remove(ide_drive_t *drive)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002919{
2920 struct cdrom_info *info = drive->driver_data;
2921
Bartlomiej Zolnierkiewicz7662d042007-05-10 00:01:10 +02002922 ide_proc_unregister_driver(drive, info->driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002923
2924 del_gendisk(info->disk);
2925
2926 ide_cd_put(info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002927}
2928
2929static void ide_cd_release(struct kref *kref)
2930{
2931 struct cdrom_info *info = to_ide_cd(kref);
2932 struct cdrom_device_info *devinfo = &info->devinfo;
2933 ide_drive_t *drive = info->drive;
2934 struct gendisk *g = info->disk;
2935
Jesper Juhl6044ec82005-11-07 01:01:32 -08002936 kfree(info->buffer);
2937 kfree(info->toc);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002938 if (devinfo->handle == drive && unregister_cdrom(devinfo))
2939 printk(KERN_ERR "%s: %s failed to unregister device from the cdrom "
2940 "driver.\n", __FUNCTION__, drive->name);
2941 drive->dsc_overlap = 0;
2942 drive->driver_data = NULL;
2943 blk_queue_prep_rq(drive->queue, NULL);
2944 g->private_data = NULL;
2945 put_disk(g);
2946 kfree(info);
2947}
2948
Russell King4031bbe2006-01-06 11:41:00 +00002949static int ide_cd_probe(ide_drive_t *);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002950
Bartlomiej Zolnierkiewiczecfd80e2007-05-10 00:01:09 +02002951#ifdef CONFIG_IDE_PROC_FS
Linus Torvalds1da177e2005-04-16 15:20:36 -07002952static int proc_idecd_read_capacity
2953 (char *page, char **start, off_t off, int count, int *eof, void *data)
2954{
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002955 ide_drive_t *drive = data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002956 int len;
2957
2958 len = sprintf(page,"%llu\n", (long long)ide_cdrom_capacity(drive));
2959 PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
2960}
2961
2962static ide_proc_entry_t idecd_proc[] = {
2963 { "capacity", S_IFREG|S_IRUGO, proc_idecd_read_capacity, NULL },
2964 { NULL, 0, NULL, NULL }
2965};
Linus Torvalds1da177e2005-04-16 15:20:36 -07002966#endif
2967
2968static ide_driver_t ide_cdrom_driver = {
Bartlomiej Zolnierkiewicz8604aff2005-05-26 14:55:34 +02002969 .gen_driver = {
Laurent Riffard4ef3b8f2005-11-18 22:15:40 +01002970 .owner = THIS_MODULE,
Bartlomiej Zolnierkiewicz8604aff2005-05-26 14:55:34 +02002971 .name = "ide-cdrom",
2972 .bus = &ide_bus_type,
Bartlomiej Zolnierkiewicz8604aff2005-05-26 14:55:34 +02002973 },
Russell King4031bbe2006-01-06 11:41:00 +00002974 .probe = ide_cd_probe,
2975 .remove = ide_cd_remove,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002976 .version = IDECD_VERSION,
2977 .media = ide_cdrom,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002978 .supports_dsc_overlap = 1,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002979 .do_request = ide_do_rw_cdrom,
2980 .end_request = ide_end_request,
2981 .error = __ide_error,
2982 .abort = __ide_abort,
Bartlomiej Zolnierkiewicz7662d042007-05-10 00:01:10 +02002983#ifdef CONFIG_IDE_PROC_FS
Linus Torvalds1da177e2005-04-16 15:20:36 -07002984 .proc = idecd_proc,
Bartlomiej Zolnierkiewicz7662d042007-05-10 00:01:10 +02002985#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07002986};
2987
2988static int idecd_open(struct inode * inode, struct file * file)
2989{
2990 struct gendisk *disk = inode->i_bdev->bd_disk;
2991 struct cdrom_info *info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002992 int rc = -ENOMEM;
2993
2994 if (!(info = ide_cd_get(disk)))
2995 return -ENXIO;
2996
Linus Torvalds1da177e2005-04-16 15:20:36 -07002997 if (!info->buffer)
Bartlomiej Zolnierkiewiczc94964a2007-02-17 02:40:24 +01002998 info->buffer = kmalloc(SECTOR_BUFFER_SIZE, GFP_KERNEL|__GFP_REPEAT);
2999
3000 if (info->buffer)
3001 rc = cdrom_open(&info->devinfo, inode, file);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003002
3003 if (rc < 0)
3004 ide_cd_put(info);
3005
3006 return rc;
3007}
3008
3009static int idecd_release(struct inode * inode, struct file * file)
3010{
3011 struct gendisk *disk = inode->i_bdev->bd_disk;
3012 struct cdrom_info *info = ide_cd_g(disk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003013
3014 cdrom_release (&info->devinfo, file);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003015
3016 ide_cd_put(info);
3017
3018 return 0;
3019}
3020
Christoph Hellwig6a2900b2006-03-23 03:00:15 -08003021static int idecd_set_spindown(struct cdrom_device_info *cdi, unsigned long arg)
3022{
3023 struct packet_command cgc;
3024 char buffer[16];
3025 int stat;
3026 char spindown;
3027
3028 if (copy_from_user(&spindown, (void __user *)arg, sizeof(char)))
3029 return -EFAULT;
3030
3031 init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_UNKNOWN);
3032
3033 stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CDROM_PAGE, 0);
3034 if (stat)
3035 return stat;
3036
3037 buffer[11] = (buffer[11] & 0xf0) | (spindown & 0x0f);
3038 return cdrom_mode_select(cdi, &cgc);
3039}
3040
3041static int idecd_get_spindown(struct cdrom_device_info *cdi, unsigned long arg)
3042{
3043 struct packet_command cgc;
3044 char buffer[16];
3045 int stat;
3046 char spindown;
3047
3048 init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_UNKNOWN);
3049
3050 stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CDROM_PAGE, 0);
3051 if (stat)
3052 return stat;
3053
3054 spindown = buffer[11] & 0x0f;
3055 if (copy_to_user((void __user *)arg, &spindown, sizeof (char)))
3056 return -EFAULT;
3057 return 0;
3058}
3059
Linus Torvalds1da177e2005-04-16 15:20:36 -07003060static int idecd_ioctl (struct inode *inode, struct file *file,
3061 unsigned int cmd, unsigned long arg)
3062{
3063 struct block_device *bdev = inode->i_bdev;
3064 struct cdrom_info *info = ide_cd_g(bdev->bd_disk);
3065 int err;
3066
Christoph Hellwig6a2900b2006-03-23 03:00:15 -08003067 switch (cmd) {
3068 case CDROMSETSPINDOWN:
3069 return idecd_set_spindown(&info->devinfo, arg);
3070 case CDROMGETSPINDOWN:
3071 return idecd_get_spindown(&info->devinfo, arg);
3072 default:
3073 break;
3074 }
3075
3076 err = generic_ide_ioctl(info->drive, file, bdev, cmd, arg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003077 if (err == -EINVAL)
3078 err = cdrom_ioctl(file, &info->devinfo, inode, cmd, arg);
3079
3080 return err;
3081}
3082
3083static int idecd_media_changed(struct gendisk *disk)
3084{
3085 struct cdrom_info *info = ide_cd_g(disk);
3086 return cdrom_media_changed(&info->devinfo);
3087}
3088
3089static int idecd_revalidate_disk(struct gendisk *disk)
3090{
3091 struct cdrom_info *info = ide_cd_g(disk);
3092 struct request_sense sense;
3093 cdrom_read_toc(info->drive, &sense);
3094 return 0;
3095}
3096
3097static struct block_device_operations idecd_ops = {
3098 .owner = THIS_MODULE,
3099 .open = idecd_open,
3100 .release = idecd_release,
3101 .ioctl = idecd_ioctl,
3102 .media_changed = idecd_media_changed,
3103 .revalidate_disk= idecd_revalidate_disk
3104};
3105
3106/* options */
3107static char *ignore = NULL;
3108
3109module_param(ignore, charp, 0400);
3110MODULE_DESCRIPTION("ATAPI CD-ROM Driver");
3111
Russell King4031bbe2006-01-06 11:41:00 +00003112static int ide_cd_probe(ide_drive_t *drive)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003113{
3114 struct cdrom_info *info;
3115 struct gendisk *g;
3116 struct request_sense sense;
3117
3118 if (!strstr("ide-cdrom", drive->driver_req))
3119 goto failed;
3120 if (!drive->present)
3121 goto failed;
3122 if (drive->media != ide_cdrom && drive->media != ide_optical)
3123 goto failed;
3124 /* skip drives that we were told to ignore */
3125 if (ignore != NULL) {
3126 if (strstr(ignore, drive->name)) {
3127 printk(KERN_INFO "ide-cd: ignoring drive %s\n", drive->name);
3128 goto failed;
3129 }
3130 }
3131 if (drive->scsi) {
3132 printk(KERN_INFO "ide-cd: passing drive %s to ide-scsi emulation.\n", drive->name);
3133 goto failed;
3134 }
Deepak Saxenaf5e3c2f2005-11-07 01:01:25 -08003135 info = kzalloc(sizeof(struct cdrom_info), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003136 if (info == NULL) {
3137 printk(KERN_ERR "%s: Can't allocate a cdrom structure\n", drive->name);
3138 goto failed;
3139 }
3140
3141 g = alloc_disk(1 << PARTN_BITS);
3142 if (!g)
3143 goto out_free_cd;
3144
3145 ide_init_disk(g, drive);
3146
Bartlomiej Zolnierkiewicz7662d042007-05-10 00:01:10 +02003147 ide_proc_register_driver(drive, &ide_cdrom_driver);
Bartlomiej Zolnierkiewicz8604aff2005-05-26 14:55:34 +02003148
Linus Torvalds1da177e2005-04-16 15:20:36 -07003149 kref_init(&info->kref);
3150
3151 info->drive = drive;
3152 info->driver = &ide_cdrom_driver;
3153 info->disk = g;
3154
3155 g->private_data = &info->driver;
3156
3157 drive->driver_data = info;
3158
Linus Torvalds1da177e2005-04-16 15:20:36 -07003159 g->minors = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003160 g->driverfs_dev = &drive->gendev;
3161 g->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE;
3162 if (ide_cdrom_setup(drive)) {
Bartlomiej Zolnierkiewicz7662d042007-05-10 00:01:10 +02003163 ide_proc_unregister_driver(drive, &ide_cdrom_driver);
Bartlomiej Zolnierkiewicz05017db2007-12-24 15:23:43 +01003164 ide_cd_release(&info->kref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003165 goto failed;
3166 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003167
3168 cdrom_read_toc(drive, &sense);
3169 g->fops = &idecd_ops;
3170 g->flags |= GENHD_FL_REMOVABLE;
3171 add_disk(g);
3172 return 0;
3173
Linus Torvalds1da177e2005-04-16 15:20:36 -07003174out_free_cd:
3175 kfree(info);
3176failed:
Bartlomiej Zolnierkiewicz8604aff2005-05-26 14:55:34 +02003177 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003178}
3179
3180static void __exit ide_cdrom_exit(void)
3181{
Bartlomiej Zolnierkiewicz8604aff2005-05-26 14:55:34 +02003182 driver_unregister(&ide_cdrom_driver.gen_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003183}
Bartlomiej Zolnierkiewicz17514e82005-11-19 22:24:35 +01003184
3185static int __init ide_cdrom_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003186{
Bartlomiej Zolnierkiewicz8604aff2005-05-26 14:55:34 +02003187 return driver_register(&ide_cdrom_driver.gen_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003188}
3189
Kay Sievers263756e2005-12-12 18:03:44 +01003190MODULE_ALIAS("ide:*m-cdrom*");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003191module_init(ide_cdrom_init);
3192module_exit(ide_cdrom_exit);
3193MODULE_LICENSE("GPL");