blob: 206d038c1a1fd2c4557570caa85c800de17baa56 [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{
Bartlomiej Zolnierkiewicz0ba11212008-02-01 23:09:21 +010096 struct cdrom_info *cd = drive->driver_data;
97
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +010098 cd->cd_flags |= IDE_CD_FLAG_MEDIA_CHANGED;
99 cd->cd_flags &= ~IDE_CD_FLAG_TOC_VALID;
Bartlomiej Zolnierkiewicz0ba11212008-02-01 23:09:21 +0100100 cd->nsectors_buffered = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700101}
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);
Bartlomiej Zolnierkiewicz4fe67172008-02-01 23:09:21 +0100660
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +0100661 if (info->cd_flags & IDE_CD_FLAG_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
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +0100697 if (info->cd_flags & IDE_CD_FLAG_DRQ_INTERRUPT) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700698 /* 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);
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +0100896 if (info->cd_flags & IDE_CD_FLAG_LIMIT_NFRAMES)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700897 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");
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +0100900 info->cd_flags |= IDE_CD_FLAG_LIMIT_NFRAMES;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700901 }
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;
Bartlomiej Zolnierkiewicz4fe67172008-02-01 23:09:21 +01001076
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01001077 info->cd_flags |= IDE_CD_FLAG_SEEKING;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001078
1079 if (retry && time_after(jiffies, info->start_seek + IDECD_SEEK_TIMER)) {
1080 if (--retry == 0) {
1081 /*
1082 * this condition is far too common, to bother
1083 * users about it
1084 */
1085 /* printk("%s: disabled DSC seek overlap\n", drive->name);*/
1086 drive->dsc_overlap = 0;
1087 }
1088 }
1089 return ide_stopped;
1090}
1091
1092static ide_startstop_t cdrom_start_seek_continuation (ide_drive_t *drive)
1093{
1094 struct request *rq = HWGROUP(drive)->rq;
1095 sector_t frame = rq->sector;
1096
1097 sector_div(frame, queue_hardsect_size(drive->queue) >> SECTOR_BITS);
1098
1099 memset(rq->cmd, 0, sizeof(rq->cmd));
1100 rq->cmd[0] = GPCMD_SEEK;
1101 put_unaligned(cpu_to_be32(frame), (unsigned int *) &rq->cmd[2]);
1102
1103 rq->timeout = ATAPI_WAIT_PC;
1104 return cdrom_transfer_packet_command(drive, rq, &cdrom_seek_intr);
1105}
1106
1107static ide_startstop_t cdrom_start_seek (ide_drive_t *drive, unsigned int block)
1108{
1109 struct cdrom_info *info = drive->driver_data;
1110
1111 info->dma = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001112 info->start_seek = jiffies;
1113 return cdrom_start_packet_command(drive, 0, cdrom_start_seek_continuation);
1114}
1115
1116/* Fix up a possibly partially-processed request so that we can
1117 start it over entirely, or even put it back on the request queue. */
1118static void restore_request (struct request *rq)
1119{
1120 if (rq->buffer != bio_data(rq->bio)) {
1121 sector_t n = (rq->buffer - (char *) bio_data(rq->bio)) / SECTOR_SIZE;
1122
1123 rq->buffer = bio_data(rq->bio);
1124 rq->nr_sectors += n;
1125 rq->sector -= n;
1126 }
1127 rq->hard_cur_sectors = rq->current_nr_sectors = bio_cur_sectors(rq->bio);
1128 rq->hard_nr_sectors = rq->nr_sectors;
1129 rq->hard_sector = rq->sector;
1130 rq->q->prep_rq_fn(rq->q, rq);
1131}
1132
1133/*
1134 * Start a read request from the CD-ROM.
1135 */
1136static ide_startstop_t cdrom_start_read (ide_drive_t *drive, unsigned int block)
1137{
1138 struct cdrom_info *info = drive->driver_data;
1139 struct request *rq = HWGROUP(drive)->rq;
1140 unsigned short sectors_per_frame;
1141
1142 sectors_per_frame = queue_hardsect_size(drive->queue) >> SECTOR_BITS;
1143
1144 /* We may be retrying this request after an error. Fix up
1145 any weirdness which might be present in the request packet. */
1146 restore_request(rq);
1147
1148 /* Satisfy whatever we can of this request from our cached sector. */
1149 if (cdrom_read_from_buffer(drive))
1150 return ide_stopped;
1151
Linus Torvalds1da177e2005-04-16 15:20:36 -07001152 /* Clear the local sector buffer. */
1153 info->nsectors_buffered = 0;
1154
1155 /* use dma, if possible. */
1156 info->dma = drive->using_dma;
1157 if ((rq->sector & (sectors_per_frame - 1)) ||
1158 (rq->nr_sectors & (sectors_per_frame - 1)))
1159 info->dma = 0;
1160
Linus Torvalds1da177e2005-04-16 15:20:36 -07001161 /* Start sending the read request to the drive. */
1162 return cdrom_start_packet_command(drive, 32768, cdrom_start_read_continuation);
1163}
1164
1165/****************************************************************************
1166 * Execute all other packet commands.
1167 */
1168
1169/* Interrupt routine for packet command completion. */
1170static ide_startstop_t cdrom_pc_intr (ide_drive_t *drive)
1171{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001172 struct request *rq = HWGROUP(drive)->rq;
Bartlomiej Zolnierkiewicz68661c52008-02-01 23:09:17 +01001173 xfer_func_t *xferfunc = NULL;
1174 int stat, ireason, len, thislen, write;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001175 u8 lowcyl = 0, highcyl = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001176
1177 /* Check for errors. */
1178 if (cdrom_decode_status(drive, 0, &stat))
1179 return ide_stopped;
1180
1181 /* Read the interrupt reason and the transfer length. */
Bartlomiej Zolnierkiewicz8606ab02007-12-24 15:23:44 +01001182 ireason = HWIF(drive)->INB(IDE_IREASON_REG) & 0x3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001183 lowcyl = HWIF(drive)->INB(IDE_BCOUNTL_REG);
1184 highcyl = HWIF(drive)->INB(IDE_BCOUNTH_REG);
1185
1186 len = lowcyl + (256 * highcyl);
1187
1188 /* If DRQ is clear, the command has completed.
1189 Complain if we still have data left to transfer. */
1190 if ((stat & DRQ_STAT) == 0) {
1191 /* Some of the trailing request sense fields are optional, and
1192 some drives don't send them. Sigh. */
1193 if (rq->cmd[0] == GPCMD_REQUEST_SENSE &&
1194 rq->data_len > 0 &&
1195 rq->data_len <= 5) {
1196 while (rq->data_len > 0) {
1197 *(unsigned char *)rq->data++ = 0;
1198 --rq->data_len;
1199 }
1200 }
1201
1202 if (rq->data_len == 0)
1203 cdrom_end_request(drive, 1);
1204 else {
Jens Axboe4aff5e22006-08-10 08:44:47 +02001205 rq->cmd_flags |= REQ_FAILED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001206 cdrom_end_request(drive, 0);
1207 }
1208 return ide_stopped;
1209 }
1210
1211 /* Figure out how much data to transfer. */
1212 thislen = rq->data_len;
Bartlomiej Zolnierkiewicz68661c52008-02-01 23:09:17 +01001213 if (thislen > len)
1214 thislen = len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001215
Bartlomiej Zolnierkiewicz8606ab02007-12-24 15:23:44 +01001216 if (ireason == 0) {
Bartlomiej Zolnierkiewicz68661c52008-02-01 23:09:17 +01001217 write = 1;
1218 xferfunc = HWIF(drive)->atapi_output_bytes;
1219 } else if (ireason == 2) {
1220 write = 0;
1221 xferfunc = HWIF(drive)->atapi_input_bytes;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001222 }
1223
Bartlomiej Zolnierkiewicz68661c52008-02-01 23:09:17 +01001224 if (xferfunc) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001225 if (!rq->data) {
Bartlomiej Zolnierkiewiczf1071e62008-02-01 23:09:17 +01001226 printk(KERN_ERR "%s: confused, missing data\n",
1227 drive->name);
Bartlomiej Zolnierkiewicz68661c52008-02-01 23:09:17 +01001228 blk_dump_rq_flags(rq, write ? "cdrom_pc_intr, write"
1229 : "cdrom_pc_intr, read");
Bartlomiej Zolnierkiewiczf1071e62008-02-01 23:09:17 +01001230 goto pad;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001231 }
1232 /* Transfer the data. */
Bartlomiej Zolnierkiewicz68661c52008-02-01 23:09:17 +01001233 xferfunc(drive, rq->data, thislen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001234
Linus Torvalds1da177e2005-04-16 15:20:36 -07001235 /* Keep count of how much data we've moved. */
Bartlomiej Zolnierkiewicz5a5222d2008-02-01 23:09:17 +01001236 len -= thislen;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001237 rq->data += thislen;
1238 rq->data_len -= thislen;
1239
Bartlomiej Zolnierkiewicz68661c52008-02-01 23:09:17 +01001240 if (write && blk_sense_request(rq))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001241 rq->sense_len += thislen;
1242 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001243 printk (KERN_ERR "%s: cdrom_pc_intr: The drive "
Rachita Kothiyal1ad55442006-06-23 02:02:56 -07001244 "appears confused (ireason = 0x%02x). "
1245 "Trying to recover by ending request.\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001246 drive->name, ireason);
Jens Axboe4aff5e22006-08-10 08:44:47 +02001247 rq->cmd_flags |= REQ_FAILED;
Rachita Kothiyal1ad55442006-06-23 02:02:56 -07001248 cdrom_end_request(drive, 0);
1249 return ide_stopped;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001250 }
Bartlomiej Zolnierkiewiczf1071e62008-02-01 23:09:17 +01001251pad:
Bartlomiej Zolnierkiewicz5a5222d2008-02-01 23:09:17 +01001252 /*
1253 * If we haven't moved enough data to satisfy the drive,
1254 * add some padding.
1255 */
1256 if (len > 0)
1257 ide_cd_pad_transfer(drive, xferfunc, len);
1258
Linus Torvalds1da177e2005-04-16 15:20:36 -07001259 /* Now we wait for another interrupt. */
1260 ide_set_handler(drive, &cdrom_pc_intr, ATAPI_WAIT_PC, cdrom_timer_expiry);
1261 return ide_started;
1262}
1263
1264static ide_startstop_t cdrom_do_pc_continuation (ide_drive_t *drive)
1265{
1266 struct request *rq = HWGROUP(drive)->rq;
1267
1268 if (!rq->timeout)
1269 rq->timeout = ATAPI_WAIT_PC;
1270
1271 /* Send the command to the drive and return. */
1272 return cdrom_transfer_packet_command(drive, rq, &cdrom_pc_intr);
1273}
1274
1275
1276static ide_startstop_t cdrom_do_packet_command (ide_drive_t *drive)
1277{
1278 int len;
1279 struct request *rq = HWGROUP(drive)->rq;
1280 struct cdrom_info *info = drive->driver_data;
1281
1282 info->dma = 0;
Jens Axboe4aff5e22006-08-10 08:44:47 +02001283 rq->cmd_flags &= ~REQ_FAILED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001284 len = rq->data_len;
1285
1286 /* Start sending the command to the drive. */
1287 return cdrom_start_packet_command(drive, len, cdrom_do_pc_continuation);
1288}
1289
1290
Alan Coxdbe217a2006-06-25 05:47:44 -07001291static int cdrom_queue_packet_command(ide_drive_t *drive, struct request *rq)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001292{
1293 struct request_sense sense;
1294 int retries = 10;
Jens Axboe4aff5e22006-08-10 08:44:47 +02001295 unsigned int flags = rq->cmd_flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001296
1297 if (rq->sense == NULL)
1298 rq->sense = &sense;
1299
1300 /* Start of retry loop. */
1301 do {
1302 int error;
1303 unsigned long time = jiffies;
Jens Axboe4aff5e22006-08-10 08:44:47 +02001304 rq->cmd_flags = flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001305
1306 error = ide_do_drive_cmd(drive, rq, ide_wait);
1307 time = jiffies - time;
1308
1309 /* FIXME: we should probably abort/retry or something
1310 * in case of failure */
Jens Axboe4aff5e22006-08-10 08:44:47 +02001311 if (rq->cmd_flags & REQ_FAILED) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001312 /* The request failed. Retry if it was due to a unit
1313 attention status
1314 (usually means media was changed). */
1315 struct request_sense *reqbuf = rq->sense;
1316
1317 if (reqbuf->sense_key == UNIT_ATTENTION)
1318 cdrom_saw_media_change(drive);
1319 else if (reqbuf->sense_key == NOT_READY &&
1320 reqbuf->asc == 4 && reqbuf->ascq != 4) {
1321 /* The drive is in the process of loading
1322 a disk. Retry, but wait a little to give
1323 the drive time to complete the load. */
1324 ssleep(2);
1325 } else {
1326 /* Otherwise, don't retry. */
1327 retries = 0;
1328 }
1329 --retries;
1330 }
1331
1332 /* End of retry loop. */
Jens Axboe4aff5e22006-08-10 08:44:47 +02001333 } while ((rq->cmd_flags & REQ_FAILED) && retries >= 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001334
1335 /* Return an error if the command failed. */
Jens Axboe4aff5e22006-08-10 08:44:47 +02001336 return (rq->cmd_flags & REQ_FAILED) ? -EIO : 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001337}
1338
1339/*
1340 * Write handling
1341 */
Arjan van de Ven858119e2006-01-14 13:20:43 -08001342static int cdrom_write_check_ireason(ide_drive_t *drive, int len, int ireason)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001343{
1344 /* Two notes about IDE interrupt reason here - 0 means that
1345 * the drive wants to receive data from us, 2 means that
1346 * the drive is expecting to transfer data to us.
1347 */
1348 if (ireason == 0)
1349 return 0;
1350 else if (ireason == 2) {
Bartlomiej Zolnierkiewicz5a5222d2008-02-01 23:09:17 +01001351 ide_hwif_t *hwif = drive->hwif;
1352
Linus Torvalds1da177e2005-04-16 15:20:36 -07001353 /* Whoops... The drive wants to send data. */
Bartlomiej Zolnierkiewicz35379c02007-12-24 15:23:43 +01001354 printk(KERN_ERR "%s: %s: wrong transfer direction!\n",
1355 drive->name, __FUNCTION__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001356
Bartlomiej Zolnierkiewicz5a5222d2008-02-01 23:09:17 +01001357 ide_cd_pad_transfer(drive, hwif->atapi_input_bytes, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001358 } else {
1359 /* Drive wants a command packet, or invalid ireason... */
Bartlomiej Zolnierkiewicz35379c02007-12-24 15:23:43 +01001360 printk(KERN_ERR "%s: %s: bad interrupt reason 0x%02x\n",
1361 drive->name, __FUNCTION__, ireason);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001362 }
1363
1364 cdrom_end_request(drive, 0);
1365 return 1;
1366}
1367
Kiyoshi Uedaaaa04c22007-12-11 17:51:23 -05001368/*
1369 * Called from blk_end_request_callback() after the data of the request
1370 * is completed and before the request is completed.
1371 * By returning value '1', blk_end_request_callback() returns immediately
1372 * without completing the request.
1373 */
1374static int cdrom_newpc_intr_dummy_cb(struct request *rq)
1375{
1376 return 1;
1377}
1378
Linus Torvalds1da177e2005-04-16 15:20:36 -07001379/*
1380 * best way to deal with dma that is not sector aligned right now... note
1381 * that in this path we are not using ->data or ->buffer at all. this irs
1382 * can replace cdrom_pc_intr, cdrom_read_intr, and cdrom_write_intr in the
1383 * future.
1384 */
1385static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
1386{
1387 struct cdrom_info *info = drive->driver_data;
1388 struct request *rq = HWGROUP(drive)->rq;
1389 int dma_error, dma, stat, ireason, len, thislen;
1390 u8 lowcyl, highcyl;
1391 xfer_func_t *xferfunc;
1392 unsigned long flags;
1393
1394 /* Check for errors. */
1395 dma_error = 0;
1396 dma = info->dma;
1397 if (dma) {
1398 info->dma = 0;
1399 dma_error = HWIF(drive)->ide_dma_end(drive);
Bartlomiej Zolnierkiewiczeba15fb2008-02-01 23:09:17 +01001400 if (dma_error) {
1401 printk(KERN_ERR "%s: DMA %s error\n", drive->name,
1402 rq_data_dir(rq) ? "write" : "read");
1403 ide_dma_off(drive);
1404 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001405 }
1406
1407 if (cdrom_decode_status(drive, 0, &stat))
1408 return ide_stopped;
1409
1410 /*
1411 * using dma, transfer is complete now
1412 */
1413 if (dma) {
Bartlomiej Zolnierkiewiczeba15fb2008-02-01 23:09:17 +01001414 if (dma_error)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001415 return ide_error(drive, "dma error", stat);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001416
Kiyoshi Uedaaaa04c22007-12-11 17:51:23 -05001417 spin_lock_irqsave(&ide_lock, flags);
1418 if (__blk_end_request(rq, 0, rq->data_len))
1419 BUG();
1420 HWGROUP(drive)->rq = NULL;
1421 spin_unlock_irqrestore(&ide_lock, flags);
1422
1423 return ide_stopped;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001424 }
1425
1426 /*
1427 * ok we fall to pio :/
1428 */
1429 ireason = HWIF(drive)->INB(IDE_IREASON_REG) & 0x3;
1430 lowcyl = HWIF(drive)->INB(IDE_BCOUNTL_REG);
1431 highcyl = HWIF(drive)->INB(IDE_BCOUNTH_REG);
1432
1433 len = lowcyl + (256 * highcyl);
1434 thislen = rq->data_len;
1435 if (thislen > len)
1436 thislen = len;
1437
1438 /*
1439 * If DRQ is clear, the command has completed.
1440 */
Kiyoshi Uedaaaa04c22007-12-11 17:51:23 -05001441 if ((stat & DRQ_STAT) == 0) {
1442 spin_lock_irqsave(&ide_lock, flags);
Jens Axboe4f4f6c22008-01-31 13:57:51 +01001443 if (__blk_end_request(rq, 0, rq->data_len))
Kiyoshi Uedaaaa04c22007-12-11 17:51:23 -05001444 BUG();
1445 HWGROUP(drive)->rq = NULL;
1446 spin_unlock_irqrestore(&ide_lock, flags);
1447
1448 return ide_stopped;
1449 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001450
1451 /*
1452 * check which way to transfer data
1453 */
1454 if (rq_data_dir(rq) == WRITE) {
1455 /*
1456 * write to drive
1457 */
1458 if (cdrom_write_check_ireason(drive, len, ireason))
1459 return ide_stopped;
1460
1461 xferfunc = HWIF(drive)->atapi_output_bytes;
1462 } else {
1463 /*
1464 * read from drive
1465 */
1466 if (cdrom_read_check_ireason(drive, len, ireason))
1467 return ide_stopped;
1468
1469 xferfunc = HWIF(drive)->atapi_input_bytes;
1470 }
1471
1472 /*
1473 * transfer data
1474 */
1475 while (thislen > 0) {
1476 int blen = blen = rq->data_len;
1477 char *ptr = rq->data;
1478
1479 /*
1480 * bio backed?
1481 */
1482 if (rq->bio) {
1483 ptr = bio_data(rq->bio);
1484 blen = bio_iovec(rq->bio)->bv_len;
1485 }
1486
1487 if (!ptr) {
1488 printk(KERN_ERR "%s: confused, missing data\n", drive->name);
1489 break;
1490 }
1491
1492 if (blen > thislen)
1493 blen = thislen;
1494
1495 xferfunc(drive, ptr, blen);
1496
1497 thislen -= blen;
1498 len -= blen;
1499 rq->data_len -= blen;
1500
1501 if (rq->bio)
Kiyoshi Uedaaaa04c22007-12-11 17:51:23 -05001502 /*
1503 * The request can't be completed until DRQ is cleared.
1504 * So complete the data, but don't complete the request
1505 * using the dummy function for the callback feature
1506 * of blk_end_request_callback().
1507 */
1508 blk_end_request_callback(rq, 0, blen,
1509 cdrom_newpc_intr_dummy_cb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001510 else
1511 rq->data += blen;
1512 }
1513
1514 /*
1515 * pad, if necessary
1516 */
Bartlomiej Zolnierkiewicz5a5222d2008-02-01 23:09:17 +01001517 if (len > 0)
1518 ide_cd_pad_transfer(drive, xferfunc, len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001519
Eric Sesterhenn125e1872006-06-23 02:06:06 -07001520 BUG_ON(HWGROUP(drive)->handler != NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001521
1522 ide_set_handler(drive, cdrom_newpc_intr, rq->timeout, NULL);
1523 return ide_started;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001524}
1525
1526static ide_startstop_t cdrom_write_intr(ide_drive_t *drive)
1527{
1528 int stat, ireason, len, sectors_to_transfer, uptodate;
1529 struct cdrom_info *info = drive->driver_data;
1530 int dma_error = 0, dma = info->dma;
1531 u8 lowcyl = 0, highcyl = 0;
1532
1533 struct request *rq = HWGROUP(drive)->rq;
1534
1535 /* Check for errors. */
1536 if (dma) {
1537 info->dma = 0;
Bartlomiej Zolnierkiewiczb481b232007-12-24 15:23:43 +01001538 dma_error = HWIF(drive)->ide_dma_end(drive);
1539 if (dma_error) {
1540 printk(KERN_ERR "%s: DMA write error\n", drive->name);
Bartlomiej Zolnierkiewicz7469aaf2007-02-17 02:40:26 +01001541 ide_dma_off(drive);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001542 }
1543 }
1544
1545 if (cdrom_decode_status(drive, 0, &stat))
1546 return ide_stopped;
1547
1548 /*
1549 * using dma, transfer is complete now
1550 */
1551 if (dma) {
1552 if (dma_error)
1553 return ide_error(drive, "dma error", stat);
1554
1555 ide_end_request(drive, 1, rq->nr_sectors);
1556 return ide_stopped;
1557 }
1558
1559 /* Read the interrupt reason and the transfer length. */
Bartlomiej Zolnierkiewicz31a71192007-12-24 15:23:43 +01001560 ireason = HWIF(drive)->INB(IDE_IREASON_REG) & 0x3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001561 lowcyl = HWIF(drive)->INB(IDE_BCOUNTL_REG);
1562 highcyl = HWIF(drive)->INB(IDE_BCOUNTH_REG);
1563
1564 len = lowcyl + (256 * highcyl);
1565
1566 /* If DRQ is clear, the command has completed. */
1567 if ((stat & DRQ_STAT) == 0) {
1568 /* If we're not done writing, complain.
1569 * Otherwise, complete the command normally.
1570 */
1571 uptodate = 1;
1572 if (rq->current_nr_sectors > 0) {
Bartlomiej Zolnierkiewiczb481b232007-12-24 15:23:43 +01001573 printk(KERN_ERR "%s: %s: data underrun (%d blocks)\n",
1574 drive->name, __FUNCTION__,
1575 rq->current_nr_sectors);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001576 uptodate = 0;
1577 }
1578 cdrom_end_request(drive, uptodate);
1579 return ide_stopped;
1580 }
1581
1582 /* Check that the drive is expecting to do the same thing we are. */
1583 if (cdrom_write_check_ireason(drive, len, ireason))
1584 return ide_stopped;
1585
1586 sectors_to_transfer = len / SECTOR_SIZE;
1587
1588 /*
1589 * now loop and write out the data
1590 */
1591 while (sectors_to_transfer > 0) {
1592 int this_transfer;
1593
1594 if (!rq->current_nr_sectors) {
Bartlomiej Zolnierkiewiczb481b232007-12-24 15:23:43 +01001595 printk(KERN_ERR "%s: %s: confused, missing data\n",
1596 drive->name, __FUNCTION__);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001597 break;
1598 }
1599
1600 /*
1601 * Figure out how many sectors we can transfer
1602 */
1603 this_transfer = min_t(int, sectors_to_transfer, rq->current_nr_sectors);
1604
1605 while (this_transfer > 0) {
1606 HWIF(drive)->atapi_output_bytes(drive, rq->buffer, SECTOR_SIZE);
1607 rq->buffer += SECTOR_SIZE;
1608 --rq->nr_sectors;
1609 --rq->current_nr_sectors;
1610 ++rq->sector;
1611 --this_transfer;
1612 --sectors_to_transfer;
1613 }
1614
1615 /*
1616 * current buffer complete, move on
1617 */
1618 if (rq->current_nr_sectors == 0 && rq->nr_sectors)
1619 cdrom_end_request(drive, 1);
1620 }
1621
1622 /* re-arm handler */
1623 ide_set_handler(drive, &cdrom_write_intr, ATAPI_WAIT_PC, NULL);
1624 return ide_started;
1625}
1626
1627static ide_startstop_t cdrom_start_write_cont(ide_drive_t *drive)
1628{
1629 struct request *rq = HWGROUP(drive)->rq;
1630
1631#if 0 /* the immediate bit */
1632 rq->cmd[1] = 1 << 3;
1633#endif
1634 rq->timeout = ATAPI_WAIT_PC;
1635
1636 return cdrom_transfer_packet_command(drive, rq, cdrom_write_intr);
1637}
1638
1639static ide_startstop_t cdrom_start_write(ide_drive_t *drive, struct request *rq)
1640{
1641 struct cdrom_info *info = drive->driver_data;
1642 struct gendisk *g = info->disk;
1643 unsigned short sectors_per_frame = queue_hardsect_size(drive->queue) >> SECTOR_BITS;
1644
1645 /*
1646 * writes *must* be hardware frame aligned
1647 */
1648 if ((rq->nr_sectors & (sectors_per_frame - 1)) ||
1649 (rq->sector & (sectors_per_frame - 1))) {
1650 cdrom_end_request(drive, 0);
1651 return ide_stopped;
1652 }
1653
1654 /*
1655 * disk has become write protected
1656 */
1657 if (g->policy) {
1658 cdrom_end_request(drive, 0);
1659 return ide_stopped;
1660 }
1661
Linus Torvalds1da177e2005-04-16 15:20:36 -07001662 info->nsectors_buffered = 0;
1663
1664 /* use dma, if possible. we don't need to check more, since we
1665 * know that the transfer is always (at least!) frame aligned */
1666 info->dma = drive->using_dma ? 1 : 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001667
1668 info->devinfo.media_written = 1;
1669
1670 /* Start sending the write request to the drive. */
1671 return cdrom_start_packet_command(drive, 32768, cdrom_start_write_cont);
1672}
1673
1674static ide_startstop_t cdrom_do_newpc_cont(ide_drive_t *drive)
1675{
1676 struct request *rq = HWGROUP(drive)->rq;
1677
1678 if (!rq->timeout)
1679 rq->timeout = ATAPI_WAIT_PC;
1680
1681 return cdrom_transfer_packet_command(drive, rq, cdrom_newpc_intr);
1682}
1683
1684static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
1685{
1686 struct cdrom_info *info = drive->driver_data;
1687
Jens Axboe4aff5e22006-08-10 08:44:47 +02001688 rq->cmd_flags |= REQ_QUIET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001689
1690 info->dma = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001691
1692 /*
1693 * sg request
1694 */
1695 if (rq->bio) {
1696 int mask = drive->queue->dma_alignment;
1697 unsigned long addr = (unsigned long) page_address(bio_page(rq->bio));
1698
Linus Torvalds1da177e2005-04-16 15:20:36 -07001699 info->dma = drive->using_dma;
1700
1701 /*
1702 * check if dma is safe
Linus Torvalds5d9e4ea2005-05-27 07:36:17 -07001703 *
1704 * NOTE! The "len" and "addr" checks should possibly have
1705 * separate masks.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001706 */
Jens Axboe4e7c6812005-05-31 17:47:36 +02001707 if ((rq->data_len & 15) || (addr & mask))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001708 info->dma = 0;
1709 }
1710
1711 /* Start sending the command to the drive. */
1712 return cdrom_start_packet_command(drive, rq->data_len, cdrom_do_newpc_cont);
1713}
1714
1715/****************************************************************************
1716 * cdrom driver request routine.
1717 */
1718static ide_startstop_t
1719ide_do_rw_cdrom (ide_drive_t *drive, struct request *rq, sector_t block)
1720{
1721 ide_startstop_t action;
1722 struct cdrom_info *info = drive->driver_data;
1723
1724 if (blk_fs_request(rq)) {
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01001725 if (info->cd_flags & IDE_CD_FLAG_SEEKING) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001726 unsigned long elapsed = jiffies - info->start_seek;
1727 int stat = HWIF(drive)->INB(IDE_STATUS_REG);
1728
1729 if ((stat & SEEK_STAT) != SEEK_STAT) {
1730 if (elapsed < IDECD_SEEK_TIMEOUT) {
1731 ide_stall_queue(drive, IDECD_SEEK_TIMER);
1732 return ide_stopped;
1733 }
1734 printk (KERN_ERR "%s: DSC timeout\n", drive->name);
1735 }
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01001736 info->cd_flags &= ~IDE_CD_FLAG_SEEKING;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001737 }
1738 if ((rq_data_dir(rq) == READ) && IDE_LARGE_SEEK(info->last_block, block, IDECD_SEEK_THRESHOLD) && drive->dsc_overlap) {
1739 action = cdrom_start_seek(drive, block);
1740 } else {
1741 if (rq_data_dir(rq) == READ)
1742 action = cdrom_start_read(drive, block);
1743 else
1744 action = cdrom_start_write(drive, rq);
1745 }
1746 info->last_block = block;
1747 return action;
Jens Axboecea28852006-10-12 15:08:45 +02001748 } else if (rq->cmd_type == REQ_TYPE_SENSE ||
1749 rq->cmd_type == REQ_TYPE_ATA_PC) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001750 return cdrom_do_packet_command(drive);
Jens Axboe4aff5e22006-08-10 08:44:47 +02001751 } else if (blk_pc_request(rq)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001752 return cdrom_do_block_pc(drive, rq);
Jens Axboe4aff5e22006-08-10 08:44:47 +02001753 } else if (blk_special_request(rq)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001754 /*
1755 * right now this can only be a reset...
1756 */
1757 cdrom_end_request(drive, 1);
1758 return ide_stopped;
1759 }
1760
1761 blk_dump_rq_flags(rq, "ide-cd bad flags");
1762 cdrom_end_request(drive, 0);
1763 return ide_stopped;
1764}
1765
1766
1767
1768/****************************************************************************
1769 * Ioctl handling.
1770 *
1771 * Routines which queue packet commands take as a final argument a pointer
1772 * to a request_sense struct. If execution of the command results
1773 * in an error with a CHECK CONDITION status, this structure will be filled
1774 * with the results of the subsequent request sense command. The pointer
1775 * can also be NULL, in which case no sense information is returned.
1776 */
1777
Linus Torvalds1da177e2005-04-16 15:20:36 -07001778static 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
Linus Torvalds1da177e2005-04-16 15:20:36 -07001799static inline
1800void lba_to_msf (int lba, byte *m, byte *s, byte *f)
1801{
1802 lba += CD_MSF_OFFSET;
1803 lba &= 0xffffff; /* negative lbas use only 24 bits */
1804 *m = lba / (CD_SECS * CD_FRAMES);
1805 lba %= (CD_SECS * CD_FRAMES);
1806 *s = lba / CD_FRAMES;
1807 *f = lba % CD_FRAMES;
1808}
1809
1810
1811static inline
1812int msf_to_lba (byte m, byte s, byte f)
1813{
1814 return (((m * CD_SECS) + s) * CD_FRAMES + f) - CD_MSF_OFFSET;
1815}
1816
1817static int cdrom_check_status(ide_drive_t *drive, struct request_sense *sense)
1818{
1819 struct request req;
1820 struct cdrom_info *info = drive->driver_data;
1821 struct cdrom_device_info *cdi = &info->devinfo;
1822
1823 cdrom_prepare_request(drive, &req);
1824
1825 req.sense = sense;
1826 req.cmd[0] = GPCMD_TEST_UNIT_READY;
Jens Axboe4aff5e22006-08-10 08:44:47 +02001827 req.cmd_flags |= REQ_QUIET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001828
Bartlomiej Zolnierkiewiczcdf60002008-02-01 23:09:22 +01001829 /*
1830 * Sanyo 3 CD changer uses byte 7 of TEST_UNIT_READY to
1831 * switch CDs instead of supporting the LOAD_UNLOAD opcode.
1832 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001833 req.cmd[7] = cdi->sanyo_slot % 3;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001834
1835 return cdrom_queue_packet_command(drive, &req);
1836}
1837
1838
1839/* Lock the door if LOCKFLAG is nonzero; unlock it otherwise. */
1840static int
1841cdrom_lockdoor(ide_drive_t *drive, int lockflag, struct request_sense *sense)
1842{
Bartlomiej Zolnierkiewicz4fe67172008-02-01 23:09:21 +01001843 struct cdrom_info *cd = drive->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001844 struct request_sense my_sense;
1845 struct request req;
1846 int stat;
1847
1848 if (sense == NULL)
1849 sense = &my_sense;
1850
1851 /* If the drive cannot lock the door, just pretend. */
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01001852 if (cd->cd_flags & IDE_CD_FLAG_NO_DOORLOCK) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001853 stat = 0;
1854 } else {
1855 cdrom_prepare_request(drive, &req);
1856 req.sense = sense;
1857 req.cmd[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL;
1858 req.cmd[4] = lockflag ? 1 : 0;
1859 stat = cdrom_queue_packet_command(drive, &req);
1860 }
1861
1862 /* If we got an illegal field error, the drive
1863 probably cannot lock the door. */
1864 if (stat != 0 &&
1865 sense->sense_key == ILLEGAL_REQUEST &&
1866 (sense->asc == 0x24 || sense->asc == 0x20)) {
1867 printk (KERN_ERR "%s: door locking not supported\n",
1868 drive->name);
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01001869 cd->cd_flags |= IDE_CD_FLAG_NO_DOORLOCK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001870 stat = 0;
1871 }
1872
1873 /* no medium, that's alright. */
1874 if (stat != 0 && sense->sense_key == NOT_READY && sense->asc == 0x3a)
1875 stat = 0;
1876
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01001877 if (stat == 0) {
1878 if (lockflag)
1879 cd->cd_flags |= IDE_CD_FLAG_DOOR_LOCKED;
1880 else
1881 cd->cd_flags &= ~IDE_CD_FLAG_DOOR_LOCKED;
1882 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001883
1884 return stat;
1885}
1886
1887
1888/* Eject the disk if EJECTFLAG is 0.
1889 If EJECTFLAG is 1, try to reload the disk. */
1890static int cdrom_eject(ide_drive_t *drive, int ejectflag,
1891 struct request_sense *sense)
1892{
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01001893 struct cdrom_info *cd = drive->driver_data;
1894 struct cdrom_device_info *cdi = &cd->devinfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001895 struct request req;
1896 char loej = 0x02;
1897
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01001898 if ((cd->cd_flags & IDE_CD_FLAG_NO_EJECT) && !ejectflag)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001899 return -EDRIVE_CANT_DO_THIS;
Bartlomiej Zolnierkiewicz4fe67172008-02-01 23:09:21 +01001900
Linus Torvalds1da177e2005-04-16 15:20:36 -07001901 /* reload fails on some drives, if the tray is locked */
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01001902 if ((cd->cd_flags & IDE_CD_FLAG_DOOR_LOCKED) && ejectflag)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001903 return 0;
1904
1905 cdrom_prepare_request(drive, &req);
1906
1907 /* only tell drive to close tray if open, if it can do that */
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01001908 if (ejectflag && (cdi->mask & CDC_CLOSE_TRAY))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001909 loej = 0;
1910
1911 req.sense = sense;
1912 req.cmd[0] = GPCMD_START_STOP_UNIT;
1913 req.cmd[4] = loej | (ejectflag != 0);
1914 return cdrom_queue_packet_command(drive, &req);
1915}
1916
1917static int cdrom_read_capacity(ide_drive_t *drive, unsigned long *capacity,
1918 unsigned long *sectors_per_frame,
1919 struct request_sense *sense)
1920{
1921 struct {
1922 __u32 lba;
1923 __u32 blocklen;
1924 } capbuf;
1925
1926 int stat;
1927 struct request req;
1928
1929 cdrom_prepare_request(drive, &req);
1930
1931 req.sense = sense;
1932 req.cmd[0] = GPCMD_READ_CDVD_CAPACITY;
1933 req.data = (char *)&capbuf;
1934 req.data_len = sizeof(capbuf);
Jens Axboe4aff5e22006-08-10 08:44:47 +02001935 req.cmd_flags |= REQ_QUIET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001936
1937 stat = cdrom_queue_packet_command(drive, &req);
1938 if (stat == 0) {
1939 *capacity = 1 + be32_to_cpu(capbuf.lba);
1940 *sectors_per_frame =
1941 be32_to_cpu(capbuf.blocklen) >> SECTOR_BITS;
1942 }
1943
1944 return stat;
1945}
1946
1947static int cdrom_read_tocentry(ide_drive_t *drive, int trackno, int msf_flag,
1948 int format, char *buf, int buflen,
1949 struct request_sense *sense)
1950{
1951 struct request req;
1952
1953 cdrom_prepare_request(drive, &req);
1954
1955 req.sense = sense;
1956 req.data = buf;
1957 req.data_len = buflen;
Jens Axboe4aff5e22006-08-10 08:44:47 +02001958 req.cmd_flags |= REQ_QUIET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001959 req.cmd[0] = GPCMD_READ_TOC_PMA_ATIP;
1960 req.cmd[6] = trackno;
1961 req.cmd[7] = (buflen >> 8);
1962 req.cmd[8] = (buflen & 0xff);
1963 req.cmd[9] = (format << 6);
1964
1965 if (msf_flag)
1966 req.cmd[1] = 2;
1967
1968 return cdrom_queue_packet_command(drive, &req);
1969}
1970
1971
1972/* Try to read the entire TOC for the disk into our internal buffer. */
1973static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense)
1974{
1975 int stat, ntracks, i;
1976 struct cdrom_info *info = drive->driver_data;
1977 struct cdrom_device_info *cdi = &info->devinfo;
1978 struct atapi_toc *toc = info->toc;
1979 struct {
1980 struct atapi_toc_header hdr;
1981 struct atapi_toc_entry ent;
1982 } ms_tmp;
1983 long last_written;
1984 unsigned long sectors_per_frame = SECTORS_PER_FRAME;
1985
1986 if (toc == NULL) {
1987 /* Try to allocate space. */
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08001988 toc = kmalloc(sizeof(struct atapi_toc), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001989 if (toc == NULL) {
1990 printk (KERN_ERR "%s: No cdrom TOC buffer!\n", drive->name);
1991 return -ENOMEM;
1992 }
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08001993 info->toc = toc;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001994 }
1995
1996 /* Check to see if the existing data is still valid.
1997 If it is, just return. */
1998 (void) cdrom_check_status(drive, sense);
1999
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002000 if (info->cd_flags & IDE_CD_FLAG_TOC_VALID)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002001 return 0;
2002
2003 /* Try to get the total cdrom capacity and sector size. */
2004 stat = cdrom_read_capacity(drive, &toc->capacity, &sectors_per_frame,
2005 sense);
2006 if (stat)
2007 toc->capacity = 0x1fffff;
2008
2009 set_capacity(info->disk, toc->capacity * sectors_per_frame);
Alan Coxdbe217a2006-06-25 05:47:44 -07002010 /* Save a private copy of te TOC capacity for error handling */
2011 drive->probed_capacity = toc->capacity * sectors_per_frame;
2012
Linus Torvalds1da177e2005-04-16 15:20:36 -07002013 blk_queue_hardsect_size(drive->queue,
2014 sectors_per_frame << SECTOR_BITS);
2015
2016 /* First read just the header, so we know how long the TOC is. */
2017 stat = cdrom_read_tocentry(drive, 0, 1, 0, (char *) &toc->hdr,
2018 sizeof(struct atapi_toc_header), sense);
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002019 if (stat)
2020 return stat;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002021
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002022 if (info->cd_flags & IDE_CD_FLAG_TOCTRACKS_AS_BCD) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002023 toc->hdr.first_track = bcd2bin(toc->hdr.first_track);
2024 toc->hdr.last_track = bcd2bin(toc->hdr.last_track);
2025 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002026
2027 ntracks = toc->hdr.last_track - toc->hdr.first_track + 1;
2028 if (ntracks <= 0)
2029 return -EIO;
2030 if (ntracks > MAX_TRACKS)
2031 ntracks = MAX_TRACKS;
2032
2033 /* Now read the whole schmeer. */
2034 stat = cdrom_read_tocentry(drive, toc->hdr.first_track, 1, 0,
2035 (char *)&toc->hdr,
2036 sizeof(struct atapi_toc_header) +
2037 (ntracks + 1) *
2038 sizeof(struct atapi_toc_entry), sense);
2039
2040 if (stat && toc->hdr.first_track > 1) {
2041 /* Cds with CDI tracks only don't have any TOC entries,
2042 despite of this the returned values are
2043 first_track == last_track = number of CDI tracks + 1,
2044 so that this case is indistinguishable from the same
2045 layout plus an additional audio track.
2046 If we get an error for the regular case, we assume
2047 a CDI without additional audio tracks. In this case
2048 the readable TOC is empty (CDI tracks are not included)
Jan Engelhardt96de0e22007-10-19 23:21:04 +02002049 and only holds the Leadout entry. Heiko Eißfeldt */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002050 ntracks = 0;
2051 stat = cdrom_read_tocentry(drive, CDROM_LEADOUT, 1, 0,
2052 (char *)&toc->hdr,
2053 sizeof(struct atapi_toc_header) +
2054 (ntracks + 1) *
2055 sizeof(struct atapi_toc_entry),
2056 sense);
Bartlomiej Zolnierkiewiczcdf60002008-02-01 23:09:22 +01002057 if (stat)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002058 return stat;
Bartlomiej Zolnierkiewiczcdf60002008-02-01 23:09:22 +01002059
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002060 if (info->cd_flags & IDE_CD_FLAG_TOCTRACKS_AS_BCD) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002061 toc->hdr.first_track = bin2bcd(CDROM_LEADOUT);
2062 toc->hdr.last_track = bin2bcd(CDROM_LEADOUT);
Bartlomiej Zolnierkiewiczcdf60002008-02-01 23:09:22 +01002063 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002064 toc->hdr.first_track = CDROM_LEADOUT;
2065 toc->hdr.last_track = CDROM_LEADOUT;
2066 }
2067 }
2068
2069 if (stat)
2070 return stat;
2071
2072 toc->hdr.toc_length = ntohs (toc->hdr.toc_length);
2073
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002074 if (info->cd_flags & IDE_CD_FLAG_TOCTRACKS_AS_BCD) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002075 toc->hdr.first_track = bcd2bin(toc->hdr.first_track);
2076 toc->hdr.last_track = bcd2bin(toc->hdr.last_track);
2077 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002078
Bartlomiej Zolnierkiewiczcdf60002008-02-01 23:09:22 +01002079 for (i = 0; i <= ntracks; i++) {
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002080 if (info->cd_flags & IDE_CD_FLAG_TOCADDR_AS_BCD) {
2081 if (info->cd_flags & IDE_CD_FLAG_TOCTRACKS_AS_BCD)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002082 toc->ent[i].track = bcd2bin(toc->ent[i].track);
2083 msf_from_bcd(&toc->ent[i].addr.msf);
2084 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002085 toc->ent[i].addr.lba = msf_to_lba (toc->ent[i].addr.msf.minute,
2086 toc->ent[i].addr.msf.second,
2087 toc->ent[i].addr.msf.frame);
2088 }
2089
2090 /* Read the multisession information. */
2091 if (toc->hdr.first_track != CDROM_LEADOUT) {
2092 /* Read the multisession information. */
2093 stat = cdrom_read_tocentry(drive, 0, 0, 1, (char *)&ms_tmp,
2094 sizeof(ms_tmp), sense);
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002095 if (stat)
2096 return stat;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002097
2098 toc->last_session_lba = be32_to_cpu(ms_tmp.ent.addr.lba);
2099 } else {
2100 ms_tmp.hdr.first_track = ms_tmp.hdr.last_track = CDROM_LEADOUT;
2101 toc->last_session_lba = msf_to_lba(0, 2, 0); /* 0m 2s 0f */
2102 }
2103
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002104 if (info->cd_flags & IDE_CD_FLAG_TOCADDR_AS_BCD) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002105 /* Re-read multisession information using MSF format */
2106 stat = cdrom_read_tocentry(drive, 0, 1, 1, (char *)&ms_tmp,
2107 sizeof(ms_tmp), sense);
2108 if (stat)
2109 return stat;
2110
2111 msf_from_bcd (&ms_tmp.ent.addr.msf);
2112 toc->last_session_lba = msf_to_lba(ms_tmp.ent.addr.msf.minute,
2113 ms_tmp.ent.addr.msf.second,
2114 ms_tmp.ent.addr.msf.frame);
2115 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002116
2117 toc->xa_flag = (ms_tmp.hdr.first_track != ms_tmp.hdr.last_track);
2118
2119 /* Now try to get the total cdrom capacity. */
2120 stat = cdrom_get_last_written(cdi, &last_written);
2121 if (!stat && (last_written > toc->capacity)) {
2122 toc->capacity = last_written;
2123 set_capacity(info->disk, toc->capacity * sectors_per_frame);
Alan Coxdbe217a2006-06-25 05:47:44 -07002124 drive->probed_capacity = toc->capacity * sectors_per_frame;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002125 }
2126
2127 /* Remember that we've read this stuff. */
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002128 info->cd_flags |= IDE_CD_FLAG_TOC_VALID;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002129
2130 return 0;
2131}
2132
2133
2134static int cdrom_read_subchannel(ide_drive_t *drive, int format, char *buf,
2135 int buflen, struct request_sense *sense)
2136{
2137 struct request req;
2138
2139 cdrom_prepare_request(drive, &req);
2140
2141 req.sense = sense;
2142 req.data = buf;
2143 req.data_len = buflen;
2144 req.cmd[0] = GPCMD_READ_SUBCHANNEL;
2145 req.cmd[1] = 2; /* MSF addressing */
2146 req.cmd[2] = 0x40; /* request subQ data */
2147 req.cmd[3] = format;
2148 req.cmd[7] = (buflen >> 8);
2149 req.cmd[8] = (buflen & 0xff);
2150 return cdrom_queue_packet_command(drive, &req);
2151}
2152
2153/* ATAPI cdrom drives are free to select the speed you request or any slower
2154 rate :-( Requesting too fast a speed will _not_ produce an error. */
2155static int cdrom_select_speed(ide_drive_t *drive, int speed,
2156 struct request_sense *sense)
2157{
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002158 struct cdrom_info *cd = drive->driver_data;
2159 struct cdrom_device_info *cdi = &cd->devinfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002160 struct request req;
2161 cdrom_prepare_request(drive, &req);
2162
2163 req.sense = sense;
2164 if (speed == 0)
2165 speed = 0xffff; /* set to max */
2166 else
2167 speed *= 177; /* Nx to kbytes/s */
2168
2169 req.cmd[0] = GPCMD_SET_SPEED;
2170 /* Read Drive speed in kbytes/second MSB */
2171 req.cmd[2] = (speed >> 8) & 0xff;
2172 /* Read Drive speed in kbytes/second LSB */
2173 req.cmd[3] = speed & 0xff;
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002174 if ((cdi->mask & (CDC_CD_R | CDC_CD_RW | CDC_DVD_R)) !=
2175 (CDC_CD_R | CDC_CD_RW | CDC_DVD_R)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002176 /* Write Drive speed in kbytes/second MSB */
2177 req.cmd[4] = (speed >> 8) & 0xff;
2178 /* Write Drive speed in kbytes/second LSB */
2179 req.cmd[5] = speed & 0xff;
2180 }
2181
2182 return cdrom_queue_packet_command(drive, &req);
2183}
2184
2185static int cdrom_play_audio(ide_drive_t *drive, int lba_start, int lba_end)
2186{
2187 struct request_sense sense;
2188 struct request req;
2189
2190 cdrom_prepare_request(drive, &req);
2191
2192 req.sense = &sense;
2193 req.cmd[0] = GPCMD_PLAY_AUDIO_MSF;
2194 lba_to_msf(lba_start, &req.cmd[3], &req.cmd[4], &req.cmd[5]);
2195 lba_to_msf(lba_end-1, &req.cmd[6], &req.cmd[7], &req.cmd[8]);
2196
2197 return cdrom_queue_packet_command(drive, &req);
2198}
2199
2200static int cdrom_get_toc_entry(ide_drive_t *drive, int track,
2201 struct atapi_toc_entry **ent)
2202{
2203 struct cdrom_info *info = drive->driver_data;
2204 struct atapi_toc *toc = info->toc;
2205 int ntracks;
2206
2207 /*
2208 * don't serve cached data, if the toc isn't valid
2209 */
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002210 if ((info->cd_flags & IDE_CD_FLAG_TOC_VALID) == 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002211 return -EINVAL;
2212
2213 /* Check validity of requested track number. */
2214 ntracks = toc->hdr.last_track - toc->hdr.first_track + 1;
2215 if (toc->hdr.first_track == CDROM_LEADOUT) ntracks = 0;
2216 if (track == CDROM_LEADOUT)
2217 *ent = &toc->ent[ntracks];
2218 else if (track < toc->hdr.first_track ||
2219 track > toc->hdr.last_track)
2220 return -EINVAL;
2221 else
2222 *ent = &toc->ent[track - toc->hdr.first_track];
2223
2224 return 0;
2225}
2226
2227/* the generic packet interface to cdrom.c */
2228static int ide_cdrom_packet(struct cdrom_device_info *cdi,
2229 struct packet_command *cgc)
2230{
2231 struct request req;
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002232 ide_drive_t *drive = cdi->handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002233
2234 if (cgc->timeout <= 0)
2235 cgc->timeout = ATAPI_WAIT_PC;
2236
2237 /* here we queue the commands from the uniform CD-ROM
2238 layer. the packet must be complete, as we do not
2239 touch it at all. */
2240 cdrom_prepare_request(drive, &req);
2241 memcpy(req.cmd, cgc->cmd, CDROM_PACKET_SIZE);
2242 if (cgc->sense)
2243 memset(cgc->sense, 0, sizeof(struct request_sense));
2244 req.data = cgc->buffer;
2245 req.data_len = cgc->buflen;
2246 req.timeout = cgc->timeout;
2247
2248 if (cgc->quiet)
Jens Axboe4aff5e22006-08-10 08:44:47 +02002249 req.cmd_flags |= REQ_QUIET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002250
2251 req.sense = cgc->sense;
2252 cgc->stat = cdrom_queue_packet_command(drive, &req);
2253 if (!cgc->stat)
2254 cgc->buflen -= req.data_len;
2255 return cgc->stat;
2256}
2257
2258static
Linus Torvalds1da177e2005-04-16 15:20:36 -07002259int ide_cdrom_audio_ioctl (struct cdrom_device_info *cdi,
2260 unsigned int cmd, void *arg)
2261
2262{
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002263 ide_drive_t *drive = cdi->handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002264 struct cdrom_info *info = drive->driver_data;
2265 int stat;
2266
2267 switch (cmd) {
2268 /*
2269 * emulate PLAY_AUDIO_TI command with PLAY_AUDIO_10, since
2270 * atapi doesn't support it
2271 */
2272 case CDROMPLAYTRKIND: {
2273 unsigned long lba_start, lba_end;
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002274 struct cdrom_ti *ti = arg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002275 struct atapi_toc_entry *first_toc, *last_toc;
2276
2277 stat = cdrom_get_toc_entry(drive, ti->cdti_trk0, &first_toc);
2278 if (stat)
2279 return stat;
2280
2281 stat = cdrom_get_toc_entry(drive, ti->cdti_trk1, &last_toc);
2282 if (stat)
2283 return stat;
2284
2285 if (ti->cdti_trk1 != CDROM_LEADOUT)
2286 ++last_toc;
2287 lba_start = first_toc->addr.lba;
2288 lba_end = last_toc->addr.lba;
2289
2290 if (lba_end <= lba_start)
2291 return -EINVAL;
2292
2293 return cdrom_play_audio(drive, lba_start, lba_end);
2294 }
2295
2296 case CDROMREADTOCHDR: {
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002297 struct cdrom_tochdr *tochdr = arg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002298 struct atapi_toc *toc;
2299
2300 /* Make sure our saved TOC is valid. */
2301 stat = cdrom_read_toc(drive, NULL);
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002302 if (stat)
2303 return stat;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002304
2305 toc = info->toc;
2306 tochdr->cdth_trk0 = toc->hdr.first_track;
2307 tochdr->cdth_trk1 = toc->hdr.last_track;
2308
2309 return 0;
2310 }
2311
2312 case CDROMREADTOCENTRY: {
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002313 struct cdrom_tocentry *tocentry = arg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002314 struct atapi_toc_entry *toce;
2315
2316 stat = cdrom_get_toc_entry(drive, tocentry->cdte_track, &toce);
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002317 if (stat)
2318 return stat;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002319
2320 tocentry->cdte_ctrl = toce->control;
2321 tocentry->cdte_adr = toce->adr;
2322 if (tocentry->cdte_format == CDROM_MSF) {
2323 lba_to_msf (toce->addr.lba,
2324 &tocentry->cdte_addr.msf.minute,
2325 &tocentry->cdte_addr.msf.second,
2326 &tocentry->cdte_addr.msf.frame);
2327 } else
2328 tocentry->cdte_addr.lba = toce->addr.lba;
2329
2330 return 0;
2331 }
2332
2333 default:
2334 return -EINVAL;
2335 }
2336}
2337
2338static
2339int ide_cdrom_reset (struct cdrom_device_info *cdi)
2340{
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002341 ide_drive_t *drive = cdi->handle;
Bartlomiej Zolnierkiewicz0ba11212008-02-01 23:09:21 +01002342 struct cdrom_info *cd = drive->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002343 struct request_sense sense;
2344 struct request req;
2345 int ret;
2346
2347 cdrom_prepare_request(drive, &req);
Jens Axboe4aff5e22006-08-10 08:44:47 +02002348 req.cmd_type = REQ_TYPE_SPECIAL;
2349 req.cmd_flags = REQ_QUIET;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002350 ret = ide_do_drive_cmd(drive, &req, ide_wait);
2351
2352 /*
2353 * A reset will unlock the door. If it was previously locked,
2354 * lock it again.
2355 */
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002356 if (cd->cd_flags & IDE_CD_FLAG_DOOR_LOCKED)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002357 (void) cdrom_lockdoor(drive, 1, &sense);
2358
2359 return ret;
2360}
2361
2362
2363static
2364int ide_cdrom_tray_move (struct cdrom_device_info *cdi, int position)
2365{
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002366 ide_drive_t *drive = cdi->handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002367 struct request_sense sense;
2368
2369 if (position) {
2370 int stat = cdrom_lockdoor(drive, 0, &sense);
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002371 if (stat)
2372 return stat;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002373 }
2374
2375 return cdrom_eject(drive, !position, &sense);
2376}
2377
2378static
2379int ide_cdrom_lock_door (struct cdrom_device_info *cdi, int lock)
2380{
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002381 ide_drive_t *drive = cdi->handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002382 return cdrom_lockdoor(drive, lock, NULL);
2383}
2384
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002385static int ide_cdrom_get_capabilities(ide_drive_t *drive, u8 *buf)
Eric Piel9235e682005-06-23 00:10:29 -07002386{
2387 struct cdrom_info *info = drive->driver_data;
2388 struct cdrom_device_info *cdi = &info->devinfo;
2389 struct packet_command cgc;
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002390 int stat, attempts = 3, size = ATAPI_CAPABILITIES_PAGE_SIZE;
Eric Piel9235e682005-06-23 00:10:29 -07002391
2392 /*
2393 * ACER50 (and others?) require the full spec length mode sense
2394 * page capabilities size, but older drives break.
2395 */
2396 if (!(!strcmp(drive->id->model, "ATAPI CD ROM DRIVE 50X MAX") ||
2397 !strcmp(drive->id->model, "WPI CDS-32X")))
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002398 size -= ATAPI_CAPABILITIES_PAGE_PAD_SIZE;
Eric Piel9235e682005-06-23 00:10:29 -07002399
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002400 init_cdrom_command(&cgc, buf, size, CGC_DATA_UNKNOWN);
Eric Piel9235e682005-06-23 00:10:29 -07002401 do { /* we seem to get stat=0x01,err=0x00 the first time (??) */
2402 stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CAPABILITIES_PAGE, 0);
2403 if (!stat)
2404 break;
2405 } while (--attempts);
2406 return stat;
2407}
2408
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002409static void ide_cdrom_update_speed(ide_drive_t *drive, u8 *buf)
Eric Piel9235e682005-06-23 00:10:29 -07002410{
Bartlomiej Zolnierkiewicz4fe67172008-02-01 23:09:21 +01002411 struct cdrom_info *cd = drive->driver_data;
Bartlomiej Zolnierkiewicz481c8c62008-02-01 23:09:20 +01002412 u16 curspeed, maxspeed;
2413
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002414 curspeed = *(u16 *)&buf[8 + 14];
2415 maxspeed = *(u16 *)&buf[8 + 8];
2416
Eric Piel9235e682005-06-23 00:10:29 -07002417 /* The ACER/AOpen 24X cdrom has the speed fields byte-swapped */
2418 if (!drive->id->model[0] &&
2419 !strncmp(drive->id->fw_rev, "241N", 4)) {
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002420 curspeed = le16_to_cpu(curspeed);
2421 maxspeed = le16_to_cpu(maxspeed);
Eric Piel9235e682005-06-23 00:10:29 -07002422 } else {
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002423 curspeed = be16_to_cpu(curspeed);
2424 maxspeed = be16_to_cpu(maxspeed);
Eric Piel9235e682005-06-23 00:10:29 -07002425 }
Bartlomiej Zolnierkiewicz481c8c62008-02-01 23:09:20 +01002426
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002427 cd->current_speed = (curspeed + (176/2)) / 176;
2428 cd->max_speed = (maxspeed + (176/2)) / 176;
Eric Piel9235e682005-06-23 00:10:29 -07002429}
2430
2431static
Linus Torvalds1da177e2005-04-16 15:20:36 -07002432int ide_cdrom_select_speed (struct cdrom_device_info *cdi, int speed)
2433{
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002434 ide_drive_t *drive = cdi->handle;
Bartlomiej Zolnierkiewicz0ba11212008-02-01 23:09:21 +01002435 struct cdrom_info *cd = drive->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002436 struct request_sense sense;
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002437 u8 buf[ATAPI_CAPABILITIES_PAGE_SIZE];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002438 int stat;
2439
2440 if ((stat = cdrom_select_speed(drive, speed, &sense)) < 0)
2441 return stat;
2442
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002443 if (!ide_cdrom_get_capabilities(drive, buf)) {
2444 ide_cdrom_update_speed(drive, buf);
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002445 cdi->speed = cd->current_speed;
Eric Piel9235e682005-06-23 00:10:29 -07002446 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002447 return 0;
2448}
2449
2450/*
2451 * add logic to try GET_EVENT command first to check for media and tray
2452 * status. this should be supported by newer cd-r/w and all DVD etc
2453 * drives
2454 */
2455static
2456int ide_cdrom_drive_status (struct cdrom_device_info *cdi, int slot_nr)
2457{
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002458 ide_drive_t *drive = cdi->handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002459 struct media_event_desc med;
2460 struct request_sense sense;
2461 int stat;
2462
2463 if (slot_nr != CDSL_CURRENT)
2464 return -EINVAL;
2465
2466 stat = cdrom_check_status(drive, &sense);
2467 if (!stat || sense.sense_key == UNIT_ATTENTION)
2468 return CDS_DISC_OK;
2469
2470 if (!cdrom_get_media_event(cdi, &med)) {
2471 if (med.media_present)
2472 return CDS_DISC_OK;
2473 else if (med.door_open)
2474 return CDS_TRAY_OPEN;
2475 else
2476 return CDS_NO_DISC;
2477 }
2478
2479 if (sense.sense_key == NOT_READY && sense.asc == 0x04 && sense.ascq == 0x04)
2480 return CDS_DISC_OK;
2481
2482 /*
2483 * If not using Mt Fuji extended media tray reports,
2484 * just return TRAY_OPEN since ATAPI doesn't provide
2485 * any other way to detect this...
2486 */
2487 if (sense.sense_key == NOT_READY) {
Alan Coxdbe217a2006-06-25 05:47:44 -07002488 if (sense.asc == 0x3a && sense.ascq == 1)
2489 return CDS_NO_DISC;
2490 else
2491 return CDS_TRAY_OPEN;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002492 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002493 return CDS_DRIVE_NOT_READY;
2494}
2495
2496static
2497int ide_cdrom_get_last_session (struct cdrom_device_info *cdi,
2498 struct cdrom_multisession *ms_info)
2499{
2500 struct atapi_toc *toc;
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002501 ide_drive_t *drive = cdi->handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002502 struct cdrom_info *info = drive->driver_data;
2503 struct request_sense sense;
2504 int ret;
2505
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002506 if ((info->cd_flags & IDE_CD_FLAG_TOC_VALID) == 0 || info->toc == NULL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002507 if ((ret = cdrom_read_toc(drive, &sense)))
2508 return ret;
2509
2510 toc = info->toc;
2511 ms_info->addr.lba = toc->last_session_lba;
2512 ms_info->xa_flag = toc->xa_flag;
2513
2514 return 0;
2515}
2516
2517static
2518int ide_cdrom_get_mcn (struct cdrom_device_info *cdi,
2519 struct cdrom_mcn *mcn_info)
2520{
2521 int stat;
2522 char mcnbuf[24];
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002523 ide_drive_t *drive = cdi->handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002524
2525/* get MCN */
2526 if ((stat = cdrom_read_subchannel(drive, 2, mcnbuf, sizeof (mcnbuf), NULL)))
2527 return stat;
2528
2529 memcpy (mcn_info->medium_catalog_number, mcnbuf+9,
2530 sizeof (mcn_info->medium_catalog_number)-1);
2531 mcn_info->medium_catalog_number[sizeof (mcn_info->medium_catalog_number)-1]
2532 = '\0';
2533
2534 return 0;
2535}
2536
2537
2538
2539/****************************************************************************
2540 * Other driver requests (open, close, check media change).
2541 */
2542
2543static
2544int ide_cdrom_check_media_change_real (struct cdrom_device_info *cdi,
2545 int slot_nr)
2546{
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002547 ide_drive_t *drive = cdi->handle;
Bartlomiej Zolnierkiewicz0ba11212008-02-01 23:09:21 +01002548 struct cdrom_info *cd = drive->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002549 int retval;
Bartlomiej Zolnierkiewicz0ba11212008-02-01 23:09:21 +01002550
Linus Torvalds1da177e2005-04-16 15:20:36 -07002551 if (slot_nr == CDSL_CURRENT) {
2552 (void) cdrom_check_status(drive, NULL);
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002553 retval = (cd->cd_flags & IDE_CD_FLAG_MEDIA_CHANGED) ? 1 : 0;
2554 cd->cd_flags &= ~IDE_CD_FLAG_MEDIA_CHANGED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002555 return retval;
2556 } else {
2557 return -EINVAL;
2558 }
2559}
2560
2561
2562static
2563int ide_cdrom_open_real (struct cdrom_device_info *cdi, int purpose)
2564{
2565 return 0;
2566}
2567
2568/*
2569 * Close down the device. Invalidate all cached blocks.
2570 */
2571
2572static
2573void ide_cdrom_release_real (struct cdrom_device_info *cdi)
2574{
2575 ide_drive_t *drive = cdi->handle;
Bartlomiej Zolnierkiewicz0ba11212008-02-01 23:09:21 +01002576 struct cdrom_info *cd = drive->driver_data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002577
2578 if (!cdi->use_count)
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002579 cd->cd_flags &= ~IDE_CD_FLAG_TOC_VALID;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002580}
2581
Bartlomiej Zolnierkiewicz20e7f7e2008-02-01 23:09:20 +01002582#define IDE_CD_CAPABILITIES \
2583 (CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK | CDC_SELECT_SPEED | \
2584 CDC_SELECT_DISC | CDC_MULTI_SESSION | CDC_MCN | CDC_MEDIA_CHANGED | \
2585 CDC_PLAY_AUDIO | CDC_RESET | CDC_DRIVE_STATUS | CDC_CD_R | \
2586 CDC_CD_RW | CDC_DVD | CDC_DVD_R | CDC_DVD_RAM | CDC_GENERIC_PACKET | \
2587 CDC_MO_DRIVE | CDC_MRW | CDC_MRW_W | CDC_RAM)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002588
Linus Torvalds1da177e2005-04-16 15:20:36 -07002589static struct cdrom_device_ops ide_cdrom_dops = {
2590 .open = ide_cdrom_open_real,
2591 .release = ide_cdrom_release_real,
2592 .drive_status = ide_cdrom_drive_status,
2593 .media_changed = ide_cdrom_check_media_change_real,
2594 .tray_move = ide_cdrom_tray_move,
2595 .lock_door = ide_cdrom_lock_door,
2596 .select_speed = ide_cdrom_select_speed,
2597 .get_last_session = ide_cdrom_get_last_session,
2598 .get_mcn = ide_cdrom_get_mcn,
2599 .reset = ide_cdrom_reset,
2600 .audio_ioctl = ide_cdrom_audio_ioctl,
Bartlomiej Zolnierkiewicz20e7f7e2008-02-01 23:09:20 +01002601 .capability = IDE_CD_CAPABILITIES,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002602 .generic_packet = ide_cdrom_packet,
2603};
2604
2605static int ide_cdrom_register (ide_drive_t *drive, int nslots)
2606{
2607 struct cdrom_info *info = drive->driver_data;
2608 struct cdrom_device_info *devinfo = &info->devinfo;
2609
2610 devinfo->ops = &ide_cdrom_dops;
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002611 devinfo->speed = info->current_speed;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002612 devinfo->capacity = nslots;
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002613 devinfo->handle = drive;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002614 strcpy(devinfo->name, drive->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002615
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002616 if (info->cd_flags & IDE_CD_FLAG_NO_SPEED_SELECT)
Bartlomiej Zolnierkiewicz3cbd8142007-12-24 15:23:43 +01002617 devinfo->mask |= CDC_SELECT_SPEED;
2618
Linus Torvalds1da177e2005-04-16 15:20:36 -07002619 devinfo->disk = info->disk;
2620 return register_cdrom(devinfo);
2621}
2622
2623static
Linus Torvalds1da177e2005-04-16 15:20:36 -07002624int ide_cdrom_probe_capabilities (ide_drive_t *drive)
2625{
Bartlomiej Zolnierkiewicz4fe67172008-02-01 23:09:21 +01002626 struct cdrom_info *cd = drive->driver_data;
2627 struct cdrom_device_info *cdi = &cd->devinfo;
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002628 u8 buf[ATAPI_CAPABILITIES_PAGE_SIZE];
2629 mechtype_t mechtype;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002630 int nslots = 1;
2631
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002632 cdi->mask = (CDC_CD_R | CDC_CD_RW | CDC_DVD | CDC_DVD_R |
2633 CDC_DVD_RAM | CDC_SELECT_DISC | CDC_PLAY_AUDIO |
2634 CDC_MO_DRIVE | CDC_RAM);
2635
Linus Torvalds1da177e2005-04-16 15:20:36 -07002636 if (drive->media == ide_optical) {
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002637 cdi->mask &= ~(CDC_MO_DRIVE | CDC_RAM);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002638 printk(KERN_ERR "%s: ATAPI magneto-optical drive\n", drive->name);
2639 return nslots;
2640 }
2641
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002642 if ((cd->cd_flags & IDE_CD_FLAG_NEC260) ||
Linus Torvalds1da177e2005-04-16 15:20:36 -07002643 !strcmp(drive->id->model,"STINGRAY 8422 IDE 8X CD-ROM 7-27-95")) {
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002644 cd->cd_flags &= ~IDE_CD_FLAG_NO_EJECT;
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002645 cdi->mask &= ~CDC_PLAY_AUDIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002646 return nslots;
2647 }
2648
2649 /*
2650 * we have to cheat a little here. the packet will eventually
2651 * be queued with ide_cdrom_packet(), which extracts the
2652 * drive from cdi->handle. Since this device hasn't been
2653 * registered with the Uniform layer yet, it can't do this.
2654 * Same goes for cdi->ops.
2655 */
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002656 cdi->handle = drive;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002657 cdi->ops = &ide_cdrom_dops;
2658
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002659 if (ide_cdrom_get_capabilities(drive, buf))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002660 return 0;
2661
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002662 if ((buf[8 + 6] & 0x01) == 0)
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002663 cd->cd_flags |= IDE_CD_FLAG_NO_DOORLOCK;
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002664 if (buf[8 + 6] & 0x08)
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002665 cd->cd_flags &= ~IDE_CD_FLAG_NO_EJECT;
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002666 if (buf[8 + 3] & 0x01)
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002667 cdi->mask &= ~CDC_CD_R;
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002668 if (buf[8 + 3] & 0x02)
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002669 cdi->mask &= ~(CDC_CD_RW | CDC_RAM);
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002670 if (buf[8 + 2] & 0x38)
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002671 cdi->mask &= ~CDC_DVD;
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002672 if (buf[8 + 3] & 0x20)
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002673 cdi->mask &= ~(CDC_DVD_RAM | CDC_RAM);
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002674 if (buf[8 + 3] & 0x10)
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002675 cdi->mask &= ~CDC_DVD_R;
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002676 if (buf[8 + 4] & 0x01)
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002677 cdi->mask &= ~CDC_PLAY_AUDIO;
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002678
2679 mechtype = buf[8 + 6] >> 5;
2680 if (mechtype == mechtype_caddy || mechtype == mechtype_popup)
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002681 cdi->mask |= CDC_CLOSE_TRAY;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002682
2683 /* Some drives used by Apple don't advertise audio play
2684 * but they do support reading TOC & audio datas
2685 */
2686 if (strcmp(drive->id->model, "MATSHITADVD-ROM SR-8187") == 0 ||
2687 strcmp(drive->id->model, "MATSHITADVD-ROM SR-8186") == 0 ||
2688 strcmp(drive->id->model, "MATSHITADVD-ROM SR-8176") == 0 ||
2689 strcmp(drive->id->model, "MATSHITADVD-ROM SR-8174") == 0)
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002690 cdi->mask &= ~CDC_PLAY_AUDIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002691
Linus Torvalds1da177e2005-04-16 15:20:36 -07002692 if (cdi->sanyo_slot > 0) {
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002693 cdi->mask &= ~CDC_SELECT_DISC;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002694 nslots = 3;
Bartlomiej Zolnierkiewiczcdf60002008-02-01 23:09:22 +01002695 } else if (mechtype == mechtype_individual_changer ||
2696 mechtype == mechtype_cartridge_changer) {
Bartlomiej Zolnierkiewicz2609d062008-02-01 23:09:19 +01002697 nslots = cdrom_number_of_slots(cdi);
2698 if (nslots > 1)
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002699 cdi->mask &= ~CDC_SELECT_DISC;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002700 }
2701
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002702 ide_cdrom_update_speed(drive, buf);
Bartlomiej Zolnierkiewicz4fe67172008-02-01 23:09:21 +01002703
Linus Torvalds1da177e2005-04-16 15:20:36 -07002704 printk(KERN_INFO "%s: ATAPI", drive->name);
Bartlomiej Zolnierkiewicz4fe67172008-02-01 23:09:21 +01002705
2706 /* don't print speed if the drive reported 0 */
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002707 if (cd->max_speed)
2708 printk(KERN_CONT " %dX", cd->max_speed);
Bartlomiej Zolnierkiewicz4fe67172008-02-01 23:09:21 +01002709
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002710 printk(KERN_CONT " %s", (cdi->mask & CDC_DVD) ? "CD-ROM" : "DVD-ROM");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002711
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002712 if ((cdi->mask & CDC_DVD_R) == 0 || (cdi->mask & CDC_DVD_RAM) == 0)
2713 printk(KERN_CONT " DVD%s%s",
2714 (cdi->mask & CDC_DVD_R) ? "" : "-R",
2715 (cdi->mask & CDC_DVD_RAM) ? "" : "-RAM");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002716
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002717 if ((cdi->mask & CDC_CD_R) == 0 || (cdi->mask & CDC_CD_RW) == 0)
2718 printk(KERN_CONT " CD%s%s",
2719 (cdi->mask & CDC_CD_R) ? "" : "-R",
2720 (cdi->mask & CDC_CD_RW) ? "" : "/RW");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002721
Bartlomiej Zolnierkiewicz3f1b86d2008-02-01 23:09:20 +01002722 if ((cdi->mask & CDC_SELECT_DISC) == 0)
2723 printk(KERN_CONT " changer w/%d slots", nslots);
2724 else
2725 printk(KERN_CONT " drive");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002726
Bartlomiej Zolnierkiewicz455d80a2008-02-01 23:09:21 +01002727 printk(KERN_CONT ", %dkB Cache\n", be16_to_cpu(*(u16 *)&buf[8 + 12]));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002728
2729 return nslots;
2730}
2731
Bartlomiej Zolnierkiewicz7662d042007-05-10 00:01:10 +02002732#ifdef CONFIG_IDE_PROC_FS
Linus Torvalds1da177e2005-04-16 15:20:36 -07002733static void ide_cdrom_add_settings(ide_drive_t *drive)
2734{
Bartlomiej Zolnierkiewicz14979432007-05-10 00:01:10 +02002735 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 -07002736}
Bartlomiej Zolnierkiewicz7662d042007-05-10 00:01:10 +02002737#else
2738static inline void ide_cdrom_add_settings(ide_drive_t *drive) { ; }
2739#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07002740
2741/*
2742 * standard prep_rq_fn that builds 10 byte cmds
2743 */
Jens Axboe165125e2007-07-24 09:28:11 +02002744static int ide_cdrom_prep_fs(struct request_queue *q, struct request *rq)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002745{
2746 int hard_sect = queue_hardsect_size(q);
2747 long block = (long)rq->hard_sector / (hard_sect >> 9);
2748 unsigned long blocks = rq->hard_nr_sectors / (hard_sect >> 9);
2749
2750 memset(rq->cmd, 0, sizeof(rq->cmd));
2751
2752 if (rq_data_dir(rq) == READ)
2753 rq->cmd[0] = GPCMD_READ_10;
2754 else
2755 rq->cmd[0] = GPCMD_WRITE_10;
2756
2757 /*
2758 * fill in lba
2759 */
2760 rq->cmd[2] = (block >> 24) & 0xff;
2761 rq->cmd[3] = (block >> 16) & 0xff;
2762 rq->cmd[4] = (block >> 8) & 0xff;
2763 rq->cmd[5] = block & 0xff;
2764
2765 /*
2766 * and transfer length
2767 */
2768 rq->cmd[7] = (blocks >> 8) & 0xff;
2769 rq->cmd[8] = blocks & 0xff;
2770 rq->cmd_len = 10;
2771 return BLKPREP_OK;
2772}
2773
2774/*
2775 * Most of the SCSI commands are supported directly by ATAPI devices.
2776 * This transform handles the few exceptions.
2777 */
2778static int ide_cdrom_prep_pc(struct request *rq)
2779{
2780 u8 *c = rq->cmd;
2781
2782 /*
2783 * Transform 6-byte read/write commands to the 10-byte version
2784 */
2785 if (c[0] == READ_6 || c[0] == WRITE_6) {
2786 c[8] = c[4];
2787 c[5] = c[3];
2788 c[4] = c[2];
2789 c[3] = c[1] & 0x1f;
2790 c[2] = 0;
2791 c[1] &= 0xe0;
2792 c[0] += (READ_10 - READ_6);
2793 rq->cmd_len = 10;
2794 return BLKPREP_OK;
2795 }
2796
2797 /*
2798 * it's silly to pretend we understand 6-byte sense commands, just
2799 * reject with ILLEGAL_REQUEST and the caller should take the
2800 * appropriate action
2801 */
2802 if (c[0] == MODE_SENSE || c[0] == MODE_SELECT) {
2803 rq->errors = ILLEGAL_REQUEST;
2804 return BLKPREP_KILL;
2805 }
2806
2807 return BLKPREP_OK;
2808}
2809
Jens Axboe165125e2007-07-24 09:28:11 +02002810static int ide_cdrom_prep_fn(struct request_queue *q, struct request *rq)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002811{
Jens Axboe4aff5e22006-08-10 08:44:47 +02002812 if (blk_fs_request(rq))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002813 return ide_cdrom_prep_fs(q, rq);
Jens Axboe4aff5e22006-08-10 08:44:47 +02002814 else if (blk_pc_request(rq))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002815 return ide_cdrom_prep_pc(rq);
2816
2817 return 0;
2818}
2819
2820static
2821int ide_cdrom_setup (ide_drive_t *drive)
2822{
Bartlomiej Zolnierkiewicz4fe67172008-02-01 23:09:21 +01002823 struct cdrom_info *cd = drive->driver_data;
2824 struct cdrom_device_info *cdi = &cd->devinfo;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002825 int nslots;
2826
2827 blk_queue_prep_rq(drive->queue, ide_cdrom_prep_fn);
2828 blk_queue_dma_alignment(drive->queue, 31);
2829 drive->queue->unplug_delay = (1 * HZ) / 1000;
2830 if (!drive->queue->unplug_delay)
2831 drive->queue->unplug_delay = 1;
2832
2833 drive->special.all = 0;
2834
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002835 cd->cd_flags |= IDE_CD_FLAG_MEDIA_CHANGED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002836
Bartlomiej Zolnierkiewiczb8d25de2008-02-01 23:09:19 +01002837 if ((drive->id->config & 0x0060) == 0x20)
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002838 cd->cd_flags |= IDE_CD_FLAG_DRQ_INTERRUPT;
2839 cd->cd_flags |= IDE_CD_FLAG_NO_EJECT;
Bartlomiej Zolnierkiewiczb8d25de2008-02-01 23:09:19 +01002840
Linus Torvalds1da177e2005-04-16 15:20:36 -07002841 /* limit transfer size per interrupt. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002842 /* a testament to the nice quality of Samsung drives... */
Bartlomiej Zolnierkiewicz4fe67172008-02-01 23:09:21 +01002843 if (!strcmp(drive->id->model, "SAMSUNG CD-ROM SCR-2430") ||
2844 !strcmp(drive->id->model, "SAMSUNG CD-ROM SCR-2432"))
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002845 cd->cd_flags |= IDE_CD_FLAG_LIMIT_NFRAMES;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002846 /* the 3231 model does not support the SET_CD_SPEED command */
2847 else if (!strcmp(drive->id->model, "SAMSUNG CD-ROM SCR-3231"))
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002848 cd->cd_flags |= IDE_CD_FLAG_NO_SPEED_SELECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002849
Linus Torvalds1da177e2005-04-16 15:20:36 -07002850 if (strcmp (drive->id->model, "V003S0DS") == 0 &&
2851 drive->id->fw_rev[4] == '1' &&
2852 drive->id->fw_rev[6] <= '2') {
2853 /* Vertos 300.
2854 Some versions of this drive like to talk BCD. */
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002855 cd->cd_flags |= (IDE_CD_FLAG_TOCTRACKS_AS_BCD |
2856 IDE_CD_FLAG_TOCADDR_AS_BCD);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002857 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002858 else if (strcmp (drive->id->model, "V006E0DS") == 0 &&
2859 drive->id->fw_rev[4] == '1' &&
2860 drive->id->fw_rev[6] <= '2') {
2861 /* Vertos 600 ESD. */
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002862 cd->cd_flags |= IDE_CD_FLAG_TOCTRACKS_AS_BCD;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002863 }
2864 else if (strcmp(drive->id->model, "NEC CD-ROM DRIVE:260") == 0 &&
2865 strncmp(drive->id->fw_rev, "1.01", 4) == 0) { /* FIXME */
2866 /* Old NEC260 (not R).
2867 This drive was released before the 1.2 version
2868 of the spec. */
Bartlomiej Zolnierkiewicz2bc4cf22008-02-01 23:09:22 +01002869 cd->cd_flags |= (IDE_CD_FLAG_TOCADDR_AS_BCD |
2870 IDE_CD_FLAG_NEC260);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002871 }
Bartlomiej Zolnierkiewiczb8d25de2008-02-01 23:09:19 +01002872 /*
2873 * Sanyo 3 CD changer uses a non-standard command for CD changing
2874 * (by default standard ATAPI support for CD changers is used).
2875 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002876 else if ((strcmp(drive->id->model, "CD-ROM CDR-C3 G") == 0) ||
2877 (strcmp(drive->id->model, "CD-ROM CDR-C3G") == 0) ||
2878 (strcmp(drive->id->model, "CD-ROM CDR_C36") == 0)) {
2879 /* uses CD in slot 0 when value is set to 3 */
2880 cdi->sanyo_slot = 3;
2881 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002882
Linus Torvalds1da177e2005-04-16 15:20:36 -07002883 nslots = ide_cdrom_probe_capabilities (drive);
2884
2885 /*
2886 * set correct block size
2887 */
2888 blk_queue_hardsect_size(drive->queue, CD_FRAMESIZE);
2889
2890 if (drive->autotune == IDE_TUNE_DEFAULT ||
2891 drive->autotune == IDE_TUNE_AUTO)
2892 drive->dsc_overlap = (drive->next != drive);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002893
2894 if (ide_cdrom_register(drive, nslots)) {
2895 printk (KERN_ERR "%s: ide_cdrom_setup failed to register device with the cdrom driver.\n", drive->name);
Bartlomiej Zolnierkiewicz4fe67172008-02-01 23:09:21 +01002896 cd->devinfo.handle = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002897 return 1;
2898 }
2899 ide_cdrom_add_settings(drive);
2900 return 0;
2901}
2902
Bartlomiej Zolnierkiewiczecfd80e2007-05-10 00:01:09 +02002903#ifdef CONFIG_IDE_PROC_FS
Linus Torvalds1da177e2005-04-16 15:20:36 -07002904static
2905sector_t ide_cdrom_capacity (ide_drive_t *drive)
2906{
2907 unsigned long capacity, sectors_per_frame;
2908
2909 if (cdrom_read_capacity(drive, &capacity, &sectors_per_frame, NULL))
2910 return 0;
2911
2912 return capacity * sectors_per_frame;
2913}
Amos Waterlandd97b32142005-10-30 15:02:10 -08002914#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07002915
Russell King4031bbe2006-01-06 11:41:00 +00002916static void ide_cd_remove(ide_drive_t *drive)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002917{
2918 struct cdrom_info *info = drive->driver_data;
2919
Bartlomiej Zolnierkiewicz7662d042007-05-10 00:01:10 +02002920 ide_proc_unregister_driver(drive, info->driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002921
2922 del_gendisk(info->disk);
2923
2924 ide_cd_put(info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002925}
2926
2927static void ide_cd_release(struct kref *kref)
2928{
2929 struct cdrom_info *info = to_ide_cd(kref);
2930 struct cdrom_device_info *devinfo = &info->devinfo;
2931 ide_drive_t *drive = info->drive;
2932 struct gendisk *g = info->disk;
2933
Jesper Juhl6044ec82005-11-07 01:01:32 -08002934 kfree(info->buffer);
2935 kfree(info->toc);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002936 if (devinfo->handle == drive && unregister_cdrom(devinfo))
2937 printk(KERN_ERR "%s: %s failed to unregister device from the cdrom "
2938 "driver.\n", __FUNCTION__, drive->name);
2939 drive->dsc_overlap = 0;
2940 drive->driver_data = NULL;
2941 blk_queue_prep_rq(drive->queue, NULL);
2942 g->private_data = NULL;
2943 put_disk(g);
2944 kfree(info);
2945}
2946
Russell King4031bbe2006-01-06 11:41:00 +00002947static int ide_cd_probe(ide_drive_t *);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002948
Bartlomiej Zolnierkiewiczecfd80e2007-05-10 00:01:09 +02002949#ifdef CONFIG_IDE_PROC_FS
Linus Torvalds1da177e2005-04-16 15:20:36 -07002950static int proc_idecd_read_capacity
2951 (char *page, char **start, off_t off, int count, int *eof, void *data)
2952{
Jesper Juhl2a91f3e2005-10-30 15:02:45 -08002953 ide_drive_t *drive = data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002954 int len;
2955
2956 len = sprintf(page,"%llu\n", (long long)ide_cdrom_capacity(drive));
2957 PROC_IDE_READ_RETURN(page,start,off,count,eof,len);
2958}
2959
2960static ide_proc_entry_t idecd_proc[] = {
2961 { "capacity", S_IFREG|S_IRUGO, proc_idecd_read_capacity, NULL },
2962 { NULL, 0, NULL, NULL }
2963};
Linus Torvalds1da177e2005-04-16 15:20:36 -07002964#endif
2965
2966static ide_driver_t ide_cdrom_driver = {
Bartlomiej Zolnierkiewicz8604aff2005-05-26 14:55:34 +02002967 .gen_driver = {
Laurent Riffard4ef3b8f2005-11-18 22:15:40 +01002968 .owner = THIS_MODULE,
Bartlomiej Zolnierkiewicz8604aff2005-05-26 14:55:34 +02002969 .name = "ide-cdrom",
2970 .bus = &ide_bus_type,
Bartlomiej Zolnierkiewicz8604aff2005-05-26 14:55:34 +02002971 },
Russell King4031bbe2006-01-06 11:41:00 +00002972 .probe = ide_cd_probe,
2973 .remove = ide_cd_remove,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002974 .version = IDECD_VERSION,
2975 .media = ide_cdrom,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002976 .supports_dsc_overlap = 1,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002977 .do_request = ide_do_rw_cdrom,
2978 .end_request = ide_end_request,
2979 .error = __ide_error,
2980 .abort = __ide_abort,
Bartlomiej Zolnierkiewicz7662d042007-05-10 00:01:10 +02002981#ifdef CONFIG_IDE_PROC_FS
Linus Torvalds1da177e2005-04-16 15:20:36 -07002982 .proc = idecd_proc,
Bartlomiej Zolnierkiewicz7662d042007-05-10 00:01:10 +02002983#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07002984};
2985
2986static int idecd_open(struct inode * inode, struct file * file)
2987{
2988 struct gendisk *disk = inode->i_bdev->bd_disk;
2989 struct cdrom_info *info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002990 int rc = -ENOMEM;
2991
2992 if (!(info = ide_cd_get(disk)))
2993 return -ENXIO;
2994
Linus Torvalds1da177e2005-04-16 15:20:36 -07002995 if (!info->buffer)
Bartlomiej Zolnierkiewiczc94964a2007-02-17 02:40:24 +01002996 info->buffer = kmalloc(SECTOR_BUFFER_SIZE, GFP_KERNEL|__GFP_REPEAT);
2997
2998 if (info->buffer)
2999 rc = cdrom_open(&info->devinfo, inode, file);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003000
3001 if (rc < 0)
3002 ide_cd_put(info);
3003
3004 return rc;
3005}
3006
3007static int idecd_release(struct inode * inode, struct file * file)
3008{
3009 struct gendisk *disk = inode->i_bdev->bd_disk;
3010 struct cdrom_info *info = ide_cd_g(disk);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003011
3012 cdrom_release (&info->devinfo, file);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003013
3014 ide_cd_put(info);
3015
3016 return 0;
3017}
3018
Christoph Hellwig6a2900b2006-03-23 03:00:15 -08003019static int idecd_set_spindown(struct cdrom_device_info *cdi, unsigned long arg)
3020{
3021 struct packet_command cgc;
3022 char buffer[16];
3023 int stat;
3024 char spindown;
3025
3026 if (copy_from_user(&spindown, (void __user *)arg, sizeof(char)))
3027 return -EFAULT;
3028
3029 init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_UNKNOWN);
3030
3031 stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CDROM_PAGE, 0);
3032 if (stat)
3033 return stat;
3034
3035 buffer[11] = (buffer[11] & 0xf0) | (spindown & 0x0f);
3036 return cdrom_mode_select(cdi, &cgc);
3037}
3038
3039static int idecd_get_spindown(struct cdrom_device_info *cdi, unsigned long arg)
3040{
3041 struct packet_command cgc;
3042 char buffer[16];
3043 int stat;
3044 char spindown;
3045
3046 init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_UNKNOWN);
3047
3048 stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CDROM_PAGE, 0);
3049 if (stat)
3050 return stat;
3051
3052 spindown = buffer[11] & 0x0f;
3053 if (copy_to_user((void __user *)arg, &spindown, sizeof (char)))
3054 return -EFAULT;
3055 return 0;
3056}
3057
Linus Torvalds1da177e2005-04-16 15:20:36 -07003058static int idecd_ioctl (struct inode *inode, struct file *file,
3059 unsigned int cmd, unsigned long arg)
3060{
3061 struct block_device *bdev = inode->i_bdev;
3062 struct cdrom_info *info = ide_cd_g(bdev->bd_disk);
3063 int err;
3064
Christoph Hellwig6a2900b2006-03-23 03:00:15 -08003065 switch (cmd) {
3066 case CDROMSETSPINDOWN:
3067 return idecd_set_spindown(&info->devinfo, arg);
3068 case CDROMGETSPINDOWN:
3069 return idecd_get_spindown(&info->devinfo, arg);
3070 default:
3071 break;
3072 }
3073
3074 err = generic_ide_ioctl(info->drive, file, bdev, cmd, arg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003075 if (err == -EINVAL)
3076 err = cdrom_ioctl(file, &info->devinfo, inode, cmd, arg);
3077
3078 return err;
3079}
3080
3081static int idecd_media_changed(struct gendisk *disk)
3082{
3083 struct cdrom_info *info = ide_cd_g(disk);
3084 return cdrom_media_changed(&info->devinfo);
3085}
3086
3087static int idecd_revalidate_disk(struct gendisk *disk)
3088{
3089 struct cdrom_info *info = ide_cd_g(disk);
3090 struct request_sense sense;
3091 cdrom_read_toc(info->drive, &sense);
3092 return 0;
3093}
3094
3095static struct block_device_operations idecd_ops = {
3096 .owner = THIS_MODULE,
3097 .open = idecd_open,
3098 .release = idecd_release,
3099 .ioctl = idecd_ioctl,
3100 .media_changed = idecd_media_changed,
3101 .revalidate_disk= idecd_revalidate_disk
3102};
3103
3104/* options */
3105static char *ignore = NULL;
3106
3107module_param(ignore, charp, 0400);
3108MODULE_DESCRIPTION("ATAPI CD-ROM Driver");
3109
Russell King4031bbe2006-01-06 11:41:00 +00003110static int ide_cd_probe(ide_drive_t *drive)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003111{
3112 struct cdrom_info *info;
3113 struct gendisk *g;
3114 struct request_sense sense;
3115
3116 if (!strstr("ide-cdrom", drive->driver_req))
3117 goto failed;
3118 if (!drive->present)
3119 goto failed;
3120 if (drive->media != ide_cdrom && drive->media != ide_optical)
3121 goto failed;
3122 /* skip drives that we were told to ignore */
3123 if (ignore != NULL) {
3124 if (strstr(ignore, drive->name)) {
3125 printk(KERN_INFO "ide-cd: ignoring drive %s\n", drive->name);
3126 goto failed;
3127 }
3128 }
3129 if (drive->scsi) {
3130 printk(KERN_INFO "ide-cd: passing drive %s to ide-scsi emulation.\n", drive->name);
3131 goto failed;
3132 }
Deepak Saxenaf5e3c2f2005-11-07 01:01:25 -08003133 info = kzalloc(sizeof(struct cdrom_info), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003134 if (info == NULL) {
3135 printk(KERN_ERR "%s: Can't allocate a cdrom structure\n", drive->name);
3136 goto failed;
3137 }
3138
3139 g = alloc_disk(1 << PARTN_BITS);
3140 if (!g)
3141 goto out_free_cd;
3142
3143 ide_init_disk(g, drive);
3144
Bartlomiej Zolnierkiewicz7662d042007-05-10 00:01:10 +02003145 ide_proc_register_driver(drive, &ide_cdrom_driver);
Bartlomiej Zolnierkiewicz8604aff2005-05-26 14:55:34 +02003146
Linus Torvalds1da177e2005-04-16 15:20:36 -07003147 kref_init(&info->kref);
3148
3149 info->drive = drive;
3150 info->driver = &ide_cdrom_driver;
3151 info->disk = g;
3152
3153 g->private_data = &info->driver;
3154
3155 drive->driver_data = info;
3156
Linus Torvalds1da177e2005-04-16 15:20:36 -07003157 g->minors = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003158 g->driverfs_dev = &drive->gendev;
3159 g->flags = GENHD_FL_CD | GENHD_FL_REMOVABLE;
3160 if (ide_cdrom_setup(drive)) {
Bartlomiej Zolnierkiewicz7662d042007-05-10 00:01:10 +02003161 ide_proc_unregister_driver(drive, &ide_cdrom_driver);
Bartlomiej Zolnierkiewicz05017db2007-12-24 15:23:43 +01003162 ide_cd_release(&info->kref);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003163 goto failed;
3164 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003165
3166 cdrom_read_toc(drive, &sense);
3167 g->fops = &idecd_ops;
3168 g->flags |= GENHD_FL_REMOVABLE;
3169 add_disk(g);
3170 return 0;
3171
Linus Torvalds1da177e2005-04-16 15:20:36 -07003172out_free_cd:
3173 kfree(info);
3174failed:
Bartlomiej Zolnierkiewicz8604aff2005-05-26 14:55:34 +02003175 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003176}
3177
3178static void __exit ide_cdrom_exit(void)
3179{
Bartlomiej Zolnierkiewicz8604aff2005-05-26 14:55:34 +02003180 driver_unregister(&ide_cdrom_driver.gen_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003181}
Bartlomiej Zolnierkiewicz17514e82005-11-19 22:24:35 +01003182
3183static int __init ide_cdrom_init(void)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003184{
Bartlomiej Zolnierkiewicz8604aff2005-05-26 14:55:34 +02003185 return driver_register(&ide_cdrom_driver.gen_driver);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003186}
3187
Kay Sievers263756e2005-12-12 18:03:44 +01003188MODULE_ALIAS("ide:*m-cdrom*");
Linus Torvalds1da177e2005-04-16 15:20:36 -07003189module_init(ide_cdrom_init);
3190module_exit(ide_cdrom_exit);
3191MODULE_LICENSE("GPL");