blob: 4bd664dd1e44f9afc3a6dbf365bea7f68a9310f7 [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 Axboe4f4f6c22008-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
2380 /*
2381 * ACER50 (and others?) require the full spec length mode sense
2382 * page capabilities size, but older drives break.
2383 */
2384 if (!(!strcmp(drive->id->model, "ATAPI CD ROM DRIVE 50X MAX") ||
2385 !strcmp(drive->id->model, "WPI CDS-32X")))
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002386 size -= ATAPI_CAPABILITIES_PAGE_PAD_SIZE;
Eric Piel9235e682005-06-23 00:10:29 -07002387
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002388 init_cdrom_command(&cgc, buf, size, CGC_DATA_UNKNOWN);
Eric Piel9235e682005-06-23 00:10:29 -07002389 do { /* we seem to get stat=0x01,err=0x00 the first time (??) */
2390 stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CAPABILITIES_PAGE, 0);
2391 if (!stat)
2392 break;
2393 } while (--attempts);
2394 return stat;
2395}
2396
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002397static void ide_cdrom_update_speed(ide_drive_t *drive, u8 *buf)
Eric Piel9235e682005-06-23 00:10:29 -07002398{
Bartlomiej Zolnierkiewicz4fe67172008-02-01 23:09:21 +01002399 struct cdrom_info *cd = drive->driver_data;
Bartlomiej Zolnierkiewicz481c8c62008-02-01 23:09:20 +01002400 u16 curspeed, maxspeed;
2401
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002402 curspeed = *(u16 *)&buf[8 + 14];
2403 maxspeed = *(u16 *)&buf[8 + 8];
2404
Eric Piel9235e682005-06-23 00:10:29 -07002405 /* The ACER/AOpen 24X cdrom has the speed fields byte-swapped */
2406 if (!drive->id->model[0] &&
2407 !strncmp(drive->id->fw_rev, "241N", 4)) {
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002408 curspeed = le16_to_cpu(curspeed);
2409 maxspeed = le16_to_cpu(maxspeed);
Eric Piel9235e682005-06-23 00:10:29 -07002410 } else {
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002411 curspeed = be16_to_cpu(curspeed);
2412 maxspeed = be16_to_cpu(maxspeed);
Eric Piel9235e682005-06-23 00:10:29 -07002413 }
Bartlomiej Zolnierkiewicz481c8c62008-02-01 23:09:20 +01002414
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002415 cd->current_speed = (curspeed + (176/2)) / 176;
2416 cd->max_speed = (maxspeed + (176/2)) / 176;
Eric Piel9235e682005-06-23 00:10:29 -07002417}
2418
2419static
Linus Torvalds1da177e2005-04-16 15:20:36 -07002420int ide_cdrom_select_speed (struct cdrom_device_info *cdi, int speed)
2421{
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002422 ide_drive_t *drive = cdi->handle;
Bartlomiej Zolnierkiewicz0ba11212008-02-01 23:09:21 +01002423 struct cdrom_info *cd = drive->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002424 struct request_sense sense;
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002425 u8 buf[ATAPI_CAPABILITIES_PAGE_SIZE];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002426 int stat;
2427
2428 if ((stat = cdrom_select_speed(drive, speed, &sense)) < 0)
2429 return stat;
2430
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002431 if (!ide_cdrom_get_capabilities(drive, buf)) {
2432 ide_cdrom_update_speed(drive, buf);
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002433 cdi->speed = cd->current_speed;
Eric Piel9235e682005-06-23 00:10:29 -07002434 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002435 return 0;
2436}
2437
2438/*
2439 * add logic to try GET_EVENT command first to check for media and tray
2440 * status. this should be supported by newer cd-r/w and all DVD etc
2441 * drives
2442 */
2443static
2444int ide_cdrom_drive_status (struct cdrom_device_info *cdi, int slot_nr)
2445{
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002446 ide_drive_t *drive = cdi->handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002447 struct media_event_desc med;
2448 struct request_sense sense;
2449 int stat;
2450
2451 if (slot_nr != CDSL_CURRENT)
2452 return -EINVAL;
2453
2454 stat = cdrom_check_status(drive, &sense);
2455 if (!stat || sense.sense_key == UNIT_ATTENTION)
2456 return CDS_DISC_OK;
2457
2458 if (!cdrom_get_media_event(cdi, &med)) {
2459 if (med.media_present)
2460 return CDS_DISC_OK;
2461 else if (med.door_open)
2462 return CDS_TRAY_OPEN;
2463 else
2464 return CDS_NO_DISC;
2465 }
2466
2467 if (sense.sense_key == NOT_READY && sense.asc == 0x04 && sense.ascq == 0x04)
2468 return CDS_DISC_OK;
2469
2470 /*
2471 * If not using Mt Fuji extended media tray reports,
2472 * just return TRAY_OPEN since ATAPI doesn't provide
2473 * any other way to detect this...
2474 */
2475 if (sense.sense_key == NOT_READY) {
Alan Coxdbe217a2006-06-25 05:47:44 -07002476 if (sense.asc == 0x3a && sense.ascq == 1)
2477 return CDS_NO_DISC;
2478 else
2479 return CDS_TRAY_OPEN;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002480 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002481 return CDS_DRIVE_NOT_READY;
2482}
2483
2484static
2485int ide_cdrom_get_last_session (struct cdrom_device_info *cdi,
2486 struct cdrom_multisession *ms_info)
2487{
2488 struct atapi_toc *toc;
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002489 ide_drive_t *drive = cdi->handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002490 struct cdrom_info *info = drive->driver_data;
2491 struct request_sense sense;
2492 int ret;
2493
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002494 if ((info->cd_flags & IDE_CD_FLAG_TOC_VALID) == 0 || info->toc == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002495 if ((ret = cdrom_read_toc(drive, &sense)))
2496 return ret;
2497
2498 toc = info->toc;
2499 ms_info->addr.lba = toc->last_session_lba;
2500 ms_info->xa_flag = toc->xa_flag;
2501
2502 return 0;
2503}
2504
2505static
2506int ide_cdrom_get_mcn (struct cdrom_device_info *cdi,
2507 struct cdrom_mcn *mcn_info)
2508{
2509 int stat;
2510 char mcnbuf[24];
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002511 ide_drive_t *drive = cdi->handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002512
2513/* get MCN */
2514 if ((stat = cdrom_read_subchannel(drive, 2, mcnbuf, sizeof (mcnbuf), NULL)))
2515 return stat;
2516
2517 memcpy (mcn_info->medium_catalog_number, mcnbuf+9,
2518 sizeof (mcn_info->medium_catalog_number)-1);
2519 mcn_info->medium_catalog_number[sizeof (mcn_info->medium_catalog_number)-1]
2520 = '\0';
2521
2522 return 0;
2523}
2524
2525
2526
2527/****************************************************************************
2528 * Other driver requests (open, close, check media change).
2529 */
2530
2531static
2532int ide_cdrom_check_media_change_real (struct cdrom_device_info *cdi,
2533 int slot_nr)
2534{
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002535 ide_drive_t *drive = cdi->handle;
Bartlomiej Zolnierkiewicz0ba11212008-02-01 23:09:21 +01002536 struct cdrom_info *cd = drive->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002537 int retval;
Bartlomiej Zolnierkiewicz0ba11212008-02-01 23:09:21 +01002538
Linus Torvalds1da177e2005-04-16 15:20:36 -07002539 if (slot_nr == CDSL_CURRENT) {
2540 (void) cdrom_check_status(drive, NULL);
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002541 retval = (cd->cd_flags & IDE_CD_FLAG_MEDIA_CHANGED) ? 1 : 0;
2542 cd->cd_flags &= ~IDE_CD_FLAG_MEDIA_CHANGED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002543 return retval;
2544 } else {
2545 return -EINVAL;
2546 }
2547}
2548
2549
2550static
2551int ide_cdrom_open_real (struct cdrom_device_info *cdi, int purpose)
2552{
2553 return 0;
2554}
2555
2556/*
2557 * Close down the device. Invalidate all cached blocks.
2558 */
2559
2560static
2561void ide_cdrom_release_real (struct cdrom_device_info *cdi)
2562{
2563 ide_drive_t *drive = cdi->handle;
Bartlomiej Zolnierkiewicz0ba11212008-02-01 23:09:21 +01002564 struct cdrom_info *cd = drive->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002565
2566 if (!cdi->use_count)
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002567 cd->cd_flags &= ~IDE_CD_FLAG_TOC_VALID;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002568}
2569
Bartlomiej Zolnierkiewicz20e7f7e2008-02-01 23:09:20 +01002570#define IDE_CD_CAPABILITIES \
2571 (CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK | CDC_SELECT_SPEED | \
2572 CDC_SELECT_DISC | CDC_MULTI_SESSION | CDC_MCN | CDC_MEDIA_CHANGED | \
2573 CDC_PLAY_AUDIO | CDC_RESET | CDC_DRIVE_STATUS | CDC_CD_R | \
2574 CDC_CD_RW | CDC_DVD | CDC_DVD_R | CDC_DVD_RAM | CDC_GENERIC_PACKET | \
2575 CDC_MO_DRIVE | CDC_MRW | CDC_MRW_W | CDC_RAM)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002576
Linus Torvalds1da177e2005-04-16 15:20:36 -07002577static struct cdrom_device_ops ide_cdrom_dops = {
2578 .open = ide_cdrom_open_real,
2579 .release = ide_cdrom_release_real,
2580 .drive_status = ide_cdrom_drive_status,
2581 .media_changed = ide_cdrom_check_media_change_real,
2582 .tray_move = ide_cdrom_tray_move,
2583 .lock_door = ide_cdrom_lock_door,
2584 .select_speed = ide_cdrom_select_speed,
2585 .get_last_session = ide_cdrom_get_last_session,
2586 .get_mcn = ide_cdrom_get_mcn,
2587 .reset = ide_cdrom_reset,
2588 .audio_ioctl = ide_cdrom_audio_ioctl,
Bartlomiej Zolnierkiewicz20e7f7e2008-02-01 23:09:20 +01002589 .capability = IDE_CD_CAPABILITIES,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002590 .generic_packet = ide_cdrom_packet,
2591};
2592
2593static int ide_cdrom_register (ide_drive_t *drive, int nslots)
2594{
2595 struct cdrom_info *info = drive->driver_data;
2596 struct cdrom_device_info *devinfo = &info->devinfo;
2597
2598 devinfo->ops = &ide_cdrom_dops;
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002599 devinfo->speed = info->current_speed;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002600 devinfo->capacity = nslots;
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002601 devinfo->handle = drive;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002602 strcpy(devinfo->name, drive->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002603
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002604 if (info->cd_flags & IDE_CD_FLAG_NO_SPEED_SELECT)
Bartlomiej Zolnierkiewicz3cbd8142007-12-24 15:23:43 +01002605 devinfo->mask |= CDC_SELECT_SPEED;
2606
Linus Torvalds1da177e2005-04-16 15:20:36 -07002607 devinfo->disk = info->disk;
2608 return register_cdrom(devinfo);
2609}
2610
2611static
Linus Torvalds1da177e2005-04-16 15:20:36 -07002612int ide_cdrom_probe_capabilities (ide_drive_t *drive)
2613{
Bartlomiej Zolnierkiewicz4fe67172008-02-01 23:09:21 +01002614 struct cdrom_info *cd = drive->driver_data;
2615 struct cdrom_device_info *cdi = &cd->devinfo;
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002616 u8 buf[ATAPI_CAPABILITIES_PAGE_SIZE];
2617 mechtype_t mechtype;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002618 int nslots = 1;
2619
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002620 cdi->mask = (CDC_CD_R | CDC_CD_RW | CDC_DVD | CDC_DVD_R |
2621 CDC_DVD_RAM | CDC_SELECT_DISC | CDC_PLAY_AUDIO |
2622 CDC_MO_DRIVE | CDC_RAM);
2623
Linus Torvalds1da177e2005-04-16 15:20:36 -07002624 if (drive->media == ide_optical) {
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002625 cdi->mask &= ~(CDC_MO_DRIVE | CDC_RAM);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002626 printk(KERN_ERR "%s: ATAPI magneto-optical drive\n", drive->name);
2627 return nslots;
2628 }
2629
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002630 if ((cd->cd_flags & IDE_CD_FLAG_NEC260) ||
Linus Torvalds1da177e2005-04-16 15:20:36 -07002631 !strcmp(drive->id->model,"STINGRAY 8422 IDE 8X CD-ROM 7-27-95")) {
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002632 cd->cd_flags &= ~IDE_CD_FLAG_NO_EJECT;
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002633 cdi->mask &= ~CDC_PLAY_AUDIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002634 return nslots;
2635 }
2636
2637 /*
2638 * we have to cheat a little here. the packet will eventually
2639 * be queued with ide_cdrom_packet(), which extracts the
2640 * drive from cdi->handle. Since this device hasn't been
2641 * registered with the Uniform layer yet, it can't do this.
2642 * Same goes for cdi->ops.
2643 */
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002644 cdi->handle = drive;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002645 cdi->ops = &ide_cdrom_dops;
2646
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002647 if (ide_cdrom_get_capabilities(drive, buf))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002648 return 0;
2649
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002650 if ((buf[8 + 6] & 0x01) == 0)
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002651 cd->cd_flags |= IDE_CD_FLAG_NO_DOORLOCK;
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002652 if (buf[8 + 6] & 0x08)
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002653 cd->cd_flags &= ~IDE_CD_FLAG_NO_EJECT;
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002654 if (buf[8 + 3] & 0x01)
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002655 cdi->mask &= ~CDC_CD_R;
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002656 if (buf[8 + 3] & 0x02)
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002657 cdi->mask &= ~(CDC_CD_RW | CDC_RAM);
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002658 if (buf[8 + 2] & 0x38)
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002659 cdi->mask &= ~CDC_DVD;
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002660 if (buf[8 + 3] & 0x20)
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002661 cdi->mask &= ~(CDC_DVD_RAM | CDC_RAM);
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002662 if (buf[8 + 3] & 0x10)
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002663 cdi->mask &= ~CDC_DVD_R;
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002664 if (buf[8 + 4] & 0x01)
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002665 cdi->mask &= ~CDC_PLAY_AUDIO;
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002666
2667 mechtype = buf[8 + 6] >> 5;
2668 if (mechtype == mechtype_caddy || mechtype == mechtype_popup)
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002669 cdi->mask |= CDC_CLOSE_TRAY;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002670
2671 /* Some drives used by Apple don't advertise audio play
2672 * but they do support reading TOC & audio datas
2673 */
2674 if (strcmp(drive->id->model, "MATSHITADVD-ROM SR-8187") == 0 ||
2675 strcmp(drive->id->model, "MATSHITADVD-ROM SR-8186") == 0 ||
2676 strcmp(drive->id->model, "MATSHITADVD-ROM SR-8176") == 0 ||
2677 strcmp(drive->id->model, "MATSHITADVD-ROM SR-8174") == 0)
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002678 cdi->mask &= ~CDC_PLAY_AUDIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002679
Linus Torvalds1da177e2005-04-16 15:20:36 -07002680 if (cdi->sanyo_slot > 0) {
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002681 cdi->mask &= ~CDC_SELECT_DISC;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002682 nslots = 3;
Bartlomiej Zolnierkiewiczcdf60002008-02-01 23:09:22 +01002683 } else if (mechtype == mechtype_individual_changer ||
2684 mechtype == mechtype_cartridge_changer) {
Bartlomiej Zolnierkiewicz2609d062008-02-01 23:09:19 +01002685 nslots = cdrom_number_of_slots(cdi);
2686 if (nslots > 1)
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002687 cdi->mask &= ~CDC_SELECT_DISC;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002688 }
2689
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002690 ide_cdrom_update_speed(drive, buf);
Bartlomiej Zolnierkiewicz4fe67172008-02-01 23:09:21 +01002691
Linus Torvalds1da177e2005-04-16 15:20:36 -07002692 printk(KERN_INFO "%s: ATAPI", drive->name);
Bartlomiej Zolnierkiewicz4fe67172008-02-01 23:09:21 +01002693
2694 /* don't print speed if the drive reported 0 */
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002695 if (cd->max_speed)
2696 printk(KERN_CONT " %dX", cd->max_speed);
Bartlomiej Zolnierkiewicz4fe67172008-02-01 23:09:21 +01002697
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002698 printk(KERN_CONT " %s", (cdi->mask & CDC_DVD) ? "CD-ROM" : "DVD-ROM");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002699
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002700 if ((cdi->mask & CDC_DVD_R) == 0 || (cdi->mask & CDC_DVD_RAM) == 0)
2701 printk(KERN_CONT " DVD%s%s",
2702 (cdi->mask & CDC_DVD_R) ? "" : "-R",
2703 (cdi->mask & CDC_DVD_RAM) ? "" : "-RAM");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002704
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002705 if ((cdi->mask & CDC_CD_R) == 0 || (cdi->mask & CDC_CD_RW) == 0)
2706 printk(KERN_CONT " CD%s%s",
2707 (cdi->mask & CDC_CD_R) ? "" : "-R",
2708 (cdi->mask & CDC_CD_RW) ? "" : "/RW");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002709
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002710 if ((cdi->mask & CDC_SELECT_DISC) == 0)
2711 printk(KERN_CONT " changer w/%d slots", nslots);
2712 else
2713 printk(KERN_CONT " drive");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002714
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002715 printk(KERN_CONT ", %dkB Cache\n", be16_to_cpu(*(u16 *)&buf[8 + 12]));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002716
2717 return nslots;
2718}
2719
Bartlomiej Zolnierkiewicz7662d042007-05-10 00:01:10 +02002720#ifdef CONFIG_IDE_PROC_FS
Linus Torvalds1da177e2005-04-16 15:20:36 -07002721static void ide_cdrom_add_settings(ide_drive_t *drive)
2722{
Bartlomiej Zolnierkiewicz14979432007-05-10 00:01:10 +02002723 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 -07002724}
Bartlomiej Zolnierkiewicz7662d042007-05-10 00:01:10 +02002725#else
2726static inline void ide_cdrom_add_settings(ide_drive_t *drive) { ; }
2727#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07002728
2729/*
2730 * standard prep_rq_fn that builds 10 byte cmds
2731 */
Jens Axboe165125e2007-07-24 09:28:11 +02002732static int ide_cdrom_prep_fs(struct request_queue *q, struct request *rq)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002733{
2734 int hard_sect = queue_hardsect_size(q);
2735 long block = (long)rq->hard_sector / (hard_sect >> 9);
2736 unsigned long blocks = rq->hard_nr_sectors / (hard_sect >> 9);
2737
2738 memset(rq->cmd, 0, sizeof(rq->cmd));
2739
2740 if (rq_data_dir(rq) == READ)
2741 rq->cmd[0] = GPCMD_READ_10;
2742 else
2743 rq->cmd[0] = GPCMD_WRITE_10;
2744
2745 /*
2746 * fill in lba
2747 */
2748 rq->cmd[2] = (block >> 24) & 0xff;
2749 rq->cmd[3] = (block >> 16) & 0xff;
2750 rq->cmd[4] = (block >> 8) & 0xff;
2751 rq->cmd[5] = block & 0xff;
2752
2753 /*
2754 * and transfer length
2755 */
2756 rq->cmd[7] = (blocks >> 8) & 0xff;
2757 rq->cmd[8] = blocks & 0xff;
2758 rq->cmd_len = 10;
2759 return BLKPREP_OK;
2760}
2761
2762/*
2763 * Most of the SCSI commands are supported directly by ATAPI devices.
2764 * This transform handles the few exceptions.
2765 */
2766static int ide_cdrom_prep_pc(struct request *rq)
2767{
2768 u8 *c = rq->cmd;
2769
2770 /*
2771 * Transform 6-byte read/write commands to the 10-byte version
2772 */
2773 if (c[0] == READ_6 || c[0] == WRITE_6) {
2774 c[8] = c[4];
2775 c[5] = c[3];
2776 c[4] = c[2];
2777 c[3] = c[1] & 0x1f;
2778 c[2] = 0;
2779 c[1] &= 0xe0;
2780 c[0] += (READ_10 - READ_6);
2781 rq->cmd_len = 10;
2782 return BLKPREP_OK;
2783 }
2784
2785 /*
2786 * it's silly to pretend we understand 6-byte sense commands, just
2787 * reject with ILLEGAL_REQUEST and the caller should take the
2788 * appropriate action
2789 */
2790 if (c[0] == MODE_SENSE || c[0] == MODE_SELECT) {
2791 rq->errors = ILLEGAL_REQUEST;
2792 return BLKPREP_KILL;
2793 }
2794
2795 return BLKPREP_OK;
2796}
2797
Jens Axboe165125e2007-07-24 09:28:11 +02002798static int ide_cdrom_prep_fn(struct request_queue *q, struct request *rq)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002799{
Jens Axboe4aff5e22006-08-10 08:44:47 +02002800 if (blk_fs_request(rq))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002801 return ide_cdrom_prep_fs(q, rq);
Jens Axboe4aff5e22006-08-10 08:44:47 +02002802 else if (blk_pc_request(rq))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002803 return ide_cdrom_prep_pc(rq);
2804
2805 return 0;
2806}
2807
2808static
2809int ide_cdrom_setup (ide_drive_t *drive)
2810{
Bartlomiej Zolnierkiewicz4fe67172008-02-01 23:09:21 +01002811 struct cdrom_info *cd = drive->driver_data;
2812 struct cdrom_device_info *cdi = &cd->devinfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002813 int nslots;
2814
2815 blk_queue_prep_rq(drive->queue, ide_cdrom_prep_fn);
2816 blk_queue_dma_alignment(drive->queue, 31);
2817 drive->queue->unplug_delay = (1 * HZ) / 1000;
2818 if (!drive->queue->unplug_delay)
2819 drive->queue->unplug_delay = 1;
2820
2821 drive->special.all = 0;
2822
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002823 cd->cd_flags |= IDE_CD_FLAG_MEDIA_CHANGED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002824
Bartlomiej Zolnierkiewiczb8d25de2008-02-01 23:09:19 +01002825 if ((drive->id->config & 0x0060) == 0x20)
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002826 cd->cd_flags |= IDE_CD_FLAG_DRQ_INTERRUPT;
2827 cd->cd_flags |= IDE_CD_FLAG_NO_EJECT;
Bartlomiej Zolnierkiewiczb8d25de2008-02-01 23:09:19 +01002828
Linus Torvalds1da177e2005-04-16 15:20:36 -07002829 /* limit transfer size per interrupt. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002830 /* a testament to the nice quality of Samsung drives... */
Bartlomiej Zolnierkiewicz4fe67172008-02-01 23:09:21 +01002831 if (!strcmp(drive->id->model, "SAMSUNG CD-ROM SCR-2430") ||
2832 !strcmp(drive->id->model, "SAMSUNG CD-ROM SCR-2432"))
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002833 cd->cd_flags |= IDE_CD_FLAG_LIMIT_NFRAMES;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002834 /* the 3231 model does not support the SET_CD_SPEED command */
2835 else if (!strcmp(drive->id->model, "SAMSUNG CD-ROM SCR-3231"))
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002836 cd->cd_flags |= IDE_CD_FLAG_NO_SPEED_SELECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002837
Linus Torvalds1da177e2005-04-16 15:20:36 -07002838 if (strcmp (drive->id->model, "V003S0DS") == 0 &&
2839 drive->id->fw_rev[4] == '1' &&
2840 drive->id->fw_rev[6] <= '2') {
2841 /* Vertos 300.
2842 Some versions of this drive like to talk BCD. */
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002843 cd->cd_flags |= (IDE_CD_FLAG_TOCTRACKS_AS_BCD |
2844 IDE_CD_FLAG_TOCADDR_AS_BCD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002845 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002846 else if (strcmp (drive->id->model, "V006E0DS") == 0 &&
2847 drive->id->fw_rev[4] == '1' &&
2848 drive->id->fw_rev[6] <= '2') {
2849 /* Vertos 600 ESD. */
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002850 cd->cd_flags |= IDE_CD_FLAG_TOCTRACKS_AS_BCD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002851 }
2852 else if (strcmp(drive->id->model, "NEC CD-ROM DRIVE:260") == 0 &&
2853 strncmp(drive->id->fw_rev, "1.01", 4) == 0) { /* FIXME */
2854 /* Old NEC260 (not R).
2855 This drive was released before the 1.2 version
2856 of the spec. */
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002857 cd->cd_flags |= (IDE_CD_FLAG_TOCADDR_AS_BCD |
2858 IDE_CD_FLAG_NEC260);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002859 }
Bartlomiej Zolnierkiewiczb8d25de2008-02-01 23:09:19 +01002860 /*
2861 * Sanyo 3 CD changer uses a non-standard command for CD changing
2862 * (by default standard ATAPI support for CD changers is used).
2863 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002864 else if ((strcmp(drive->id->model, "CD-ROM CDR-C3 G") == 0) ||
2865 (strcmp(drive->id->model, "CD-ROM CDR-C3G") == 0) ||
2866 (strcmp(drive->id->model, "CD-ROM CDR_C36") == 0)) {
2867 /* uses CD in slot 0 when value is set to 3 */
2868 cdi->sanyo_slot = 3;
2869 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002870
Linus Torvalds1da177e2005-04-16 15:20:36 -07002871 nslots = ide_cdrom_probe_capabilities (drive);
2872
2873 /*
2874 * set correct block size
2875 */
2876 blk_queue_hardsect_size(drive->queue, CD_FRAMESIZE);
2877
2878 if (drive->autotune == IDE_TUNE_DEFAULT ||
2879 drive->autotune == IDE_TUNE_AUTO)
2880 drive->dsc_overlap = (drive->next != drive);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002881
2882 if (ide_cdrom_register(drive, nslots)) {
2883 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 +01002884 cd->devinfo.handle = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002885 return 1;
2886 }
2887 ide_cdrom_add_settings(drive);
2888 return 0;
2889}
2890
Bartlomiej Zolnierkiewiczecfd80e2007-05-10 00:01:09 +02002891#ifdef CONFIG_IDE_PROC_FS
Linus Torvalds1da177e2005-04-16 15:20:36 -07002892static
2893sector_t ide_cdrom_capacity (ide_drive_t *drive)
2894{
2895 unsigned long capacity, sectors_per_frame;
2896
2897 if (cdrom_read_capacity(drive, &capacity, &sectors_per_frame, NULL))
2898 return 0;
2899
2900 return capacity * sectors_per_frame;
2901}
Amos Waterlandd97b32142005-10-30 15:02:10 -08002902#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07002903
Russell King4031bbe2006-01-06 11:41:00 +00002904static void ide_cd_remove(ide_drive_t *drive)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002905{
2906 struct cdrom_info *info = drive->driver_data;
2907
Bartlomiej Zolnierkiewicz7662d042007-05-10 00:01:10 +02002908 ide_proc_unregister_driver(drive, info->driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002909
2910 del_gendisk(info->disk);
2911
2912 ide_cd_put(info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002913}
2914
2915static void ide_cd_release(struct kref *kref)
2916{
2917 struct cdrom_info *info = to_ide_cd(kref);
2918 struct cdrom_device_info *devinfo = &info->devinfo;
2919 ide_drive_t *drive = info->drive;
2920 struct gendisk *g = info->disk;
2921
Jesper Juhl6044ec82005-11-07 01:01:32 -08002922 kfree(info->buffer);
2923 kfree(info->toc);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002924 if (devinfo->handle == drive && unregister_cdrom(devinfo))
2925 printk(KERN_ERR "%s: %s failed to unregister device from the cdrom "
2926 "driver.\n", __FUNCTION__, drive->name);
2927 drive->dsc_overlap = 0;
2928 drive->driver_data = NULL;
2929 blk_queue_prep_rq(drive->queue, NULL);
2930 g->private_data = NULL;
2931 put_disk(g);
2932 kfree(info);
2933}
2934
Russell King4031bbe2006-01-06 11:41:00 +00002935static int ide_cd_probe(ide_drive_t *);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002936
Bartlomiej Zolnierkiewiczecfd80e2007-05-10 00:01:09 +02002937#ifdef CONFIG_IDE_PROC_FS
Linus Torvalds1da177e2005-04-16 15:20:36 -07002938static int proc_idecd_read_capacity
2939 (char *page, char **start, off_t off, int count, int *eof, void *data)
2940{
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002941 ide_drive_t *drive = data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002942 int len;
2943
2944 len = sprintf(page,"%llu\n", (long long)ide_cdrom_capacity(drive));
2945 PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
2946}
2947
2948static ide_proc_entry_t idecd_proc[] = {
2949 { "capacity", S_IFREG|S_IRUGO, proc_idecd_read_capacity, NULL },
2950 { NULL, 0, NULL, NULL }
2951};
Linus Torvalds1da177e2005-04-16 15:20:36 -07002952#endif
2953
2954static ide_driver_t ide_cdrom_driver = {
Bartlomiej Zolnierkiewicz8604aff2005-05-26 14:55:34 +02002955 .gen_driver = {
Laurent Riffard4ef3b8f2005-11-18 22:15:40 +01002956 .owner = THIS_MODULE,
Bartlomiej Zolnierkiewicz8604aff2005-05-26 14:55:34 +02002957 .name = "ide-cdrom",
2958 .bus = &ide_bus_type,
Bartlomiej Zolnierkiewicz8604aff2005-05-26 14:55:34 +02002959 },
Russell King4031bbe2006-01-06 11:41:00 +00002960 .probe = ide_cd_probe,
2961 .remove = ide_cd_remove,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002962 .version = IDECD_VERSION,
2963 .media = ide_cdrom,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002964 .supports_dsc_overlap = 1,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002965 .do_request = ide_do_rw_cdrom,
2966 .end_request = ide_end_request,
2967 .error = __ide_error,
2968 .abort = __ide_abort,
Bartlomiej Zolnierkiewicz7662d042007-05-10 00:01:10 +02002969#ifdef CONFIG_IDE_PROC_FS
Linus Torvalds1da177e2005-04-16 15:20:36 -07002970 .proc = idecd_proc,
Bartlomiej Zolnierkiewicz7662d042007-05-10 00:01:10 +02002971#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07002972};
2973
2974static int idecd_open(struct inode * inode, struct file * file)
2975{
2976 struct gendisk *disk = inode->i_bdev->bd_disk;
2977 struct cdrom_info *info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002978 int rc = -ENOMEM;
2979
2980 if (!(info = ide_cd_get(disk)))
2981 return -ENXIO;
2982
Linus Torvalds1da177e2005-04-16 15:20:36 -07002983 if (!info->buffer)
Bartlomiej Zolnierkiewiczc94964a2007-02-17 02:40:24 +01002984 info->buffer = kmalloc(SECTOR_BUFFER_SIZE, GFP_KERNEL|__GFP_REPEAT);
2985
2986 if (info->buffer)
2987 rc = cdrom_open(&info->devinfo, inode, file);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002988
2989 if (rc < 0)
2990 ide_cd_put(info);
2991
2992 return rc;
2993}
2994
2995static int idecd_release(struct inode * inode, struct file * file)
2996{
2997 struct gendisk *disk = inode->i_bdev->bd_disk;
2998 struct cdrom_info *info = ide_cd_g(disk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002999
3000 cdrom_release (&info->devinfo, file);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003001
3002 ide_cd_put(info);
3003
3004 return 0;
3005}
3006
Christoph Hellwig6a2900b2006-03-23 03:00:15 -08003007static int idecd_set_spindown(struct cdrom_device_info *cdi, unsigned long arg)
3008{
3009 struct packet_command cgc;
3010 char buffer[16];
3011 int stat;
3012 char spindown;
3013
3014 if (copy_from_user(&spindown, (void __user *)arg, sizeof(char)))
3015 return -EFAULT;
3016
3017 init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_UNKNOWN);
3018
3019 stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CDROM_PAGE, 0);
3020 if (stat)
3021 return stat;
3022
3023 buffer[11] = (buffer[11] & 0xf0) | (spindown & 0x0f);
3024 return cdrom_mode_select(cdi, &cgc);
3025}
3026
3027static int idecd_get_spindown(struct cdrom_device_info *cdi, unsigned long arg)
3028{
3029 struct packet_command cgc;
3030 char buffer[16];
3031 int stat;
3032 char spindown;
3033
3034 init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_UNKNOWN);
3035
3036 stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CDROM_PAGE, 0);
3037 if (stat)
3038 return stat;
3039
3040 spindown = buffer[11] & 0x0f;
3041 if (copy_to_user((void __user *)arg, &spindown, sizeof (char)))
3042 return -EFAULT;
3043 return 0;
3044}
3045
Linus Torvalds1da177e2005-04-16 15:20:36 -07003046static int idecd_ioctl (struct inode *inode, struct file *file,
3047 unsigned int cmd, unsigned long arg)
3048{
3049 struct block_device *bdev = inode->i_bdev;
3050 struct cdrom_info *info = ide_cd_g(bdev->bd_disk);
3051 int err;
3052
Christoph Hellwig6a2900b2006-03-23 03:00:15 -08003053 switch (cmd) {
3054 case CDROMSETSPINDOWN:
3055 return idecd_set_spindown(&info->devinfo, arg);
3056 case CDROMGETSPINDOWN:
3057 return idecd_get_spindown(&info->devinfo, arg);
3058 default:
3059 break;
3060 }
3061
3062 err = generic_ide_ioctl(info->drive, file, bdev, cmd, arg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003063 if (err == -EINVAL)
3064 err = cdrom_ioctl(file, &info->devinfo, inode, cmd, arg);
3065
3066 return err;
3067}
3068
3069static int idecd_media_changed(struct gendisk *disk)
3070{
3071 struct cdrom_info *info = ide_cd_g(disk);
3072 return cdrom_media_changed(&info->devinfo);
3073}
3074
3075static int idecd_revalidate_disk(struct gendisk *disk)
3076{
3077 struct cdrom_info *info = ide_cd_g(disk);
3078 struct request_sense sense;
3079 cdrom_read_toc(info->drive, &sense);
3080 return 0;
3081}
3082
3083static struct block_device_operations idecd_ops = {
3084 .owner = THIS_MODULE,
3085 .open = idecd_open,
3086 .release = idecd_release,
3087 .ioctl = idecd_ioctl,
3088 .media_changed = idecd_media_changed,
3089 .revalidate_disk= idecd_revalidate_disk
3090};
3091
3092/* options */
3093static char *ignore = NULL;
3094
3095module_param(ignore, charp, 0400);
3096MODULE_DESCRIPTION("ATAPI CD-ROM Driver");
3097
Russell King4031bbe2006-01-06 11:41:00 +00003098static int ide_cd_probe(ide_drive_t *drive)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003099{
3100 struct cdrom_info *info;
3101 struct gendisk *g;
3102 struct request_sense sense;
3103
3104 if (!strstr("ide-cdrom", drive->driver_req))
3105 goto failed;
3106 if (!drive->present)
3107 goto failed;
3108 if (drive->media != ide_cdrom && drive->media != ide_optical)
3109 goto failed;
3110 /* skip drives that we were told to ignore */
3111 if (ignore != NULL) {
3112 if (strstr(ignore, drive->name)) {
3113 printk(KERN_INFO "ide-cd: ignoring drive %s\n", drive->name);
3114 goto failed;
3115 }
3116 }
3117 if (drive->scsi) {
3118 printk(KERN_INFO "ide-cd: passing drive %s to ide-scsi emulation.\n", drive->name);
3119 goto failed;
3120 }
Deepak Saxenaf5e3c2f2005-11-07 01:01:25 -08003121 info = kzalloc(sizeof(struct cdrom_info), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003122 if (info == NULL) {
3123 printk(KERN_ERR "%s: Can't allocate a cdrom structure\n", drive->name);
3124 goto failed;
3125 }
3126
3127 g = alloc_disk(1 << PARTN_BITS);
3128 if (!g)
3129 goto out_free_cd;
3130
3131 ide_init_disk(g, drive);
3132
Bartlomiej Zolnierkiewicz7662d042007-05-10 00:01:10 +02003133 ide_proc_register_driver(drive, &ide_cdrom_driver);
Bartlomiej Zolnierkiewicz8604aff2005-05-26 14:55:34 +02003134
Linus Torvalds1da177e2005-04-16 15:20:36 -07003135 kref_init(&info->kref);
3136
3137 info->drive = drive;
3138 info->driver = &ide_cdrom_driver;
3139 info->disk = g;
3140
3141 g->private_data = &info->driver;
3142
3143 drive->driver_data = info;
3144
Linus Torvalds1da177e2005-04-16 15:20:36 -07003145 g->minors = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003146 g->driverfs_dev = &drive->gendev;
3147 g->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE;
3148 if (ide_cdrom_setup(drive)) {
Bartlomiej Zolnierkiewicz7662d042007-05-10 00:01:10 +02003149 ide_proc_unregister_driver(drive, &ide_cdrom_driver);
Bartlomiej Zolnierkiewicz05017db2007-12-24 15:23:43 +01003150 ide_cd_release(&info->kref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003151 goto failed;
3152 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003153
3154 cdrom_read_toc(drive, &sense);
3155 g->fops = &idecd_ops;
3156 g->flags |= GENHD_FL_REMOVABLE;
3157 add_disk(g);
3158 return 0;
3159
Linus Torvalds1da177e2005-04-16 15:20:36 -07003160out_free_cd:
3161 kfree(info);
3162failed:
Bartlomiej Zolnierkiewicz8604aff2005-05-26 14:55:34 +02003163 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003164}
3165
3166static void __exit ide_cdrom_exit(void)
3167{
Bartlomiej Zolnierkiewicz8604aff2005-05-26 14:55:34 +02003168 driver_unregister(&ide_cdrom_driver.gen_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003169}
Bartlomiej Zolnierkiewicz17514e82005-11-19 22:24:35 +01003170
3171static int __init ide_cdrom_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003172{
Bartlomiej Zolnierkiewicz8604aff2005-05-26 14:55:34 +02003173 return driver_register(&ide_cdrom_driver.gen_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003174}
3175
Kay Sievers263756e2005-12-12 18:03:44 +01003176MODULE_ALIAS("ide:*m-cdrom*");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003177module_init(ide_cdrom_init);
3178module_exit(ide_cdrom_exit);
3179MODULE_LICENSE("GPL");