blob: 945d730617c87d5a1137b7fec3989257963a5b23 [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>
Linus Torvalds1da177e2005-04-16 15:20:36 -070049
50#include <scsi/scsi.h> /* For SCSI -> ATAPI command conversion */
51
52#include <asm/irq.h>
53#include <asm/io.h>
54#include <asm/byteorder.h>
55#include <asm/uaccess.h>
56#include <asm/unaligned.h>
57
58#include "ide-cd.h"
59
Arjan van de Vencf8b8972006-03-23 03:00:45 -080060static DEFINE_MUTEX(idecd_ref_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -070061
62#define to_ide_cd(obj) container_of(obj, struct cdrom_info, kref)
63
64#define ide_cd_g(disk) \
65 container_of((disk)->private_data, struct cdrom_info, driver)
66
67static struct cdrom_info *ide_cd_get(struct gendisk *disk)
68{
69 struct cdrom_info *cd = NULL;
70
Arjan van de Vencf8b8972006-03-23 03:00:45 -080071 mutex_lock(&idecd_ref_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -070072 cd = ide_cd_g(disk);
73 if (cd)
74 kref_get(&cd->kref);
Arjan van de Vencf8b8972006-03-23 03:00:45 -080075 mutex_unlock(&idecd_ref_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -070076 return cd;
77}
78
79static void ide_cd_release(struct kref *);
80
81static void ide_cd_put(struct cdrom_info *cd)
82{
Arjan van de Vencf8b8972006-03-23 03:00:45 -080083 mutex_lock(&idecd_ref_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -070084 kref_put(&cd->kref, ide_cd_release);
Arjan van de Vencf8b8972006-03-23 03:00:45 -080085 mutex_unlock(&idecd_ref_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -070086}
87
88/****************************************************************************
89 * Generic packet command support and error handling routines.
90 */
91
92/* Mark that we've seen a media change, and invalidate our internal
93 buffers. */
94static void cdrom_saw_media_change (ide_drive_t *drive)
95{
96 struct cdrom_info *info = drive->driver_data;
97
98 CDROM_STATE_FLAGS (drive)->media_changed = 1;
99 CDROM_STATE_FLAGS (drive)->toc_valid = 0;
100 info->nsectors_buffered = 0;
101}
102
103static int cdrom_log_sense(ide_drive_t *drive, struct request *rq,
104 struct request_sense *sense)
105{
106 int log = 0;
107
Jens Axboe4aff5e22006-08-10 08:44:47 +0200108 if (!sense || !rq || (rq->cmd_flags & REQ_QUIET))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700109 return 0;
110
111 switch (sense->sense_key) {
112 case NO_SENSE: case RECOVERED_ERROR:
113 break;
114 case NOT_READY:
115 /*
116 * don't care about tray state messages for
117 * e.g. capacity commands or in-progress or
118 * becoming ready
119 */
120 if (sense->asc == 0x3a || sense->asc == 0x04)
121 break;
122 log = 1;
123 break;
124 case ILLEGAL_REQUEST:
125 /*
126 * don't log START_STOP unit with LoEj set, since
127 * we cannot reliably check if drive can auto-close
128 */
129 if (rq->cmd[0] == GPCMD_START_STOP_UNIT && sense->asc == 0x24)
Alan Coxdbe217a2006-06-25 05:47:44 -0700130 break;
131 log = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700132 break;
133 case UNIT_ATTENTION:
134 /*
135 * Make good and sure we've seen this potential media
136 * change. Some drives (i.e. Creative) fail to present
137 * the correct sense key in the error register.
138 */
139 cdrom_saw_media_change(drive);
140 break;
141 default:
142 log = 1;
143 break;
144 }
145 return log;
146}
147
148static
149void cdrom_analyze_sense_data(ide_drive_t *drive,
150 struct request *failed_command,
151 struct request_sense *sense)
152{
Alan Coxdbe217a2006-06-25 05:47:44 -0700153 unsigned long sector;
154 unsigned long bio_sectors;
155 unsigned long valid;
156 struct cdrom_info *info = drive->driver_data;
157
Linus Torvalds1da177e2005-04-16 15:20:36 -0700158 if (!cdrom_log_sense(drive, failed_command, sense))
159 return;
160
161 /*
162 * If a read toc is executed for a CD-R or CD-RW medium where
163 * the first toc has not been recorded yet, it will fail with
164 * 05/24/00 (which is a confusing error)
165 */
166 if (failed_command && failed_command->cmd[0] == GPCMD_READ_TOC_PMA_ATIP)
167 if (sense->sense_key == 0x05 && sense->asc == 0x24)
168 return;
169
Alan Coxdbe217a2006-06-25 05:47:44 -0700170 if (sense->error_code == 0x70) { /* Current Error */
171 switch(sense->sense_key) {
172 case MEDIUM_ERROR:
173 case VOLUME_OVERFLOW:
174 case ILLEGAL_REQUEST:
175 if (!sense->valid)
176 break;
177 if (failed_command == NULL ||
178 !blk_fs_request(failed_command))
179 break;
180 sector = (sense->information[0] << 24) |
181 (sense->information[1] << 16) |
182 (sense->information[2] << 8) |
183 (sense->information[3]);
184
185 bio_sectors = bio_sectors(failed_command->bio);
186 if (bio_sectors < 4)
187 bio_sectors = 4;
188 if (drive->queue->hardsect_size == 2048)
189 sector <<= 2; /* Device sector size is 2K */
190 sector &= ~(bio_sectors -1);
191 valid = (sector - failed_command->sector) << 9;
192
193 if (valid < 0)
194 valid = 0;
195 if (sector < get_capacity(info->disk) &&
196 drive->probed_capacity - sector < 4 * 75) {
197 set_capacity(info->disk, sector);
198 }
199 }
200 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700201#if VERBOSE_IDE_CD_ERRORS
202 {
203 int i;
Matt Mackall70d1d472005-07-12 13:58:09 -0700204 const char *s = "bad sense key!";
Linus Torvalds1da177e2005-04-16 15:20:36 -0700205 char buf[80];
206
207 printk ("ATAPI device %s:\n", drive->name);
208 if (sense->error_code==0x70)
209 printk(" Error: ");
210 else if (sense->error_code==0x71)
211 printk(" Deferred Error: ");
212 else if (sense->error_code == 0x7f)
213 printk(" Vendor-specific Error: ");
214 else
215 printk(" Unknown Error Type: ");
216
Robert P. J. Day74c8f972007-07-09 23:17:57 +0200217 if (sense->sense_key < ARRAY_SIZE(sense_key_texts))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700218 s = sense_key_texts[sense->sense_key];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700219
220 printk("%s -- (Sense key=0x%02x)\n", s, sense->sense_key);
221
222 if (sense->asc == 0x40) {
223 sprintf(buf, "Diagnostic failure on component 0x%02x",
224 sense->ascq);
225 s = buf;
226 } else {
Robert P. J. Day74c8f972007-07-09 23:17:57 +0200227 int lo = 0, mid, hi = ARRAY_SIZE(sense_data_texts);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700228 unsigned long key = (sense->sense_key << 16);
229 key |= (sense->asc << 8);
230 if (!(sense->ascq >= 0x80 && sense->ascq <= 0xdd))
231 key |= sense->ascq;
232 s = NULL;
233
234 while (hi > lo) {
235 mid = (lo + hi) / 2;
236 if (sense_data_texts[mid].asc_ascq == key ||
237 sense_data_texts[mid].asc_ascq == (0xff0000|key)) {
238 s = sense_data_texts[mid].text;
239 break;
240 }
241 else if (sense_data_texts[mid].asc_ascq > key)
242 hi = mid;
243 else
244 lo = mid+1;
245 }
246 }
247
248 if (s == NULL) {
249 if (sense->asc > 0x80)
250 s = "(vendor-specific error)";
251 else
252 s = "(reserved error code)";
253 }
254
255 printk(KERN_ERR " %s -- (asc=0x%02x, ascq=0x%02x)\n",
256 s, sense->asc, sense->ascq);
257
258 if (failed_command != NULL) {
259
Robert P. J. Day74c8f972007-07-09 23:17:57 +0200260 int lo=0, mid, hi= ARRAY_SIZE(packet_command_texts);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700261 s = NULL;
262
263 while (hi > lo) {
264 mid = (lo + hi) / 2;
265 if (packet_command_texts[mid].packet_command ==
266 failed_command->cmd[0]) {
267 s = packet_command_texts[mid].text;
268 break;
269 }
270 if (packet_command_texts[mid].packet_command >
271 failed_command->cmd[0])
272 hi = mid;
273 else
274 lo = mid+1;
275 }
276
277 printk (KERN_ERR " The failed \"%s\" packet command was: \n \"", s);
278 for (i=0; i<sizeof (failed_command->cmd); i++)
279 printk ("%02x ", failed_command->cmd[i]);
280 printk ("\"\n");
281 }
282
283 /* The SKSV bit specifies validity of the sense_key_specific
284 * in the next two commands. It is bit 7 of the first byte.
285 * In the case of NOT_READY, if SKSV is set the drive can
286 * give us nice ETA readings.
287 */
288 if (sense->sense_key == NOT_READY && (sense->sks[0] & 0x80)) {
289 int progress = (sense->sks[1] << 8 | sense->sks[2]) * 100;
290 printk(KERN_ERR " Command is %02d%% complete\n", progress / 0xffff);
291
292 }
293
294 if (sense->sense_key == ILLEGAL_REQUEST &&
295 (sense->sks[0] & 0x80) != 0) {
296 printk(KERN_ERR " Error in %s byte %d",
297 (sense->sks[0] & 0x40) != 0 ?
298 "command packet" : "command data",
299 (sense->sks[1] << 8) + sense->sks[2]);
300
301 if ((sense->sks[0] & 0x40) != 0)
302 printk (" bit %d", sense->sks[0] & 0x07);
303
304 printk ("\n");
305 }
306 }
307
308#else /* not VERBOSE_IDE_CD_ERRORS */
309
310 /* Suppress printing unit attention and `in progress of becoming ready'
311 errors when we're not being verbose. */
312
313 if (sense->sense_key == UNIT_ATTENTION ||
314 (sense->sense_key == NOT_READY && (sense->asc == 4 ||
315 sense->asc == 0x3a)))
316 return;
317
318 printk(KERN_ERR "%s: error code: 0x%02x sense_key: 0x%02x asc: 0x%02x ascq: 0x%02x\n",
319 drive->name,
320 sense->error_code, sense->sense_key,
321 sense->asc, sense->ascq);
322#endif /* not VERBOSE_IDE_CD_ERRORS */
323}
324
325/*
326 * Initialize a ide-cd packet command request
327 */
328static void cdrom_prepare_request(ide_drive_t *drive, struct request *rq)
329{
330 struct cdrom_info *cd = drive->driver_data;
331
332 ide_init_drive_cmd(rq);
Jens Axboecea28852006-10-12 15:08:45 +0200333 rq->cmd_type = REQ_TYPE_ATA_PC;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700334 rq->rq_disk = cd->disk;
335}
336
337static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense,
338 struct request *failed_command)
339{
340 struct cdrom_info *info = drive->driver_data;
341 struct request *rq = &info->request_sense_request;
342
343 if (sense == NULL)
344 sense = &info->sense_data;
345
346 /* stuff the sense request in front of our current request */
347 cdrom_prepare_request(drive, rq);
348
349 rq->data = sense;
350 rq->cmd[0] = GPCMD_REQUEST_SENSE;
351 rq->cmd[4] = rq->data_len = 18;
352
Jens Axboe4aff5e22006-08-10 08:44:47 +0200353 rq->cmd_type = REQ_TYPE_SENSE;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700354
355 /* NOTE! Save the failed command in "rq->buffer" */
356 rq->buffer = (void *) failed_command;
357
358 (void) ide_do_drive_cmd(drive, rq, ide_preempt);
359}
360
361static void cdrom_end_request (ide_drive_t *drive, int uptodate)
362{
363 struct request *rq = HWGROUP(drive)->rq;
364 int nsectors = rq->hard_cur_sectors;
365
Jens Axboe4aff5e22006-08-10 08:44:47 +0200366 if (blk_sense_request(rq) && uptodate) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700367 /*
Jens Axboe4aff5e22006-08-10 08:44:47 +0200368 * For REQ_TYPE_SENSE, "rq->buffer" points to the original
369 * failed request
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370 */
371 struct request *failed = (struct request *) rq->buffer;
372 struct cdrom_info *info = drive->driver_data;
373 void *sense = &info->sense_data;
374 unsigned long flags;
375
376 if (failed) {
377 if (failed->sense) {
378 sense = failed->sense;
379 failed->sense_len = rq->sense_len;
380 }
Alan Coxdbe217a2006-06-25 05:47:44 -0700381 cdrom_analyze_sense_data(drive, failed, sense);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700382 /*
383 * now end failed request
384 */
Alan Coxdbe217a2006-06-25 05:47:44 -0700385 if (blk_fs_request(failed)) {
386 if (ide_end_dequeued_request(drive, failed, 0,
387 failed->hard_nr_sectors))
388 BUG();
389 } else {
390 spin_lock_irqsave(&ide_lock, flags);
Kiyoshi Ueda5e36bb62008-01-28 10:34:20 +0100391 if (__blk_end_request(failed, -EIO,
392 failed->data_len))
393 BUG();
Alan Coxdbe217a2006-06-25 05:47:44 -0700394 spin_unlock_irqrestore(&ide_lock, flags);
395 }
396 } else
397 cdrom_analyze_sense_data(drive, NULL, sense);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700398 }
399
400 if (!rq->current_nr_sectors && blk_fs_request(rq))
401 uptodate = 1;
402 /* make sure it's fully ended */
403 if (blk_pc_request(rq))
404 nsectors = (rq->data_len + 511) >> 9;
405 if (!nsectors)
406 nsectors = 1;
407
408 ide_end_request(drive, uptodate, nsectors);
409}
410
Alan Coxdbe217a2006-06-25 05:47:44 -0700411static void ide_dump_status_no_sense(ide_drive_t *drive, const char *msg, u8 stat)
412{
413 if (stat & 0x80)
414 return;
415 ide_dump_status(drive, msg, stat);
416}
417
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418/* Returns 0 if the request should be continued.
419 Returns 1 if the request was ended. */
420static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
421{
422 struct request *rq = HWGROUP(drive)->rq;
423 int stat, err, sense_key;
424
425 /* Check for errors. */
426 stat = HWIF(drive)->INB(IDE_STATUS_REG);
427 if (stat_ret)
428 *stat_ret = stat;
429
430 if (OK_STAT(stat, good_stat, BAD_R_STAT))
431 return 0;
432
433 /* Get the IDE error register. */
434 err = HWIF(drive)->INB(IDE_ERROR_REG);
435 sense_key = err >> 4;
436
437 if (rq == NULL) {
438 printk("%s: missing rq in cdrom_decode_status\n", drive->name);
439 return 1;
440 }
441
Jens Axboe4aff5e22006-08-10 08:44:47 +0200442 if (blk_sense_request(rq)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700443 /* We got an error trying to get sense info
444 from the drive (probably while trying
445 to recover from a former error). Just give up. */
446
Jens Axboe4aff5e22006-08-10 08:44:47 +0200447 rq->cmd_flags |= REQ_FAILED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700448 cdrom_end_request(drive, 0);
449 ide_error(drive, "request sense failure", stat);
450 return 1;
451
Jens Axboe8770c012006-10-12 17:24:52 +0200452 } else if (blk_pc_request(rq) || rq->cmd_type == REQ_TYPE_ATA_PC) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700453 /* All other functions, except for READ. */
454 unsigned long flags;
455
456 /*
457 * if we have an error, pass back CHECK_CONDITION as the
458 * scsi status byte
459 */
Jens Axboeb7156732006-11-13 18:05:02 +0100460 if (blk_pc_request(rq) && !rq->errors)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700461 rq->errors = SAM_STAT_CHECK_CONDITION;
462
463 /* Check for tray open. */
464 if (sense_key == NOT_READY) {
465 cdrom_saw_media_change (drive);
466 } else if (sense_key == UNIT_ATTENTION) {
467 /* Check for media change. */
468 cdrom_saw_media_change (drive);
469 /*printk("%s: media changed\n",drive->name);*/
470 return 0;
Stuart Hayes76ca1af2007-04-10 22:38:43 +0200471 } else if ((sense_key == ILLEGAL_REQUEST) &&
472 (rq->cmd[0] == GPCMD_START_STOP_UNIT)) {
473 /*
474 * Don't print error message for this condition--
475 * SFF8090i indicates that 5/24/00 is the correct
476 * response to a request to close the tray if the
477 * drive doesn't have that capability.
478 * cdrom_log_sense() knows this!
479 */
Jens Axboe4aff5e22006-08-10 08:44:47 +0200480 } else if (!(rq->cmd_flags & REQ_QUIET)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700481 /* Otherwise, print an error. */
482 ide_dump_status(drive, "packet command error", stat);
483 }
484
Jens Axboe4aff5e22006-08-10 08:44:47 +0200485 rq->cmd_flags |= REQ_FAILED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700486
487 /*
488 * instead of playing games with moving completions around,
489 * remove failed request completely and end it when the
490 * request sense has completed
491 */
492 if (stat & ERR_STAT) {
493 spin_lock_irqsave(&ide_lock, flags);
494 blkdev_dequeue_request(rq);
495 HWGROUP(drive)->rq = NULL;
496 spin_unlock_irqrestore(&ide_lock, flags);
497
498 cdrom_queue_request_sense(drive, rq->sense, rq);
499 } else
500 cdrom_end_request(drive, 0);
501
502 } else if (blk_fs_request(rq)) {
503 int do_end_request = 0;
504
505 /* Handle errors from READ and WRITE requests. */
506
507 if (blk_noretry_request(rq))
508 do_end_request = 1;
509
510 if (sense_key == NOT_READY) {
511 /* Tray open. */
512 if (rq_data_dir(rq) == READ) {
513 cdrom_saw_media_change (drive);
514
515 /* Fail the request. */
516 printk ("%s: tray open\n", drive->name);
517 do_end_request = 1;
518 } else {
519 struct cdrom_info *info = drive->driver_data;
520
521 /* allow the drive 5 seconds to recover, some
522 * devices will return this error while flushing
523 * data from cache */
524 if (!rq->errors)
525 info->write_timeout = jiffies + ATAPI_WAIT_WRITE_BUSY;
526 rq->errors = 1;
527 if (time_after(jiffies, info->write_timeout))
528 do_end_request = 1;
529 else {
530 unsigned long flags;
531
532 /*
533 * take a breather relying on the
534 * unplug timer to kick us again
535 */
536 spin_lock_irqsave(&ide_lock, flags);
537 blk_plug_device(drive->queue);
538 spin_unlock_irqrestore(&ide_lock,flags);
539 return 1;
540 }
541 }
542 } else if (sense_key == UNIT_ATTENTION) {
543 /* Media change. */
544 cdrom_saw_media_change (drive);
545
546 /* Arrange to retry the request.
547 But be sure to give up if we've retried
548 too many times. */
549 if (++rq->errors > ERROR_MAX)
550 do_end_request = 1;
551 } else if (sense_key == ILLEGAL_REQUEST ||
552 sense_key == DATA_PROTECT) {
553 /* No point in retrying after an illegal
554 request or data protect error.*/
Alan Coxdbe217a2006-06-25 05:47:44 -0700555 ide_dump_status_no_sense (drive, "command error", stat);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700556 do_end_request = 1;
557 } else if (sense_key == MEDIUM_ERROR) {
558 /* No point in re-trying a zillion times on a bad
559 * sector... If we got here the error is not correctable */
Alan Coxdbe217a2006-06-25 05:47:44 -0700560 ide_dump_status_no_sense (drive, "media error (bad sector)", stat);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700561 do_end_request = 1;
562 } else if (sense_key == BLANK_CHECK) {
563 /* Disk appears blank ?? */
Alan Coxdbe217a2006-06-25 05:47:44 -0700564 ide_dump_status_no_sense (drive, "media error (blank)", stat);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700565 do_end_request = 1;
566 } else if ((err & ~ABRT_ERR) != 0) {
567 /* Go to the default handler
568 for other errors. */
569 ide_error(drive, "cdrom_decode_status", stat);
570 return 1;
571 } else if ((++rq->errors > ERROR_MAX)) {
572 /* We've racked up too many retries. Abort. */
573 do_end_request = 1;
574 }
575
Alan Coxdbe217a2006-06-25 05:47:44 -0700576 /* End a request through request sense analysis when we have
577 sense data. We need this in order to perform end of media
578 processing */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700579
Alan Coxdbe217a2006-06-25 05:47:44 -0700580 if (do_end_request) {
581 if (stat & ERR_STAT) {
582 unsigned long flags;
583 spin_lock_irqsave(&ide_lock, flags);
584 blkdev_dequeue_request(rq);
585 HWGROUP(drive)->rq = NULL;
586 spin_unlock_irqrestore(&ide_lock, flags);
587
588 cdrom_queue_request_sense(drive, rq->sense, rq);
589 } else
590 cdrom_end_request(drive, 0);
591 } else {
592 /* If we got a CHECK_CONDITION status,
593 queue a request sense command. */
594 if (stat & ERR_STAT)
595 cdrom_queue_request_sense(drive, NULL, NULL);
596 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700597 } else {
598 blk_dump_rq_flags(rq, "ide-cd: bad rq");
599 cdrom_end_request(drive, 0);
600 }
601
602 /* Retry, or handle the next request. */
603 return 1;
604}
605
606static int cdrom_timer_expiry(ide_drive_t *drive)
607{
608 struct request *rq = HWGROUP(drive)->rq;
609 unsigned long wait = 0;
610
611 /*
612 * Some commands are *slow* and normally take a long time to
613 * complete. Usually we can use the ATAPI "disconnect" to bypass
614 * this, but not all commands/drives support that. Let
615 * ide_timer_expiry keep polling us for these.
616 */
617 switch (rq->cmd[0]) {
618 case GPCMD_BLANK:
619 case GPCMD_FORMAT_UNIT:
620 case GPCMD_RESERVE_RZONE_TRACK:
621 case GPCMD_CLOSE_TRACK:
622 case GPCMD_FLUSH_CACHE:
623 wait = ATAPI_WAIT_PC;
624 break;
625 default:
Jens Axboe4aff5e22006-08-10 08:44:47 +0200626 if (!(rq->cmd_flags & REQ_QUIET))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700627 printk(KERN_INFO "ide-cd: cmd 0x%x timed out\n", rq->cmd[0]);
628 wait = 0;
629 break;
630 }
631 return wait;
632}
633
634/* Set up the device registers for transferring a packet command on DEV,
635 expecting to later transfer XFERLEN bytes. HANDLER is the routine
636 which actually transfers the command to the drive. If this is a
637 drq_interrupt device, this routine will arrange for HANDLER to be
638 called when the interrupt from the drive arrives. Otherwise, HANDLER
639 will be called immediately after the drive is prepared for the transfer. */
640
641static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive,
642 int xferlen,
643 ide_handler_t *handler)
644{
645 ide_startstop_t startstop;
646 struct cdrom_info *info = drive->driver_data;
647 ide_hwif_t *hwif = drive->hwif;
648
649 /* Wait for the controller to be idle. */
650 if (ide_wait_stat(&startstop, drive, 0, BUSY_STAT, WAIT_READY))
651 return startstop;
652
Bartlomiej Zolnierkiewicz3a6a3542008-01-25 22:17:13 +0100653 /* FIXME: for Virtual DMA we must check harder */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700654 if (info->dma)
655 info->dma = !hwif->dma_setup(drive);
656
657 /* Set up the controller registers. */
Bartlomiej Zolnierkiewicz2fc57382008-01-25 22:17:13 +0100658 ide_pktcmd_tf_load(drive, IDE_TFLAG_OUT_NSECT | IDE_TFLAG_OUT_LBAL |
659 IDE_TFLAG_NO_SELECT_MASK, xferlen, info->dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700660
661 if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) {
Albert Leef0dd8712007-02-17 02:40:21 +0100662 /* waiting for CDB interrupt, not DMA yet. */
663 if (info->dma)
664 drive->waiting_for_dma = 0;
665
Linus Torvalds1da177e2005-04-16 15:20:36 -0700666 /* packet command */
667 ide_execute_command(drive, WIN_PACKETCMD, handler, ATAPI_WAIT_PC, cdrom_timer_expiry);
668 return ide_started;
669 } else {
670 unsigned long flags;
671
672 /* packet command */
673 spin_lock_irqsave(&ide_lock, flags);
674 hwif->OUTBSYNC(drive, WIN_PACKETCMD, IDE_COMMAND_REG);
675 ndelay(400);
676 spin_unlock_irqrestore(&ide_lock, flags);
677
678 return (*handler) (drive);
679 }
680}
681
682/* Send a packet command to DRIVE described by CMD_BUF and CMD_LEN.
683 The device registers must have already been prepared
684 by cdrom_start_packet_command.
685 HANDLER is the interrupt handler to call when the command completes
686 or there's data ready. */
687/*
688 * changed 5 parameters to 3 for dvd-ram
689 * struct packet_command *pc; now packet_command_t *pc;
690 */
691#define ATAPI_MIN_CDB_BYTES 12
692static ide_startstop_t cdrom_transfer_packet_command (ide_drive_t *drive,
693 struct request *rq,
694 ide_handler_t *handler)
695{
696 ide_hwif_t *hwif = drive->hwif;
697 int cmd_len;
698 struct cdrom_info *info = drive->driver_data;
699 ide_startstop_t startstop;
700
701 if (CDROM_CONFIG_FLAGS(drive)->drq_interrupt) {
702 /* Here we should have been called after receiving an interrupt
703 from the device. DRQ should how be set. */
704
705 /* Check for errors. */
706 if (cdrom_decode_status(drive, DRQ_STAT, NULL))
707 return ide_stopped;
Albert Leef0dd8712007-02-17 02:40:21 +0100708
709 /* Ok, next interrupt will be DMA interrupt. */
710 if (info->dma)
711 drive->waiting_for_dma = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700712 } else {
713 /* Otherwise, we must wait for DRQ to get set. */
714 if (ide_wait_stat(&startstop, drive, DRQ_STAT,
715 BUSY_STAT, WAIT_READY))
716 return startstop;
717 }
718
719 /* Arm the interrupt handler. */
720 ide_set_handler(drive, handler, rq->timeout, cdrom_timer_expiry);
721
722 /* ATAPI commands get padded out to 12 bytes minimum */
723 cmd_len = COMMAND_SIZE(rq->cmd[0]);
724 if (cmd_len < ATAPI_MIN_CDB_BYTES)
725 cmd_len = ATAPI_MIN_CDB_BYTES;
726
727 /* Send the command to the device. */
728 HWIF(drive)->atapi_output_bytes(drive, rq->cmd, cmd_len);
729
730 /* Start the DMA if need be */
731 if (info->dma)
732 hwif->dma_start(drive);
733
734 return ide_started;
735}
736
737/****************************************************************************
738 * Block read functions.
739 */
740
Bartlomiej Zolnierkiewicz68661c52008-02-01 23:09:17 +0100741typedef void (xfer_func_t)(ide_drive_t *, void *, u32);
742
Bartlomiej Zolnierkiewicz5a5222d2008-02-01 23:09:17 +0100743static void ide_cd_pad_transfer(ide_drive_t *drive, xfer_func_t *xf, int len)
744{
745 while (len > 0) {
746 int dum = 0;
747 xf(drive, &dum, sizeof(dum));
748 len -= sizeof(dum);
749 }
750}
751
Linus Torvalds1da177e2005-04-16 15:20:36 -0700752/*
753 * Buffer up to SECTORS_TO_TRANSFER sectors from the drive in our sector
754 * buffer. Once the first sector is added, any subsequent sectors are
755 * assumed to be continuous (until the buffer is cleared). For the first
756 * sector added, SECTOR is its sector number. (SECTOR is then ignored until
757 * the buffer is cleared.)
758 */
759static void cdrom_buffer_sectors (ide_drive_t *drive, unsigned long sector,
760 int sectors_to_transfer)
761{
762 struct cdrom_info *info = drive->driver_data;
763
764 /* Number of sectors to read into the buffer. */
765 int sectors_to_buffer = min_t(int, sectors_to_transfer,
766 (SECTOR_BUFFER_SIZE >> SECTOR_BITS) -
767 info->nsectors_buffered);
768
769 char *dest;
770
771 /* If we couldn't get a buffer, don't try to buffer anything... */
772 if (info->buffer == NULL)
773 sectors_to_buffer = 0;
774
775 /* If this is the first sector in the buffer, remember its number. */
776 if (info->nsectors_buffered == 0)
777 info->sector_buffered = sector;
778
779 /* Read the data into the buffer. */
780 dest = info->buffer + info->nsectors_buffered * SECTOR_SIZE;
781 while (sectors_to_buffer > 0) {
782 HWIF(drive)->atapi_input_bytes(drive, dest, SECTOR_SIZE);
783 --sectors_to_buffer;
784 --sectors_to_transfer;
785 ++info->nsectors_buffered;
786 dest += SECTOR_SIZE;
787 }
788
789 /* Throw away any remaining data. */
790 while (sectors_to_transfer > 0) {
791 static char dum[SECTOR_SIZE];
792 HWIF(drive)->atapi_input_bytes(drive, dum, sizeof (dum));
793 --sectors_to_transfer;
794 }
795}
796
797/*
798 * Check the contents of the interrupt reason register from the cdrom
799 * and attempt to recover if there are problems. Returns 0 if everything's
800 * ok; nonzero if the request has been terminated.
801 */
Arjan van de Ven858119e2006-01-14 13:20:43 -0800802static
Linus Torvalds1da177e2005-04-16 15:20:36 -0700803int cdrom_read_check_ireason (ide_drive_t *drive, int len, int ireason)
804{
805 if (ireason == 2)
806 return 0;
807 else if (ireason == 0) {
Bartlomiej Zolnierkiewicz5a5222d2008-02-01 23:09:17 +0100808 ide_hwif_t *hwif = drive->hwif;
809
Linus Torvalds1da177e2005-04-16 15:20:36 -0700810 /* Whoops... The drive is expecting to receive data from us! */
Bartlomiej Zolnierkiewicz35379c02007-12-24 15:23:43 +0100811 printk(KERN_ERR "%s: %s: wrong transfer direction!\n",
812 drive->name, __FUNCTION__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700813
814 /* Throw some data at the drive so it doesn't hang
815 and quit this request. */
Bartlomiej Zolnierkiewicz5a5222d2008-02-01 23:09:17 +0100816 ide_cd_pad_transfer(drive, hwif->atapi_output_bytes, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700817 } else if (ireason == 1) {
818 /* Some drives (ASUS) seem to tell us that status
819 * info is available. just get it and ignore.
820 */
821 (void) HWIF(drive)->INB(IDE_STATUS_REG);
822 return 0;
823 } else {
824 /* Drive wants a command packet, or invalid ireason... */
Bartlomiej Zolnierkiewicz35379c02007-12-24 15:23:43 +0100825 printk(KERN_ERR "%s: %s: bad interrupt reason 0x%02x\n",
826 drive->name, __FUNCTION__, ireason);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700827 }
828
829 cdrom_end_request(drive, 0);
830 return -1;
831}
832
833/*
834 * Interrupt routine. Called when a read request has completed.
835 */
836static ide_startstop_t cdrom_read_intr (ide_drive_t *drive)
837{
838 int stat;
839 int ireason, len, sectors_to_transfer, nskip;
840 struct cdrom_info *info = drive->driver_data;
841 u8 lowcyl = 0, highcyl = 0;
842 int dma = info->dma, dma_error = 0;
843
844 struct request *rq = HWGROUP(drive)->rq;
845
846 /*
847 * handle dma case
848 */
849 if (dma) {
850 info->dma = 0;
Bartlomiej Zolnierkiewicz52ef2ed2007-12-24 15:23:43 +0100851 dma_error = HWIF(drive)->ide_dma_end(drive);
852 if (dma_error) {
853 printk(KERN_ERR "%s: DMA read error\n", drive->name);
Bartlomiej Zolnierkiewicz7469aaf2007-02-17 02:40:26 +0100854 ide_dma_off(drive);
Bartlomiej Zolnierkiewicz52ef2ed2007-12-24 15:23:43 +0100855 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700856 }
857
858 if (cdrom_decode_status(drive, 0, &stat))
859 return ide_stopped;
860
861 if (dma) {
862 if (!dma_error) {
863 ide_end_request(drive, 1, rq->nr_sectors);
864 return ide_stopped;
865 } else
866 return ide_error(drive, "dma error", stat);
867 }
868
869 /* Read the interrupt reason and the transfer length. */
870 ireason = HWIF(drive)->INB(IDE_IREASON_REG) & 0x3;
871 lowcyl = HWIF(drive)->INB(IDE_BCOUNTL_REG);
872 highcyl = HWIF(drive)->INB(IDE_BCOUNTH_REG);
873
874 len = lowcyl + (256 * highcyl);
875
876 /* If DRQ is clear, the command has completed. */
877 if ((stat & DRQ_STAT) == 0) {
878 /* If we're not done filling the current buffer, complain.
879 Otherwise, complete the command normally. */
880 if (rq->current_nr_sectors > 0) {
881 printk (KERN_ERR "%s: cdrom_read_intr: data underrun (%d blocks)\n",
882 drive->name, rq->current_nr_sectors);
Jens Axboe4aff5e22006-08-10 08:44:47 +0200883 rq->cmd_flags |= REQ_FAILED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700884 cdrom_end_request(drive, 0);
885 } else
886 cdrom_end_request(drive, 1);
887 return ide_stopped;
888 }
889
890 /* Check that the drive is expecting to do the same thing we are. */
891 if (cdrom_read_check_ireason (drive, len, ireason))
892 return ide_stopped;
893
894 /* Assume that the drive will always provide data in multiples
895 of at least SECTOR_SIZE, as it gets hairy to keep track
896 of the transfers otherwise. */
897 if ((len % SECTOR_SIZE) != 0) {
898 printk (KERN_ERR "%s: cdrom_read_intr: Bad transfer size %d\n",
899 drive->name, len);
900 if (CDROM_CONFIG_FLAGS(drive)->limit_nframes)
901 printk (KERN_ERR " This drive is not supported by this version of the driver\n");
902 else {
903 printk (KERN_ERR " Trying to limit transfer sizes\n");
904 CDROM_CONFIG_FLAGS(drive)->limit_nframes = 1;
905 }
906 cdrom_end_request(drive, 0);
907 return ide_stopped;
908 }
909
910 /* The number of sectors we need to read from the drive. */
911 sectors_to_transfer = len / SECTOR_SIZE;
912
913 /* First, figure out if we need to bit-bucket
914 any of the leading sectors. */
915 nskip = min_t(int, rq->current_nr_sectors - bio_cur_sectors(rq->bio), sectors_to_transfer);
916
917 while (nskip > 0) {
918 /* We need to throw away a sector. */
919 static char dum[SECTOR_SIZE];
920 HWIF(drive)->atapi_input_bytes(drive, dum, sizeof (dum));
921
922 --rq->current_nr_sectors;
923 --nskip;
924 --sectors_to_transfer;
925 }
926
927 /* Now loop while we still have data to read from the drive. */
928 while (sectors_to_transfer > 0) {
929 int this_transfer;
930
931 /* If we've filled the present buffer but there's another
932 chained buffer after it, move on. */
933 if (rq->current_nr_sectors == 0 && rq->nr_sectors)
934 cdrom_end_request(drive, 1);
935
936 /* If the buffers are full, cache the rest of the data in our
937 internal buffer. */
938 if (rq->current_nr_sectors == 0) {
939 cdrom_buffer_sectors(drive, rq->sector, sectors_to_transfer);
940 sectors_to_transfer = 0;
941 } else {
942 /* Transfer data to the buffers.
943 Figure out how many sectors we can transfer
944 to the current buffer. */
945 this_transfer = min_t(int, sectors_to_transfer,
946 rq->current_nr_sectors);
947
948 /* Read this_transfer sectors
949 into the current buffer. */
950 while (this_transfer > 0) {
951 HWIF(drive)->atapi_input_bytes(drive, rq->buffer, SECTOR_SIZE);
952 rq->buffer += SECTOR_SIZE;
953 --rq->nr_sectors;
954 --rq->current_nr_sectors;
955 ++rq->sector;
956 --this_transfer;
957 --sectors_to_transfer;
958 }
959 }
960 }
961
962 /* Done moving data! Wait for another interrupt. */
963 ide_set_handler(drive, &cdrom_read_intr, ATAPI_WAIT_PC, NULL);
964 return ide_started;
965}
966
967/*
968 * Try to satisfy some of the current read request from our cached data.
969 * Returns nonzero if the request has been completed, zero otherwise.
970 */
971static int cdrom_read_from_buffer (ide_drive_t *drive)
972{
973 struct cdrom_info *info = drive->driver_data;
974 struct request *rq = HWGROUP(drive)->rq;
975 unsigned short sectors_per_frame;
976
977 sectors_per_frame = queue_hardsect_size(drive->queue) >> SECTOR_BITS;
978
979 /* Can't do anything if there's no buffer. */
980 if (info->buffer == NULL) return 0;
981
982 /* Loop while this request needs data and the next block is present
983 in our cache. */
984 while (rq->nr_sectors > 0 &&
985 rq->sector >= info->sector_buffered &&
986 rq->sector < info->sector_buffered + info->nsectors_buffered) {
987 if (rq->current_nr_sectors == 0)
988 cdrom_end_request(drive, 1);
989
990 memcpy (rq->buffer,
991 info->buffer +
992 (rq->sector - info->sector_buffered) * SECTOR_SIZE,
993 SECTOR_SIZE);
994 rq->buffer += SECTOR_SIZE;
995 --rq->current_nr_sectors;
996 --rq->nr_sectors;
997 ++rq->sector;
998 }
999
1000 /* If we've satisfied the current request,
1001 terminate it successfully. */
1002 if (rq->nr_sectors == 0) {
1003 cdrom_end_request(drive, 1);
1004 return -1;
1005 }
1006
1007 /* Move on to the next buffer if needed. */
1008 if (rq->current_nr_sectors == 0)
1009 cdrom_end_request(drive, 1);
1010
1011 /* If this condition does not hold, then the kluge i use to
1012 represent the number of sectors to skip at the start of a transfer
1013 will fail. I think that this will never happen, but let's be
1014 paranoid and check. */
1015 if (rq->current_nr_sectors < bio_cur_sectors(rq->bio) &&
1016 (rq->sector & (sectors_per_frame - 1))) {
1017 printk(KERN_ERR "%s: cdrom_read_from_buffer: buffer botch (%ld)\n",
1018 drive->name, (long)rq->sector);
1019 cdrom_end_request(drive, 0);
1020 return -1;
1021 }
1022
1023 return 0;
1024}
1025
1026/*
1027 * Routine to send a read packet command to the drive.
1028 * This is usually called directly from cdrom_start_read.
1029 * However, for drq_interrupt devices, it is called from an interrupt
1030 * when the drive is ready to accept the command.
1031 */
1032static ide_startstop_t cdrom_start_read_continuation (ide_drive_t *drive)
1033{
1034 struct request *rq = HWGROUP(drive)->rq;
1035 unsigned short sectors_per_frame;
1036 int nskip;
1037
1038 sectors_per_frame = queue_hardsect_size(drive->queue) >> SECTOR_BITS;
1039
1040 /* If the requested sector doesn't start on a cdrom block boundary,
1041 we must adjust the start of the transfer so that it does,
1042 and remember to skip the first few sectors.
1043 If the CURRENT_NR_SECTORS field is larger than the size
1044 of the buffer, it will mean that we're to skip a number
1045 of sectors equal to the amount by which CURRENT_NR_SECTORS
1046 is larger than the buffer size. */
1047 nskip = rq->sector & (sectors_per_frame - 1);
1048 if (nskip > 0) {
1049 /* Sanity check... */
1050 if (rq->current_nr_sectors != bio_cur_sectors(rq->bio) &&
1051 (rq->sector & (sectors_per_frame - 1))) {
1052 printk(KERN_ERR "%s: cdrom_start_read_continuation: buffer botch (%u)\n",
1053 drive->name, rq->current_nr_sectors);
1054 cdrom_end_request(drive, 0);
1055 return ide_stopped;
1056 }
1057 rq->current_nr_sectors += nskip;
1058 }
1059
1060 /* Set up the command */
1061 rq->timeout = ATAPI_WAIT_PC;
1062
1063 /* Send the command to the drive and return. */
1064 return cdrom_transfer_packet_command(drive, rq, &cdrom_read_intr);
1065}
1066
1067
1068#define IDECD_SEEK_THRESHOLD (1000) /* 1000 blocks */
1069#define IDECD_SEEK_TIMER (5 * WAIT_MIN_SLEEP) /* 100 ms */
1070#define IDECD_SEEK_TIMEOUT (2 * WAIT_CMD) /* 20 sec */
1071
1072static ide_startstop_t cdrom_seek_intr (ide_drive_t *drive)
1073{
1074 struct cdrom_info *info = drive->driver_data;
1075 int stat;
1076 static int retry = 10;
1077
1078 if (cdrom_decode_status(drive, 0, &stat))
1079 return ide_stopped;
1080 CDROM_CONFIG_FLAGS(drive)->seeking = 1;
1081
1082 if (retry && time_after(jiffies, info->start_seek + IDECD_SEEK_TIMER)) {
1083 if (--retry == 0) {
1084 /*
1085 * this condition is far too common, to bother
1086 * users about it
1087 */
1088 /* printk("%s: disabled DSC seek overlap\n", drive->name);*/
1089 drive->dsc_overlap = 0;
1090 }
1091 }
1092 return ide_stopped;
1093}
1094
1095static ide_startstop_t cdrom_start_seek_continuation (ide_drive_t *drive)
1096{
1097 struct request *rq = HWGROUP(drive)->rq;
1098 sector_t frame = rq->sector;
1099
1100 sector_div(frame, queue_hardsect_size(drive->queue) >> SECTOR_BITS);
1101
1102 memset(rq->cmd, 0, sizeof(rq->cmd));
1103 rq->cmd[0] = GPCMD_SEEK;
1104 put_unaligned(cpu_to_be32(frame), (unsigned int *) &rq->cmd[2]);
1105
1106 rq->timeout = ATAPI_WAIT_PC;
1107 return cdrom_transfer_packet_command(drive, rq, &cdrom_seek_intr);
1108}
1109
1110static ide_startstop_t cdrom_start_seek (ide_drive_t *drive, unsigned int block)
1111{
1112 struct cdrom_info *info = drive->driver_data;
1113
1114 info->dma = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001115 info->start_seek = jiffies;
1116 return cdrom_start_packet_command(drive, 0, cdrom_start_seek_continuation);
1117}
1118
1119/* Fix up a possibly partially-processed request so that we can
1120 start it over entirely, or even put it back on the request queue. */
1121static void restore_request (struct request *rq)
1122{
1123 if (rq->buffer != bio_data(rq->bio)) {
1124 sector_t n = (rq->buffer - (char *) bio_data(rq->bio)) / SECTOR_SIZE;
1125
1126 rq->buffer = bio_data(rq->bio);
1127 rq->nr_sectors += n;
1128 rq->sector -= n;
1129 }
1130 rq->hard_cur_sectors = rq->current_nr_sectors = bio_cur_sectors(rq->bio);
1131 rq->hard_nr_sectors = rq->nr_sectors;
1132 rq->hard_sector = rq->sector;
1133 rq->q->prep_rq_fn(rq->q, rq);
1134}
1135
1136/*
1137 * Start a read request from the CD-ROM.
1138 */
1139static ide_startstop_t cdrom_start_read (ide_drive_t *drive, unsigned int block)
1140{
1141 struct cdrom_info *info = drive->driver_data;
1142 struct request *rq = HWGROUP(drive)->rq;
1143 unsigned short sectors_per_frame;
1144
1145 sectors_per_frame = queue_hardsect_size(drive->queue) >> SECTOR_BITS;
1146
1147 /* We may be retrying this request after an error. Fix up
1148 any weirdness which might be present in the request packet. */
1149 restore_request(rq);
1150
1151 /* Satisfy whatever we can of this request from our cached sector. */
1152 if (cdrom_read_from_buffer(drive))
1153 return ide_stopped;
1154
Linus Torvalds1da177e2005-04-16 15:20:36 -07001155 /* Clear the local sector buffer. */
1156 info->nsectors_buffered = 0;
1157
1158 /* use dma, if possible. */
1159 info->dma = drive->using_dma;
1160 if ((rq->sector & (sectors_per_frame - 1)) ||
1161 (rq->nr_sectors & (sectors_per_frame - 1)))
1162 info->dma = 0;
1163
Linus Torvalds1da177e2005-04-16 15:20:36 -07001164 /* Start sending the read request to the drive. */
1165 return cdrom_start_packet_command(drive, 32768, cdrom_start_read_continuation);
1166}
1167
1168/****************************************************************************
1169 * Execute all other packet commands.
1170 */
1171
1172/* Interrupt routine for packet command completion. */
1173static ide_startstop_t cdrom_pc_intr (ide_drive_t *drive)
1174{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001175 struct request *rq = HWGROUP(drive)->rq;
Bartlomiej Zolnierkiewicz68661c52008-02-01 23:09:17 +01001176 xfer_func_t *xferfunc = NULL;
1177 int stat, ireason, len, thislen, write;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001178 u8 lowcyl = 0, highcyl = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001179
1180 /* Check for errors. */
1181 if (cdrom_decode_status(drive, 0, &stat))
1182 return ide_stopped;
1183
1184 /* Read the interrupt reason and the transfer length. */
Bartlomiej Zolnierkiewicz8606ab02007-12-24 15:23:44 +01001185 ireason = HWIF(drive)->INB(IDE_IREASON_REG) & 0x3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001186 lowcyl = HWIF(drive)->INB(IDE_BCOUNTL_REG);
1187 highcyl = HWIF(drive)->INB(IDE_BCOUNTH_REG);
1188
1189 len = lowcyl + (256 * highcyl);
1190
1191 /* If DRQ is clear, the command has completed.
1192 Complain if we still have data left to transfer. */
1193 if ((stat & DRQ_STAT) == 0) {
1194 /* Some of the trailing request sense fields are optional, and
1195 some drives don't send them. Sigh. */
1196 if (rq->cmd[0] == GPCMD_REQUEST_SENSE &&
1197 rq->data_len > 0 &&
1198 rq->data_len <= 5) {
1199 while (rq->data_len > 0) {
1200 *(unsigned char *)rq->data++ = 0;
1201 --rq->data_len;
1202 }
1203 }
1204
1205 if (rq->data_len == 0)
1206 cdrom_end_request(drive, 1);
1207 else {
1208 /* Comment this out, because this always happens
1209 right after a reset occurs, and it is annoying to
1210 always print expected stuff. */
1211 /*
1212 printk ("%s: cdrom_pc_intr: data underrun %d\n",
1213 drive->name, pc->buflen);
1214 */
Jens Axboe4aff5e22006-08-10 08:44:47 +02001215 rq->cmd_flags |= REQ_FAILED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001216 cdrom_end_request(drive, 0);
1217 }
1218 return ide_stopped;
1219 }
1220
1221 /* Figure out how much data to transfer. */
1222 thislen = rq->data_len;
Bartlomiej Zolnierkiewicz68661c52008-02-01 23:09:17 +01001223 if (thislen > len)
1224 thislen = len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001225
Bartlomiej Zolnierkiewicz8606ab02007-12-24 15:23:44 +01001226 if (ireason == 0) {
Bartlomiej Zolnierkiewicz68661c52008-02-01 23:09:17 +01001227 write = 1;
1228 xferfunc = HWIF(drive)->atapi_output_bytes;
1229 } else if (ireason == 2) {
1230 write = 0;
1231 xferfunc = HWIF(drive)->atapi_input_bytes;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001232 }
1233
Bartlomiej Zolnierkiewicz68661c52008-02-01 23:09:17 +01001234 if (xferfunc) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001235 if (!rq->data) {
Bartlomiej Zolnierkiewiczf1071e62008-02-01 23:09:17 +01001236 printk(KERN_ERR "%s: confused, missing data\n",
1237 drive->name);
Bartlomiej Zolnierkiewicz68661c52008-02-01 23:09:17 +01001238 blk_dump_rq_flags(rq, write ? "cdrom_pc_intr, write"
1239 : "cdrom_pc_intr, read");
Bartlomiej Zolnierkiewiczf1071e62008-02-01 23:09:17 +01001240 goto pad;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001241 }
1242 /* Transfer the data. */
Bartlomiej Zolnierkiewicz68661c52008-02-01 23:09:17 +01001243 xferfunc(drive, rq->data, thislen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001244
Linus Torvalds1da177e2005-04-16 15:20:36 -07001245 /* Keep count of how much data we've moved. */
Bartlomiej Zolnierkiewicz5a5222d2008-02-01 23:09:17 +01001246 len -= thislen;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001247 rq->data += thislen;
1248 rq->data_len -= thislen;
1249
Bartlomiej Zolnierkiewicz68661c52008-02-01 23:09:17 +01001250 if (write && blk_sense_request(rq))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001251 rq->sense_len += thislen;
1252 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001253 printk (KERN_ERR "%s: cdrom_pc_intr: The drive "
Rachita Kothiyal1ad55442006-06-23 02:02:56 -07001254 "appears confused (ireason = 0x%02x). "
1255 "Trying to recover by ending request.\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001256 drive->name, ireason);
Jens Axboe4aff5e22006-08-10 08:44:47 +02001257 rq->cmd_flags |= REQ_FAILED;
Rachita Kothiyal1ad55442006-06-23 02:02:56 -07001258 cdrom_end_request(drive, 0);
1259 return ide_stopped;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001260 }
Bartlomiej Zolnierkiewiczf1071e62008-02-01 23:09:17 +01001261pad:
Bartlomiej Zolnierkiewicz5a5222d2008-02-01 23:09:17 +01001262 /*
1263 * If we haven't moved enough data to satisfy the drive,
1264 * add some padding.
1265 */
1266 if (len > 0)
1267 ide_cd_pad_transfer(drive, xferfunc, len);
1268
Linus Torvalds1da177e2005-04-16 15:20:36 -07001269 /* Now we wait for another interrupt. */
1270 ide_set_handler(drive, &cdrom_pc_intr, ATAPI_WAIT_PC, cdrom_timer_expiry);
1271 return ide_started;
1272}
1273
1274static ide_startstop_t cdrom_do_pc_continuation (ide_drive_t *drive)
1275{
1276 struct request *rq = HWGROUP(drive)->rq;
1277
1278 if (!rq->timeout)
1279 rq->timeout = ATAPI_WAIT_PC;
1280
1281 /* Send the command to the drive and return. */
1282 return cdrom_transfer_packet_command(drive, rq, &cdrom_pc_intr);
1283}
1284
1285
1286static ide_startstop_t cdrom_do_packet_command (ide_drive_t *drive)
1287{
1288 int len;
1289 struct request *rq = HWGROUP(drive)->rq;
1290 struct cdrom_info *info = drive->driver_data;
1291
1292 info->dma = 0;
Jens Axboe4aff5e22006-08-10 08:44:47 +02001293 rq->cmd_flags &= ~REQ_FAILED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001294 len = rq->data_len;
1295
1296 /* Start sending the command to the drive. */
1297 return cdrom_start_packet_command(drive, len, cdrom_do_pc_continuation);
1298}
1299
1300
Alan Coxdbe217a2006-06-25 05:47:44 -07001301static int cdrom_queue_packet_command(ide_drive_t *drive, struct request *rq)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001302{
1303 struct request_sense sense;
1304 int retries = 10;
Jens Axboe4aff5e22006-08-10 08:44:47 +02001305 unsigned int flags = rq->cmd_flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001306
1307 if (rq->sense == NULL)
1308 rq->sense = &sense;
1309
1310 /* Start of retry loop. */
1311 do {
1312 int error;
1313 unsigned long time = jiffies;
Jens Axboe4aff5e22006-08-10 08:44:47 +02001314 rq->cmd_flags = flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001315
1316 error = ide_do_drive_cmd(drive, rq, ide_wait);
1317 time = jiffies - time;
1318
1319 /* FIXME: we should probably abort/retry or something
1320 * in case of failure */
Jens Axboe4aff5e22006-08-10 08:44:47 +02001321 if (rq->cmd_flags & REQ_FAILED) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001322 /* The request failed. Retry if it was due to a unit
1323 attention status
1324 (usually means media was changed). */
1325 struct request_sense *reqbuf = rq->sense;
1326
1327 if (reqbuf->sense_key == UNIT_ATTENTION)
1328 cdrom_saw_media_change(drive);
1329 else if (reqbuf->sense_key == NOT_READY &&
1330 reqbuf->asc == 4 && reqbuf->ascq != 4) {
1331 /* The drive is in the process of loading
1332 a disk. Retry, but wait a little to give
1333 the drive time to complete the load. */
1334 ssleep(2);
1335 } else {
1336 /* Otherwise, don't retry. */
1337 retries = 0;
1338 }
1339 --retries;
1340 }
1341
1342 /* End of retry loop. */
Jens Axboe4aff5e22006-08-10 08:44:47 +02001343 } while ((rq->cmd_flags & REQ_FAILED) && retries >= 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001344
1345 /* Return an error if the command failed. */
Jens Axboe4aff5e22006-08-10 08:44:47 +02001346 return (rq->cmd_flags & REQ_FAILED) ? -EIO : 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001347}
1348
1349/*
1350 * Write handling
1351 */
Arjan van de Ven858119e2006-01-14 13:20:43 -08001352static int cdrom_write_check_ireason(ide_drive_t *drive, int len, int ireason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001353{
1354 /* Two notes about IDE interrupt reason here - 0 means that
1355 * the drive wants to receive data from us, 2 means that
1356 * the drive is expecting to transfer data to us.
1357 */
1358 if (ireason == 0)
1359 return 0;
1360 else if (ireason == 2) {
Bartlomiej Zolnierkiewicz5a5222d2008-02-01 23:09:17 +01001361 ide_hwif_t *hwif = drive->hwif;
1362
Linus Torvalds1da177e2005-04-16 15:20:36 -07001363 /* Whoops... The drive wants to send data. */
Bartlomiej Zolnierkiewicz35379c02007-12-24 15:23:43 +01001364 printk(KERN_ERR "%s: %s: wrong transfer direction!\n",
1365 drive->name, __FUNCTION__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001366
Bartlomiej Zolnierkiewicz5a5222d2008-02-01 23:09:17 +01001367 ide_cd_pad_transfer(drive, hwif->atapi_input_bytes, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001368 } else {
1369 /* Drive wants a command packet, or invalid ireason... */
Bartlomiej Zolnierkiewicz35379c02007-12-24 15:23:43 +01001370 printk(KERN_ERR "%s: %s: bad interrupt reason 0x%02x\n",
1371 drive->name, __FUNCTION__, ireason);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001372 }
1373
1374 cdrom_end_request(drive, 0);
1375 return 1;
1376}
1377
Kiyoshi Uedaaaa04c22007-12-11 17:51:23 -05001378/*
1379 * Called from blk_end_request_callback() after the data of the request
1380 * is completed and before the request is completed.
1381 * By returning value '1', blk_end_request_callback() returns immediately
1382 * without completing the request.
1383 */
1384static int cdrom_newpc_intr_dummy_cb(struct request *rq)
1385{
1386 return 1;
1387}
1388
Linus Torvalds1da177e2005-04-16 15:20:36 -07001389/*
1390 * best way to deal with dma that is not sector aligned right now... note
1391 * that in this path we are not using ->data or ->buffer at all. this irs
1392 * can replace cdrom_pc_intr, cdrom_read_intr, and cdrom_write_intr in the
1393 * future.
1394 */
1395static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
1396{
1397 struct cdrom_info *info = drive->driver_data;
1398 struct request *rq = HWGROUP(drive)->rq;
1399 int dma_error, dma, stat, ireason, len, thislen;
1400 u8 lowcyl, highcyl;
1401 xfer_func_t *xferfunc;
1402 unsigned long flags;
1403
1404 /* Check for errors. */
1405 dma_error = 0;
1406 dma = info->dma;
1407 if (dma) {
1408 info->dma = 0;
1409 dma_error = HWIF(drive)->ide_dma_end(drive);
Bartlomiej Zolnierkiewiczeba15fb2008-02-01 23:09:17 +01001410 if (dma_error) {
1411 printk(KERN_ERR "%s: DMA %s error\n", drive->name,
1412 rq_data_dir(rq) ? "write" : "read");
1413 ide_dma_off(drive);
1414 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001415 }
1416
1417 if (cdrom_decode_status(drive, 0, &stat))
1418 return ide_stopped;
1419
1420 /*
1421 * using dma, transfer is complete now
1422 */
1423 if (dma) {
Bartlomiej Zolnierkiewiczeba15fb2008-02-01 23:09:17 +01001424 if (dma_error)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001425 return ide_error(drive, "dma error", stat);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001426
Kiyoshi Uedaaaa04c22007-12-11 17:51:23 -05001427 spin_lock_irqsave(&ide_lock, flags);
1428 if (__blk_end_request(rq, 0, rq->data_len))
1429 BUG();
1430 HWGROUP(drive)->rq = NULL;
1431 spin_unlock_irqrestore(&ide_lock, flags);
1432
1433 return ide_stopped;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001434 }
1435
1436 /*
1437 * ok we fall to pio :/
1438 */
1439 ireason = HWIF(drive)->INB(IDE_IREASON_REG) & 0x3;
1440 lowcyl = HWIF(drive)->INB(IDE_BCOUNTL_REG);
1441 highcyl = HWIF(drive)->INB(IDE_BCOUNTH_REG);
1442
1443 len = lowcyl + (256 * highcyl);
1444 thislen = rq->data_len;
1445 if (thislen > len)
1446 thislen = len;
1447
1448 /*
1449 * If DRQ is clear, the command has completed.
1450 */
Kiyoshi Uedaaaa04c22007-12-11 17:51:23 -05001451 if ((stat & DRQ_STAT) == 0) {
1452 spin_lock_irqsave(&ide_lock, flags);
Jens Axboe4f4f6c252008-01-31 13:57:51 +01001453 if (__blk_end_request(rq, 0, rq->data_len))
Kiyoshi Uedaaaa04c22007-12-11 17:51:23 -05001454 BUG();
1455 HWGROUP(drive)->rq = NULL;
1456 spin_unlock_irqrestore(&ide_lock, flags);
1457
1458 return ide_stopped;
1459 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001460
1461 /*
1462 * check which way to transfer data
1463 */
1464 if (rq_data_dir(rq) == WRITE) {
1465 /*
1466 * write to drive
1467 */
1468 if (cdrom_write_check_ireason(drive, len, ireason))
1469 return ide_stopped;
1470
1471 xferfunc = HWIF(drive)->atapi_output_bytes;
1472 } else {
1473 /*
1474 * read from drive
1475 */
1476 if (cdrom_read_check_ireason(drive, len, ireason))
1477 return ide_stopped;
1478
1479 xferfunc = HWIF(drive)->atapi_input_bytes;
1480 }
1481
1482 /*
1483 * transfer data
1484 */
1485 while (thislen > 0) {
1486 int blen = blen = rq->data_len;
1487 char *ptr = rq->data;
1488
1489 /*
1490 * bio backed?
1491 */
1492 if (rq->bio) {
1493 ptr = bio_data(rq->bio);
1494 blen = bio_iovec(rq->bio)->bv_len;
1495 }
1496
1497 if (!ptr) {
1498 printk(KERN_ERR "%s: confused, missing data\n", drive->name);
1499 break;
1500 }
1501
1502 if (blen > thislen)
1503 blen = thislen;
1504
1505 xferfunc(drive, ptr, blen);
1506
1507 thislen -= blen;
1508 len -= blen;
1509 rq->data_len -= blen;
1510
1511 if (rq->bio)
Kiyoshi Uedaaaa04c22007-12-11 17:51:23 -05001512 /*
1513 * The request can't be completed until DRQ is cleared.
1514 * So complete the data, but don't complete the request
1515 * using the dummy function for the callback feature
1516 * of blk_end_request_callback().
1517 */
1518 blk_end_request_callback(rq, 0, blen,
1519 cdrom_newpc_intr_dummy_cb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001520 else
1521 rq->data += blen;
1522 }
1523
1524 /*
1525 * pad, if necessary
1526 */
Bartlomiej Zolnierkiewicz5a5222d2008-02-01 23:09:17 +01001527 if (len > 0)
1528 ide_cd_pad_transfer(drive, xferfunc, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001529
Eric Sesterhenn125e1872006-06-23 02:06:06 -07001530 BUG_ON(HWGROUP(drive)->handler != NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001531
1532 ide_set_handler(drive, cdrom_newpc_intr, rq->timeout, NULL);
1533 return ide_started;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001534}
1535
1536static ide_startstop_t cdrom_write_intr(ide_drive_t *drive)
1537{
1538 int stat, ireason, len, sectors_to_transfer, uptodate;
1539 struct cdrom_info *info = drive->driver_data;
1540 int dma_error = 0, dma = info->dma;
1541 u8 lowcyl = 0, highcyl = 0;
1542
1543 struct request *rq = HWGROUP(drive)->rq;
1544
1545 /* Check for errors. */
1546 if (dma) {
1547 info->dma = 0;
Bartlomiej Zolnierkiewiczb481b232007-12-24 15:23:43 +01001548 dma_error = HWIF(drive)->ide_dma_end(drive);
1549 if (dma_error) {
1550 printk(KERN_ERR "%s: DMA write error\n", drive->name);
Bartlomiej Zolnierkiewicz7469aaf2007-02-17 02:40:26 +01001551 ide_dma_off(drive);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001552 }
1553 }
1554
1555 if (cdrom_decode_status(drive, 0, &stat))
1556 return ide_stopped;
1557
1558 /*
1559 * using dma, transfer is complete now
1560 */
1561 if (dma) {
1562 if (dma_error)
1563 return ide_error(drive, "dma error", stat);
1564
1565 ide_end_request(drive, 1, rq->nr_sectors);
1566 return ide_stopped;
1567 }
1568
1569 /* Read the interrupt reason and the transfer length. */
Bartlomiej Zolnierkiewicz31a71192007-12-24 15:23:43 +01001570 ireason = HWIF(drive)->INB(IDE_IREASON_REG) & 0x3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001571 lowcyl = HWIF(drive)->INB(IDE_BCOUNTL_REG);
1572 highcyl = HWIF(drive)->INB(IDE_BCOUNTH_REG);
1573
1574 len = lowcyl + (256 * highcyl);
1575
1576 /* If DRQ is clear, the command has completed. */
1577 if ((stat & DRQ_STAT) == 0) {
1578 /* If we're not done writing, complain.
1579 * Otherwise, complete the command normally.
1580 */
1581 uptodate = 1;
1582 if (rq->current_nr_sectors > 0) {
Bartlomiej Zolnierkiewiczb481b232007-12-24 15:23:43 +01001583 printk(KERN_ERR "%s: %s: data underrun (%d blocks)\n",
1584 drive->name, __FUNCTION__,
1585 rq->current_nr_sectors);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001586 uptodate = 0;
1587 }
1588 cdrom_end_request(drive, uptodate);
1589 return ide_stopped;
1590 }
1591
1592 /* Check that the drive is expecting to do the same thing we are. */
1593 if (cdrom_write_check_ireason(drive, len, ireason))
1594 return ide_stopped;
1595
1596 sectors_to_transfer = len / SECTOR_SIZE;
1597
1598 /*
1599 * now loop and write out the data
1600 */
1601 while (sectors_to_transfer > 0) {
1602 int this_transfer;
1603
1604 if (!rq->current_nr_sectors) {
Bartlomiej Zolnierkiewiczb481b232007-12-24 15:23:43 +01001605 printk(KERN_ERR "%s: %s: confused, missing data\n",
1606 drive->name, __FUNCTION__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001607 break;
1608 }
1609
1610 /*
1611 * Figure out how many sectors we can transfer
1612 */
1613 this_transfer = min_t(int, sectors_to_transfer, rq->current_nr_sectors);
1614
1615 while (this_transfer > 0) {
1616 HWIF(drive)->atapi_output_bytes(drive, rq->buffer, SECTOR_SIZE);
1617 rq->buffer += SECTOR_SIZE;
1618 --rq->nr_sectors;
1619 --rq->current_nr_sectors;
1620 ++rq->sector;
1621 --this_transfer;
1622 --sectors_to_transfer;
1623 }
1624
1625 /*
1626 * current buffer complete, move on
1627 */
1628 if (rq->current_nr_sectors == 0 && rq->nr_sectors)
1629 cdrom_end_request(drive, 1);
1630 }
1631
1632 /* re-arm handler */
1633 ide_set_handler(drive, &cdrom_write_intr, ATAPI_WAIT_PC, NULL);
1634 return ide_started;
1635}
1636
1637static ide_startstop_t cdrom_start_write_cont(ide_drive_t *drive)
1638{
1639 struct request *rq = HWGROUP(drive)->rq;
1640
1641#if 0 /* the immediate bit */
1642 rq->cmd[1] = 1 << 3;
1643#endif
1644 rq->timeout = ATAPI_WAIT_PC;
1645
1646 return cdrom_transfer_packet_command(drive, rq, cdrom_write_intr);
1647}
1648
1649static ide_startstop_t cdrom_start_write(ide_drive_t *drive, struct request *rq)
1650{
1651 struct cdrom_info *info = drive->driver_data;
1652 struct gendisk *g = info->disk;
1653 unsigned short sectors_per_frame = queue_hardsect_size(drive->queue) >> SECTOR_BITS;
1654
1655 /*
1656 * writes *must* be hardware frame aligned
1657 */
1658 if ((rq->nr_sectors & (sectors_per_frame - 1)) ||
1659 (rq->sector & (sectors_per_frame - 1))) {
1660 cdrom_end_request(drive, 0);
1661 return ide_stopped;
1662 }
1663
1664 /*
1665 * disk has become write protected
1666 */
1667 if (g->policy) {
1668 cdrom_end_request(drive, 0);
1669 return ide_stopped;
1670 }
1671
Linus Torvalds1da177e2005-04-16 15:20:36 -07001672 info->nsectors_buffered = 0;
1673
1674 /* use dma, if possible. we don't need to check more, since we
1675 * know that the transfer is always (at least!) frame aligned */
1676 info->dma = drive->using_dma ? 1 : 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001677
1678 info->devinfo.media_written = 1;
1679
1680 /* Start sending the write request to the drive. */
1681 return cdrom_start_packet_command(drive, 32768, cdrom_start_write_cont);
1682}
1683
1684static ide_startstop_t cdrom_do_newpc_cont(ide_drive_t *drive)
1685{
1686 struct request *rq = HWGROUP(drive)->rq;
1687
1688 if (!rq->timeout)
1689 rq->timeout = ATAPI_WAIT_PC;
1690
1691 return cdrom_transfer_packet_command(drive, rq, cdrom_newpc_intr);
1692}
1693
1694static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
1695{
1696 struct cdrom_info *info = drive->driver_data;
1697
Jens Axboe4aff5e22006-08-10 08:44:47 +02001698 rq->cmd_flags |= REQ_QUIET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001699
1700 info->dma = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001701
1702 /*
1703 * sg request
1704 */
1705 if (rq->bio) {
1706 int mask = drive->queue->dma_alignment;
1707 unsigned long addr = (unsigned long) page_address(bio_page(rq->bio));
1708
Linus Torvalds1da177e2005-04-16 15:20:36 -07001709 info->dma = drive->using_dma;
1710
1711 /*
1712 * check if dma is safe
Linus Torvalds5d9e4ea2005-05-27 07:36:17 -07001713 *
1714 * NOTE! The "len" and "addr" checks should possibly have
1715 * separate masks.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001716 */
Jens Axboe4e7c6812005-05-31 17:47:36 +02001717 if ((rq->data_len & 15) || (addr & mask))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001718 info->dma = 0;
1719 }
1720
1721 /* Start sending the command to the drive. */
1722 return cdrom_start_packet_command(drive, rq->data_len, cdrom_do_newpc_cont);
1723}
1724
1725/****************************************************************************
1726 * cdrom driver request routine.
1727 */
1728static ide_startstop_t
1729ide_do_rw_cdrom (ide_drive_t *drive, struct request *rq, sector_t block)
1730{
1731 ide_startstop_t action;
1732 struct cdrom_info *info = drive->driver_data;
1733
1734 if (blk_fs_request(rq)) {
1735 if (CDROM_CONFIG_FLAGS(drive)->seeking) {
1736 unsigned long elapsed = jiffies - info->start_seek;
1737 int stat = HWIF(drive)->INB(IDE_STATUS_REG);
1738
1739 if ((stat & SEEK_STAT) != SEEK_STAT) {
1740 if (elapsed < IDECD_SEEK_TIMEOUT) {
1741 ide_stall_queue(drive, IDECD_SEEK_TIMER);
1742 return ide_stopped;
1743 }
1744 printk (KERN_ERR "%s: DSC timeout\n", drive->name);
1745 }
1746 CDROM_CONFIG_FLAGS(drive)->seeking = 0;
1747 }
1748 if ((rq_data_dir(rq) == READ) && IDE_LARGE_SEEK(info->last_block, block, IDECD_SEEK_THRESHOLD) && drive->dsc_overlap) {
1749 action = cdrom_start_seek(drive, block);
1750 } else {
1751 if (rq_data_dir(rq) == READ)
1752 action = cdrom_start_read(drive, block);
1753 else
1754 action = cdrom_start_write(drive, rq);
1755 }
1756 info->last_block = block;
1757 return action;
Jens Axboecea28852006-10-12 15:08:45 +02001758 } else if (rq->cmd_type == REQ_TYPE_SENSE ||
1759 rq->cmd_type == REQ_TYPE_ATA_PC) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001760 return cdrom_do_packet_command(drive);
Jens Axboe4aff5e22006-08-10 08:44:47 +02001761 } else if (blk_pc_request(rq)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001762 return cdrom_do_block_pc(drive, rq);
Jens Axboe4aff5e22006-08-10 08:44:47 +02001763 } else if (blk_special_request(rq)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001764 /*
1765 * right now this can only be a reset...
1766 */
1767 cdrom_end_request(drive, 1);
1768 return ide_stopped;
1769 }
1770
1771 blk_dump_rq_flags(rq, "ide-cd bad flags");
1772 cdrom_end_request(drive, 0);
1773 return ide_stopped;
1774}
1775
1776
1777
1778/****************************************************************************
1779 * Ioctl handling.
1780 *
1781 * Routines which queue packet commands take as a final argument a pointer
1782 * to a request_sense struct. If execution of the command results
1783 * in an error with a CHECK CONDITION status, this structure will be filled
1784 * with the results of the subsequent request sense command. The pointer
1785 * can also be NULL, in which case no sense information is returned.
1786 */
1787
1788#if ! STANDARD_ATAPI
1789static inline
1790int bin2bcd (int x)
1791{
1792 return (x%10) | ((x/10) << 4);
1793}
1794
1795
1796static inline
1797int bcd2bin (int x)
1798{
1799 return (x >> 4) * 10 + (x & 0x0f);
1800}
1801
1802static
1803void msf_from_bcd (struct atapi_msf *msf)
1804{
1805 msf->minute = bcd2bin (msf->minute);
1806 msf->second = bcd2bin (msf->second);
1807 msf->frame = bcd2bin (msf->frame);
1808}
1809
1810#endif /* not STANDARD_ATAPI */
1811
1812
1813static inline
1814void lba_to_msf (int lba, byte *m, byte *s, byte *f)
1815{
1816 lba += CD_MSF_OFFSET;
1817 lba &= 0xffffff; /* negative lbas use only 24 bits */
1818 *m = lba / (CD_SECS * CD_FRAMES);
1819 lba %= (CD_SECS * CD_FRAMES);
1820 *s = lba / CD_FRAMES;
1821 *f = lba % CD_FRAMES;
1822}
1823
1824
1825static inline
1826int msf_to_lba (byte m, byte s, byte f)
1827{
1828 return (((m * CD_SECS) + s) * CD_FRAMES + f) - CD_MSF_OFFSET;
1829}
1830
1831static int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense)
1832{
1833 struct request req;
1834 struct cdrom_info *info = drive->driver_data;
1835 struct cdrom_device_info *cdi = &info->devinfo;
1836
1837 cdrom_prepare_request(drive, &req);
1838
1839 req.sense = sense;
1840 req.cmd[0] = GPCMD_TEST_UNIT_READY;
Jens Axboe4aff5e22006-08-10 08:44:47 +02001841 req.cmd_flags |= REQ_QUIET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001842
1843#if ! STANDARD_ATAPI
1844 /* the Sanyo 3 CD changer uses byte 7 of TEST_UNIT_READY to
1845 switch CDs instead of supporting the LOAD_UNLOAD opcode */
1846
1847 req.cmd[7] = cdi->sanyo_slot % 3;
1848#endif /* not STANDARD_ATAPI */
1849
1850 return cdrom_queue_packet_command(drive, &req);
1851}
1852
1853
1854/* Lock the door if LOCKFLAG is nonzero; unlock it otherwise. */
1855static int
1856cdrom_lockdoor(ide_drive_t *drive, int lockflag, struct request_sense *sense)
1857{
1858 struct request_sense my_sense;
1859 struct request req;
1860 int stat;
1861
1862 if (sense == NULL)
1863 sense = &my_sense;
1864
1865 /* If the drive cannot lock the door, just pretend. */
1866 if (CDROM_CONFIG_FLAGS(drive)->no_doorlock) {
1867 stat = 0;
1868 } else {
1869 cdrom_prepare_request(drive, &req);
1870 req.sense = sense;
1871 req.cmd[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL;
1872 req.cmd[4] = lockflag ? 1 : 0;
1873 stat = cdrom_queue_packet_command(drive, &req);
1874 }
1875
1876 /* If we got an illegal field error, the drive
1877 probably cannot lock the door. */
1878 if (stat != 0 &&
1879 sense->sense_key == ILLEGAL_REQUEST &&
1880 (sense->asc == 0x24 || sense->asc == 0x20)) {
1881 printk (KERN_ERR "%s: door locking not supported\n",
1882 drive->name);
1883 CDROM_CONFIG_FLAGS(drive)->no_doorlock = 1;
1884 stat = 0;
1885 }
1886
1887 /* no medium, that's alright. */
1888 if (stat != 0 && sense->sense_key == NOT_READY && sense->asc == 0x3a)
1889 stat = 0;
1890
1891 if (stat == 0)
1892 CDROM_STATE_FLAGS(drive)->door_locked = lockflag;
1893
1894 return stat;
1895}
1896
1897
1898/* Eject the disk if EJECTFLAG is 0.
1899 If EJECTFLAG is 1, try to reload the disk. */
1900static int cdrom_eject(ide_drive_t *drive, int ejectflag,
1901 struct request_sense *sense)
1902{
1903 struct request req;
1904 char loej = 0x02;
1905
1906 if (CDROM_CONFIG_FLAGS(drive)->no_eject && !ejectflag)
1907 return -EDRIVE_CANT_DO_THIS;
1908
1909 /* reload fails on some drives, if the tray is locked */
1910 if (CDROM_STATE_FLAGS(drive)->door_locked && ejectflag)
1911 return 0;
1912
1913 cdrom_prepare_request(drive, &req);
1914
1915 /* only tell drive to close tray if open, if it can do that */
1916 if (ejectflag && !CDROM_CONFIG_FLAGS(drive)->close_tray)
1917 loej = 0;
1918
1919 req.sense = sense;
1920 req.cmd[0] = GPCMD_START_STOP_UNIT;
1921 req.cmd[4] = loej | (ejectflag != 0);
1922 return cdrom_queue_packet_command(drive, &req);
1923}
1924
1925static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
1926 unsigned long *sectors_per_frame,
1927 struct request_sense *sense)
1928{
1929 struct {
1930 __u32 lba;
1931 __u32 blocklen;
1932 } capbuf;
1933
1934 int stat;
1935 struct request req;
1936
1937 cdrom_prepare_request(drive, &req);
1938
1939 req.sense = sense;
1940 req.cmd[0] = GPCMD_READ_CDVD_CAPACITY;
1941 req.data = (char *)&capbuf;
1942 req.data_len = sizeof(capbuf);
Jens Axboe4aff5e22006-08-10 08:44:47 +02001943 req.cmd_flags |= REQ_QUIET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001944
1945 stat = cdrom_queue_packet_command(drive, &req);
1946 if (stat == 0) {
1947 *capacity = 1 + be32_to_cpu(capbuf.lba);
1948 *sectors_per_frame =
1949 be32_to_cpu(capbuf.blocklen) >> SECTOR_BITS;
1950 }
1951
1952 return stat;
1953}
1954
1955static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag,
1956 int format, char *buf, int buflen,
1957 struct request_sense *sense)
1958{
1959 struct request req;
1960
1961 cdrom_prepare_request(drive, &req);
1962
1963 req.sense = sense;
1964 req.data = buf;
1965 req.data_len = buflen;
Jens Axboe4aff5e22006-08-10 08:44:47 +02001966 req.cmd_flags |= REQ_QUIET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001967 req.cmd[0] = GPCMD_READ_TOC_PMA_ATIP;
1968 req.cmd[6] = trackno;
1969 req.cmd[7] = (buflen >> 8);
1970 req.cmd[8] = (buflen & 0xff);
1971 req.cmd[9] = (format << 6);
1972
1973 if (msf_flag)
1974 req.cmd[1] = 2;
1975
1976 return cdrom_queue_packet_command(drive, &req);
1977}
1978
1979
1980/* Try to read the entire TOC for the disk into our internal buffer. */
1981static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense)
1982{
1983 int stat, ntracks, i;
1984 struct cdrom_info *info = drive->driver_data;
1985 struct cdrom_device_info *cdi = &info->devinfo;
1986 struct atapi_toc *toc = info->toc;
1987 struct {
1988 struct atapi_toc_header hdr;
1989 struct atapi_toc_entry ent;
1990 } ms_tmp;
1991 long last_written;
1992 unsigned long sectors_per_frame = SECTORS_PER_FRAME;
1993
1994 if (toc == NULL) {
1995 /* Try to allocate space. */
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08001996 toc = kmalloc(sizeof(struct atapi_toc), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001997 if (toc == NULL) {
1998 printk (KERN_ERR "%s: No cdrom TOC buffer!\n", drive->name);
1999 return -ENOMEM;
2000 }
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002001 info->toc = toc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002002 }
2003
2004 /* Check to see if the existing data is still valid.
2005 If it is, just return. */
2006 (void) cdrom_check_status(drive, sense);
2007
2008 if (CDROM_STATE_FLAGS(drive)->toc_valid)
2009 return 0;
2010
2011 /* Try to get the total cdrom capacity and sector size. */
2012 stat = cdrom_read_capacity(drive, &toc->capacity, &sectors_per_frame,
2013 sense);
2014 if (stat)
2015 toc->capacity = 0x1fffff;
2016
2017 set_capacity(info->disk, toc->capacity * sectors_per_frame);
Alan Coxdbe217a2006-06-25 05:47:44 -07002018 /* Save a private copy of te TOC capacity for error handling */
2019 drive->probed_capacity = toc->capacity * sectors_per_frame;
2020
Linus Torvalds1da177e2005-04-16 15:20:36 -07002021 blk_queue_hardsect_size(drive->queue,
2022 sectors_per_frame << SECTOR_BITS);
2023
2024 /* First read just the header, so we know how long the TOC is. */
2025 stat = cdrom_read_tocentry(drive, 0, 1, 0, (char *) &toc->hdr,
2026 sizeof(struct atapi_toc_header), sense);
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002027 if (stat)
2028 return stat;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002029
2030#if ! STANDARD_ATAPI
2031 if (CDROM_CONFIG_FLAGS(drive)->toctracks_as_bcd) {
2032 toc->hdr.first_track = bcd2bin(toc->hdr.first_track);
2033 toc->hdr.last_track = bcd2bin(toc->hdr.last_track);
2034 }
2035#endif /* not STANDARD_ATAPI */
2036
2037 ntracks = toc->hdr.last_track - toc->hdr.first_track + 1;
2038 if (ntracks <= 0)
2039 return -EIO;
2040 if (ntracks > MAX_TRACKS)
2041 ntracks = MAX_TRACKS;
2042
2043 /* Now read the whole schmeer. */
2044 stat = cdrom_read_tocentry(drive, toc->hdr.first_track, 1, 0,
2045 (char *)&toc->hdr,
2046 sizeof(struct atapi_toc_header) +
2047 (ntracks + 1) *
2048 sizeof(struct atapi_toc_entry), sense);
2049
2050 if (stat && toc->hdr.first_track > 1) {
2051 /* Cds with CDI tracks only don't have any TOC entries,
2052 despite of this the returned values are
2053 first_track == last_track = number of CDI tracks + 1,
2054 so that this case is indistinguishable from the same
2055 layout plus an additional audio track.
2056 If we get an error for the regular case, we assume
2057 a CDI without additional audio tracks. In this case
2058 the readable TOC is empty (CDI tracks are not included)
Jan Engelhardt96de0e22007-10-19 23:21:04 +02002059 and only holds the Leadout entry. Heiko Eißfeldt */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002060 ntracks = 0;
2061 stat = cdrom_read_tocentry(drive, CDROM_LEADOUT, 1, 0,
2062 (char *)&toc->hdr,
2063 sizeof(struct atapi_toc_header) +
2064 (ntracks + 1) *
2065 sizeof(struct atapi_toc_entry),
2066 sense);
2067 if (stat) {
2068 return stat;
2069 }
2070#if ! STANDARD_ATAPI
2071 if (CDROM_CONFIG_FLAGS(drive)->toctracks_as_bcd) {
2072 toc->hdr.first_track = bin2bcd(CDROM_LEADOUT);
2073 toc->hdr.last_track = bin2bcd(CDROM_LEADOUT);
2074 } else
2075#endif /* not STANDARD_ATAPI */
2076 {
2077 toc->hdr.first_track = CDROM_LEADOUT;
2078 toc->hdr.last_track = CDROM_LEADOUT;
2079 }
2080 }
2081
2082 if (stat)
2083 return stat;
2084
2085 toc->hdr.toc_length = ntohs (toc->hdr.toc_length);
2086
2087#if ! STANDARD_ATAPI
2088 if (CDROM_CONFIG_FLAGS(drive)->toctracks_as_bcd) {
2089 toc->hdr.first_track = bcd2bin(toc->hdr.first_track);
2090 toc->hdr.last_track = bcd2bin(toc->hdr.last_track);
2091 }
2092#endif /* not STANDARD_ATAPI */
2093
2094 for (i=0; i<=ntracks; i++) {
2095#if ! STANDARD_ATAPI
2096 if (CDROM_CONFIG_FLAGS(drive)->tocaddr_as_bcd) {
2097 if (CDROM_CONFIG_FLAGS(drive)->toctracks_as_bcd)
2098 toc->ent[i].track = bcd2bin(toc->ent[i].track);
2099 msf_from_bcd(&toc->ent[i].addr.msf);
2100 }
2101#endif /* not STANDARD_ATAPI */
2102 toc->ent[i].addr.lba = msf_to_lba (toc->ent[i].addr.msf.minute,
2103 toc->ent[i].addr.msf.second,
2104 toc->ent[i].addr.msf.frame);
2105 }
2106
2107 /* Read the multisession information. */
2108 if (toc->hdr.first_track != CDROM_LEADOUT) {
2109 /* Read the multisession information. */
2110 stat = cdrom_read_tocentry(drive, 0, 0, 1, (char *)&ms_tmp,
2111 sizeof(ms_tmp), sense);
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002112 if (stat)
2113 return stat;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002114
2115 toc->last_session_lba = be32_to_cpu(ms_tmp.ent.addr.lba);
2116 } else {
2117 ms_tmp.hdr.first_track = ms_tmp.hdr.last_track = CDROM_LEADOUT;
2118 toc->last_session_lba = msf_to_lba(0, 2, 0); /* 0m 2s 0f */
2119 }
2120
2121#if ! STANDARD_ATAPI
2122 if (CDROM_CONFIG_FLAGS(drive)->tocaddr_as_bcd) {
2123 /* Re-read multisession information using MSF format */
2124 stat = cdrom_read_tocentry(drive, 0, 1, 1, (char *)&ms_tmp,
2125 sizeof(ms_tmp), sense);
2126 if (stat)
2127 return stat;
2128
2129 msf_from_bcd (&ms_tmp.ent.addr.msf);
2130 toc->last_session_lba = msf_to_lba(ms_tmp.ent.addr.msf.minute,
2131 ms_tmp.ent.addr.msf.second,
2132 ms_tmp.ent.addr.msf.frame);
2133 }
2134#endif /* not STANDARD_ATAPI */
2135
2136 toc->xa_flag = (ms_tmp.hdr.first_track != ms_tmp.hdr.last_track);
2137
2138 /* Now try to get the total cdrom capacity. */
2139 stat = cdrom_get_last_written(cdi, &last_written);
2140 if (!stat && (last_written > toc->capacity)) {
2141 toc->capacity = last_written;
2142 set_capacity(info->disk, toc->capacity * sectors_per_frame);
Alan Coxdbe217a2006-06-25 05:47:44 -07002143 drive->probed_capacity = toc->capacity * sectors_per_frame;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002144 }
2145
2146 /* Remember that we've read this stuff. */
2147 CDROM_STATE_FLAGS(drive)->toc_valid = 1;
2148
2149 return 0;
2150}
2151
2152
2153static int cdrom_read_subchannel(ide_drive_t *drive, int format, char *buf,
2154 int buflen, struct request_sense *sense)
2155{
2156 struct request req;
2157
2158 cdrom_prepare_request(drive, &req);
2159
2160 req.sense = sense;
2161 req.data = buf;
2162 req.data_len = buflen;
2163 req.cmd[0] = GPCMD_READ_SUBCHANNEL;
2164 req.cmd[1] = 2; /* MSF addressing */
2165 req.cmd[2] = 0x40; /* request subQ data */
2166 req.cmd[3] = format;
2167 req.cmd[7] = (buflen >> 8);
2168 req.cmd[8] = (buflen & 0xff);
2169 return cdrom_queue_packet_command(drive, &req);
2170}
2171
2172/* ATAPI cdrom drives are free to select the speed you request or any slower
2173 rate :-( Requesting too fast a speed will _not_ produce an error. */
2174static int cdrom_select_speed(ide_drive_t *drive, int speed,
2175 struct request_sense *sense)
2176{
2177 struct request req;
2178 cdrom_prepare_request(drive, &req);
2179
2180 req.sense = sense;
2181 if (speed == 0)
2182 speed = 0xffff; /* set to max */
2183 else
2184 speed *= 177; /* Nx to kbytes/s */
2185
2186 req.cmd[0] = GPCMD_SET_SPEED;
2187 /* Read Drive speed in kbytes/second MSB */
2188 req.cmd[2] = (speed >> 8) & 0xff;
2189 /* Read Drive speed in kbytes/second LSB */
2190 req.cmd[3] = speed & 0xff;
2191 if (CDROM_CONFIG_FLAGS(drive)->cd_r ||
2192 CDROM_CONFIG_FLAGS(drive)->cd_rw ||
2193 CDROM_CONFIG_FLAGS(drive)->dvd_r) {
2194 /* Write Drive speed in kbytes/second MSB */
2195 req.cmd[4] = (speed >> 8) & 0xff;
2196 /* Write Drive speed in kbytes/second LSB */
2197 req.cmd[5] = speed & 0xff;
2198 }
2199
2200 return cdrom_queue_packet_command(drive, &req);
2201}
2202
2203static int cdrom_play_audio(ide_drive_t *drive, int lba_start, int lba_end)
2204{
2205 struct request_sense sense;
2206 struct request req;
2207
2208 cdrom_prepare_request(drive, &req);
2209
2210 req.sense = &sense;
2211 req.cmd[0] = GPCMD_PLAY_AUDIO_MSF;
2212 lba_to_msf(lba_start, &req.cmd[3], &req.cmd[4], &req.cmd[5]);
2213 lba_to_msf(lba_end-1, &req.cmd[6], &req.cmd[7], &req.cmd[8]);
2214
2215 return cdrom_queue_packet_command(drive, &req);
2216}
2217
2218static int cdrom_get_toc_entry(ide_drive_t *drive, int track,
2219 struct atapi_toc_entry **ent)
2220{
2221 struct cdrom_info *info = drive->driver_data;
2222 struct atapi_toc *toc = info->toc;
2223 int ntracks;
2224
2225 /*
2226 * don't serve cached data, if the toc isn't valid
2227 */
2228 if (!CDROM_STATE_FLAGS(drive)->toc_valid)
2229 return -EINVAL;
2230
2231 /* Check validity of requested track number. */
2232 ntracks = toc->hdr.last_track - toc->hdr.first_track + 1;
2233 if (toc->hdr.first_track == CDROM_LEADOUT) ntracks = 0;
2234 if (track == CDROM_LEADOUT)
2235 *ent = &toc->ent[ntracks];
2236 else if (track < toc->hdr.first_track ||
2237 track > toc->hdr.last_track)
2238 return -EINVAL;
2239 else
2240 *ent = &toc->ent[track - toc->hdr.first_track];
2241
2242 return 0;
2243}
2244
2245/* the generic packet interface to cdrom.c */
2246static int ide_cdrom_packet(struct cdrom_device_info *cdi,
2247 struct packet_command *cgc)
2248{
2249 struct request req;
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002250 ide_drive_t *drive = cdi->handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002251
2252 if (cgc->timeout <= 0)
2253 cgc->timeout = ATAPI_WAIT_PC;
2254
2255 /* here we queue the commands from the uniform CD-ROM
2256 layer. the packet must be complete, as we do not
2257 touch it at all. */
2258 cdrom_prepare_request(drive, &req);
2259 memcpy(req.cmd, cgc->cmd, CDROM_PACKET_SIZE);
2260 if (cgc->sense)
2261 memset(cgc->sense, 0, sizeof(struct request_sense));
2262 req.data = cgc->buffer;
2263 req.data_len = cgc->buflen;
2264 req.timeout = cgc->timeout;
2265
2266 if (cgc->quiet)
Jens Axboe4aff5e22006-08-10 08:44:47 +02002267 req.cmd_flags |= REQ_QUIET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002268
2269 req.sense = cgc->sense;
2270 cgc->stat = cdrom_queue_packet_command(drive, &req);
2271 if (!cgc->stat)
2272 cgc->buflen -= req.data_len;
2273 return cgc->stat;
2274}
2275
2276static
Linus Torvalds1da177e2005-04-16 15:20:36 -07002277int ide_cdrom_audio_ioctl (struct cdrom_device_info *cdi,
2278 unsigned int cmd, void *arg)
2279
2280{
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002281 ide_drive_t *drive = cdi->handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002282 struct cdrom_info *info = drive->driver_data;
2283 int stat;
2284
2285 switch (cmd) {
2286 /*
2287 * emulate PLAY_AUDIO_TI command with PLAY_AUDIO_10, since
2288 * atapi doesn't support it
2289 */
2290 case CDROMPLAYTRKIND: {
2291 unsigned long lba_start, lba_end;
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002292 struct cdrom_ti *ti = arg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002293 struct atapi_toc_entry *first_toc, *last_toc;
2294
2295 stat = cdrom_get_toc_entry(drive, ti->cdti_trk0, &first_toc);
2296 if (stat)
2297 return stat;
2298
2299 stat = cdrom_get_toc_entry(drive, ti->cdti_trk1, &last_toc);
2300 if (stat)
2301 return stat;
2302
2303 if (ti->cdti_trk1 != CDROM_LEADOUT)
2304 ++last_toc;
2305 lba_start = first_toc->addr.lba;
2306 lba_end = last_toc->addr.lba;
2307
2308 if (lba_end <= lba_start)
2309 return -EINVAL;
2310
2311 return cdrom_play_audio(drive, lba_start, lba_end);
2312 }
2313
2314 case CDROMREADTOCHDR: {
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002315 struct cdrom_tochdr *tochdr = arg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002316 struct atapi_toc *toc;
2317
2318 /* Make sure our saved TOC is valid. */
2319 stat = cdrom_read_toc(drive, NULL);
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002320 if (stat)
2321 return stat;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002322
2323 toc = info->toc;
2324 tochdr->cdth_trk0 = toc->hdr.first_track;
2325 tochdr->cdth_trk1 = toc->hdr.last_track;
2326
2327 return 0;
2328 }
2329
2330 case CDROMREADTOCENTRY: {
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002331 struct cdrom_tocentry *tocentry = arg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002332 struct atapi_toc_entry *toce;
2333
2334 stat = cdrom_get_toc_entry(drive, tocentry->cdte_track, &toce);
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002335 if (stat)
2336 return stat;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002337
2338 tocentry->cdte_ctrl = toce->control;
2339 tocentry->cdte_adr = toce->adr;
2340 if (tocentry->cdte_format == CDROM_MSF) {
2341 lba_to_msf (toce->addr.lba,
2342 &tocentry->cdte_addr.msf.minute,
2343 &tocentry->cdte_addr.msf.second,
2344 &tocentry->cdte_addr.msf.frame);
2345 } else
2346 tocentry->cdte_addr.lba = toce->addr.lba;
2347
2348 return 0;
2349 }
2350
2351 default:
2352 return -EINVAL;
2353 }
2354}
2355
2356static
2357int ide_cdrom_reset (struct cdrom_device_info *cdi)
2358{
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002359 ide_drive_t *drive = cdi->handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002360 struct request_sense sense;
2361 struct request req;
2362 int ret;
2363
2364 cdrom_prepare_request(drive, &req);
Jens Axboe4aff5e22006-08-10 08:44:47 +02002365 req.cmd_type = REQ_TYPE_SPECIAL;
2366 req.cmd_flags = REQ_QUIET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002367 ret = ide_do_drive_cmd(drive, &req, ide_wait);
2368
2369 /*
2370 * A reset will unlock the door. If it was previously locked,
2371 * lock it again.
2372 */
2373 if (CDROM_STATE_FLAGS(drive)->door_locked)
2374 (void) cdrom_lockdoor(drive, 1, &sense);
2375
2376 return ret;
2377}
2378
2379
2380static
2381int ide_cdrom_tray_move (struct cdrom_device_info *cdi, int position)
2382{
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002383 ide_drive_t *drive = cdi->handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002384 struct request_sense sense;
2385
2386 if (position) {
2387 int stat = cdrom_lockdoor(drive, 0, &sense);
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002388 if (stat)
2389 return stat;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002390 }
2391
2392 return cdrom_eject(drive, !position, &sense);
2393}
2394
2395static
2396int ide_cdrom_lock_door (struct cdrom_device_info *cdi, int lock)
2397{
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002398 ide_drive_t *drive = cdi->handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002399 return cdrom_lockdoor(drive, lock, NULL);
2400}
2401
2402static
Eric Piel9235e682005-06-23 00:10:29 -07002403int ide_cdrom_get_capabilities(ide_drive_t *drive, struct atapi_capabilities_page *cap)
2404{
2405 struct cdrom_info *info = drive->driver_data;
2406 struct cdrom_device_info *cdi = &info->devinfo;
2407 struct packet_command cgc;
2408 int stat, attempts = 3, size = sizeof(*cap);
2409
2410 /*
2411 * ACER50 (and others?) require the full spec length mode sense
2412 * page capabilities size, but older drives break.
2413 */
2414 if (!(!strcmp(drive->id->model, "ATAPI CD ROM DRIVE 50X MAX") ||
2415 !strcmp(drive->id->model, "WPI CDS-32X")))
2416 size -= sizeof(cap->pad);
2417
2418 init_cdrom_command(&cgc, cap, size, CGC_DATA_UNKNOWN);
2419 do { /* we seem to get stat=0x01,err=0x00 the first time (??) */
2420 stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CAPABILITIES_PAGE, 0);
2421 if (!stat)
2422 break;
2423 } while (--attempts);
2424 return stat;
2425}
2426
2427static
2428void ide_cdrom_update_speed (ide_drive_t *drive, struct atapi_capabilities_page *cap)
2429{
2430 /* The ACER/AOpen 24X cdrom has the speed fields byte-swapped */
2431 if (!drive->id->model[0] &&
2432 !strncmp(drive->id->fw_rev, "241N", 4)) {
2433 CDROM_STATE_FLAGS(drive)->current_speed =
Bartlomiej Zolnierkiewiczaa5dc8e2007-12-24 15:23:43 +01002434 (le16_to_cpu(cap->curspeed) + (176/2)) / 176;
Eric Piel9235e682005-06-23 00:10:29 -07002435 CDROM_CONFIG_FLAGS(drive)->max_speed =
Bartlomiej Zolnierkiewiczaa5dc8e2007-12-24 15:23:43 +01002436 (le16_to_cpu(cap->maxspeed) + (176/2)) / 176;
Eric Piel9235e682005-06-23 00:10:29 -07002437 } else {
2438 CDROM_STATE_FLAGS(drive)->current_speed =
Bartlomiej Zolnierkiewiczaa5dc8e2007-12-24 15:23:43 +01002439 (be16_to_cpu(cap->curspeed) + (176/2)) / 176;
Eric Piel9235e682005-06-23 00:10:29 -07002440 CDROM_CONFIG_FLAGS(drive)->max_speed =
Bartlomiej Zolnierkiewiczaa5dc8e2007-12-24 15:23:43 +01002441 (be16_to_cpu(cap->maxspeed) + (176/2)) / 176;
Eric Piel9235e682005-06-23 00:10:29 -07002442 }
2443}
2444
2445static
Linus Torvalds1da177e2005-04-16 15:20:36 -07002446int ide_cdrom_select_speed (struct cdrom_device_info *cdi, int speed)
2447{
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002448 ide_drive_t *drive = cdi->handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002449 struct request_sense sense;
Eric Piel9235e682005-06-23 00:10:29 -07002450 struct atapi_capabilities_page cap;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002451 int stat;
2452
2453 if ((stat = cdrom_select_speed(drive, speed, &sense)) < 0)
2454 return stat;
2455
Eric Piel9235e682005-06-23 00:10:29 -07002456 if (!ide_cdrom_get_capabilities(drive, &cap)) {
2457 ide_cdrom_update_speed(drive, &cap);
2458 cdi->speed = CDROM_STATE_FLAGS(drive)->current_speed;
2459 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002460 return 0;
2461}
2462
2463/*
2464 * add logic to try GET_EVENT command first to check for media and tray
2465 * status. this should be supported by newer cd-r/w and all DVD etc
2466 * drives
2467 */
2468static
2469int ide_cdrom_drive_status (struct cdrom_device_info *cdi, int slot_nr)
2470{
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002471 ide_drive_t *drive = cdi->handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002472 struct media_event_desc med;
2473 struct request_sense sense;
2474 int stat;
2475
2476 if (slot_nr != CDSL_CURRENT)
2477 return -EINVAL;
2478
2479 stat = cdrom_check_status(drive, &sense);
2480 if (!stat || sense.sense_key == UNIT_ATTENTION)
2481 return CDS_DISC_OK;
2482
2483 if (!cdrom_get_media_event(cdi, &med)) {
2484 if (med.media_present)
2485 return CDS_DISC_OK;
2486 else if (med.door_open)
2487 return CDS_TRAY_OPEN;
2488 else
2489 return CDS_NO_DISC;
2490 }
2491
2492 if (sense.sense_key == NOT_READY && sense.asc == 0x04 && sense.ascq == 0x04)
2493 return CDS_DISC_OK;
2494
2495 /*
2496 * If not using Mt Fuji extended media tray reports,
2497 * just return TRAY_OPEN since ATAPI doesn't provide
2498 * any other way to detect this...
2499 */
2500 if (sense.sense_key == NOT_READY) {
Alan Coxdbe217a2006-06-25 05:47:44 -07002501 if (sense.asc == 0x3a && sense.ascq == 1)
2502 return CDS_NO_DISC;
2503 else
2504 return CDS_TRAY_OPEN;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002505 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002506 return CDS_DRIVE_NOT_READY;
2507}
2508
2509static
2510int ide_cdrom_get_last_session (struct cdrom_device_info *cdi,
2511 struct cdrom_multisession *ms_info)
2512{
2513 struct atapi_toc *toc;
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002514 ide_drive_t *drive = cdi->handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002515 struct cdrom_info *info = drive->driver_data;
2516 struct request_sense sense;
2517 int ret;
2518
2519 if (!CDROM_STATE_FLAGS(drive)->toc_valid || info->toc == NULL)
2520 if ((ret = cdrom_read_toc(drive, &sense)))
2521 return ret;
2522
2523 toc = info->toc;
2524 ms_info->addr.lba = toc->last_session_lba;
2525 ms_info->xa_flag = toc->xa_flag;
2526
2527 return 0;
2528}
2529
2530static
2531int ide_cdrom_get_mcn (struct cdrom_device_info *cdi,
2532 struct cdrom_mcn *mcn_info)
2533{
2534 int stat;
2535 char mcnbuf[24];
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002536 ide_drive_t *drive = cdi->handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002537
2538/* get MCN */
2539 if ((stat = cdrom_read_subchannel(drive, 2, mcnbuf, sizeof (mcnbuf), NULL)))
2540 return stat;
2541
2542 memcpy (mcn_info->medium_catalog_number, mcnbuf+9,
2543 sizeof (mcn_info->medium_catalog_number)-1);
2544 mcn_info->medium_catalog_number[sizeof (mcn_info->medium_catalog_number)-1]
2545 = '\0';
2546
2547 return 0;
2548}
2549
2550
2551
2552/****************************************************************************
2553 * Other driver requests (open, close, check media change).
2554 */
2555
2556static
2557int ide_cdrom_check_media_change_real (struct cdrom_device_info *cdi,
2558 int slot_nr)
2559{
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002560 ide_drive_t *drive = cdi->handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002561 int retval;
2562
2563 if (slot_nr == CDSL_CURRENT) {
2564 (void) cdrom_check_status(drive, NULL);
2565 retval = CDROM_STATE_FLAGS(drive)->media_changed;
2566 CDROM_STATE_FLAGS(drive)->media_changed = 0;
2567 return retval;
2568 } else {
2569 return -EINVAL;
2570 }
2571}
2572
2573
2574static
2575int ide_cdrom_open_real (struct cdrom_device_info *cdi, int purpose)
2576{
2577 return 0;
2578}
2579
2580/*
2581 * Close down the device. Invalidate all cached blocks.
2582 */
2583
2584static
2585void ide_cdrom_release_real (struct cdrom_device_info *cdi)
2586{
2587 ide_drive_t *drive = cdi->handle;
2588
2589 if (!cdi->use_count)
2590 CDROM_STATE_FLAGS(drive)->toc_valid = 0;
2591}
2592
2593
2594
2595/****************************************************************************
2596 * Device initialization.
2597 */
2598static struct cdrom_device_ops ide_cdrom_dops = {
2599 .open = ide_cdrom_open_real,
2600 .release = ide_cdrom_release_real,
2601 .drive_status = ide_cdrom_drive_status,
2602 .media_changed = ide_cdrom_check_media_change_real,
2603 .tray_move = ide_cdrom_tray_move,
2604 .lock_door = ide_cdrom_lock_door,
2605 .select_speed = ide_cdrom_select_speed,
2606 .get_last_session = ide_cdrom_get_last_session,
2607 .get_mcn = ide_cdrom_get_mcn,
2608 .reset = ide_cdrom_reset,
2609 .audio_ioctl = ide_cdrom_audio_ioctl,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002610 .capability = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK |
2611 CDC_SELECT_SPEED | CDC_SELECT_DISC |
2612 CDC_MULTI_SESSION | CDC_MCN |
2613 CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO | CDC_RESET |
Christoph Hellwig6a2900b2006-03-23 03:00:15 -08002614 CDC_DRIVE_STATUS | CDC_CD_R |
Linus Torvalds1da177e2005-04-16 15:20:36 -07002615 CDC_CD_RW | CDC_DVD | CDC_DVD_R| CDC_DVD_RAM |
2616 CDC_GENERIC_PACKET | CDC_MO_DRIVE | CDC_MRW |
2617 CDC_MRW_W | CDC_RAM,
2618 .generic_packet = ide_cdrom_packet,
2619};
2620
2621static int ide_cdrom_register (ide_drive_t *drive, int nslots)
2622{
2623 struct cdrom_info *info = drive->driver_data;
2624 struct cdrom_device_info *devinfo = &info->devinfo;
2625
2626 devinfo->ops = &ide_cdrom_dops;
2627 devinfo->mask = 0;
2628 devinfo->speed = CDROM_STATE_FLAGS(drive)->current_speed;
2629 devinfo->capacity = nslots;
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002630 devinfo->handle = drive;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002631 strcpy(devinfo->name, drive->name);
2632
2633 /* set capability mask to match the probe. */
2634 if (!CDROM_CONFIG_FLAGS(drive)->cd_r)
2635 devinfo->mask |= CDC_CD_R;
2636 if (!CDROM_CONFIG_FLAGS(drive)->cd_rw)
2637 devinfo->mask |= CDC_CD_RW;
2638 if (!CDROM_CONFIG_FLAGS(drive)->dvd)
2639 devinfo->mask |= CDC_DVD;
2640 if (!CDROM_CONFIG_FLAGS(drive)->dvd_r)
2641 devinfo->mask |= CDC_DVD_R;
2642 if (!CDROM_CONFIG_FLAGS(drive)->dvd_ram)
2643 devinfo->mask |= CDC_DVD_RAM;
2644 if (!CDROM_CONFIG_FLAGS(drive)->is_changer)
2645 devinfo->mask |= CDC_SELECT_DISC;
2646 if (!CDROM_CONFIG_FLAGS(drive)->audio_play)
2647 devinfo->mask |= CDC_PLAY_AUDIO;
2648 if (!CDROM_CONFIG_FLAGS(drive)->close_tray)
2649 devinfo->mask |= CDC_CLOSE_TRAY;
2650 if (!CDROM_CONFIG_FLAGS(drive)->mo_drive)
2651 devinfo->mask |= CDC_MO_DRIVE;
Andrey Borzenkovc0400dc2006-01-10 11:27:00 +01002652 if (!CDROM_CONFIG_FLAGS(drive)->ram)
2653 devinfo->mask |= CDC_RAM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002654
Bartlomiej Zolnierkiewicz3cbd8142007-12-24 15:23:43 +01002655 if (CDROM_CONFIG_FLAGS(drive)->no_speed_select)
2656 devinfo->mask |= CDC_SELECT_SPEED;
2657
Linus Torvalds1da177e2005-04-16 15:20:36 -07002658 devinfo->disk = info->disk;
2659 return register_cdrom(devinfo);
2660}
2661
2662static
Linus Torvalds1da177e2005-04-16 15:20:36 -07002663int ide_cdrom_probe_capabilities (ide_drive_t *drive)
2664{
2665 struct cdrom_info *info = drive->driver_data;
2666 struct cdrom_device_info *cdi = &info->devinfo;
2667 struct atapi_capabilities_page cap;
2668 int nslots = 1;
2669
2670 if (drive->media == ide_optical) {
2671 CDROM_CONFIG_FLAGS(drive)->mo_drive = 1;
2672 CDROM_CONFIG_FLAGS(drive)->ram = 1;
2673 printk(KERN_ERR "%s: ATAPI magneto-optical drive\n", drive->name);
2674 return nslots;
2675 }
2676
2677 if (CDROM_CONFIG_FLAGS(drive)->nec260 ||
2678 !strcmp(drive->id->model,"STINGRAY 8422 IDE 8X CD-ROM 7-27-95")) {
2679 CDROM_CONFIG_FLAGS(drive)->no_eject = 0;
2680 CDROM_CONFIG_FLAGS(drive)->audio_play = 1;
2681 return nslots;
2682 }
2683
2684 /*
2685 * we have to cheat a little here. the packet will eventually
2686 * be queued with ide_cdrom_packet(), which extracts the
2687 * drive from cdi->handle. Since this device hasn't been
2688 * registered with the Uniform layer yet, it can't do this.
2689 * Same goes for cdi->ops.
2690 */
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002691 cdi->handle = drive;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002692 cdi->ops = &ide_cdrom_dops;
2693
2694 if (ide_cdrom_get_capabilities(drive, &cap))
2695 return 0;
2696
2697 if (cap.lock == 0)
2698 CDROM_CONFIG_FLAGS(drive)->no_doorlock = 1;
2699 if (cap.eject)
2700 CDROM_CONFIG_FLAGS(drive)->no_eject = 0;
2701 if (cap.cd_r_write)
2702 CDROM_CONFIG_FLAGS(drive)->cd_r = 1;
2703 if (cap.cd_rw_write) {
2704 CDROM_CONFIG_FLAGS(drive)->cd_rw = 1;
2705 CDROM_CONFIG_FLAGS(drive)->ram = 1;
2706 }
2707 if (cap.test_write)
2708 CDROM_CONFIG_FLAGS(drive)->test_write = 1;
2709 if (cap.dvd_ram_read || cap.dvd_r_read || cap.dvd_rom)
2710 CDROM_CONFIG_FLAGS(drive)->dvd = 1;
2711 if (cap.dvd_ram_write) {
2712 CDROM_CONFIG_FLAGS(drive)->dvd_ram = 1;
2713 CDROM_CONFIG_FLAGS(drive)->ram = 1;
2714 }
2715 if (cap.dvd_r_write)
2716 CDROM_CONFIG_FLAGS(drive)->dvd_r = 1;
2717 if (cap.audio_play)
2718 CDROM_CONFIG_FLAGS(drive)->audio_play = 1;
2719 if (cap.mechtype == mechtype_caddy || cap.mechtype == mechtype_popup)
2720 CDROM_CONFIG_FLAGS(drive)->close_tray = 0;
2721
2722 /* Some drives used by Apple don't advertise audio play
2723 * but they do support reading TOC & audio datas
2724 */
2725 if (strcmp(drive->id->model, "MATSHITADVD-ROM SR-8187") == 0 ||
2726 strcmp(drive->id->model, "MATSHITADVD-ROM SR-8186") == 0 ||
2727 strcmp(drive->id->model, "MATSHITADVD-ROM SR-8176") == 0 ||
2728 strcmp(drive->id->model, "MATSHITADVD-ROM SR-8174") == 0)
2729 CDROM_CONFIG_FLAGS(drive)->audio_play = 1;
2730
2731#if ! STANDARD_ATAPI
2732 if (cdi->sanyo_slot > 0) {
2733 CDROM_CONFIG_FLAGS(drive)->is_changer = 1;
2734 nslots = 3;
2735 }
2736
2737 else
2738#endif /* not STANDARD_ATAPI */
2739 if (cap.mechtype == mechtype_individual_changer ||
2740 cap.mechtype == mechtype_cartridge_changer) {
2741 if ((nslots = cdrom_number_of_slots(cdi)) > 1) {
2742 CDROM_CONFIG_FLAGS(drive)->is_changer = 1;
2743 CDROM_CONFIG_FLAGS(drive)->supp_disc_present = 1;
2744 }
2745 }
2746
Eric Piel9235e682005-06-23 00:10:29 -07002747 ide_cdrom_update_speed(drive, &cap);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002748 /* don't print speed if the drive reported 0.
2749 */
2750 printk(KERN_INFO "%s: ATAPI", drive->name);
2751 if (CDROM_CONFIG_FLAGS(drive)->max_speed)
2752 printk(" %dX", CDROM_CONFIG_FLAGS(drive)->max_speed);
2753 printk(" %s", CDROM_CONFIG_FLAGS(drive)->dvd ? "DVD-ROM" : "CD-ROM");
2754
2755 if (CDROM_CONFIG_FLAGS(drive)->dvd_r|CDROM_CONFIG_FLAGS(drive)->dvd_ram)
2756 printk(" DVD%s%s",
2757 (CDROM_CONFIG_FLAGS(drive)->dvd_r)? "-R" : "",
2758 (CDROM_CONFIG_FLAGS(drive)->dvd_ram)? "-RAM" : "");
2759
2760 if (CDROM_CONFIG_FLAGS(drive)->cd_r|CDROM_CONFIG_FLAGS(drive)->cd_rw)
2761 printk(" CD%s%s",
2762 (CDROM_CONFIG_FLAGS(drive)->cd_r)? "-R" : "",
2763 (CDROM_CONFIG_FLAGS(drive)->cd_rw)? "/RW" : "");
2764
2765 if (CDROM_CONFIG_FLAGS(drive)->is_changer)
2766 printk(" changer w/%d slots", nslots);
2767 else
2768 printk(" drive");
2769
Bartlomiej Zolnierkiewicz3ab7efe2007-12-12 23:31:58 +01002770 printk(KERN_CONT ", %dkB Cache\n", be16_to_cpu(cap.buffer_size));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002771
2772 return nslots;
2773}
2774
Bartlomiej Zolnierkiewicz7662d042007-05-10 00:01:10 +02002775#ifdef CONFIG_IDE_PROC_FS
Linus Torvalds1da177e2005-04-16 15:20:36 -07002776static void ide_cdrom_add_settings(ide_drive_t *drive)
2777{
Bartlomiej Zolnierkiewicz14979432007-05-10 00:01:10 +02002778 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 -07002779}
Bartlomiej Zolnierkiewicz7662d042007-05-10 00:01:10 +02002780#else
2781static inline void ide_cdrom_add_settings(ide_drive_t *drive) { ; }
2782#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07002783
2784/*
2785 * standard prep_rq_fn that builds 10 byte cmds
2786 */
Jens Axboe165125e2007-07-24 09:28:11 +02002787static int ide_cdrom_prep_fs(struct request_queue *q, struct request *rq)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002788{
2789 int hard_sect = queue_hardsect_size(q);
2790 long block = (long)rq->hard_sector / (hard_sect >> 9);
2791 unsigned long blocks = rq->hard_nr_sectors / (hard_sect >> 9);
2792
2793 memset(rq->cmd, 0, sizeof(rq->cmd));
2794
2795 if (rq_data_dir(rq) == READ)
2796 rq->cmd[0] = GPCMD_READ_10;
2797 else
2798 rq->cmd[0] = GPCMD_WRITE_10;
2799
2800 /*
2801 * fill in lba
2802 */
2803 rq->cmd[2] = (block >> 24) & 0xff;
2804 rq->cmd[3] = (block >> 16) & 0xff;
2805 rq->cmd[4] = (block >> 8) & 0xff;
2806 rq->cmd[5] = block & 0xff;
2807
2808 /*
2809 * and transfer length
2810 */
2811 rq->cmd[7] = (blocks >> 8) & 0xff;
2812 rq->cmd[8] = blocks & 0xff;
2813 rq->cmd_len = 10;
2814 return BLKPREP_OK;
2815}
2816
2817/*
2818 * Most of the SCSI commands are supported directly by ATAPI devices.
2819 * This transform handles the few exceptions.
2820 */
2821static int ide_cdrom_prep_pc(struct request *rq)
2822{
2823 u8 *c = rq->cmd;
2824
2825 /*
2826 * Transform 6-byte read/write commands to the 10-byte version
2827 */
2828 if (c[0] == READ_6 || c[0] == WRITE_6) {
2829 c[8] = c[4];
2830 c[5] = c[3];
2831 c[4] = c[2];
2832 c[3] = c[1] & 0x1f;
2833 c[2] = 0;
2834 c[1] &= 0xe0;
2835 c[0] += (READ_10 - READ_6);
2836 rq->cmd_len = 10;
2837 return BLKPREP_OK;
2838 }
2839
2840 /*
2841 * it's silly to pretend we understand 6-byte sense commands, just
2842 * reject with ILLEGAL_REQUEST and the caller should take the
2843 * appropriate action
2844 */
2845 if (c[0] == MODE_SENSE || c[0] == MODE_SELECT) {
2846 rq->errors = ILLEGAL_REQUEST;
2847 return BLKPREP_KILL;
2848 }
2849
2850 return BLKPREP_OK;
2851}
2852
Jens Axboe165125e2007-07-24 09:28:11 +02002853static int ide_cdrom_prep_fn(struct request_queue *q, struct request *rq)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002854{
Jens Axboe4aff5e22006-08-10 08:44:47 +02002855 if (blk_fs_request(rq))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002856 return ide_cdrom_prep_fs(q, rq);
Jens Axboe4aff5e22006-08-10 08:44:47 +02002857 else if (blk_pc_request(rq))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002858 return ide_cdrom_prep_pc(rq);
2859
2860 return 0;
2861}
2862
2863static
2864int ide_cdrom_setup (ide_drive_t *drive)
2865{
2866 struct cdrom_info *info = drive->driver_data;
2867 struct cdrom_device_info *cdi = &info->devinfo;
2868 int nslots;
2869
2870 blk_queue_prep_rq(drive->queue, ide_cdrom_prep_fn);
2871 blk_queue_dma_alignment(drive->queue, 31);
2872 drive->queue->unplug_delay = (1 * HZ) / 1000;
2873 if (!drive->queue->unplug_delay)
2874 drive->queue->unplug_delay = 1;
2875
2876 drive->special.all = 0;
2877
2878 CDROM_STATE_FLAGS(drive)->media_changed = 1;
2879 CDROM_STATE_FLAGS(drive)->toc_valid = 0;
2880 CDROM_STATE_FLAGS(drive)->door_locked = 0;
2881
2882#if NO_DOOR_LOCKING
2883 CDROM_CONFIG_FLAGS(drive)->no_doorlock = 1;
2884#else
2885 CDROM_CONFIG_FLAGS(drive)->no_doorlock = 0;
2886#endif
2887
2888 CDROM_CONFIG_FLAGS(drive)->drq_interrupt = ((drive->id->config & 0x0060) == 0x20);
2889 CDROM_CONFIG_FLAGS(drive)->is_changer = 0;
2890 CDROM_CONFIG_FLAGS(drive)->cd_r = 0;
2891 CDROM_CONFIG_FLAGS(drive)->cd_rw = 0;
2892 CDROM_CONFIG_FLAGS(drive)->test_write = 0;
2893 CDROM_CONFIG_FLAGS(drive)->dvd = 0;
2894 CDROM_CONFIG_FLAGS(drive)->dvd_r = 0;
2895 CDROM_CONFIG_FLAGS(drive)->dvd_ram = 0;
2896 CDROM_CONFIG_FLAGS(drive)->no_eject = 1;
2897 CDROM_CONFIG_FLAGS(drive)->supp_disc_present = 0;
2898 CDROM_CONFIG_FLAGS(drive)->audio_play = 0;
2899 CDROM_CONFIG_FLAGS(drive)->close_tray = 1;
2900
2901 /* limit transfer size per interrupt. */
2902 CDROM_CONFIG_FLAGS(drive)->limit_nframes = 0;
2903 /* a testament to the nice quality of Samsung drives... */
2904 if (!strcmp(drive->id->model, "SAMSUNG CD-ROM SCR-2430"))
2905 CDROM_CONFIG_FLAGS(drive)->limit_nframes = 1;
2906 else if (!strcmp(drive->id->model, "SAMSUNG CD-ROM SCR-2432"))
2907 CDROM_CONFIG_FLAGS(drive)->limit_nframes = 1;
2908 /* the 3231 model does not support the SET_CD_SPEED command */
2909 else if (!strcmp(drive->id->model, "SAMSUNG CD-ROM SCR-3231"))
Bartlomiej Zolnierkiewicz3cbd8142007-12-24 15:23:43 +01002910 CDROM_CONFIG_FLAGS(drive)->no_speed_select = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002911
2912#if ! STANDARD_ATAPI
2913 /* by default Sanyo 3 CD changer support is turned off and
2914 ATAPI Rev 2.2+ standard support for CD changers is used */
2915 cdi->sanyo_slot = 0;
2916
2917 CDROM_CONFIG_FLAGS(drive)->nec260 = 0;
2918 CDROM_CONFIG_FLAGS(drive)->toctracks_as_bcd = 0;
2919 CDROM_CONFIG_FLAGS(drive)->tocaddr_as_bcd = 0;
2920 CDROM_CONFIG_FLAGS(drive)->playmsf_as_bcd = 0;
2921 CDROM_CONFIG_FLAGS(drive)->subchan_as_bcd = 0;
2922
2923 if (strcmp (drive->id->model, "V003S0DS") == 0 &&
2924 drive->id->fw_rev[4] == '1' &&
2925 drive->id->fw_rev[6] <= '2') {
2926 /* Vertos 300.
2927 Some versions of this drive like to talk BCD. */
2928 CDROM_CONFIG_FLAGS(drive)->toctracks_as_bcd = 1;
2929 CDROM_CONFIG_FLAGS(drive)->tocaddr_as_bcd = 1;
2930 CDROM_CONFIG_FLAGS(drive)->playmsf_as_bcd = 1;
2931 CDROM_CONFIG_FLAGS(drive)->subchan_as_bcd = 1;
2932 }
2933
2934 else if (strcmp (drive->id->model, "V006E0DS") == 0 &&
2935 drive->id->fw_rev[4] == '1' &&
2936 drive->id->fw_rev[6] <= '2') {
2937 /* Vertos 600 ESD. */
2938 CDROM_CONFIG_FLAGS(drive)->toctracks_as_bcd = 1;
2939 }
2940 else if (strcmp(drive->id->model, "NEC CD-ROM DRIVE:260") == 0 &&
2941 strncmp(drive->id->fw_rev, "1.01", 4) == 0) { /* FIXME */
2942 /* Old NEC260 (not R).
2943 This drive was released before the 1.2 version
2944 of the spec. */
2945 CDROM_CONFIG_FLAGS(drive)->tocaddr_as_bcd = 1;
2946 CDROM_CONFIG_FLAGS(drive)->playmsf_as_bcd = 1;
2947 CDROM_CONFIG_FLAGS(drive)->subchan_as_bcd = 1;
2948 CDROM_CONFIG_FLAGS(drive)->nec260 = 1;
2949 }
2950 else if (strcmp(drive->id->model, "WEARNES CDD-120") == 0 &&
2951 strncmp(drive->id->fw_rev, "A1.1", 4) == 0) { /* FIXME */
2952 /* Wearnes */
2953 CDROM_CONFIG_FLAGS(drive)->playmsf_as_bcd = 1;
2954 CDROM_CONFIG_FLAGS(drive)->subchan_as_bcd = 1;
2955 }
2956 /* Sanyo 3 CD changer uses a non-standard command
2957 for CD changing */
2958 else if ((strcmp(drive->id->model, "CD-ROM CDR-C3 G") == 0) ||
2959 (strcmp(drive->id->model, "CD-ROM CDR-C3G") == 0) ||
2960 (strcmp(drive->id->model, "CD-ROM CDR_C36") == 0)) {
2961 /* uses CD in slot 0 when value is set to 3 */
2962 cdi->sanyo_slot = 3;
2963 }
2964#endif /* not STANDARD_ATAPI */
2965
2966 info->toc = NULL;
2967 info->buffer = NULL;
2968 info->sector_buffered = 0;
2969 info->nsectors_buffered = 0;
2970 info->changer_info = NULL;
2971 info->last_block = 0;
2972 info->start_seek = 0;
2973
2974 nslots = ide_cdrom_probe_capabilities (drive);
2975
2976 /*
2977 * set correct block size
2978 */
2979 blk_queue_hardsect_size(drive->queue, CD_FRAMESIZE);
2980
2981 if (drive->autotune == IDE_TUNE_DEFAULT ||
2982 drive->autotune == IDE_TUNE_AUTO)
2983 drive->dsc_overlap = (drive->next != drive);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002984
2985 if (ide_cdrom_register(drive, nslots)) {
2986 printk (KERN_ERR "%s: ide_cdrom_setup failed to register device with the cdrom driver.\n", drive->name);
2987 info->devinfo.handle = NULL;
2988 return 1;
2989 }
2990 ide_cdrom_add_settings(drive);
2991 return 0;
2992}
2993
Bartlomiej Zolnierkiewiczecfd80e2007-05-10 00:01:09 +02002994#ifdef CONFIG_IDE_PROC_FS
Linus Torvalds1da177e2005-04-16 15:20:36 -07002995static
2996sector_t ide_cdrom_capacity (ide_drive_t *drive)
2997{
2998 unsigned long capacity, sectors_per_frame;
2999
3000 if (cdrom_read_capacity(drive, &capacity, &sectors_per_frame, NULL))
3001 return 0;
3002
3003 return capacity * sectors_per_frame;
3004}
Amos Waterlandd97b32142005-10-30 15:02:10 -08003005#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07003006
Russell King4031bbe2006-01-06 11:41:00 +00003007static void ide_cd_remove(ide_drive_t *drive)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003008{
3009 struct cdrom_info *info = drive->driver_data;
3010
Bartlomiej Zolnierkiewicz7662d042007-05-10 00:01:10 +02003011 ide_proc_unregister_driver(drive, info->driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003012
3013 del_gendisk(info->disk);
3014
3015 ide_cd_put(info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003016}
3017
3018static void ide_cd_release(struct kref *kref)
3019{
3020 struct cdrom_info *info = to_ide_cd(kref);
3021 struct cdrom_device_info *devinfo = &info->devinfo;
3022 ide_drive_t *drive = info->drive;
3023 struct gendisk *g = info->disk;
3024
Jesper Juhl6044ec82005-11-07 01:01:32 -08003025 kfree(info->buffer);
3026 kfree(info->toc);
3027 kfree(info->changer_info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003028 if (devinfo->handle == drive && unregister_cdrom(devinfo))
3029 printk(KERN_ERR "%s: %s failed to unregister device from the cdrom "
3030 "driver.\n", __FUNCTION__, drive->name);
3031 drive->dsc_overlap = 0;
3032 drive->driver_data = NULL;
3033 blk_queue_prep_rq(drive->queue, NULL);
3034 g->private_data = NULL;
3035 put_disk(g);
3036 kfree(info);
3037}
3038
Russell King4031bbe2006-01-06 11:41:00 +00003039static int ide_cd_probe(ide_drive_t *);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003040
Bartlomiej Zolnierkiewiczecfd80e2007-05-10 00:01:09 +02003041#ifdef CONFIG_IDE_PROC_FS
Linus Torvalds1da177e2005-04-16 15:20:36 -07003042static int proc_idecd_read_capacity
3043 (char *page, char **start, off_t off, int count, int *eof, void *data)
3044{
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08003045 ide_drive_t *drive = data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003046 int len;
3047
3048 len = sprintf(page,"%llu\n", (long long)ide_cdrom_capacity(drive));
3049 PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
3050}
3051
3052static ide_proc_entry_t idecd_proc[] = {
3053 { "capacity", S_IFREG|S_IRUGO, proc_idecd_read_capacity, NULL },
3054 { NULL, 0, NULL, NULL }
3055};
Linus Torvalds1da177e2005-04-16 15:20:36 -07003056#endif
3057
3058static ide_driver_t ide_cdrom_driver = {
Bartlomiej Zolnierkiewicz8604aff2005-05-26 14:55:34 +02003059 .gen_driver = {
Laurent Riffard4ef3b8f2005-11-18 22:15:40 +01003060 .owner = THIS_MODULE,
Bartlomiej Zolnierkiewicz8604aff2005-05-26 14:55:34 +02003061 .name = "ide-cdrom",
3062 .bus = &ide_bus_type,
Bartlomiej Zolnierkiewicz8604aff2005-05-26 14:55:34 +02003063 },
Russell King4031bbe2006-01-06 11:41:00 +00003064 .probe = ide_cd_probe,
3065 .remove = ide_cd_remove,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003066 .version = IDECD_VERSION,
3067 .media = ide_cdrom,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003068 .supports_dsc_overlap = 1,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003069 .do_request = ide_do_rw_cdrom,
3070 .end_request = ide_end_request,
3071 .error = __ide_error,
3072 .abort = __ide_abort,
Bartlomiej Zolnierkiewicz7662d042007-05-10 00:01:10 +02003073#ifdef CONFIG_IDE_PROC_FS
Linus Torvalds1da177e2005-04-16 15:20:36 -07003074 .proc = idecd_proc,
Bartlomiej Zolnierkiewicz7662d042007-05-10 00:01:10 +02003075#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07003076};
3077
3078static int idecd_open(struct inode * inode, struct file * file)
3079{
3080 struct gendisk *disk = inode->i_bdev->bd_disk;
3081 struct cdrom_info *info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003082 int rc = -ENOMEM;
3083
3084 if (!(info = ide_cd_get(disk)))
3085 return -ENXIO;
3086
Linus Torvalds1da177e2005-04-16 15:20:36 -07003087 if (!info->buffer)
Bartlomiej Zolnierkiewiczc94964a2007-02-17 02:40:24 +01003088 info->buffer = kmalloc(SECTOR_BUFFER_SIZE, GFP_KERNEL|__GFP_REPEAT);
3089
3090 if (info->buffer)
3091 rc = cdrom_open(&info->devinfo, inode, file);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003092
3093 if (rc < 0)
3094 ide_cd_put(info);
3095
3096 return rc;
3097}
3098
3099static int idecd_release(struct inode * inode, struct file * file)
3100{
3101 struct gendisk *disk = inode->i_bdev->bd_disk;
3102 struct cdrom_info *info = ide_cd_g(disk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003103
3104 cdrom_release (&info->devinfo, file);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003105
3106 ide_cd_put(info);
3107
3108 return 0;
3109}
3110
Christoph Hellwig6a2900b2006-03-23 03:00:15 -08003111static int idecd_set_spindown(struct cdrom_device_info *cdi, unsigned long arg)
3112{
3113 struct packet_command cgc;
3114 char buffer[16];
3115 int stat;
3116 char spindown;
3117
3118 if (copy_from_user(&spindown, (void __user *)arg, sizeof(char)))
3119 return -EFAULT;
3120
3121 init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_UNKNOWN);
3122
3123 stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CDROM_PAGE, 0);
3124 if (stat)
3125 return stat;
3126
3127 buffer[11] = (buffer[11] & 0xf0) | (spindown & 0x0f);
3128 return cdrom_mode_select(cdi, &cgc);
3129}
3130
3131static int idecd_get_spindown(struct cdrom_device_info *cdi, unsigned long arg)
3132{
3133 struct packet_command cgc;
3134 char buffer[16];
3135 int stat;
3136 char spindown;
3137
3138 init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_UNKNOWN);
3139
3140 stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CDROM_PAGE, 0);
3141 if (stat)
3142 return stat;
3143
3144 spindown = buffer[11] & 0x0f;
3145 if (copy_to_user((void __user *)arg, &spindown, sizeof (char)))
3146 return -EFAULT;
3147 return 0;
3148}
3149
Linus Torvalds1da177e2005-04-16 15:20:36 -07003150static int idecd_ioctl (struct inode *inode, struct file *file,
3151 unsigned int cmd, unsigned long arg)
3152{
3153 struct block_device *bdev = inode->i_bdev;
3154 struct cdrom_info *info = ide_cd_g(bdev->bd_disk);
3155 int err;
3156
Christoph Hellwig6a2900b2006-03-23 03:00:15 -08003157 switch (cmd) {
3158 case CDROMSETSPINDOWN:
3159 return idecd_set_spindown(&info->devinfo, arg);
3160 case CDROMGETSPINDOWN:
3161 return idecd_get_spindown(&info->devinfo, arg);
3162 default:
3163 break;
3164 }
3165
3166 err = generic_ide_ioctl(info->drive, file, bdev, cmd, arg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003167 if (err == -EINVAL)
3168 err = cdrom_ioctl(file, &info->devinfo, inode, cmd, arg);
3169
3170 return err;
3171}
3172
3173static int idecd_media_changed(struct gendisk *disk)
3174{
3175 struct cdrom_info *info = ide_cd_g(disk);
3176 return cdrom_media_changed(&info->devinfo);
3177}
3178
3179static int idecd_revalidate_disk(struct gendisk *disk)
3180{
3181 struct cdrom_info *info = ide_cd_g(disk);
3182 struct request_sense sense;
3183 cdrom_read_toc(info->drive, &sense);
3184 return 0;
3185}
3186
3187static struct block_device_operations idecd_ops = {
3188 .owner = THIS_MODULE,
3189 .open = idecd_open,
3190 .release = idecd_release,
3191 .ioctl = idecd_ioctl,
3192 .media_changed = idecd_media_changed,
3193 .revalidate_disk= idecd_revalidate_disk
3194};
3195
3196/* options */
3197static char *ignore = NULL;
3198
3199module_param(ignore, charp, 0400);
3200MODULE_DESCRIPTION("ATAPI CD-ROM Driver");
3201
Russell King4031bbe2006-01-06 11:41:00 +00003202static int ide_cd_probe(ide_drive_t *drive)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003203{
3204 struct cdrom_info *info;
3205 struct gendisk *g;
3206 struct request_sense sense;
3207
3208 if (!strstr("ide-cdrom", drive->driver_req))
3209 goto failed;
3210 if (!drive->present)
3211 goto failed;
3212 if (drive->media != ide_cdrom && drive->media != ide_optical)
3213 goto failed;
3214 /* skip drives that we were told to ignore */
3215 if (ignore != NULL) {
3216 if (strstr(ignore, drive->name)) {
3217 printk(KERN_INFO "ide-cd: ignoring drive %s\n", drive->name);
3218 goto failed;
3219 }
3220 }
3221 if (drive->scsi) {
3222 printk(KERN_INFO "ide-cd: passing drive %s to ide-scsi emulation.\n", drive->name);
3223 goto failed;
3224 }
Deepak Saxenaf5e3c2f2005-11-07 01:01:25 -08003225 info = kzalloc(sizeof(struct cdrom_info), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003226 if (info == NULL) {
3227 printk(KERN_ERR "%s: Can't allocate a cdrom structure\n", drive->name);
3228 goto failed;
3229 }
3230
3231 g = alloc_disk(1 << PARTN_BITS);
3232 if (!g)
3233 goto out_free_cd;
3234
3235 ide_init_disk(g, drive);
3236
Bartlomiej Zolnierkiewicz7662d042007-05-10 00:01:10 +02003237 ide_proc_register_driver(drive, &ide_cdrom_driver);
Bartlomiej Zolnierkiewicz8604aff2005-05-26 14:55:34 +02003238
Linus Torvalds1da177e2005-04-16 15:20:36 -07003239 kref_init(&info->kref);
3240
3241 info->drive = drive;
3242 info->driver = &ide_cdrom_driver;
3243 info->disk = g;
3244
3245 g->private_data = &info->driver;
3246
3247 drive->driver_data = info;
3248
Linus Torvalds1da177e2005-04-16 15:20:36 -07003249 g->minors = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003250 g->driverfs_dev = &drive->gendev;
3251 g->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE;
3252 if (ide_cdrom_setup(drive)) {
Bartlomiej Zolnierkiewicz7662d042007-05-10 00:01:10 +02003253 ide_proc_unregister_driver(drive, &ide_cdrom_driver);
Bartlomiej Zolnierkiewicz05017db2007-12-24 15:23:43 +01003254 ide_cd_release(&info->kref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003255 goto failed;
3256 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003257
3258 cdrom_read_toc(drive, &sense);
3259 g->fops = &idecd_ops;
3260 g->flags |= GENHD_FL_REMOVABLE;
3261 add_disk(g);
3262 return 0;
3263
Linus Torvalds1da177e2005-04-16 15:20:36 -07003264out_free_cd:
3265 kfree(info);
3266failed:
Bartlomiej Zolnierkiewicz8604aff2005-05-26 14:55:34 +02003267 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003268}
3269
3270static void __exit ide_cdrom_exit(void)
3271{
Bartlomiej Zolnierkiewicz8604aff2005-05-26 14:55:34 +02003272 driver_unregister(&ide_cdrom_driver.gen_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003273}
Bartlomiej Zolnierkiewicz17514e82005-11-19 22:24:35 +01003274
3275static int __init ide_cdrom_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003276{
Bartlomiej Zolnierkiewicz8604aff2005-05-26 14:55:34 +02003277 return driver_register(&ide_cdrom_driver.gen_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003278}
3279
Kay Sievers263756e2005-12-12 18:03:44 +01003280MODULE_ALIAS("ide:*m-cdrom*");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003281module_init(ide_cdrom_init);
3282module_exit(ide_cdrom_exit);
3283MODULE_LICENSE("GPL");