blob: 81247a0587e6c88d8c74b8399bdbb83c34df2de6 [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. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700687#define ATAPI_MIN_CDB_BYTES 12
688static ide_startstop_t cdrom_transfer_packet_command (ide_drive_t *drive,
689 struct request *rq,
690 ide_handler_t *handler)
691{
692 ide_hwif_t *hwif = drive->hwif;
693 int cmd_len;
694 struct cdrom_info *info = drive->driver_data;
695 ide_startstop_t startstop;
696
697 if (CDROM_CONFIG_FLAGS(drive)->drq_interrupt) {
698 /* Here we should have been called after receiving an interrupt
699 from the device. DRQ should how be set. */
700
701 /* Check for errors. */
702 if (cdrom_decode_status(drive, DRQ_STAT, NULL))
703 return ide_stopped;
Albert Leef0dd8712007-02-17 02:40:21 +0100704
705 /* Ok, next interrupt will be DMA interrupt. */
706 if (info->dma)
707 drive->waiting_for_dma = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700708 } else {
709 /* Otherwise, we must wait for DRQ to get set. */
710 if (ide_wait_stat(&startstop, drive, DRQ_STAT,
711 BUSY_STAT, WAIT_READY))
712 return startstop;
713 }
714
715 /* Arm the interrupt handler. */
716 ide_set_handler(drive, handler, rq->timeout, cdrom_timer_expiry);
717
718 /* ATAPI commands get padded out to 12 bytes minimum */
719 cmd_len = COMMAND_SIZE(rq->cmd[0]);
720 if (cmd_len < ATAPI_MIN_CDB_BYTES)
721 cmd_len = ATAPI_MIN_CDB_BYTES;
722
723 /* Send the command to the device. */
724 HWIF(drive)->atapi_output_bytes(drive, rq->cmd, cmd_len);
725
726 /* Start the DMA if need be */
727 if (info->dma)
728 hwif->dma_start(drive);
729
730 return ide_started;
731}
732
733/****************************************************************************
734 * Block read functions.
735 */
736
Bartlomiej Zolnierkiewicz68661c52008-02-01 23:09:17 +0100737typedef void (xfer_func_t)(ide_drive_t *, void *, u32);
738
Bartlomiej Zolnierkiewicz5a5222d2008-02-01 23:09:17 +0100739static void ide_cd_pad_transfer(ide_drive_t *drive, xfer_func_t *xf, int len)
740{
741 while (len > 0) {
742 int dum = 0;
743 xf(drive, &dum, sizeof(dum));
744 len -= sizeof(dum);
745 }
746}
747
Linus Torvalds1da177e2005-04-16 15:20:36 -0700748/*
749 * Buffer up to SECTORS_TO_TRANSFER sectors from the drive in our sector
750 * buffer. Once the first sector is added, any subsequent sectors are
751 * assumed to be continuous (until the buffer is cleared). For the first
752 * sector added, SECTOR is its sector number. (SECTOR is then ignored until
753 * the buffer is cleared.)
754 */
755static void cdrom_buffer_sectors (ide_drive_t *drive, unsigned long sector,
756 int sectors_to_transfer)
757{
758 struct cdrom_info *info = drive->driver_data;
759
760 /* Number of sectors to read into the buffer. */
761 int sectors_to_buffer = min_t(int, sectors_to_transfer,
762 (SECTOR_BUFFER_SIZE >> SECTOR_BITS) -
763 info->nsectors_buffered);
764
765 char *dest;
766
767 /* If we couldn't get a buffer, don't try to buffer anything... */
768 if (info->buffer == NULL)
769 sectors_to_buffer = 0;
770
771 /* If this is the first sector in the buffer, remember its number. */
772 if (info->nsectors_buffered == 0)
773 info->sector_buffered = sector;
774
775 /* Read the data into the buffer. */
776 dest = info->buffer + info->nsectors_buffered * SECTOR_SIZE;
777 while (sectors_to_buffer > 0) {
778 HWIF(drive)->atapi_input_bytes(drive, dest, SECTOR_SIZE);
779 --sectors_to_buffer;
780 --sectors_to_transfer;
781 ++info->nsectors_buffered;
782 dest += SECTOR_SIZE;
783 }
784
785 /* Throw away any remaining data. */
786 while (sectors_to_transfer > 0) {
787 static char dum[SECTOR_SIZE];
788 HWIF(drive)->atapi_input_bytes(drive, dum, sizeof (dum));
789 --sectors_to_transfer;
790 }
791}
792
793/*
794 * Check the contents of the interrupt reason register from the cdrom
795 * and attempt to recover if there are problems. Returns 0 if everything's
796 * ok; nonzero if the request has been terminated.
797 */
Arjan van de Ven858119e2006-01-14 13:20:43 -0800798static
Linus Torvalds1da177e2005-04-16 15:20:36 -0700799int cdrom_read_check_ireason (ide_drive_t *drive, int len, int ireason)
800{
801 if (ireason == 2)
802 return 0;
803 else if (ireason == 0) {
Bartlomiej Zolnierkiewicz5a5222d2008-02-01 23:09:17 +0100804 ide_hwif_t *hwif = drive->hwif;
805
Linus Torvalds1da177e2005-04-16 15:20:36 -0700806 /* Whoops... The drive is expecting to receive data from us! */
Bartlomiej Zolnierkiewicz35379c02007-12-24 15:23:43 +0100807 printk(KERN_ERR "%s: %s: wrong transfer direction!\n",
808 drive->name, __FUNCTION__);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700809
810 /* Throw some data at the drive so it doesn't hang
811 and quit this request. */
Bartlomiej Zolnierkiewicz5a5222d2008-02-01 23:09:17 +0100812 ide_cd_pad_transfer(drive, hwif->atapi_output_bytes, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700813 } else if (ireason == 1) {
814 /* Some drives (ASUS) seem to tell us that status
815 * info is available. just get it and ignore.
816 */
817 (void) HWIF(drive)->INB(IDE_STATUS_REG);
818 return 0;
819 } else {
820 /* Drive wants a command packet, or invalid ireason... */
Bartlomiej Zolnierkiewicz35379c02007-12-24 15:23:43 +0100821 printk(KERN_ERR "%s: %s: bad interrupt reason 0x%02x\n",
822 drive->name, __FUNCTION__, ireason);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700823 }
824
825 cdrom_end_request(drive, 0);
826 return -1;
827}
828
829/*
830 * Interrupt routine. Called when a read request has completed.
831 */
832static ide_startstop_t cdrom_read_intr (ide_drive_t *drive)
833{
834 int stat;
835 int ireason, len, sectors_to_transfer, nskip;
836 struct cdrom_info *info = drive->driver_data;
837 u8 lowcyl = 0, highcyl = 0;
838 int dma = info->dma, dma_error = 0;
839
840 struct request *rq = HWGROUP(drive)->rq;
841
842 /*
843 * handle dma case
844 */
845 if (dma) {
846 info->dma = 0;
Bartlomiej Zolnierkiewicz52ef2ed2007-12-24 15:23:43 +0100847 dma_error = HWIF(drive)->ide_dma_end(drive);
848 if (dma_error) {
849 printk(KERN_ERR "%s: DMA read error\n", drive->name);
Bartlomiej Zolnierkiewicz7469aaf2007-02-17 02:40:26 +0100850 ide_dma_off(drive);
Bartlomiej Zolnierkiewicz52ef2ed2007-12-24 15:23:43 +0100851 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700852 }
853
854 if (cdrom_decode_status(drive, 0, &stat))
855 return ide_stopped;
856
857 if (dma) {
858 if (!dma_error) {
859 ide_end_request(drive, 1, rq->nr_sectors);
860 return ide_stopped;
861 } else
862 return ide_error(drive, "dma error", stat);
863 }
864
865 /* Read the interrupt reason and the transfer length. */
866 ireason = HWIF(drive)->INB(IDE_IREASON_REG) & 0x3;
867 lowcyl = HWIF(drive)->INB(IDE_BCOUNTL_REG);
868 highcyl = HWIF(drive)->INB(IDE_BCOUNTH_REG);
869
870 len = lowcyl + (256 * highcyl);
871
872 /* If DRQ is clear, the command has completed. */
873 if ((stat & DRQ_STAT) == 0) {
874 /* If we're not done filling the current buffer, complain.
875 Otherwise, complete the command normally. */
876 if (rq->current_nr_sectors > 0) {
877 printk (KERN_ERR "%s: cdrom_read_intr: data underrun (%d blocks)\n",
878 drive->name, rq->current_nr_sectors);
Jens Axboe4aff5e22006-08-10 08:44:47 +0200879 rq->cmd_flags |= REQ_FAILED;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700880 cdrom_end_request(drive, 0);
881 } else
882 cdrom_end_request(drive, 1);
883 return ide_stopped;
884 }
885
886 /* Check that the drive is expecting to do the same thing we are. */
887 if (cdrom_read_check_ireason (drive, len, ireason))
888 return ide_stopped;
889
890 /* Assume that the drive will always provide data in multiples
891 of at least SECTOR_SIZE, as it gets hairy to keep track
892 of the transfers otherwise. */
893 if ((len % SECTOR_SIZE) != 0) {
894 printk (KERN_ERR "%s: cdrom_read_intr: Bad transfer size %d\n",
895 drive->name, len);
896 if (CDROM_CONFIG_FLAGS(drive)->limit_nframes)
897 printk (KERN_ERR " This drive is not supported by this version of the driver\n");
898 else {
899 printk (KERN_ERR " Trying to limit transfer sizes\n");
900 CDROM_CONFIG_FLAGS(drive)->limit_nframes = 1;
901 }
902 cdrom_end_request(drive, 0);
903 return ide_stopped;
904 }
905
906 /* The number of sectors we need to read from the drive. */
907 sectors_to_transfer = len / SECTOR_SIZE;
908
909 /* First, figure out if we need to bit-bucket
910 any of the leading sectors. */
911 nskip = min_t(int, rq->current_nr_sectors - bio_cur_sectors(rq->bio), sectors_to_transfer);
912
913 while (nskip > 0) {
914 /* We need to throw away a sector. */
915 static char dum[SECTOR_SIZE];
916 HWIF(drive)->atapi_input_bytes(drive, dum, sizeof (dum));
917
918 --rq->current_nr_sectors;
919 --nskip;
920 --sectors_to_transfer;
921 }
922
923 /* Now loop while we still have data to read from the drive. */
924 while (sectors_to_transfer > 0) {
925 int this_transfer;
926
927 /* If we've filled the present buffer but there's another
928 chained buffer after it, move on. */
929 if (rq->current_nr_sectors == 0 && rq->nr_sectors)
930 cdrom_end_request(drive, 1);
931
932 /* If the buffers are full, cache the rest of the data in our
933 internal buffer. */
934 if (rq->current_nr_sectors == 0) {
935 cdrom_buffer_sectors(drive, rq->sector, sectors_to_transfer);
936 sectors_to_transfer = 0;
937 } else {
938 /* Transfer data to the buffers.
939 Figure out how many sectors we can transfer
940 to the current buffer. */
941 this_transfer = min_t(int, sectors_to_transfer,
942 rq->current_nr_sectors);
943
944 /* Read this_transfer sectors
945 into the current buffer. */
946 while (this_transfer > 0) {
947 HWIF(drive)->atapi_input_bytes(drive, rq->buffer, SECTOR_SIZE);
948 rq->buffer += SECTOR_SIZE;
949 --rq->nr_sectors;
950 --rq->current_nr_sectors;
951 ++rq->sector;
952 --this_transfer;
953 --sectors_to_transfer;
954 }
955 }
956 }
957
958 /* Done moving data! Wait for another interrupt. */
959 ide_set_handler(drive, &cdrom_read_intr, ATAPI_WAIT_PC, NULL);
960 return ide_started;
961}
962
963/*
964 * Try to satisfy some of the current read request from our cached data.
965 * Returns nonzero if the request has been completed, zero otherwise.
966 */
967static int cdrom_read_from_buffer (ide_drive_t *drive)
968{
969 struct cdrom_info *info = drive->driver_data;
970 struct request *rq = HWGROUP(drive)->rq;
971 unsigned short sectors_per_frame;
972
973 sectors_per_frame = queue_hardsect_size(drive->queue) >> SECTOR_BITS;
974
975 /* Can't do anything if there's no buffer. */
976 if (info->buffer == NULL) return 0;
977
978 /* Loop while this request needs data and the next block is present
979 in our cache. */
980 while (rq->nr_sectors > 0 &&
981 rq->sector >= info->sector_buffered &&
982 rq->sector < info->sector_buffered + info->nsectors_buffered) {
983 if (rq->current_nr_sectors == 0)
984 cdrom_end_request(drive, 1);
985
986 memcpy (rq->buffer,
987 info->buffer +
988 (rq->sector - info->sector_buffered) * SECTOR_SIZE,
989 SECTOR_SIZE);
990 rq->buffer += SECTOR_SIZE;
991 --rq->current_nr_sectors;
992 --rq->nr_sectors;
993 ++rq->sector;
994 }
995
996 /* If we've satisfied the current request,
997 terminate it successfully. */
998 if (rq->nr_sectors == 0) {
999 cdrom_end_request(drive, 1);
1000 return -1;
1001 }
1002
1003 /* Move on to the next buffer if needed. */
1004 if (rq->current_nr_sectors == 0)
1005 cdrom_end_request(drive, 1);
1006
1007 /* If this condition does not hold, then the kluge i use to
1008 represent the number of sectors to skip at the start of a transfer
1009 will fail. I think that this will never happen, but let's be
1010 paranoid and check. */
1011 if (rq->current_nr_sectors < bio_cur_sectors(rq->bio) &&
1012 (rq->sector & (sectors_per_frame - 1))) {
1013 printk(KERN_ERR "%s: cdrom_read_from_buffer: buffer botch (%ld)\n",
1014 drive->name, (long)rq->sector);
1015 cdrom_end_request(drive, 0);
1016 return -1;
1017 }
1018
1019 return 0;
1020}
1021
1022/*
1023 * Routine to send a read packet command to the drive.
1024 * This is usually called directly from cdrom_start_read.
1025 * However, for drq_interrupt devices, it is called from an interrupt
1026 * when the drive is ready to accept the command.
1027 */
1028static ide_startstop_t cdrom_start_read_continuation (ide_drive_t *drive)
1029{
1030 struct request *rq = HWGROUP(drive)->rq;
1031 unsigned short sectors_per_frame;
1032 int nskip;
1033
1034 sectors_per_frame = queue_hardsect_size(drive->queue) >> SECTOR_BITS;
1035
1036 /* If the requested sector doesn't start on a cdrom block boundary,
1037 we must adjust the start of the transfer so that it does,
1038 and remember to skip the first few sectors.
1039 If the CURRENT_NR_SECTORS field is larger than the size
1040 of the buffer, it will mean that we're to skip a number
1041 of sectors equal to the amount by which CURRENT_NR_SECTORS
1042 is larger than the buffer size. */
1043 nskip = rq->sector & (sectors_per_frame - 1);
1044 if (nskip > 0) {
1045 /* Sanity check... */
1046 if (rq->current_nr_sectors != bio_cur_sectors(rq->bio) &&
1047 (rq->sector & (sectors_per_frame - 1))) {
1048 printk(KERN_ERR "%s: cdrom_start_read_continuation: buffer botch (%u)\n",
1049 drive->name, rq->current_nr_sectors);
1050 cdrom_end_request(drive, 0);
1051 return ide_stopped;
1052 }
1053 rq->current_nr_sectors += nskip;
1054 }
1055
1056 /* Set up the command */
1057 rq->timeout = ATAPI_WAIT_PC;
1058
1059 /* Send the command to the drive and return. */
1060 return cdrom_transfer_packet_command(drive, rq, &cdrom_read_intr);
1061}
1062
1063
1064#define IDECD_SEEK_THRESHOLD (1000) /* 1000 blocks */
1065#define IDECD_SEEK_TIMER (5 * WAIT_MIN_SLEEP) /* 100 ms */
1066#define IDECD_SEEK_TIMEOUT (2 * WAIT_CMD) /* 20 sec */
1067
1068static ide_startstop_t cdrom_seek_intr (ide_drive_t *drive)
1069{
1070 struct cdrom_info *info = drive->driver_data;
1071 int stat;
1072 static int retry = 10;
1073
1074 if (cdrom_decode_status(drive, 0, &stat))
1075 return ide_stopped;
1076 CDROM_CONFIG_FLAGS(drive)->seeking = 1;
1077
1078 if (retry && time_after(jiffies, info->start_seek + IDECD_SEEK_TIMER)) {
1079 if (--retry == 0) {
1080 /*
1081 * this condition is far too common, to bother
1082 * users about it
1083 */
1084 /* printk("%s: disabled DSC seek overlap\n", drive->name);*/
1085 drive->dsc_overlap = 0;
1086 }
1087 }
1088 return ide_stopped;
1089}
1090
1091static ide_startstop_t cdrom_start_seek_continuation (ide_drive_t *drive)
1092{
1093 struct request *rq = HWGROUP(drive)->rq;
1094 sector_t frame = rq->sector;
1095
1096 sector_div(frame, queue_hardsect_size(drive->queue) >> SECTOR_BITS);
1097
1098 memset(rq->cmd, 0, sizeof(rq->cmd));
1099 rq->cmd[0] = GPCMD_SEEK;
1100 put_unaligned(cpu_to_be32(frame), (unsigned int *) &rq->cmd[2]);
1101
1102 rq->timeout = ATAPI_WAIT_PC;
1103 return cdrom_transfer_packet_command(drive, rq, &cdrom_seek_intr);
1104}
1105
1106static ide_startstop_t cdrom_start_seek (ide_drive_t *drive, unsigned int block)
1107{
1108 struct cdrom_info *info = drive->driver_data;
1109
1110 info->dma = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001111 info->start_seek = jiffies;
1112 return cdrom_start_packet_command(drive, 0, cdrom_start_seek_continuation);
1113}
1114
1115/* Fix up a possibly partially-processed request so that we can
1116 start it over entirely, or even put it back on the request queue. */
1117static void restore_request (struct request *rq)
1118{
1119 if (rq->buffer != bio_data(rq->bio)) {
1120 sector_t n = (rq->buffer - (char *) bio_data(rq->bio)) / SECTOR_SIZE;
1121
1122 rq->buffer = bio_data(rq->bio);
1123 rq->nr_sectors += n;
1124 rq->sector -= n;
1125 }
1126 rq->hard_cur_sectors = rq->current_nr_sectors = bio_cur_sectors(rq->bio);
1127 rq->hard_nr_sectors = rq->nr_sectors;
1128 rq->hard_sector = rq->sector;
1129 rq->q->prep_rq_fn(rq->q, rq);
1130}
1131
1132/*
1133 * Start a read request from the CD-ROM.
1134 */
1135static ide_startstop_t cdrom_start_read (ide_drive_t *drive, unsigned int block)
1136{
1137 struct cdrom_info *info = drive->driver_data;
1138 struct request *rq = HWGROUP(drive)->rq;
1139 unsigned short sectors_per_frame;
1140
1141 sectors_per_frame = queue_hardsect_size(drive->queue) >> SECTOR_BITS;
1142
1143 /* We may be retrying this request after an error. Fix up
1144 any weirdness which might be present in the request packet. */
1145 restore_request(rq);
1146
1147 /* Satisfy whatever we can of this request from our cached sector. */
1148 if (cdrom_read_from_buffer(drive))
1149 return ide_stopped;
1150
Linus Torvalds1da177e2005-04-16 15:20:36 -07001151 /* Clear the local sector buffer. */
1152 info->nsectors_buffered = 0;
1153
1154 /* use dma, if possible. */
1155 info->dma = drive->using_dma;
1156 if ((rq->sector & (sectors_per_frame - 1)) ||
1157 (rq->nr_sectors & (sectors_per_frame - 1)))
1158 info->dma = 0;
1159
Linus Torvalds1da177e2005-04-16 15:20:36 -07001160 /* Start sending the read request to the drive. */
1161 return cdrom_start_packet_command(drive, 32768, cdrom_start_read_continuation);
1162}
1163
1164/****************************************************************************
1165 * Execute all other packet commands.
1166 */
1167
1168/* Interrupt routine for packet command completion. */
1169static ide_startstop_t cdrom_pc_intr (ide_drive_t *drive)
1170{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001171 struct request *rq = HWGROUP(drive)->rq;
Bartlomiej Zolnierkiewicz68661c52008-02-01 23:09:17 +01001172 xfer_func_t *xferfunc = NULL;
1173 int stat, ireason, len, thislen, write;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001174 u8 lowcyl = 0, highcyl = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001175
1176 /* Check for errors. */
1177 if (cdrom_decode_status(drive, 0, &stat))
1178 return ide_stopped;
1179
1180 /* Read the interrupt reason and the transfer length. */
Bartlomiej Zolnierkiewicz8606ab02007-12-24 15:23:44 +01001181 ireason = HWIF(drive)->INB(IDE_IREASON_REG) & 0x3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001182 lowcyl = HWIF(drive)->INB(IDE_BCOUNTL_REG);
1183 highcyl = HWIF(drive)->INB(IDE_BCOUNTH_REG);
1184
1185 len = lowcyl + (256 * highcyl);
1186
1187 /* If DRQ is clear, the command has completed.
1188 Complain if we still have data left to transfer. */
1189 if ((stat & DRQ_STAT) == 0) {
1190 /* Some of the trailing request sense fields are optional, and
1191 some drives don't send them. Sigh. */
1192 if (rq->cmd[0] == GPCMD_REQUEST_SENSE &&
1193 rq->data_len > 0 &&
1194 rq->data_len <= 5) {
1195 while (rq->data_len > 0) {
1196 *(unsigned char *)rq->data++ = 0;
1197 --rq->data_len;
1198 }
1199 }
1200
1201 if (rq->data_len == 0)
1202 cdrom_end_request(drive, 1);
1203 else {
Jens Axboe4aff5e22006-08-10 08:44:47 +02001204 rq->cmd_flags |= REQ_FAILED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001205 cdrom_end_request(drive, 0);
1206 }
1207 return ide_stopped;
1208 }
1209
1210 /* Figure out how much data to transfer. */
1211 thislen = rq->data_len;
Bartlomiej Zolnierkiewicz68661c52008-02-01 23:09:17 +01001212 if (thislen > len)
1213 thislen = len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001214
Bartlomiej Zolnierkiewicz8606ab02007-12-24 15:23:44 +01001215 if (ireason == 0) {
Bartlomiej Zolnierkiewicz68661c52008-02-01 23:09:17 +01001216 write = 1;
1217 xferfunc = HWIF(drive)->atapi_output_bytes;
1218 } else if (ireason == 2) {
1219 write = 0;
1220 xferfunc = HWIF(drive)->atapi_input_bytes;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001221 }
1222
Bartlomiej Zolnierkiewicz68661c52008-02-01 23:09:17 +01001223 if (xferfunc) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001224 if (!rq->data) {
Bartlomiej Zolnierkiewiczf1071e62008-02-01 23:09:17 +01001225 printk(KERN_ERR "%s: confused, missing data\n",
1226 drive->name);
Bartlomiej Zolnierkiewicz68661c52008-02-01 23:09:17 +01001227 blk_dump_rq_flags(rq, write ? "cdrom_pc_intr, write"
1228 : "cdrom_pc_intr, read");
Bartlomiej Zolnierkiewiczf1071e62008-02-01 23:09:17 +01001229 goto pad;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001230 }
1231 /* Transfer the data. */
Bartlomiej Zolnierkiewicz68661c52008-02-01 23:09:17 +01001232 xferfunc(drive, rq->data, thislen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001233
Linus Torvalds1da177e2005-04-16 15:20:36 -07001234 /* Keep count of how much data we've moved. */
Bartlomiej Zolnierkiewicz5a5222d2008-02-01 23:09:17 +01001235 len -= thislen;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001236 rq->data += thislen;
1237 rq->data_len -= thislen;
1238
Bartlomiej Zolnierkiewicz68661c52008-02-01 23:09:17 +01001239 if (write && blk_sense_request(rq))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001240 rq->sense_len += thislen;
1241 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001242 printk (KERN_ERR "%s: cdrom_pc_intr: The drive "
Rachita Kothiyal1ad55442006-06-23 02:02:56 -07001243 "appears confused (ireason = 0x%02x). "
1244 "Trying to recover by ending request.\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001245 drive->name, ireason);
Jens Axboe4aff5e22006-08-10 08:44:47 +02001246 rq->cmd_flags |= REQ_FAILED;
Rachita Kothiyal1ad55442006-06-23 02:02:56 -07001247 cdrom_end_request(drive, 0);
1248 return ide_stopped;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001249 }
Bartlomiej Zolnierkiewiczf1071e62008-02-01 23:09:17 +01001250pad:
Bartlomiej Zolnierkiewicz5a5222d2008-02-01 23:09:17 +01001251 /*
1252 * If we haven't moved enough data to satisfy the drive,
1253 * add some padding.
1254 */
1255 if (len > 0)
1256 ide_cd_pad_transfer(drive, xferfunc, len);
1257
Linus Torvalds1da177e2005-04-16 15:20:36 -07001258 /* Now we wait for another interrupt. */
1259 ide_set_handler(drive, &cdrom_pc_intr, ATAPI_WAIT_PC, cdrom_timer_expiry);
1260 return ide_started;
1261}
1262
1263static ide_startstop_t cdrom_do_pc_continuation (ide_drive_t *drive)
1264{
1265 struct request *rq = HWGROUP(drive)->rq;
1266
1267 if (!rq->timeout)
1268 rq->timeout = ATAPI_WAIT_PC;
1269
1270 /* Send the command to the drive and return. */
1271 return cdrom_transfer_packet_command(drive, rq, &cdrom_pc_intr);
1272}
1273
1274
1275static ide_startstop_t cdrom_do_packet_command (ide_drive_t *drive)
1276{
1277 int len;
1278 struct request *rq = HWGROUP(drive)->rq;
1279 struct cdrom_info *info = drive->driver_data;
1280
1281 info->dma = 0;
Jens Axboe4aff5e22006-08-10 08:44:47 +02001282 rq->cmd_flags &= ~REQ_FAILED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001283 len = rq->data_len;
1284
1285 /* Start sending the command to the drive. */
1286 return cdrom_start_packet_command(drive, len, cdrom_do_pc_continuation);
1287}
1288
1289
Alan Coxdbe217a2006-06-25 05:47:44 -07001290static int cdrom_queue_packet_command(ide_drive_t *drive, struct request *rq)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001291{
1292 struct request_sense sense;
1293 int retries = 10;
Jens Axboe4aff5e22006-08-10 08:44:47 +02001294 unsigned int flags = rq->cmd_flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001295
1296 if (rq->sense == NULL)
1297 rq->sense = &sense;
1298
1299 /* Start of retry loop. */
1300 do {
1301 int error;
1302 unsigned long time = jiffies;
Jens Axboe4aff5e22006-08-10 08:44:47 +02001303 rq->cmd_flags = flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001304
1305 error = ide_do_drive_cmd(drive, rq, ide_wait);
1306 time = jiffies - time;
1307
1308 /* FIXME: we should probably abort/retry or something
1309 * in case of failure */
Jens Axboe4aff5e22006-08-10 08:44:47 +02001310 if (rq->cmd_flags & REQ_FAILED) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001311 /* The request failed. Retry if it was due to a unit
1312 attention status
1313 (usually means media was changed). */
1314 struct request_sense *reqbuf = rq->sense;
1315
1316 if (reqbuf->sense_key == UNIT_ATTENTION)
1317 cdrom_saw_media_change(drive);
1318 else if (reqbuf->sense_key == NOT_READY &&
1319 reqbuf->asc == 4 && reqbuf->ascq != 4) {
1320 /* The drive is in the process of loading
1321 a disk. Retry, but wait a little to give
1322 the drive time to complete the load. */
1323 ssleep(2);
1324 } else {
1325 /* Otherwise, don't retry. */
1326 retries = 0;
1327 }
1328 --retries;
1329 }
1330
1331 /* End of retry loop. */
Jens Axboe4aff5e22006-08-10 08:44:47 +02001332 } while ((rq->cmd_flags & REQ_FAILED) && retries >= 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001333
1334 /* Return an error if the command failed. */
Jens Axboe4aff5e22006-08-10 08:44:47 +02001335 return (rq->cmd_flags & REQ_FAILED) ? -EIO : 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001336}
1337
1338/*
1339 * Write handling
1340 */
Arjan van de Ven858119e2006-01-14 13:20:43 -08001341static int cdrom_write_check_ireason(ide_drive_t *drive, int len, int ireason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001342{
1343 /* Two notes about IDE interrupt reason here - 0 means that
1344 * the drive wants to receive data from us, 2 means that
1345 * the drive is expecting to transfer data to us.
1346 */
1347 if (ireason == 0)
1348 return 0;
1349 else if (ireason == 2) {
Bartlomiej Zolnierkiewicz5a5222d2008-02-01 23:09:17 +01001350 ide_hwif_t *hwif = drive->hwif;
1351
Linus Torvalds1da177e2005-04-16 15:20:36 -07001352 /* Whoops... The drive wants to send data. */
Bartlomiej Zolnierkiewicz35379c02007-12-24 15:23:43 +01001353 printk(KERN_ERR "%s: %s: wrong transfer direction!\n",
1354 drive->name, __FUNCTION__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001355
Bartlomiej Zolnierkiewicz5a5222d2008-02-01 23:09:17 +01001356 ide_cd_pad_transfer(drive, hwif->atapi_input_bytes, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001357 } else {
1358 /* Drive wants a command packet, or invalid ireason... */
Bartlomiej Zolnierkiewicz35379c02007-12-24 15:23:43 +01001359 printk(KERN_ERR "%s: %s: bad interrupt reason 0x%02x\n",
1360 drive->name, __FUNCTION__, ireason);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001361 }
1362
1363 cdrom_end_request(drive, 0);
1364 return 1;
1365}
1366
Kiyoshi Uedaaaa04c22007-12-11 17:51:23 -05001367/*
1368 * Called from blk_end_request_callback() after the data of the request
1369 * is completed and before the request is completed.
1370 * By returning value '1', blk_end_request_callback() returns immediately
1371 * without completing the request.
1372 */
1373static int cdrom_newpc_intr_dummy_cb(struct request *rq)
1374{
1375 return 1;
1376}
1377
Linus Torvalds1da177e2005-04-16 15:20:36 -07001378/*
1379 * best way to deal with dma that is not sector aligned right now... note
1380 * that in this path we are not using ->data or ->buffer at all. this irs
1381 * can replace cdrom_pc_intr, cdrom_read_intr, and cdrom_write_intr in the
1382 * future.
1383 */
1384static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
1385{
1386 struct cdrom_info *info = drive->driver_data;
1387 struct request *rq = HWGROUP(drive)->rq;
1388 int dma_error, dma, stat, ireason, len, thislen;
1389 u8 lowcyl, highcyl;
1390 xfer_func_t *xferfunc;
1391 unsigned long flags;
1392
1393 /* Check for errors. */
1394 dma_error = 0;
1395 dma = info->dma;
1396 if (dma) {
1397 info->dma = 0;
1398 dma_error = HWIF(drive)->ide_dma_end(drive);
Bartlomiej Zolnierkiewiczeba15fb2008-02-01 23:09:17 +01001399 if (dma_error) {
1400 printk(KERN_ERR "%s: DMA %s error\n", drive->name,
1401 rq_data_dir(rq) ? "write" : "read");
1402 ide_dma_off(drive);
1403 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001404 }
1405
1406 if (cdrom_decode_status(drive, 0, &stat))
1407 return ide_stopped;
1408
1409 /*
1410 * using dma, transfer is complete now
1411 */
1412 if (dma) {
Bartlomiej Zolnierkiewiczeba15fb2008-02-01 23:09:17 +01001413 if (dma_error)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001414 return ide_error(drive, "dma error", stat);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001415
Kiyoshi Uedaaaa04c22007-12-11 17:51:23 -05001416 spin_lock_irqsave(&ide_lock, flags);
1417 if (__blk_end_request(rq, 0, rq->data_len))
1418 BUG();
1419 HWGROUP(drive)->rq = NULL;
1420 spin_unlock_irqrestore(&ide_lock, flags);
1421
1422 return ide_stopped;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001423 }
1424
1425 /*
1426 * ok we fall to pio :/
1427 */
1428 ireason = HWIF(drive)->INB(IDE_IREASON_REG) & 0x3;
1429 lowcyl = HWIF(drive)->INB(IDE_BCOUNTL_REG);
1430 highcyl = HWIF(drive)->INB(IDE_BCOUNTH_REG);
1431
1432 len = lowcyl + (256 * highcyl);
1433 thislen = rq->data_len;
1434 if (thislen > len)
1435 thislen = len;
1436
1437 /*
1438 * If DRQ is clear, the command has completed.
1439 */
Kiyoshi Uedaaaa04c22007-12-11 17:51:23 -05001440 if ((stat & DRQ_STAT) == 0) {
1441 spin_lock_irqsave(&ide_lock, flags);
Jens Axboe4f4f6c22008-01-31 13:57:51 +01001442 if (__blk_end_request(rq, 0, rq->data_len))
Kiyoshi Uedaaaa04c22007-12-11 17:51:23 -05001443 BUG();
1444 HWGROUP(drive)->rq = NULL;
1445 spin_unlock_irqrestore(&ide_lock, flags);
1446
1447 return ide_stopped;
1448 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001449
1450 /*
1451 * check which way to transfer data
1452 */
1453 if (rq_data_dir(rq) == WRITE) {
1454 /*
1455 * write to drive
1456 */
1457 if (cdrom_write_check_ireason(drive, len, ireason))
1458 return ide_stopped;
1459
1460 xferfunc = HWIF(drive)->atapi_output_bytes;
1461 } else {
1462 /*
1463 * read from drive
1464 */
1465 if (cdrom_read_check_ireason(drive, len, ireason))
1466 return ide_stopped;
1467
1468 xferfunc = HWIF(drive)->atapi_input_bytes;
1469 }
1470
1471 /*
1472 * transfer data
1473 */
1474 while (thislen > 0) {
1475 int blen = blen = rq->data_len;
1476 char *ptr = rq->data;
1477
1478 /*
1479 * bio backed?
1480 */
1481 if (rq->bio) {
1482 ptr = bio_data(rq->bio);
1483 blen = bio_iovec(rq->bio)->bv_len;
1484 }
1485
1486 if (!ptr) {
1487 printk(KERN_ERR "%s: confused, missing data\n", drive->name);
1488 break;
1489 }
1490
1491 if (blen > thislen)
1492 blen = thislen;
1493
1494 xferfunc(drive, ptr, blen);
1495
1496 thislen -= blen;
1497 len -= blen;
1498 rq->data_len -= blen;
1499
1500 if (rq->bio)
Kiyoshi Uedaaaa04c22007-12-11 17:51:23 -05001501 /*
1502 * The request can't be completed until DRQ is cleared.
1503 * So complete the data, but don't complete the request
1504 * using the dummy function for the callback feature
1505 * of blk_end_request_callback().
1506 */
1507 blk_end_request_callback(rq, 0, blen,
1508 cdrom_newpc_intr_dummy_cb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001509 else
1510 rq->data += blen;
1511 }
1512
1513 /*
1514 * pad, if necessary
1515 */
Bartlomiej Zolnierkiewicz5a5222d2008-02-01 23:09:17 +01001516 if (len > 0)
1517 ide_cd_pad_transfer(drive, xferfunc, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001518
Eric Sesterhenn125e1872006-06-23 02:06:06 -07001519 BUG_ON(HWGROUP(drive)->handler != NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001520
1521 ide_set_handler(drive, cdrom_newpc_intr, rq->timeout, NULL);
1522 return ide_started;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001523}
1524
1525static ide_startstop_t cdrom_write_intr(ide_drive_t *drive)
1526{
1527 int stat, ireason, len, sectors_to_transfer, uptodate;
1528 struct cdrom_info *info = drive->driver_data;
1529 int dma_error = 0, dma = info->dma;
1530 u8 lowcyl = 0, highcyl = 0;
1531
1532 struct request *rq = HWGROUP(drive)->rq;
1533
1534 /* Check for errors. */
1535 if (dma) {
1536 info->dma = 0;
Bartlomiej Zolnierkiewiczb481b232007-12-24 15:23:43 +01001537 dma_error = HWIF(drive)->ide_dma_end(drive);
1538 if (dma_error) {
1539 printk(KERN_ERR "%s: DMA write error\n", drive->name);
Bartlomiej Zolnierkiewicz7469aaf2007-02-17 02:40:26 +01001540 ide_dma_off(drive);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001541 }
1542 }
1543
1544 if (cdrom_decode_status(drive, 0, &stat))
1545 return ide_stopped;
1546
1547 /*
1548 * using dma, transfer is complete now
1549 */
1550 if (dma) {
1551 if (dma_error)
1552 return ide_error(drive, "dma error", stat);
1553
1554 ide_end_request(drive, 1, rq->nr_sectors);
1555 return ide_stopped;
1556 }
1557
1558 /* Read the interrupt reason and the transfer length. */
Bartlomiej Zolnierkiewicz31a71192007-12-24 15:23:43 +01001559 ireason = HWIF(drive)->INB(IDE_IREASON_REG) & 0x3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001560 lowcyl = HWIF(drive)->INB(IDE_BCOUNTL_REG);
1561 highcyl = HWIF(drive)->INB(IDE_BCOUNTH_REG);
1562
1563 len = lowcyl + (256 * highcyl);
1564
1565 /* If DRQ is clear, the command has completed. */
1566 if ((stat & DRQ_STAT) == 0) {
1567 /* If we're not done writing, complain.
1568 * Otherwise, complete the command normally.
1569 */
1570 uptodate = 1;
1571 if (rq->current_nr_sectors > 0) {
Bartlomiej Zolnierkiewiczb481b232007-12-24 15:23:43 +01001572 printk(KERN_ERR "%s: %s: data underrun (%d blocks)\n",
1573 drive->name, __FUNCTION__,
1574 rq->current_nr_sectors);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001575 uptodate = 0;
1576 }
1577 cdrom_end_request(drive, uptodate);
1578 return ide_stopped;
1579 }
1580
1581 /* Check that the drive is expecting to do the same thing we are. */
1582 if (cdrom_write_check_ireason(drive, len, ireason))
1583 return ide_stopped;
1584
1585 sectors_to_transfer = len / SECTOR_SIZE;
1586
1587 /*
1588 * now loop and write out the data
1589 */
1590 while (sectors_to_transfer > 0) {
1591 int this_transfer;
1592
1593 if (!rq->current_nr_sectors) {
Bartlomiej Zolnierkiewiczb481b232007-12-24 15:23:43 +01001594 printk(KERN_ERR "%s: %s: confused, missing data\n",
1595 drive->name, __FUNCTION__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001596 break;
1597 }
1598
1599 /*
1600 * Figure out how many sectors we can transfer
1601 */
1602 this_transfer = min_t(int, sectors_to_transfer, rq->current_nr_sectors);
1603
1604 while (this_transfer > 0) {
1605 HWIF(drive)->atapi_output_bytes(drive, rq->buffer, SECTOR_SIZE);
1606 rq->buffer += SECTOR_SIZE;
1607 --rq->nr_sectors;
1608 --rq->current_nr_sectors;
1609 ++rq->sector;
1610 --this_transfer;
1611 --sectors_to_transfer;
1612 }
1613
1614 /*
1615 * current buffer complete, move on
1616 */
1617 if (rq->current_nr_sectors == 0 && rq->nr_sectors)
1618 cdrom_end_request(drive, 1);
1619 }
1620
1621 /* re-arm handler */
1622 ide_set_handler(drive, &cdrom_write_intr, ATAPI_WAIT_PC, NULL);
1623 return ide_started;
1624}
1625
1626static ide_startstop_t cdrom_start_write_cont(ide_drive_t *drive)
1627{
1628 struct request *rq = HWGROUP(drive)->rq;
1629
1630#if 0 /* the immediate bit */
1631 rq->cmd[1] = 1 << 3;
1632#endif
1633 rq->timeout = ATAPI_WAIT_PC;
1634
1635 return cdrom_transfer_packet_command(drive, rq, cdrom_write_intr);
1636}
1637
1638static ide_startstop_t cdrom_start_write(ide_drive_t *drive, struct request *rq)
1639{
1640 struct cdrom_info *info = drive->driver_data;
1641 struct gendisk *g = info->disk;
1642 unsigned short sectors_per_frame = queue_hardsect_size(drive->queue) >> SECTOR_BITS;
1643
1644 /*
1645 * writes *must* be hardware frame aligned
1646 */
1647 if ((rq->nr_sectors & (sectors_per_frame - 1)) ||
1648 (rq->sector & (sectors_per_frame - 1))) {
1649 cdrom_end_request(drive, 0);
1650 return ide_stopped;
1651 }
1652
1653 /*
1654 * disk has become write protected
1655 */
1656 if (g->policy) {
1657 cdrom_end_request(drive, 0);
1658 return ide_stopped;
1659 }
1660
Linus Torvalds1da177e2005-04-16 15:20:36 -07001661 info->nsectors_buffered = 0;
1662
1663 /* use dma, if possible. we don't need to check more, since we
1664 * know that the transfer is always (at least!) frame aligned */
1665 info->dma = drive->using_dma ? 1 : 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001666
1667 info->devinfo.media_written = 1;
1668
1669 /* Start sending the write request to the drive. */
1670 return cdrom_start_packet_command(drive, 32768, cdrom_start_write_cont);
1671}
1672
1673static ide_startstop_t cdrom_do_newpc_cont(ide_drive_t *drive)
1674{
1675 struct request *rq = HWGROUP(drive)->rq;
1676
1677 if (!rq->timeout)
1678 rq->timeout = ATAPI_WAIT_PC;
1679
1680 return cdrom_transfer_packet_command(drive, rq, cdrom_newpc_intr);
1681}
1682
1683static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
1684{
1685 struct cdrom_info *info = drive->driver_data;
1686
Jens Axboe4aff5e22006-08-10 08:44:47 +02001687 rq->cmd_flags |= REQ_QUIET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001688
1689 info->dma = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001690
1691 /*
1692 * sg request
1693 */
1694 if (rq->bio) {
1695 int mask = drive->queue->dma_alignment;
1696 unsigned long addr = (unsigned long) page_address(bio_page(rq->bio));
1697
Linus Torvalds1da177e2005-04-16 15:20:36 -07001698 info->dma = drive->using_dma;
1699
1700 /*
1701 * check if dma is safe
Linus Torvalds5d9e4ea2005-05-27 07:36:17 -07001702 *
1703 * NOTE! The "len" and "addr" checks should possibly have
1704 * separate masks.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001705 */
Jens Axboe4e7c6812005-05-31 17:47:36 +02001706 if ((rq->data_len & 15) || (addr & mask))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001707 info->dma = 0;
1708 }
1709
1710 /* Start sending the command to the drive. */
1711 return cdrom_start_packet_command(drive, rq->data_len, cdrom_do_newpc_cont);
1712}
1713
1714/****************************************************************************
1715 * cdrom driver request routine.
1716 */
1717static ide_startstop_t
1718ide_do_rw_cdrom (ide_drive_t *drive, struct request *rq, sector_t block)
1719{
1720 ide_startstop_t action;
1721 struct cdrom_info *info = drive->driver_data;
1722
1723 if (blk_fs_request(rq)) {
1724 if (CDROM_CONFIG_FLAGS(drive)->seeking) {
1725 unsigned long elapsed = jiffies - info->start_seek;
1726 int stat = HWIF(drive)->INB(IDE_STATUS_REG);
1727
1728 if ((stat & SEEK_STAT) != SEEK_STAT) {
1729 if (elapsed < IDECD_SEEK_TIMEOUT) {
1730 ide_stall_queue(drive, IDECD_SEEK_TIMER);
1731 return ide_stopped;
1732 }
1733 printk (KERN_ERR "%s: DSC timeout\n", drive->name);
1734 }
1735 CDROM_CONFIG_FLAGS(drive)->seeking = 0;
1736 }
1737 if ((rq_data_dir(rq) == READ) && IDE_LARGE_SEEK(info->last_block, block, IDECD_SEEK_THRESHOLD) && drive->dsc_overlap) {
1738 action = cdrom_start_seek(drive, block);
1739 } else {
1740 if (rq_data_dir(rq) == READ)
1741 action = cdrom_start_read(drive, block);
1742 else
1743 action = cdrom_start_write(drive, rq);
1744 }
1745 info->last_block = block;
1746 return action;
Jens Axboecea28852006-10-12 15:08:45 +02001747 } else if (rq->cmd_type == REQ_TYPE_SENSE ||
1748 rq->cmd_type == REQ_TYPE_ATA_PC) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001749 return cdrom_do_packet_command(drive);
Jens Axboe4aff5e22006-08-10 08:44:47 +02001750 } else if (blk_pc_request(rq)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001751 return cdrom_do_block_pc(drive, rq);
Jens Axboe4aff5e22006-08-10 08:44:47 +02001752 } else if (blk_special_request(rq)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001753 /*
1754 * right now this can only be a reset...
1755 */
1756 cdrom_end_request(drive, 1);
1757 return ide_stopped;
1758 }
1759
1760 blk_dump_rq_flags(rq, "ide-cd bad flags");
1761 cdrom_end_request(drive, 0);
1762 return ide_stopped;
1763}
1764
1765
1766
1767/****************************************************************************
1768 * Ioctl handling.
1769 *
1770 * Routines which queue packet commands take as a final argument a pointer
1771 * to a request_sense struct. If execution of the command results
1772 * in an error with a CHECK CONDITION status, this structure will be filled
1773 * with the results of the subsequent request sense command. The pointer
1774 * can also be NULL, in which case no sense information is returned.
1775 */
1776
1777#if ! STANDARD_ATAPI
1778static inline
1779int bin2bcd (int x)
1780{
1781 return (x%10) | ((x/10) << 4);
1782}
1783
1784
1785static inline
1786int bcd2bin (int x)
1787{
1788 return (x >> 4) * 10 + (x & 0x0f);
1789}
1790
1791static
1792void msf_from_bcd (struct atapi_msf *msf)
1793{
1794 msf->minute = bcd2bin (msf->minute);
1795 msf->second = bcd2bin (msf->second);
1796 msf->frame = bcd2bin (msf->frame);
1797}
1798
1799#endif /* not STANDARD_ATAPI */
1800
1801
1802static inline
1803void lba_to_msf (int lba, byte *m, byte *s, byte *f)
1804{
1805 lba += CD_MSF_OFFSET;
1806 lba &= 0xffffff; /* negative lbas use only 24 bits */
1807 *m = lba / (CD_SECS * CD_FRAMES);
1808 lba %= (CD_SECS * CD_FRAMES);
1809 *s = lba / CD_FRAMES;
1810 *f = lba % CD_FRAMES;
1811}
1812
1813
1814static inline
1815int msf_to_lba (byte m, byte s, byte f)
1816{
1817 return (((m * CD_SECS) + s) * CD_FRAMES + f) - CD_MSF_OFFSET;
1818}
1819
1820static int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense)
1821{
1822 struct request req;
1823 struct cdrom_info *info = drive->driver_data;
1824 struct cdrom_device_info *cdi = &info->devinfo;
1825
1826 cdrom_prepare_request(drive, &req);
1827
1828 req.sense = sense;
1829 req.cmd[0] = GPCMD_TEST_UNIT_READY;
Jens Axboe4aff5e22006-08-10 08:44:47 +02001830 req.cmd_flags |= REQ_QUIET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001831
1832#if ! STANDARD_ATAPI
1833 /* the Sanyo 3 CD changer uses byte 7 of TEST_UNIT_READY to
1834 switch CDs instead of supporting the LOAD_UNLOAD opcode */
1835
1836 req.cmd[7] = cdi->sanyo_slot % 3;
1837#endif /* not STANDARD_ATAPI */
1838
1839 return cdrom_queue_packet_command(drive, &req);
1840}
1841
1842
1843/* Lock the door if LOCKFLAG is nonzero; unlock it otherwise. */
1844static int
1845cdrom_lockdoor(ide_drive_t *drive, int lockflag, struct request_sense *sense)
1846{
1847 struct request_sense my_sense;
1848 struct request req;
1849 int stat;
1850
1851 if (sense == NULL)
1852 sense = &my_sense;
1853
1854 /* If the drive cannot lock the door, just pretend. */
1855 if (CDROM_CONFIG_FLAGS(drive)->no_doorlock) {
1856 stat = 0;
1857 } else {
1858 cdrom_prepare_request(drive, &req);
1859 req.sense = sense;
1860 req.cmd[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL;
1861 req.cmd[4] = lockflag ? 1 : 0;
1862 stat = cdrom_queue_packet_command(drive, &req);
1863 }
1864
1865 /* If we got an illegal field error, the drive
1866 probably cannot lock the door. */
1867 if (stat != 0 &&
1868 sense->sense_key == ILLEGAL_REQUEST &&
1869 (sense->asc == 0x24 || sense->asc == 0x20)) {
1870 printk (KERN_ERR "%s: door locking not supported\n",
1871 drive->name);
1872 CDROM_CONFIG_FLAGS(drive)->no_doorlock = 1;
1873 stat = 0;
1874 }
1875
1876 /* no medium, that's alright. */
1877 if (stat != 0 && sense->sense_key == NOT_READY && sense->asc == 0x3a)
1878 stat = 0;
1879
1880 if (stat == 0)
1881 CDROM_STATE_FLAGS(drive)->door_locked = lockflag;
1882
1883 return stat;
1884}
1885
1886
1887/* Eject the disk if EJECTFLAG is 0.
1888 If EJECTFLAG is 1, try to reload the disk. */
1889static int cdrom_eject(ide_drive_t *drive, int ejectflag,
1890 struct request_sense *sense)
1891{
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01001892 struct cdrom_info *cd = drive->driver_data;
1893 struct cdrom_device_info *cdi = &cd->devinfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001894 struct request req;
1895 char loej = 0x02;
1896
1897 if (CDROM_CONFIG_FLAGS(drive)->no_eject && !ejectflag)
1898 return -EDRIVE_CANT_DO_THIS;
1899
1900 /* reload fails on some drives, if the tray is locked */
1901 if (CDROM_STATE_FLAGS(drive)->door_locked && ejectflag)
1902 return 0;
1903
1904 cdrom_prepare_request(drive, &req);
1905
1906 /* only tell drive to close tray if open, if it can do that */
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01001907 if (ejectflag && (cdi->mask & CDC_CLOSE_TRAY))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001908 loej = 0;
1909
1910 req.sense = sense;
1911 req.cmd[0] = GPCMD_START_STOP_UNIT;
1912 req.cmd[4] = loej | (ejectflag != 0);
1913 return cdrom_queue_packet_command(drive, &req);
1914}
1915
1916static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
1917 unsigned long *sectors_per_frame,
1918 struct request_sense *sense)
1919{
1920 struct {
1921 __u32 lba;
1922 __u32 blocklen;
1923 } capbuf;
1924
1925 int stat;
1926 struct request req;
1927
1928 cdrom_prepare_request(drive, &req);
1929
1930 req.sense = sense;
1931 req.cmd[0] = GPCMD_READ_CDVD_CAPACITY;
1932 req.data = (char *)&capbuf;
1933 req.data_len = sizeof(capbuf);
Jens Axboe4aff5e22006-08-10 08:44:47 +02001934 req.cmd_flags |= REQ_QUIET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001935
1936 stat = cdrom_queue_packet_command(drive, &req);
1937 if (stat == 0) {
1938 *capacity = 1 + be32_to_cpu(capbuf.lba);
1939 *sectors_per_frame =
1940 be32_to_cpu(capbuf.blocklen) >> SECTOR_BITS;
1941 }
1942
1943 return stat;
1944}
1945
1946static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag,
1947 int format, char *buf, int buflen,
1948 struct request_sense *sense)
1949{
1950 struct request req;
1951
1952 cdrom_prepare_request(drive, &req);
1953
1954 req.sense = sense;
1955 req.data = buf;
1956 req.data_len = buflen;
Jens Axboe4aff5e22006-08-10 08:44:47 +02001957 req.cmd_flags |= REQ_QUIET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001958 req.cmd[0] = GPCMD_READ_TOC_PMA_ATIP;
1959 req.cmd[6] = trackno;
1960 req.cmd[7] = (buflen >> 8);
1961 req.cmd[8] = (buflen & 0xff);
1962 req.cmd[9] = (format << 6);
1963
1964 if (msf_flag)
1965 req.cmd[1] = 2;
1966
1967 return cdrom_queue_packet_command(drive, &req);
1968}
1969
1970
1971/* Try to read the entire TOC for the disk into our internal buffer. */
1972static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense)
1973{
1974 int stat, ntracks, i;
1975 struct cdrom_info *info = drive->driver_data;
1976 struct cdrom_device_info *cdi = &info->devinfo;
1977 struct atapi_toc *toc = info->toc;
1978 struct {
1979 struct atapi_toc_header hdr;
1980 struct atapi_toc_entry ent;
1981 } ms_tmp;
1982 long last_written;
1983 unsigned long sectors_per_frame = SECTORS_PER_FRAME;
1984
1985 if (toc == NULL) {
1986 /* Try to allocate space. */
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08001987 toc = kmalloc(sizeof(struct atapi_toc), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001988 if (toc == NULL) {
1989 printk (KERN_ERR "%s: No cdrom TOC buffer!\n", drive->name);
1990 return -ENOMEM;
1991 }
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08001992 info->toc = toc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001993 }
1994
1995 /* Check to see if the existing data is still valid.
1996 If it is, just return. */
1997 (void) cdrom_check_status(drive, sense);
1998
1999 if (CDROM_STATE_FLAGS(drive)->toc_valid)
2000 return 0;
2001
2002 /* Try to get the total cdrom capacity and sector size. */
2003 stat = cdrom_read_capacity(drive, &toc->capacity, &sectors_per_frame,
2004 sense);
2005 if (stat)
2006 toc->capacity = 0x1fffff;
2007
2008 set_capacity(info->disk, toc->capacity * sectors_per_frame);
Alan Coxdbe217a2006-06-25 05:47:44 -07002009 /* Save a private copy of te TOC capacity for error handling */
2010 drive->probed_capacity = toc->capacity * sectors_per_frame;
2011
Linus Torvalds1da177e2005-04-16 15:20:36 -07002012 blk_queue_hardsect_size(drive->queue,
2013 sectors_per_frame << SECTOR_BITS);
2014
2015 /* First read just the header, so we know how long the TOC is. */
2016 stat = cdrom_read_tocentry(drive, 0, 1, 0, (char *) &toc->hdr,
2017 sizeof(struct atapi_toc_header), sense);
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002018 if (stat)
2019 return stat;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002020
2021#if ! STANDARD_ATAPI
2022 if (CDROM_CONFIG_FLAGS(drive)->toctracks_as_bcd) {
2023 toc->hdr.first_track = bcd2bin(toc->hdr.first_track);
2024 toc->hdr.last_track = bcd2bin(toc->hdr.last_track);
2025 }
2026#endif /* not STANDARD_ATAPI */
2027
2028 ntracks = toc->hdr.last_track - toc->hdr.first_track + 1;
2029 if (ntracks <= 0)
2030 return -EIO;
2031 if (ntracks > MAX_TRACKS)
2032 ntracks = MAX_TRACKS;
2033
2034 /* Now read the whole schmeer. */
2035 stat = cdrom_read_tocentry(drive, toc->hdr.first_track, 1, 0,
2036 (char *)&toc->hdr,
2037 sizeof(struct atapi_toc_header) +
2038 (ntracks + 1) *
2039 sizeof(struct atapi_toc_entry), sense);
2040
2041 if (stat && toc->hdr.first_track > 1) {
2042 /* Cds with CDI tracks only don't have any TOC entries,
2043 despite of this the returned values are
2044 first_track == last_track = number of CDI tracks + 1,
2045 so that this case is indistinguishable from the same
2046 layout plus an additional audio track.
2047 If we get an error for the regular case, we assume
2048 a CDI without additional audio tracks. In this case
2049 the readable TOC is empty (CDI tracks are not included)
Jan Engelhardt96de0e22007-10-19 23:21:04 +02002050 and only holds the Leadout entry. Heiko Eißfeldt */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002051 ntracks = 0;
2052 stat = cdrom_read_tocentry(drive, CDROM_LEADOUT, 1, 0,
2053 (char *)&toc->hdr,
2054 sizeof(struct atapi_toc_header) +
2055 (ntracks + 1) *
2056 sizeof(struct atapi_toc_entry),
2057 sense);
2058 if (stat) {
2059 return stat;
2060 }
2061#if ! STANDARD_ATAPI
2062 if (CDROM_CONFIG_FLAGS(drive)->toctracks_as_bcd) {
2063 toc->hdr.first_track = bin2bcd(CDROM_LEADOUT);
2064 toc->hdr.last_track = bin2bcd(CDROM_LEADOUT);
2065 } else
2066#endif /* not STANDARD_ATAPI */
2067 {
2068 toc->hdr.first_track = CDROM_LEADOUT;
2069 toc->hdr.last_track = CDROM_LEADOUT;
2070 }
2071 }
2072
2073 if (stat)
2074 return stat;
2075
2076 toc->hdr.toc_length = ntohs (toc->hdr.toc_length);
2077
2078#if ! STANDARD_ATAPI
2079 if (CDROM_CONFIG_FLAGS(drive)->toctracks_as_bcd) {
2080 toc->hdr.first_track = bcd2bin(toc->hdr.first_track);
2081 toc->hdr.last_track = bcd2bin(toc->hdr.last_track);
2082 }
2083#endif /* not STANDARD_ATAPI */
2084
2085 for (i=0; i<=ntracks; i++) {
2086#if ! STANDARD_ATAPI
2087 if (CDROM_CONFIG_FLAGS(drive)->tocaddr_as_bcd) {
2088 if (CDROM_CONFIG_FLAGS(drive)->toctracks_as_bcd)
2089 toc->ent[i].track = bcd2bin(toc->ent[i].track);
2090 msf_from_bcd(&toc->ent[i].addr.msf);
2091 }
2092#endif /* not STANDARD_ATAPI */
2093 toc->ent[i].addr.lba = msf_to_lba (toc->ent[i].addr.msf.minute,
2094 toc->ent[i].addr.msf.second,
2095 toc->ent[i].addr.msf.frame);
2096 }
2097
2098 /* Read the multisession information. */
2099 if (toc->hdr.first_track != CDROM_LEADOUT) {
2100 /* Read the multisession information. */
2101 stat = cdrom_read_tocentry(drive, 0, 0, 1, (char *)&ms_tmp,
2102 sizeof(ms_tmp), sense);
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002103 if (stat)
2104 return stat;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002105
2106 toc->last_session_lba = be32_to_cpu(ms_tmp.ent.addr.lba);
2107 } else {
2108 ms_tmp.hdr.first_track = ms_tmp.hdr.last_track = CDROM_LEADOUT;
2109 toc->last_session_lba = msf_to_lba(0, 2, 0); /* 0m 2s 0f */
2110 }
2111
2112#if ! STANDARD_ATAPI
2113 if (CDROM_CONFIG_FLAGS(drive)->tocaddr_as_bcd) {
2114 /* Re-read multisession information using MSF format */
2115 stat = cdrom_read_tocentry(drive, 0, 1, 1, (char *)&ms_tmp,
2116 sizeof(ms_tmp), sense);
2117 if (stat)
2118 return stat;
2119
2120 msf_from_bcd (&ms_tmp.ent.addr.msf);
2121 toc->last_session_lba = msf_to_lba(ms_tmp.ent.addr.msf.minute,
2122 ms_tmp.ent.addr.msf.second,
2123 ms_tmp.ent.addr.msf.frame);
2124 }
2125#endif /* not STANDARD_ATAPI */
2126
2127 toc->xa_flag = (ms_tmp.hdr.first_track != ms_tmp.hdr.last_track);
2128
2129 /* Now try to get the total cdrom capacity. */
2130 stat = cdrom_get_last_written(cdi, &last_written);
2131 if (!stat && (last_written > toc->capacity)) {
2132 toc->capacity = last_written;
2133 set_capacity(info->disk, toc->capacity * sectors_per_frame);
Alan Coxdbe217a2006-06-25 05:47:44 -07002134 drive->probed_capacity = toc->capacity * sectors_per_frame;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002135 }
2136
2137 /* Remember that we've read this stuff. */
2138 CDROM_STATE_FLAGS(drive)->toc_valid = 1;
2139
2140 return 0;
2141}
2142
2143
2144static int cdrom_read_subchannel(ide_drive_t *drive, int format, char *buf,
2145 int buflen, struct request_sense *sense)
2146{
2147 struct request req;
2148
2149 cdrom_prepare_request(drive, &req);
2150
2151 req.sense = sense;
2152 req.data = buf;
2153 req.data_len = buflen;
2154 req.cmd[0] = GPCMD_READ_SUBCHANNEL;
2155 req.cmd[1] = 2; /* MSF addressing */
2156 req.cmd[2] = 0x40; /* request subQ data */
2157 req.cmd[3] = format;
2158 req.cmd[7] = (buflen >> 8);
2159 req.cmd[8] = (buflen & 0xff);
2160 return cdrom_queue_packet_command(drive, &req);
2161}
2162
2163/* ATAPI cdrom drives are free to select the speed you request or any slower
2164 rate :-( Requesting too fast a speed will _not_ produce an error. */
2165static int cdrom_select_speed(ide_drive_t *drive, int speed,
2166 struct request_sense *sense)
2167{
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002168 struct cdrom_info *cd = drive->driver_data;
2169 struct cdrom_device_info *cdi = &cd->devinfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002170 struct request req;
2171 cdrom_prepare_request(drive, &req);
2172
2173 req.sense = sense;
2174 if (speed == 0)
2175 speed = 0xffff; /* set to max */
2176 else
2177 speed *= 177; /* Nx to kbytes/s */
2178
2179 req.cmd[0] = GPCMD_SET_SPEED;
2180 /* Read Drive speed in kbytes/second MSB */
2181 req.cmd[2] = (speed >> 8) & 0xff;
2182 /* Read Drive speed in kbytes/second LSB */
2183 req.cmd[3] = speed & 0xff;
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002184 if ((cdi->mask & (CDC_CD_R | CDC_CD_RW | CDC_DVD_R)) !=
2185 (CDC_CD_R | CDC_CD_RW | CDC_DVD_R)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002186 /* Write Drive speed in kbytes/second MSB */
2187 req.cmd[4] = (speed >> 8) & 0xff;
2188 /* Write Drive speed in kbytes/second LSB */
2189 req.cmd[5] = speed & 0xff;
2190 }
2191
2192 return cdrom_queue_packet_command(drive, &req);
2193}
2194
2195static int cdrom_play_audio(ide_drive_t *drive, int lba_start, int lba_end)
2196{
2197 struct request_sense sense;
2198 struct request req;
2199
2200 cdrom_prepare_request(drive, &req);
2201
2202 req.sense = &sense;
2203 req.cmd[0] = GPCMD_PLAY_AUDIO_MSF;
2204 lba_to_msf(lba_start, &req.cmd[3], &req.cmd[4], &req.cmd[5]);
2205 lba_to_msf(lba_end-1, &req.cmd[6], &req.cmd[7], &req.cmd[8]);
2206
2207 return cdrom_queue_packet_command(drive, &req);
2208}
2209
2210static int cdrom_get_toc_entry(ide_drive_t *drive, int track,
2211 struct atapi_toc_entry **ent)
2212{
2213 struct cdrom_info *info = drive->driver_data;
2214 struct atapi_toc *toc = info->toc;
2215 int ntracks;
2216
2217 /*
2218 * don't serve cached data, if the toc isn't valid
2219 */
2220 if (!CDROM_STATE_FLAGS(drive)->toc_valid)
2221 return -EINVAL;
2222
2223 /* Check validity of requested track number. */
2224 ntracks = toc->hdr.last_track - toc->hdr.first_track + 1;
2225 if (toc->hdr.first_track == CDROM_LEADOUT) ntracks = 0;
2226 if (track == CDROM_LEADOUT)
2227 *ent = &toc->ent[ntracks];
2228 else if (track < toc->hdr.first_track ||
2229 track > toc->hdr.last_track)
2230 return -EINVAL;
2231 else
2232 *ent = &toc->ent[track - toc->hdr.first_track];
2233
2234 return 0;
2235}
2236
2237/* the generic packet interface to cdrom.c */
2238static int ide_cdrom_packet(struct cdrom_device_info *cdi,
2239 struct packet_command *cgc)
2240{
2241 struct request req;
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002242 ide_drive_t *drive = cdi->handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002243
2244 if (cgc->timeout <= 0)
2245 cgc->timeout = ATAPI_WAIT_PC;
2246
2247 /* here we queue the commands from the uniform CD-ROM
2248 layer. the packet must be complete, as we do not
2249 touch it at all. */
2250 cdrom_prepare_request(drive, &req);
2251 memcpy(req.cmd, cgc->cmd, CDROM_PACKET_SIZE);
2252 if (cgc->sense)
2253 memset(cgc->sense, 0, sizeof(struct request_sense));
2254 req.data = cgc->buffer;
2255 req.data_len = cgc->buflen;
2256 req.timeout = cgc->timeout;
2257
2258 if (cgc->quiet)
Jens Axboe4aff5e22006-08-10 08:44:47 +02002259 req.cmd_flags |= REQ_QUIET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002260
2261 req.sense = cgc->sense;
2262 cgc->stat = cdrom_queue_packet_command(drive, &req);
2263 if (!cgc->stat)
2264 cgc->buflen -= req.data_len;
2265 return cgc->stat;
2266}
2267
2268static
Linus Torvalds1da177e2005-04-16 15:20:36 -07002269int ide_cdrom_audio_ioctl (struct cdrom_device_info *cdi,
2270 unsigned int cmd, void *arg)
2271
2272{
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002273 ide_drive_t *drive = cdi->handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002274 struct cdrom_info *info = drive->driver_data;
2275 int stat;
2276
2277 switch (cmd) {
2278 /*
2279 * emulate PLAY_AUDIO_TI command with PLAY_AUDIO_10, since
2280 * atapi doesn't support it
2281 */
2282 case CDROMPLAYTRKIND: {
2283 unsigned long lba_start, lba_end;
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002284 struct cdrom_ti *ti = arg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002285 struct atapi_toc_entry *first_toc, *last_toc;
2286
2287 stat = cdrom_get_toc_entry(drive, ti->cdti_trk0, &first_toc);
2288 if (stat)
2289 return stat;
2290
2291 stat = cdrom_get_toc_entry(drive, ti->cdti_trk1, &last_toc);
2292 if (stat)
2293 return stat;
2294
2295 if (ti->cdti_trk1 != CDROM_LEADOUT)
2296 ++last_toc;
2297 lba_start = first_toc->addr.lba;
2298 lba_end = last_toc->addr.lba;
2299
2300 if (lba_end <= lba_start)
2301 return -EINVAL;
2302
2303 return cdrom_play_audio(drive, lba_start, lba_end);
2304 }
2305
2306 case CDROMREADTOCHDR: {
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002307 struct cdrom_tochdr *tochdr = arg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002308 struct atapi_toc *toc;
2309
2310 /* Make sure our saved TOC is valid. */
2311 stat = cdrom_read_toc(drive, NULL);
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002312 if (stat)
2313 return stat;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002314
2315 toc = info->toc;
2316 tochdr->cdth_trk0 = toc->hdr.first_track;
2317 tochdr->cdth_trk1 = toc->hdr.last_track;
2318
2319 return 0;
2320 }
2321
2322 case CDROMREADTOCENTRY: {
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002323 struct cdrom_tocentry *tocentry = arg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002324 struct atapi_toc_entry *toce;
2325
2326 stat = cdrom_get_toc_entry(drive, tocentry->cdte_track, &toce);
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002327 if (stat)
2328 return stat;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002329
2330 tocentry->cdte_ctrl = toce->control;
2331 tocentry->cdte_adr = toce->adr;
2332 if (tocentry->cdte_format == CDROM_MSF) {
2333 lba_to_msf (toce->addr.lba,
2334 &tocentry->cdte_addr.msf.minute,
2335 &tocentry->cdte_addr.msf.second,
2336 &tocentry->cdte_addr.msf.frame);
2337 } else
2338 tocentry->cdte_addr.lba = toce->addr.lba;
2339
2340 return 0;
2341 }
2342
2343 default:
2344 return -EINVAL;
2345 }
2346}
2347
2348static
2349int ide_cdrom_reset (struct cdrom_device_info *cdi)
2350{
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002351 ide_drive_t *drive = cdi->handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002352 struct request_sense sense;
2353 struct request req;
2354 int ret;
2355
2356 cdrom_prepare_request(drive, &req);
Jens Axboe4aff5e22006-08-10 08:44:47 +02002357 req.cmd_type = REQ_TYPE_SPECIAL;
2358 req.cmd_flags = REQ_QUIET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002359 ret = ide_do_drive_cmd(drive, &req, ide_wait);
2360
2361 /*
2362 * A reset will unlock the door. If it was previously locked,
2363 * lock it again.
2364 */
2365 if (CDROM_STATE_FLAGS(drive)->door_locked)
2366 (void) cdrom_lockdoor(drive, 1, &sense);
2367
2368 return ret;
2369}
2370
2371
2372static
2373int ide_cdrom_tray_move (struct cdrom_device_info *cdi, int position)
2374{
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002375 ide_drive_t *drive = cdi->handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002376 struct request_sense sense;
2377
2378 if (position) {
2379 int stat = cdrom_lockdoor(drive, 0, &sense);
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002380 if (stat)
2381 return stat;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002382 }
2383
2384 return cdrom_eject(drive, !position, &sense);
2385}
2386
2387static
2388int ide_cdrom_lock_door (struct cdrom_device_info *cdi, int lock)
2389{
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002390 ide_drive_t *drive = cdi->handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002391 return cdrom_lockdoor(drive, lock, NULL);
2392}
2393
2394static
Eric Piel9235e682005-06-23 00:10:29 -07002395int ide_cdrom_get_capabilities(ide_drive_t *drive, struct atapi_capabilities_page *cap)
2396{
2397 struct cdrom_info *info = drive->driver_data;
2398 struct cdrom_device_info *cdi = &info->devinfo;
2399 struct packet_command cgc;
2400 int stat, attempts = 3, size = sizeof(*cap);
2401
2402 /*
2403 * ACER50 (and others?) require the full spec length mode sense
2404 * page capabilities size, but older drives break.
2405 */
2406 if (!(!strcmp(drive->id->model, "ATAPI CD ROM DRIVE 50X MAX") ||
2407 !strcmp(drive->id->model, "WPI CDS-32X")))
2408 size -= sizeof(cap->pad);
2409
2410 init_cdrom_command(&cgc, cap, size, CGC_DATA_UNKNOWN);
2411 do { /* we seem to get stat=0x01,err=0x00 the first time (??) */
2412 stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CAPABILITIES_PAGE, 0);
2413 if (!stat)
2414 break;
2415 } while (--attempts);
2416 return stat;
2417}
2418
2419static
2420void ide_cdrom_update_speed (ide_drive_t *drive, struct atapi_capabilities_page *cap)
2421{
Bartlomiej Zolnierkiewicz481c8c62008-02-01 23:09:20 +01002422 u16 curspeed, maxspeed;
2423
Eric Piel9235e682005-06-23 00:10:29 -07002424 /* The ACER/AOpen 24X cdrom has the speed fields byte-swapped */
2425 if (!drive->id->model[0] &&
2426 !strncmp(drive->id->fw_rev, "241N", 4)) {
Bartlomiej Zolnierkiewicz481c8c62008-02-01 23:09:20 +01002427 curspeed = le16_to_cpu(cap->curspeed);
2428 maxspeed = le16_to_cpu(cap->maxspeed);
Eric Piel9235e682005-06-23 00:10:29 -07002429 } else {
Bartlomiej Zolnierkiewicz481c8c62008-02-01 23:09:20 +01002430 curspeed = be16_to_cpu(cap->curspeed);
2431 maxspeed = be16_to_cpu(cap->maxspeed);
Eric Piel9235e682005-06-23 00:10:29 -07002432 }
Bartlomiej Zolnierkiewicz481c8c62008-02-01 23:09:20 +01002433
2434 CDROM_STATE_FLAGS(drive)->current_speed = (curspeed + (176/2)) / 176;
2435 CDROM_CONFIG_FLAGS(drive)->max_speed = (maxspeed + (176/2)) / 176;
Eric Piel9235e682005-06-23 00:10:29 -07002436}
2437
2438static
Linus Torvalds1da177e2005-04-16 15:20:36 -07002439int ide_cdrom_select_speed (struct cdrom_device_info *cdi, int speed)
2440{
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002441 ide_drive_t *drive = cdi->handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002442 struct request_sense sense;
Eric Piel9235e682005-06-23 00:10:29 -07002443 struct atapi_capabilities_page cap;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002444 int stat;
2445
2446 if ((stat = cdrom_select_speed(drive, speed, &sense)) < 0)
2447 return stat;
2448
Eric Piel9235e682005-06-23 00:10:29 -07002449 if (!ide_cdrom_get_capabilities(drive, &cap)) {
2450 ide_cdrom_update_speed(drive, &cap);
2451 cdi->speed = CDROM_STATE_FLAGS(drive)->current_speed;
2452 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002453 return 0;
2454}
2455
2456/*
2457 * add logic to try GET_EVENT command first to check for media and tray
2458 * status. this should be supported by newer cd-r/w and all DVD etc
2459 * drives
2460 */
2461static
2462int ide_cdrom_drive_status (struct cdrom_device_info *cdi, int slot_nr)
2463{
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002464 ide_drive_t *drive = cdi->handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002465 struct media_event_desc med;
2466 struct request_sense sense;
2467 int stat;
2468
2469 if (slot_nr != CDSL_CURRENT)
2470 return -EINVAL;
2471
2472 stat = cdrom_check_status(drive, &sense);
2473 if (!stat || sense.sense_key == UNIT_ATTENTION)
2474 return CDS_DISC_OK;
2475
2476 if (!cdrom_get_media_event(cdi, &med)) {
2477 if (med.media_present)
2478 return CDS_DISC_OK;
2479 else if (med.door_open)
2480 return CDS_TRAY_OPEN;
2481 else
2482 return CDS_NO_DISC;
2483 }
2484
2485 if (sense.sense_key == NOT_READY && sense.asc == 0x04 && sense.ascq == 0x04)
2486 return CDS_DISC_OK;
2487
2488 /*
2489 * If not using Mt Fuji extended media tray reports,
2490 * just return TRAY_OPEN since ATAPI doesn't provide
2491 * any other way to detect this...
2492 */
2493 if (sense.sense_key == NOT_READY) {
Alan Coxdbe217a2006-06-25 05:47:44 -07002494 if (sense.asc == 0x3a && sense.ascq == 1)
2495 return CDS_NO_DISC;
2496 else
2497 return CDS_TRAY_OPEN;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002498 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002499 return CDS_DRIVE_NOT_READY;
2500}
2501
2502static
2503int ide_cdrom_get_last_session (struct cdrom_device_info *cdi,
2504 struct cdrom_multisession *ms_info)
2505{
2506 struct atapi_toc *toc;
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002507 ide_drive_t *drive = cdi->handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002508 struct cdrom_info *info = drive->driver_data;
2509 struct request_sense sense;
2510 int ret;
2511
2512 if (!CDROM_STATE_FLAGS(drive)->toc_valid || info->toc == NULL)
2513 if ((ret = cdrom_read_toc(drive, &sense)))
2514 return ret;
2515
2516 toc = info->toc;
2517 ms_info->addr.lba = toc->last_session_lba;
2518 ms_info->xa_flag = toc->xa_flag;
2519
2520 return 0;
2521}
2522
2523static
2524int ide_cdrom_get_mcn (struct cdrom_device_info *cdi,
2525 struct cdrom_mcn *mcn_info)
2526{
2527 int stat;
2528 char mcnbuf[24];
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002529 ide_drive_t *drive = cdi->handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002530
2531/* get MCN */
2532 if ((stat = cdrom_read_subchannel(drive, 2, mcnbuf, sizeof (mcnbuf), NULL)))
2533 return stat;
2534
2535 memcpy (mcn_info->medium_catalog_number, mcnbuf+9,
2536 sizeof (mcn_info->medium_catalog_number)-1);
2537 mcn_info->medium_catalog_number[sizeof (mcn_info->medium_catalog_number)-1]
2538 = '\0';
2539
2540 return 0;
2541}
2542
2543
2544
2545/****************************************************************************
2546 * Other driver requests (open, close, check media change).
2547 */
2548
2549static
2550int ide_cdrom_check_media_change_real (struct cdrom_device_info *cdi,
2551 int slot_nr)
2552{
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002553 ide_drive_t *drive = cdi->handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002554 int retval;
2555
2556 if (slot_nr == CDSL_CURRENT) {
2557 (void) cdrom_check_status(drive, NULL);
2558 retval = CDROM_STATE_FLAGS(drive)->media_changed;
2559 CDROM_STATE_FLAGS(drive)->media_changed = 0;
2560 return retval;
2561 } else {
2562 return -EINVAL;
2563 }
2564}
2565
2566
2567static
2568int ide_cdrom_open_real (struct cdrom_device_info *cdi, int purpose)
2569{
2570 return 0;
2571}
2572
2573/*
2574 * Close down the device. Invalidate all cached blocks.
2575 */
2576
2577static
2578void ide_cdrom_release_real (struct cdrom_device_info *cdi)
2579{
2580 ide_drive_t *drive = cdi->handle;
2581
2582 if (!cdi->use_count)
2583 CDROM_STATE_FLAGS(drive)->toc_valid = 0;
2584}
2585
Bartlomiej Zolnierkiewicz20e7f7e2008-02-01 23:09:20 +01002586#define IDE_CD_CAPABILITIES \
2587 (CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK | CDC_SELECT_SPEED | \
2588 CDC_SELECT_DISC | CDC_MULTI_SESSION | CDC_MCN | CDC_MEDIA_CHANGED | \
2589 CDC_PLAY_AUDIO | CDC_RESET | CDC_DRIVE_STATUS | CDC_CD_R | \
2590 CDC_CD_RW | CDC_DVD | CDC_DVD_R | CDC_DVD_RAM | CDC_GENERIC_PACKET | \
2591 CDC_MO_DRIVE | CDC_MRW | CDC_MRW_W | CDC_RAM)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002592
Linus Torvalds1da177e2005-04-16 15:20:36 -07002593static struct cdrom_device_ops ide_cdrom_dops = {
2594 .open = ide_cdrom_open_real,
2595 .release = ide_cdrom_release_real,
2596 .drive_status = ide_cdrom_drive_status,
2597 .media_changed = ide_cdrom_check_media_change_real,
2598 .tray_move = ide_cdrom_tray_move,
2599 .lock_door = ide_cdrom_lock_door,
2600 .select_speed = ide_cdrom_select_speed,
2601 .get_last_session = ide_cdrom_get_last_session,
2602 .get_mcn = ide_cdrom_get_mcn,
2603 .reset = ide_cdrom_reset,
2604 .audio_ioctl = ide_cdrom_audio_ioctl,
Bartlomiej Zolnierkiewicz20e7f7e2008-02-01 23:09:20 +01002605 .capability = IDE_CD_CAPABILITIES,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002606 .generic_packet = ide_cdrom_packet,
2607};
2608
2609static int ide_cdrom_register (ide_drive_t *drive, int nslots)
2610{
2611 struct cdrom_info *info = drive->driver_data;
2612 struct cdrom_device_info *devinfo = &info->devinfo;
2613
2614 devinfo->ops = &ide_cdrom_dops;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002615 devinfo->speed = CDROM_STATE_FLAGS(drive)->current_speed;
2616 devinfo->capacity = nslots;
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002617 devinfo->handle = drive;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002618 strcpy(devinfo->name, drive->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002619
Bartlomiej Zolnierkiewicz3cbd8142007-12-24 15:23:43 +01002620 if (CDROM_CONFIG_FLAGS(drive)->no_speed_select)
2621 devinfo->mask |= CDC_SELECT_SPEED;
2622
Linus Torvalds1da177e2005-04-16 15:20:36 -07002623 devinfo->disk = info->disk;
2624 return register_cdrom(devinfo);
2625}
2626
2627static
Linus Torvalds1da177e2005-04-16 15:20:36 -07002628int ide_cdrom_probe_capabilities (ide_drive_t *drive)
2629{
2630 struct cdrom_info *info = drive->driver_data;
2631 struct cdrom_device_info *cdi = &info->devinfo;
2632 struct atapi_capabilities_page cap;
2633 int nslots = 1;
2634
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002635 cdi->mask = (CDC_CD_R | CDC_CD_RW | CDC_DVD | CDC_DVD_R |
2636 CDC_DVD_RAM | CDC_SELECT_DISC | CDC_PLAY_AUDIO |
2637 CDC_MO_DRIVE | CDC_RAM);
2638
Linus Torvalds1da177e2005-04-16 15:20:36 -07002639 if (drive->media == ide_optical) {
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002640 cdi->mask &= ~(CDC_MO_DRIVE | CDC_RAM);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002641 printk(KERN_ERR "%s: ATAPI magneto-optical drive\n", drive->name);
2642 return nslots;
2643 }
2644
2645 if (CDROM_CONFIG_FLAGS(drive)->nec260 ||
2646 !strcmp(drive->id->model,"STINGRAY 8422 IDE 8X CD-ROM 7-27-95")) {
2647 CDROM_CONFIG_FLAGS(drive)->no_eject = 0;
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002648 cdi->mask &= ~CDC_PLAY_AUDIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002649 return nslots;
2650 }
2651
2652 /*
2653 * we have to cheat a little here. the packet will eventually
2654 * be queued with ide_cdrom_packet(), which extracts the
2655 * drive from cdi->handle. Since this device hasn't been
2656 * registered with the Uniform layer yet, it can't do this.
2657 * Same goes for cdi->ops.
2658 */
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002659 cdi->handle = drive;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002660 cdi->ops = &ide_cdrom_dops;
2661
2662 if (ide_cdrom_get_capabilities(drive, &cap))
2663 return 0;
2664
2665 if (cap.lock == 0)
2666 CDROM_CONFIG_FLAGS(drive)->no_doorlock = 1;
2667 if (cap.eject)
2668 CDROM_CONFIG_FLAGS(drive)->no_eject = 0;
2669 if (cap.cd_r_write)
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002670 cdi->mask &= ~CDC_CD_R;
2671 if (cap.cd_rw_write)
2672 cdi->mask &= ~(CDC_CD_RW | CDC_RAM);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002673 if (cap.dvd_ram_read || cap.dvd_r_read || cap.dvd_rom)
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002674 cdi->mask &= ~CDC_DVD;
2675 if (cap.dvd_ram_write)
2676 cdi->mask &= ~(CDC_DVD_RAM | CDC_RAM);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002677 if (cap.dvd_r_write)
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002678 cdi->mask &= ~CDC_DVD_R;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002679 if (cap.audio_play)
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002680 cdi->mask &= ~CDC_PLAY_AUDIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002681 if (cap.mechtype == mechtype_caddy || cap.mechtype == mechtype_popup)
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002682 cdi->mask |= CDC_CLOSE_TRAY;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002683
2684 /* Some drives used by Apple don't advertise audio play
2685 * but they do support reading TOC & audio datas
2686 */
2687 if (strcmp(drive->id->model, "MATSHITADVD-ROM SR-8187") == 0 ||
2688 strcmp(drive->id->model, "MATSHITADVD-ROM SR-8186") == 0 ||
2689 strcmp(drive->id->model, "MATSHITADVD-ROM SR-8176") == 0 ||
2690 strcmp(drive->id->model, "MATSHITADVD-ROM SR-8174") == 0)
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002691 cdi->mask &= ~CDC_PLAY_AUDIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002692
2693#if ! STANDARD_ATAPI
2694 if (cdi->sanyo_slot > 0) {
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002695 cdi->mask &= ~CDC_SELECT_DISC;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002696 nslots = 3;
2697 }
2698
2699 else
2700#endif /* not STANDARD_ATAPI */
2701 if (cap.mechtype == mechtype_individual_changer ||
2702 cap.mechtype == mechtype_cartridge_changer) {
Bartlomiej Zolnierkiewicz2609d062008-02-01 23:09:19 +01002703 nslots = cdrom_number_of_slots(cdi);
2704 if (nslots > 1)
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002705 cdi->mask &= ~CDC_SELECT_DISC;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002706 }
2707
Eric Piel9235e682005-06-23 00:10:29 -07002708 ide_cdrom_update_speed(drive, &cap);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002709 /* don't print speed if the drive reported 0.
2710 */
2711 printk(KERN_INFO "%s: ATAPI", drive->name);
2712 if (CDROM_CONFIG_FLAGS(drive)->max_speed)
2713 printk(" %dX", CDROM_CONFIG_FLAGS(drive)->max_speed);
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002714 printk(KERN_CONT " %s", (cdi->mask & CDC_DVD) ? "CD-ROM" : "DVD-ROM");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002715
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002716 if ((cdi->mask & CDC_DVD_R) == 0 || (cdi->mask & CDC_DVD_RAM) == 0)
2717 printk(KERN_CONT " DVD%s%s",
2718 (cdi->mask & CDC_DVD_R) ? "" : "-R",
2719 (cdi->mask & CDC_DVD_RAM) ? "" : "-RAM");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002720
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002721 if ((cdi->mask & CDC_CD_R) == 0 || (cdi->mask & CDC_CD_RW) == 0)
2722 printk(KERN_CONT " CD%s%s",
2723 (cdi->mask & CDC_CD_R) ? "" : "-R",
2724 (cdi->mask & CDC_CD_RW) ? "" : "/RW");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002725
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002726 if ((cdi->mask & CDC_SELECT_DISC) == 0)
2727 printk(KERN_CONT " changer w/%d slots", nslots);
2728 else
2729 printk(KERN_CONT " drive");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002730
Bartlomiej Zolnierkiewicz3ab7efe2007-12-12 23:31:58 +01002731 printk(KERN_CONT ", %dkB Cache\n", be16_to_cpu(cap.buffer_size));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002732
2733 return nslots;
2734}
2735
Bartlomiej Zolnierkiewicz7662d042007-05-10 00:01:10 +02002736#ifdef CONFIG_IDE_PROC_FS
Linus Torvalds1da177e2005-04-16 15:20:36 -07002737static void ide_cdrom_add_settings(ide_drive_t *drive)
2738{
Bartlomiej Zolnierkiewicz14979432007-05-10 00:01:10 +02002739 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 -07002740}
Bartlomiej Zolnierkiewicz7662d042007-05-10 00:01:10 +02002741#else
2742static inline void ide_cdrom_add_settings(ide_drive_t *drive) { ; }
2743#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07002744
2745/*
2746 * standard prep_rq_fn that builds 10 byte cmds
2747 */
Jens Axboe165125e2007-07-24 09:28:11 +02002748static int ide_cdrom_prep_fs(struct request_queue *q, struct request *rq)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002749{
2750 int hard_sect = queue_hardsect_size(q);
2751 long block = (long)rq->hard_sector / (hard_sect >> 9);
2752 unsigned long blocks = rq->hard_nr_sectors / (hard_sect >> 9);
2753
2754 memset(rq->cmd, 0, sizeof(rq->cmd));
2755
2756 if (rq_data_dir(rq) == READ)
2757 rq->cmd[0] = GPCMD_READ_10;
2758 else
2759 rq->cmd[0] = GPCMD_WRITE_10;
2760
2761 /*
2762 * fill in lba
2763 */
2764 rq->cmd[2] = (block >> 24) & 0xff;
2765 rq->cmd[3] = (block >> 16) & 0xff;
2766 rq->cmd[4] = (block >> 8) & 0xff;
2767 rq->cmd[5] = block & 0xff;
2768
2769 /*
2770 * and transfer length
2771 */
2772 rq->cmd[7] = (blocks >> 8) & 0xff;
2773 rq->cmd[8] = blocks & 0xff;
2774 rq->cmd_len = 10;
2775 return BLKPREP_OK;
2776}
2777
2778/*
2779 * Most of the SCSI commands are supported directly by ATAPI devices.
2780 * This transform handles the few exceptions.
2781 */
2782static int ide_cdrom_prep_pc(struct request *rq)
2783{
2784 u8 *c = rq->cmd;
2785
2786 /*
2787 * Transform 6-byte read/write commands to the 10-byte version
2788 */
2789 if (c[0] == READ_6 || c[0] == WRITE_6) {
2790 c[8] = c[4];
2791 c[5] = c[3];
2792 c[4] = c[2];
2793 c[3] = c[1] & 0x1f;
2794 c[2] = 0;
2795 c[1] &= 0xe0;
2796 c[0] += (READ_10 - READ_6);
2797 rq->cmd_len = 10;
2798 return BLKPREP_OK;
2799 }
2800
2801 /*
2802 * it's silly to pretend we understand 6-byte sense commands, just
2803 * reject with ILLEGAL_REQUEST and the caller should take the
2804 * appropriate action
2805 */
2806 if (c[0] == MODE_SENSE || c[0] == MODE_SELECT) {
2807 rq->errors = ILLEGAL_REQUEST;
2808 return BLKPREP_KILL;
2809 }
2810
2811 return BLKPREP_OK;
2812}
2813
Jens Axboe165125e2007-07-24 09:28:11 +02002814static int ide_cdrom_prep_fn(struct request_queue *q, struct request *rq)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002815{
Jens Axboe4aff5e22006-08-10 08:44:47 +02002816 if (blk_fs_request(rq))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002817 return ide_cdrom_prep_fs(q, rq);
Jens Axboe4aff5e22006-08-10 08:44:47 +02002818 else if (blk_pc_request(rq))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002819 return ide_cdrom_prep_pc(rq);
2820
2821 return 0;
2822}
2823
2824static
2825int ide_cdrom_setup (ide_drive_t *drive)
2826{
2827 struct cdrom_info *info = drive->driver_data;
2828 struct cdrom_device_info *cdi = &info->devinfo;
2829 int nslots;
2830
2831 blk_queue_prep_rq(drive->queue, ide_cdrom_prep_fn);
2832 blk_queue_dma_alignment(drive->queue, 31);
2833 drive->queue->unplug_delay = (1 * HZ) / 1000;
2834 if (!drive->queue->unplug_delay)
2835 drive->queue->unplug_delay = 1;
2836
2837 drive->special.all = 0;
2838
2839 CDROM_STATE_FLAGS(drive)->media_changed = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002840
2841#if NO_DOOR_LOCKING
2842 CDROM_CONFIG_FLAGS(drive)->no_doorlock = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002843#endif
Bartlomiej Zolnierkiewiczb8d25de2008-02-01 23:09:19 +01002844 if ((drive->id->config & 0x0060) == 0x20)
2845 CDROM_CONFIG_FLAGS(drive)->drq_interrupt = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002846 CDROM_CONFIG_FLAGS(drive)->no_eject = 1;
Bartlomiej Zolnierkiewiczb8d25de2008-02-01 23:09:19 +01002847
Linus Torvalds1da177e2005-04-16 15:20:36 -07002848 /* limit transfer size per interrupt. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002849 /* a testament to the nice quality of Samsung drives... */
2850 if (!strcmp(drive->id->model, "SAMSUNG CD-ROM SCR-2430"))
2851 CDROM_CONFIG_FLAGS(drive)->limit_nframes = 1;
2852 else if (!strcmp(drive->id->model, "SAMSUNG CD-ROM SCR-2432"))
2853 CDROM_CONFIG_FLAGS(drive)->limit_nframes = 1;
2854 /* the 3231 model does not support the SET_CD_SPEED command */
2855 else if (!strcmp(drive->id->model, "SAMSUNG CD-ROM SCR-3231"))
Bartlomiej Zolnierkiewicz3cbd8142007-12-24 15:23:43 +01002856 CDROM_CONFIG_FLAGS(drive)->no_speed_select = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002857
2858#if ! STANDARD_ATAPI
Linus Torvalds1da177e2005-04-16 15:20:36 -07002859 if (strcmp (drive->id->model, "V003S0DS") == 0 &&
2860 drive->id->fw_rev[4] == '1' &&
2861 drive->id->fw_rev[6] <= '2') {
2862 /* Vertos 300.
2863 Some versions of this drive like to talk BCD. */
2864 CDROM_CONFIG_FLAGS(drive)->toctracks_as_bcd = 1;
2865 CDROM_CONFIG_FLAGS(drive)->tocaddr_as_bcd = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002866 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002867 else if (strcmp (drive->id->model, "V006E0DS") == 0 &&
2868 drive->id->fw_rev[4] == '1' &&
2869 drive->id->fw_rev[6] <= '2') {
2870 /* Vertos 600 ESD. */
2871 CDROM_CONFIG_FLAGS(drive)->toctracks_as_bcd = 1;
2872 }
2873 else if (strcmp(drive->id->model, "NEC CD-ROM DRIVE:260") == 0 &&
2874 strncmp(drive->id->fw_rev, "1.01", 4) == 0) { /* FIXME */
2875 /* Old NEC260 (not R).
2876 This drive was released before the 1.2 version
2877 of the spec. */
2878 CDROM_CONFIG_FLAGS(drive)->tocaddr_as_bcd = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002879 CDROM_CONFIG_FLAGS(drive)->nec260 = 1;
2880 }
Bartlomiej Zolnierkiewiczb8d25de2008-02-01 23:09:19 +01002881 /*
2882 * Sanyo 3 CD changer uses a non-standard command for CD changing
2883 * (by default standard ATAPI support for CD changers is used).
2884 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002885 else if ((strcmp(drive->id->model, "CD-ROM CDR-C3 G") == 0) ||
2886 (strcmp(drive->id->model, "CD-ROM CDR-C3G") == 0) ||
2887 (strcmp(drive->id->model, "CD-ROM CDR_C36") == 0)) {
2888 /* uses CD in slot 0 when value is set to 3 */
2889 cdi->sanyo_slot = 3;
2890 }
2891#endif /* not STANDARD_ATAPI */
2892
Linus Torvalds1da177e2005-04-16 15:20:36 -07002893 nslots = ide_cdrom_probe_capabilities (drive);
2894
2895 /*
2896 * set correct block size
2897 */
2898 blk_queue_hardsect_size(drive->queue, CD_FRAMESIZE);
2899
2900 if (drive->autotune == IDE_TUNE_DEFAULT ||
2901 drive->autotune == IDE_TUNE_AUTO)
2902 drive->dsc_overlap = (drive->next != drive);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002903
2904 if (ide_cdrom_register(drive, nslots)) {
2905 printk (KERN_ERR "%s: ide_cdrom_setup failed to register device with the cdrom driver.\n", drive->name);
2906 info->devinfo.handle = NULL;
2907 return 1;
2908 }
2909 ide_cdrom_add_settings(drive);
2910 return 0;
2911}
2912
Bartlomiej Zolnierkiewiczecfd80e2007-05-10 00:01:09 +02002913#ifdef CONFIG_IDE_PROC_FS
Linus Torvalds1da177e2005-04-16 15:20:36 -07002914static
2915sector_t ide_cdrom_capacity (ide_drive_t *drive)
2916{
2917 unsigned long capacity, sectors_per_frame;
2918
2919 if (cdrom_read_capacity(drive, &capacity, &sectors_per_frame, NULL))
2920 return 0;
2921
2922 return capacity * sectors_per_frame;
2923}
Amos Waterlandd97b32142005-10-30 15:02:10 -08002924#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07002925
Russell King4031bbe2006-01-06 11:41:00 +00002926static void ide_cd_remove(ide_drive_t *drive)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002927{
2928 struct cdrom_info *info = drive->driver_data;
2929
Bartlomiej Zolnierkiewicz7662d042007-05-10 00:01:10 +02002930 ide_proc_unregister_driver(drive, info->driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002931
2932 del_gendisk(info->disk);
2933
2934 ide_cd_put(info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002935}
2936
2937static void ide_cd_release(struct kref *kref)
2938{
2939 struct cdrom_info *info = to_ide_cd(kref);
2940 struct cdrom_device_info *devinfo = &info->devinfo;
2941 ide_drive_t *drive = info->drive;
2942 struct gendisk *g = info->disk;
2943
Jesper Juhl6044ec82005-11-07 01:01:32 -08002944 kfree(info->buffer);
2945 kfree(info->toc);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002946 if (devinfo->handle == drive && unregister_cdrom(devinfo))
2947 printk(KERN_ERR "%s: %s failed to unregister device from the cdrom "
2948 "driver.\n", __FUNCTION__, drive->name);
2949 drive->dsc_overlap = 0;
2950 drive->driver_data = NULL;
2951 blk_queue_prep_rq(drive->queue, NULL);
2952 g->private_data = NULL;
2953 put_disk(g);
2954 kfree(info);
2955}
2956
Russell King4031bbe2006-01-06 11:41:00 +00002957static int ide_cd_probe(ide_drive_t *);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002958
Bartlomiej Zolnierkiewiczecfd80e2007-05-10 00:01:09 +02002959#ifdef CONFIG_IDE_PROC_FS
Linus Torvalds1da177e2005-04-16 15:20:36 -07002960static int proc_idecd_read_capacity
2961 (char *page, char **start, off_t off, int count, int *eof, void *data)
2962{
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002963 ide_drive_t *drive = data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002964 int len;
2965
2966 len = sprintf(page,"%llu\n", (long long)ide_cdrom_capacity(drive));
2967 PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
2968}
2969
2970static ide_proc_entry_t idecd_proc[] = {
2971 { "capacity", S_IFREG|S_IRUGO, proc_idecd_read_capacity, NULL },
2972 { NULL, 0, NULL, NULL }
2973};
Linus Torvalds1da177e2005-04-16 15:20:36 -07002974#endif
2975
2976static ide_driver_t ide_cdrom_driver = {
Bartlomiej Zolnierkiewicz8604aff2005-05-26 14:55:34 +02002977 .gen_driver = {
Laurent Riffard4ef3b8f2005-11-18 22:15:40 +01002978 .owner = THIS_MODULE,
Bartlomiej Zolnierkiewicz8604aff2005-05-26 14:55:34 +02002979 .name = "ide-cdrom",
2980 .bus = &ide_bus_type,
Bartlomiej Zolnierkiewicz8604aff2005-05-26 14:55:34 +02002981 },
Russell King4031bbe2006-01-06 11:41:00 +00002982 .probe = ide_cd_probe,
2983 .remove = ide_cd_remove,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002984 .version = IDECD_VERSION,
2985 .media = ide_cdrom,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002986 .supports_dsc_overlap = 1,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002987 .do_request = ide_do_rw_cdrom,
2988 .end_request = ide_end_request,
2989 .error = __ide_error,
2990 .abort = __ide_abort,
Bartlomiej Zolnierkiewicz7662d042007-05-10 00:01:10 +02002991#ifdef CONFIG_IDE_PROC_FS
Linus Torvalds1da177e2005-04-16 15:20:36 -07002992 .proc = idecd_proc,
Bartlomiej Zolnierkiewicz7662d042007-05-10 00:01:10 +02002993#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07002994};
2995
2996static int idecd_open(struct inode * inode, struct file * file)
2997{
2998 struct gendisk *disk = inode->i_bdev->bd_disk;
2999 struct cdrom_info *info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003000 int rc = -ENOMEM;
3001
3002 if (!(info = ide_cd_get(disk)))
3003 return -ENXIO;
3004
Linus Torvalds1da177e2005-04-16 15:20:36 -07003005 if (!info->buffer)
Bartlomiej Zolnierkiewiczc94964a2007-02-17 02:40:24 +01003006 info->buffer = kmalloc(SECTOR_BUFFER_SIZE, GFP_KERNEL|__GFP_REPEAT);
3007
3008 if (info->buffer)
3009 rc = cdrom_open(&info->devinfo, inode, file);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003010
3011 if (rc < 0)
3012 ide_cd_put(info);
3013
3014 return rc;
3015}
3016
3017static int idecd_release(struct inode * inode, struct file * file)
3018{
3019 struct gendisk *disk = inode->i_bdev->bd_disk;
3020 struct cdrom_info *info = ide_cd_g(disk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003021
3022 cdrom_release (&info->devinfo, file);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003023
3024 ide_cd_put(info);
3025
3026 return 0;
3027}
3028
Christoph Hellwig6a2900b2006-03-23 03:00:15 -08003029static int idecd_set_spindown(struct cdrom_device_info *cdi, unsigned long arg)
3030{
3031 struct packet_command cgc;
3032 char buffer[16];
3033 int stat;
3034 char spindown;
3035
3036 if (copy_from_user(&spindown, (void __user *)arg, sizeof(char)))
3037 return -EFAULT;
3038
3039 init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_UNKNOWN);
3040
3041 stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CDROM_PAGE, 0);
3042 if (stat)
3043 return stat;
3044
3045 buffer[11] = (buffer[11] & 0xf0) | (spindown & 0x0f);
3046 return cdrom_mode_select(cdi, &cgc);
3047}
3048
3049static int idecd_get_spindown(struct cdrom_device_info *cdi, unsigned long arg)
3050{
3051 struct packet_command cgc;
3052 char buffer[16];
3053 int stat;
3054 char spindown;
3055
3056 init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_UNKNOWN);
3057
3058 stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CDROM_PAGE, 0);
3059 if (stat)
3060 return stat;
3061
3062 spindown = buffer[11] & 0x0f;
3063 if (copy_to_user((void __user *)arg, &spindown, sizeof (char)))
3064 return -EFAULT;
3065 return 0;
3066}
3067
Linus Torvalds1da177e2005-04-16 15:20:36 -07003068static int idecd_ioctl (struct inode *inode, struct file *file,
3069 unsigned int cmd, unsigned long arg)
3070{
3071 struct block_device *bdev = inode->i_bdev;
3072 struct cdrom_info *info = ide_cd_g(bdev->bd_disk);
3073 int err;
3074
Christoph Hellwig6a2900b2006-03-23 03:00:15 -08003075 switch (cmd) {
3076 case CDROMSETSPINDOWN:
3077 return idecd_set_spindown(&info->devinfo, arg);
3078 case CDROMGETSPINDOWN:
3079 return idecd_get_spindown(&info->devinfo, arg);
3080 default:
3081 break;
3082 }
3083
3084 err = generic_ide_ioctl(info->drive, file, bdev, cmd, arg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003085 if (err == -EINVAL)
3086 err = cdrom_ioctl(file, &info->devinfo, inode, cmd, arg);
3087
3088 return err;
3089}
3090
3091static int idecd_media_changed(struct gendisk *disk)
3092{
3093 struct cdrom_info *info = ide_cd_g(disk);
3094 return cdrom_media_changed(&info->devinfo);
3095}
3096
3097static int idecd_revalidate_disk(struct gendisk *disk)
3098{
3099 struct cdrom_info *info = ide_cd_g(disk);
3100 struct request_sense sense;
3101 cdrom_read_toc(info->drive, &sense);
3102 return 0;
3103}
3104
3105static struct block_device_operations idecd_ops = {
3106 .owner = THIS_MODULE,
3107 .open = idecd_open,
3108 .release = idecd_release,
3109 .ioctl = idecd_ioctl,
3110 .media_changed = idecd_media_changed,
3111 .revalidate_disk= idecd_revalidate_disk
3112};
3113
3114/* options */
3115static char *ignore = NULL;
3116
3117module_param(ignore, charp, 0400);
3118MODULE_DESCRIPTION("ATAPI CD-ROM Driver");
3119
Russell King4031bbe2006-01-06 11:41:00 +00003120static int ide_cd_probe(ide_drive_t *drive)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003121{
3122 struct cdrom_info *info;
3123 struct gendisk *g;
3124 struct request_sense sense;
3125
3126 if (!strstr("ide-cdrom", drive->driver_req))
3127 goto failed;
3128 if (!drive->present)
3129 goto failed;
3130 if (drive->media != ide_cdrom && drive->media != ide_optical)
3131 goto failed;
3132 /* skip drives that we were told to ignore */
3133 if (ignore != NULL) {
3134 if (strstr(ignore, drive->name)) {
3135 printk(KERN_INFO "ide-cd: ignoring drive %s\n", drive->name);
3136 goto failed;
3137 }
3138 }
3139 if (drive->scsi) {
3140 printk(KERN_INFO "ide-cd: passing drive %s to ide-scsi emulation.\n", drive->name);
3141 goto failed;
3142 }
Deepak Saxenaf5e3c2f2005-11-07 01:01:25 -08003143 info = kzalloc(sizeof(struct cdrom_info), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003144 if (info == NULL) {
3145 printk(KERN_ERR "%s: Can't allocate a cdrom structure\n", drive->name);
3146 goto failed;
3147 }
3148
3149 g = alloc_disk(1 << PARTN_BITS);
3150 if (!g)
3151 goto out_free_cd;
3152
3153 ide_init_disk(g, drive);
3154
Bartlomiej Zolnierkiewicz7662d042007-05-10 00:01:10 +02003155 ide_proc_register_driver(drive, &ide_cdrom_driver);
Bartlomiej Zolnierkiewicz8604aff2005-05-26 14:55:34 +02003156
Linus Torvalds1da177e2005-04-16 15:20:36 -07003157 kref_init(&info->kref);
3158
3159 info->drive = drive;
3160 info->driver = &ide_cdrom_driver;
3161 info->disk = g;
3162
3163 g->private_data = &info->driver;
3164
3165 drive->driver_data = info;
3166
Linus Torvalds1da177e2005-04-16 15:20:36 -07003167 g->minors = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003168 g->driverfs_dev = &drive->gendev;
3169 g->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE;
3170 if (ide_cdrom_setup(drive)) {
Bartlomiej Zolnierkiewicz7662d042007-05-10 00:01:10 +02003171 ide_proc_unregister_driver(drive, &ide_cdrom_driver);
Bartlomiej Zolnierkiewicz05017db2007-12-24 15:23:43 +01003172 ide_cd_release(&info->kref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003173 goto failed;
3174 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003175
3176 cdrom_read_toc(drive, &sense);
3177 g->fops = &idecd_ops;
3178 g->flags |= GENHD_FL_REMOVABLE;
3179 add_disk(g);
3180 return 0;
3181
Linus Torvalds1da177e2005-04-16 15:20:36 -07003182out_free_cd:
3183 kfree(info);
3184failed:
Bartlomiej Zolnierkiewicz8604aff2005-05-26 14:55:34 +02003185 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003186}
3187
3188static void __exit ide_cdrom_exit(void)
3189{
Bartlomiej Zolnierkiewicz8604aff2005-05-26 14:55:34 +02003190 driver_unregister(&ide_cdrom_driver.gen_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003191}
Bartlomiej Zolnierkiewicz17514e82005-11-19 22:24:35 +01003192
3193static int __init ide_cdrom_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003194{
Bartlomiej Zolnierkiewicz8604aff2005-05-26 14:55:34 +02003195 return driver_register(&ide_cdrom_driver.gen_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003196}
3197
Kay Sievers263756e2005-12-12 18:03:44 +01003198MODULE_ALIAS("ide:*m-cdrom*");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003199module_init(ide_cdrom_init);
3200module_exit(ide_cdrom_exit);
3201MODULE_LICENSE("GPL");