forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathide-cd.c
3569 lines (3039 loc) · 102 KB
/
ide-cd.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
* linux/drivers/ide/ide-cd.c
*
* Copyright (C) 1994, 1995, 1996 scott snyder <[email protected]>
* Copyright (C) 1996-1998 Erik Andersen <[email protected]>
* Copyright (C) 1998-2000 Jens Axboe <[email protected]>
*
* May be copied or modified under the terms of the GNU General Public
* License. See linux/COPYING for more information.
*
* ATAPI CD-ROM driver. To be used with ide.c.
* See Documentation/cdrom/ide-cd for usage information.
*
* Suggestions are welcome. Patches that work are more welcome though. ;-)
* For those wishing to work on this driver, please be sure you download
* and comply with the latest Mt. Fuji (SFF8090 version 4) and ATAPI
* (SFF-8020i rev 2.6) standards. These documents can be obtained by
* anonymous ftp from:
* ftp://fission.dt.wdc.com/pub/standards/SFF_atapi/spec/SFF8020-r2.6/PS/8020r26.ps
* ftp://ftp.avc-pioneer.com/Mtfuji4/Spec/Fuji4r10.pdf
*
* Drives that deviate from these standards will be accommodated as much
* as possible via compile time or command-line options. Since I only have
* a few drives, you generally need to send me patches...
*
* ----------------------------------
* TO DO LIST:
* -Make it so that Pioneer CD DR-A24X and friends don't get screwed up on
* boot
*
* ----------------------------------
* 1.00 Oct 31, 1994 -- Initial version.
* 1.01 Nov 2, 1994 -- Fixed problem with starting request in
* cdrom_check_status.
* 1.03 Nov 25, 1994 -- leaving unmask_intr[] as a user-setting (as for disks)
* (from mlord) -- minor changes to cdrom_setup()
* -- renamed ide_dev_s to ide_drive_t, enable irq on command
* 2.00 Nov 27, 1994 -- Generalize packet command interface;
* add audio ioctls.
* 2.01 Dec 3, 1994 -- Rework packet command interface to handle devices
* which send an interrupt when ready for a command.
* 2.02 Dec 11, 1994 -- Cache the TOC in the driver.
* Don't use SCMD_PLAYAUDIO_TI; it's not included
* in the current version of ATAPI.
* Try to use LBA instead of track or MSF addressing
* when possible.
* Don't wait for READY_STAT.
* 2.03 Jan 10, 1995 -- Rewrite block read routines to handle block sizes
* other than 2k and to move multiple sectors in a
* single transaction.
* 2.04 Apr 21, 1995 -- Add work-around for Creative Labs CD220E drives.
* Thanks to Nick Saw <[email protected]> for
* help in figuring this out. Ditto for Acer and
* Aztech drives, which seem to have the same problem.
* 2.04b May 30, 1995 -- Fix to match changes in ide.c version 3.16 -ml
* 2.05 Jun 8, 1995 -- Don't attempt to retry after an illegal request
* or data protect error.
* Use HWIF and DEV_HWIF macros as in ide.c.
* Always try to do a request_sense after
* a failed command.
* Include an option to give textual descriptions
* of ATAPI errors.
* Fix a bug in handling the sector cache which
* showed up if the drive returned data in 512 byte
* blocks (like Pioneer drives). Thanks to
* Richard Hirst <[email protected]> for diagnosing this.
* Properly supply the page number field in the
* MODE_SELECT command.
* PLAYAUDIO12 is broken on the Aztech; work around it.
* 2.05x Aug 11, 1995 -- lots of data structure renaming/restructuring in ide.c
* (my apologies to Scott, but now ide-cd.c is independent)
* 3.00 Aug 22, 1995 -- Implement CDROMMULTISESSION ioctl.
* Implement CDROMREADAUDIO ioctl (UNTESTED).
* Use input_ide_data() and output_ide_data().
* Add door locking.
* Fix usage count leak in cdrom_open, which happened
* when a read-write mount was attempted.
* Try to load the disk on open.
* Implement CDROMEJECT_SW ioctl (off by default).
* Read total cdrom capacity during open.
* Rearrange logic in cdrom_decode_status. Issue
* request sense commands for failed packet commands
* from here instead of from cdrom_queue_packet_command.
* Fix a race condition in retrieving error information.
* Suppress printing normal unit attention errors and
* some drive not ready errors.
* Implement CDROMVOLREAD ioctl.
* Implement CDROMREADMODE1/2 ioctls.
* Fix race condition in setting up interrupt handlers
* when the `serialize' option is used.
* 3.01 Sep 2, 1995 -- Fix ordering of reenabling interrupts in
* cdrom_queue_request.
* Another try at using ide_[input,output]_data.
* 3.02 Sep 16, 1995 -- Stick total disk capacity in partition table as well.
* Make VERBOSE_IDE_CD_ERRORS dump failed command again.
* Dump out more information for ILLEGAL REQUEST errs.
* Fix handling of errors occurring before the
* packet command is transferred.
* Fix transfers with odd bytelengths.
* 3.03 Oct 27, 1995 -- Some Creative drives have an id of just `CD'.
* `DCI-2S10' drives are broken too.
* 3.04 Nov 20, 1995 -- So are Vertos drives.
* 3.05 Dec 1, 1995 -- Changes to go with overhaul of ide.c and ide-tape.c
* 3.06 Dec 16, 1995 -- Add support needed for partitions.
* More workarounds for Vertos bugs (based on patches
* from Holger Dietze <[email protected]>).
* Try to eliminate byteorder assumptions.
* Use atapi_cdrom_subchnl struct definition.
* Add STANDARD_ATAPI compilation option.
* 3.07 Jan 29, 1996 -- More twiddling for broken drives: Sony 55D,
* Vertos 300.
* Add NO_DOOR_LOCKING configuration option.
* Handle drive_cmd requests w/NULL args (for hdparm -t).
* Work around sporadic Sony55e audio play problem.
* 3.07a Feb 11, 1996 -- check drive->id for NULL before dereferencing, to fix
* problem with "hde=cdrom" with no drive present. -ml
* 3.08 Mar 6, 1996 -- More Vertos workarounds.
* 3.09 Apr 5, 1996 -- Add CDROMCLOSETRAY ioctl.
* Switch to using MSF addressing for audio commands.
* Reformat to match kernel tabbing style.
* Add CDROM_GET_UPC ioctl.
* 3.10 Apr 10, 1996 -- Fix compilation error with STANDARD_ATAPI.
* 3.11 Apr 29, 1996 -- Patch from Heiko Eissfeldt <[email protected]>
* to remove redundant verify_area calls.
* 3.12 May 7, 1996 -- Rudimentary changer support. Based on patches
* from Gerhard Zuber <[email protected]>.
* Let open succeed even if there's no loaded disc.
* 3.13 May 19, 1996 -- Fixes for changer code.
* 3.14 May 29, 1996 -- Add work-around for Vertos 600.
* (From Hennus Bergman <[email protected]>.)
* 3.15 July 2, 1996 -- Added support for Sanyo 3 CD changers
* from Ben Galliart <[email protected]> with
* special help from Jeff Lightfoot
* 3.15a July 9, 1996 -- Improved Sanyo 3 CD changer identification
* 3.16 Jul 28, 1996 -- Fix from Gadi to reduce kernel stack usage for ioctl.
* 3.17 Sep 17, 1996 -- Tweak audio reads for some drives.
* Start changing CDROMLOADFROMSLOT to CDROM_SELECT_DISC.
* 3.18 Oct 31, 1996 -- Added module and DMA support.
*
*
* 4.00 Nov 5, 1996 -- New ide-cd maintainer,
* Erik B. Andersen <[email protected]>
* -- Newer Creative drives don't always set the error
* register correctly. Make sure we see media changes
* regardless.
* -- Integrate with generic cdrom driver.
* -- CDROMGETSPINDOWN and CDROMSETSPINDOWN ioctls, based on
* a patch from Ciro Cattuto <>.
* -- Call set_device_ro.
* -- Implement CDROMMECHANISMSTATUS and CDROMSLOTTABLE
* ioctls, based on patch by Erik Andersen
* -- Add some probes of drive capability during setup.
*
* 4.01 Nov 11, 1996 -- Split into ide-cd.c and ide-cd.h
* -- Removed CDROMMECHANISMSTATUS and CDROMSLOTTABLE
* ioctls in favor of a generalized approach
* using the generic cdrom driver.
* -- Fully integrated with the 2.1.X kernel.
* -- Other stuff that I forgot (lots of changes)
*
* 4.02 Dec 01, 1996 -- Applied patch from Gadi Oxman <[email protected]>
* to fix the drive door locking problems.
*
* 4.03 Dec 04, 1996 -- Added DSC overlap support.
* 4.04 Dec 29, 1996 -- Added CDROMREADRAW ioclt based on patch
* by Ales Makarov ([email protected])
*
* 4.05 Nov 20, 1997 -- Modified to print more drive info on init
* Minor other changes
* Fix errors on CDROMSTOP (If you have a "Dolphin",
* you must define IHAVEADOLPHIN)
* Added identifier so new Sanyo CD-changer works
* Better detection if door locking isn't supported
*
* 4.06 Dec 17, 1997 -- fixed endless "tray open" messages -ml
* 4.07 Dec 17, 1997 -- fallback to set pc->stat on "tray open"
* 4.08 Dec 18, 1997 -- spew less noise when tray is empty
* -- fix speed display for ACER 24X, 18X
* 4.09 Jan 04, 1998 -- fix handling of the last block so we return
* an end of file instead of an I/O error (Gadi)
* 4.10 Jan 24, 1998 -- fixed a bug so now changers can change to a new
* slot when there is no disc in the current slot.
* -- Fixed a memory leak where info->changer_info was
* malloc'ed but never free'd when closing the device.
* -- Cleaned up the global namespace a bit by making more
* functions static that should already have been.
* 4.11 Mar 12, 1998 -- Added support for the CDROM_SELECT_SPEED ioctl
* based on a patch for 2.0.33 by Jelle Foks
* <[email protected]>, a patch for 2.0.33
* by Toni Giorgino <[email protected]>, the SCSI
* version, and my own efforts. -erik
* -- Fixed a stupid bug which egcs was kind enough to
* inform me of where "Illegal mode for this track"
* was never returned due to a comparison on data
* types of limited range.
* 4.12 Mar 29, 1998 -- Fixed bug in CDROM_SELECT_SPEED so write speed is
* now set ionly for CD-R and CD-RW drives. I had
* removed this support because it produced errors.
* It produced errors _only_ for non-writers. duh.
* 4.13 May 05, 1998 -- Suppress useless "in progress of becoming ready"
* messages, since this is not an error.
* -- Change error messages to be const
* -- Remove a "\t" which looks ugly in the syslogs
* 4.14 July 17, 1998 -- Change to pointing to .ps version of ATAPI spec
* since the .pdf version doesn't seem to work...
* -- Updated the TODO list to something more current.
*
* 4.15 Aug 25, 1998 -- Updated ide-cd.h to respect mechine endianess,
* patch thanks to "Eddie C. Dost" <[email protected]>
*
* 4.50 Oct 19, 1998 -- New maintainers!
* Jens Axboe <[email protected]>
* Chris Zwilling <[email protected]>
*
* 4.51 Dec 23, 1998 -- Jens Axboe <[email protected]>
* - ide_cdrom_reset enabled since the ide subsystem
* handles resets fine now. <[email protected]>
* - Transfer size fix for Samsung CD-ROMs, thanks to
* "Ville Hallik" <[email protected]>.
* - other minor stuff.
*
* 4.52 Jan 19, 1999 -- Jens Axboe <[email protected]>
* - Detect DVD-ROM/RAM drives
*
* 4.53 Feb 22, 1999 - Include other model Samsung and one Goldstar
* drive in transfer size limit.
* - Fix the I/O error when doing eject without a medium
* loaded on some drives.
* - CDROMREADMODE2 is now implemented through
* CDROMREADRAW, since many drives don't support
* MODE2 (even though ATAPI 2.6 says they must).
* - Added ignore parameter to ide-cd (as a module), eg
* insmod ide-cd ignore='hda hdb'
* Useful when using ide-cd in conjunction with
* ide-scsi. TODO: non-modular way of doing the
* same.
*
* 4.54 Aug 5, 1999 - Support for MMC2 class commands through the generic
* packet interface to cdrom.c.
* - Unified audio ioctl support, most of it.
* - cleaned up various deprecated verify_area().
* - Added ide_cdrom_packet() as the interface for
* the Uniform generic_packet().
* - bunch of other stuff, will fill in logs later.
* - report 1 slot for non-changers, like the other
* cd-rom drivers. don't report select disc for
* non-changers as well.
* - mask out audio playing, if the device can't do it.
*
* 4.55 Sep 1, 1999 - Eliminated the rest of the audio ioctls, except
* for CDROMREADTOC[ENTRY|HEADER]. Some of the drivers
* use this independently of the actual audio handling.
* They will disappear later when I get the time to
* do it cleanly.
* - Minimize the TOC reading - only do it when we
* know a media change has occurred.
* - Moved all the CDROMREADx ioctls to the Uniform layer.
* - Heiko Eissfeldt <[email protected]> supplied
* some fixes for CDI.
* - CD-ROM leaving door locked fix from Andries
* Brouwer <[email protected]>
* - Erik Andersen <[email protected]> unified
* commands across the various drivers and how
* sense errors are handled.
*
* 4.56 Sep 12, 1999 - Removed changer support - it is now in the
* Uniform layer.
* - Added partition based multisession handling.
* - Mode sense and mode select moved to the
* Uniform layer.
* - Fixed a problem with WPI CDS-32X drive - it
* failed the capabilities
*
* 4.57 Apr 7, 2000 - Fixed sense reporting.
* - Fixed possible oops in ide_cdrom_get_last_session()
* - Fix locking mania and make ide_cdrom_reset relock
* - Stop spewing errors to log when magicdev polls with
* TEST_UNIT_READY on some drives.
* - Various fixes from Tobias Ringstrom:
* tray if it was locked prior to the reset.
* - cdrom_read_capacity returns one frame too little.
* - Fix real capacity reporting.
*
* 4.58 May 1, 2000 - Clean up ACER50 stuff.
* - Fix small problem with ide_cdrom_capacity
*
* 4.59 Aug 11, 2000 - Fix changer problem in cdrom_read_toc, we weren't
* correctly sensing a disc change.
* - Rearranged some code
* - Use extended sense on drives that support it for
* correctly reporting tray status -- from
* Michael D Johnson <[email protected]>
* 4.60 Dec 17, 2003 - Add mt rainier support
* - Bump timeout for packet commands, matches sr
* - Odd stuff
* 4.61 Jan 22, 2004 - support hardware sector sizes other than 2kB,
* Pascal Schmidt <[email protected]>
*
*************************************************************************/
#define IDECD_VERSION "4.61"
#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/timer.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/errno.h>
#include <linux/cdrom.h>
#include <linux/ide.h>
#include <linux/completion.h>
#include <linux/mutex.h>
#include <scsi/scsi.h> /* For SCSI -> ATAPI command conversion */
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/byteorder.h>
#include <asm/uaccess.h>
#include <asm/unaligned.h>
#include "ide-cd.h"
static DEFINE_MUTEX(idecd_ref_mutex);
#define to_ide_cd(obj) container_of(obj, struct cdrom_info, kref)
#define ide_cd_g(disk) \
container_of((disk)->private_data, struct cdrom_info, driver)
static struct cdrom_info *ide_cd_get(struct gendisk *disk)
{
struct cdrom_info *cd = NULL;
mutex_lock(&idecd_ref_mutex);
cd = ide_cd_g(disk);
if (cd)
kref_get(&cd->kref);
mutex_unlock(&idecd_ref_mutex);
return cd;
}
static void ide_cd_release(struct kref *);
static void ide_cd_put(struct cdrom_info *cd)
{
mutex_lock(&idecd_ref_mutex);
kref_put(&cd->kref, ide_cd_release);
mutex_unlock(&idecd_ref_mutex);
}
/****************************************************************************
* Generic packet command support and error handling routines.
*/
/* Mark that we've seen a media change, and invalidate our internal
buffers. */
static void cdrom_saw_media_change (ide_drive_t *drive)
{
struct cdrom_info *info = drive->driver_data;
CDROM_STATE_FLAGS (drive)->media_changed = 1;
CDROM_STATE_FLAGS (drive)->toc_valid = 0;
info->nsectors_buffered = 0;
}
static int cdrom_log_sense(ide_drive_t *drive, struct request *rq,
struct request_sense *sense)
{
int log = 0;
if (!sense || !rq || (rq->flags & REQ_QUIET))
return 0;
switch (sense->sense_key) {
case NO_SENSE: case RECOVERED_ERROR:
break;
case NOT_READY:
/*
* don't care about tray state messages for
* e.g. capacity commands or in-progress or
* becoming ready
*/
if (sense->asc == 0x3a || sense->asc == 0x04)
break;
log = 1;
break;
case ILLEGAL_REQUEST:
/*
* don't log START_STOP unit with LoEj set, since
* we cannot reliably check if drive can auto-close
*/
if (rq->cmd[0] == GPCMD_START_STOP_UNIT && sense->asc == 0x24)
break;
log = 1;
break;
case UNIT_ATTENTION:
/*
* Make good and sure we've seen this potential media
* change. Some drives (i.e. Creative) fail to present
* the correct sense key in the error register.
*/
cdrom_saw_media_change(drive);
break;
default:
log = 1;
break;
}
return log;
}
static
void cdrom_analyze_sense_data(ide_drive_t *drive,
struct request *failed_command,
struct request_sense *sense)
{
unsigned long sector;
unsigned long bio_sectors;
unsigned long valid;
struct cdrom_info *info = drive->driver_data;
if (!cdrom_log_sense(drive, failed_command, sense))
return;
/*
* If a read toc is executed for a CD-R or CD-RW medium where
* the first toc has not been recorded yet, it will fail with
* 05/24/00 (which is a confusing error)
*/
if (failed_command && failed_command->cmd[0] == GPCMD_READ_TOC_PMA_ATIP)
if (sense->sense_key == 0x05 && sense->asc == 0x24)
return;
if (sense->error_code == 0x70) { /* Current Error */
switch(sense->sense_key) {
case MEDIUM_ERROR:
case VOLUME_OVERFLOW:
case ILLEGAL_REQUEST:
if (!sense->valid)
break;
if (failed_command == NULL ||
!blk_fs_request(failed_command))
break;
sector = (sense->information[0] << 24) |
(sense->information[1] << 16) |
(sense->information[2] << 8) |
(sense->information[3]);
bio_sectors = bio_sectors(failed_command->bio);
if (bio_sectors < 4)
bio_sectors = 4;
if (drive->queue->hardsect_size == 2048)
sector <<= 2; /* Device sector size is 2K */
sector &= ~(bio_sectors -1);
valid = (sector - failed_command->sector) << 9;
if (valid < 0)
valid = 0;
if (sector < get_capacity(info->disk) &&
drive->probed_capacity - sector < 4 * 75) {
set_capacity(info->disk, sector);
}
}
}
#if VERBOSE_IDE_CD_ERRORS
{
int i;
const char *s = "bad sense key!";
char buf[80];
printk ("ATAPI device %s:\n", drive->name);
if (sense->error_code==0x70)
printk(" Error: ");
else if (sense->error_code==0x71)
printk(" Deferred Error: ");
else if (sense->error_code == 0x7f)
printk(" Vendor-specific Error: ");
else
printk(" Unknown Error Type: ");
if (sense->sense_key < ARY_LEN(sense_key_texts))
s = sense_key_texts[sense->sense_key];
printk("%s -- (Sense key=0x%02x)\n", s, sense->sense_key);
if (sense->asc == 0x40) {
sprintf(buf, "Diagnostic failure on component 0x%02x",
sense->ascq);
s = buf;
} else {
int lo = 0, mid, hi = ARY_LEN(sense_data_texts);
unsigned long key = (sense->sense_key << 16);
key |= (sense->asc << 8);
if (!(sense->ascq >= 0x80 && sense->ascq <= 0xdd))
key |= sense->ascq;
s = NULL;
while (hi > lo) {
mid = (lo + hi) / 2;
if (sense_data_texts[mid].asc_ascq == key ||
sense_data_texts[mid].asc_ascq == (0xff0000|key)) {
s = sense_data_texts[mid].text;
break;
}
else if (sense_data_texts[mid].asc_ascq > key)
hi = mid;
else
lo = mid+1;
}
}
if (s == NULL) {
if (sense->asc > 0x80)
s = "(vendor-specific error)";
else
s = "(reserved error code)";
}
printk(KERN_ERR " %s -- (asc=0x%02x, ascq=0x%02x)\n",
s, sense->asc, sense->ascq);
if (failed_command != NULL) {
int lo=0, mid, hi= ARY_LEN (packet_command_texts);
s = NULL;
while (hi > lo) {
mid = (lo + hi) / 2;
if (packet_command_texts[mid].packet_command ==
failed_command->cmd[0]) {
s = packet_command_texts[mid].text;
break;
}
if (packet_command_texts[mid].packet_command >
failed_command->cmd[0])
hi = mid;
else
lo = mid+1;
}
printk (KERN_ERR " The failed \"%s\" packet command was: \n \"", s);
for (i=0; i<sizeof (failed_command->cmd); i++)
printk ("%02x ", failed_command->cmd[i]);
printk ("\"\n");
}
/* The SKSV bit specifies validity of the sense_key_specific
* in the next two commands. It is bit 7 of the first byte.
* In the case of NOT_READY, if SKSV is set the drive can
* give us nice ETA readings.
*/
if (sense->sense_key == NOT_READY && (sense->sks[0] & 0x80)) {
int progress = (sense->sks[1] << 8 | sense->sks[2]) * 100;
printk(KERN_ERR " Command is %02d%% complete\n", progress / 0xffff);
}
if (sense->sense_key == ILLEGAL_REQUEST &&
(sense->sks[0] & 0x80) != 0) {
printk(KERN_ERR " Error in %s byte %d",
(sense->sks[0] & 0x40) != 0 ?
"command packet" : "command data",
(sense->sks[1] << 8) + sense->sks[2]);
if ((sense->sks[0] & 0x40) != 0)
printk (" bit %d", sense->sks[0] & 0x07);
printk ("\n");
}
}
#else /* not VERBOSE_IDE_CD_ERRORS */
/* Suppress printing unit attention and `in progress of becoming ready'
errors when we're not being verbose. */
if (sense->sense_key == UNIT_ATTENTION ||
(sense->sense_key == NOT_READY && (sense->asc == 4 ||
sense->asc == 0x3a)))
return;
printk(KERN_ERR "%s: error code: 0x%02x sense_key: 0x%02x asc: 0x%02x ascq: 0x%02x\n",
drive->name,
sense->error_code, sense->sense_key,
sense->asc, sense->ascq);
#endif /* not VERBOSE_IDE_CD_ERRORS */
}
/*
* Initialize a ide-cd packet command request
*/
static void cdrom_prepare_request(ide_drive_t *drive, struct request *rq)
{
struct cdrom_info *cd = drive->driver_data;
ide_init_drive_cmd(rq);
rq->flags = REQ_PC;
rq->rq_disk = cd->disk;
}
static void cdrom_queue_request_sense(ide_drive_t *drive, void *sense,
struct request *failed_command)
{
struct cdrom_info *info = drive->driver_data;
struct request *rq = &info->request_sense_request;
if (sense == NULL)
sense = &info->sense_data;
/* stuff the sense request in front of our current request */
cdrom_prepare_request(drive, rq);
rq->data = sense;
rq->cmd[0] = GPCMD_REQUEST_SENSE;
rq->cmd[4] = rq->data_len = 18;
rq->flags = REQ_SENSE;
/* NOTE! Save the failed command in "rq->buffer" */
rq->buffer = (void *) failed_command;
(void) ide_do_drive_cmd(drive, rq, ide_preempt);
}
static void cdrom_end_request (ide_drive_t *drive, int uptodate)
{
struct request *rq = HWGROUP(drive)->rq;
int nsectors = rq->hard_cur_sectors;
if ((rq->flags & REQ_SENSE) && uptodate) {
/*
* For REQ_SENSE, "rq->buffer" points to the original failed
* request
*/
struct request *failed = (struct request *) rq->buffer;
struct cdrom_info *info = drive->driver_data;
void *sense = &info->sense_data;
unsigned long flags;
if (failed) {
if (failed->sense) {
sense = failed->sense;
failed->sense_len = rq->sense_len;
}
cdrom_analyze_sense_data(drive, failed, sense);
/*
* now end failed request
*/
if (blk_fs_request(failed)) {
if (ide_end_dequeued_request(drive, failed, 0,
failed->hard_nr_sectors))
BUG();
} else {
spin_lock_irqsave(&ide_lock, flags);
end_that_request_chunk(failed, 0,
failed->data_len);
end_that_request_last(failed, 0);
spin_unlock_irqrestore(&ide_lock, flags);
}
} else
cdrom_analyze_sense_data(drive, NULL, sense);
}
if (!rq->current_nr_sectors && blk_fs_request(rq))
uptodate = 1;
/* make sure it's fully ended */
if (blk_pc_request(rq))
nsectors = (rq->data_len + 511) >> 9;
if (!nsectors)
nsectors = 1;
ide_end_request(drive, uptodate, nsectors);
}
static void ide_dump_status_no_sense(ide_drive_t *drive, const char *msg, u8 stat)
{
if (stat & 0x80)
return;
ide_dump_status(drive, msg, stat);
}
/* Returns 0 if the request should be continued.
Returns 1 if the request was ended. */
static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
{
struct request *rq = HWGROUP(drive)->rq;
int stat, err, sense_key;
/* Check for errors. */
stat = HWIF(drive)->INB(IDE_STATUS_REG);
if (stat_ret)
*stat_ret = stat;
if (OK_STAT(stat, good_stat, BAD_R_STAT))
return 0;
/* Get the IDE error register. */
err = HWIF(drive)->INB(IDE_ERROR_REG);
sense_key = err >> 4;
if (rq == NULL) {
printk("%s: missing rq in cdrom_decode_status\n", drive->name);
return 1;
}
if (rq->flags & REQ_SENSE) {
/* We got an error trying to get sense info
from the drive (probably while trying
to recover from a former error). Just give up. */
rq->flags |= REQ_FAILED;
cdrom_end_request(drive, 0);
ide_error(drive, "request sense failure", stat);
return 1;
} else if (rq->flags & (REQ_PC | REQ_BLOCK_PC)) {
/* All other functions, except for READ. */
unsigned long flags;
/*
* if we have an error, pass back CHECK_CONDITION as the
* scsi status byte
*/
if ((rq->flags & REQ_BLOCK_PC) && !rq->errors)
rq->errors = SAM_STAT_CHECK_CONDITION;
/* Check for tray open. */
if (sense_key == NOT_READY) {
cdrom_saw_media_change (drive);
} else if (sense_key == UNIT_ATTENTION) {
/* Check for media change. */
cdrom_saw_media_change (drive);
/*printk("%s: media changed\n",drive->name);*/
return 0;
} else if (!(rq->flags & REQ_QUIET)) {
/* Otherwise, print an error. */
ide_dump_status(drive, "packet command error", stat);
}
rq->flags |= REQ_FAILED;
/*
* instead of playing games with moving completions around,
* remove failed request completely and end it when the
* request sense has completed
*/
if (stat & ERR_STAT) {
spin_lock_irqsave(&ide_lock, flags);
blkdev_dequeue_request(rq);
HWGROUP(drive)->rq = NULL;
spin_unlock_irqrestore(&ide_lock, flags);
cdrom_queue_request_sense(drive, rq->sense, rq);
} else
cdrom_end_request(drive, 0);
} else if (blk_fs_request(rq)) {
int do_end_request = 0;
/* Handle errors from READ and WRITE requests. */
if (blk_noretry_request(rq))
do_end_request = 1;
if (sense_key == NOT_READY) {
/* Tray open. */
if (rq_data_dir(rq) == READ) {
cdrom_saw_media_change (drive);
/* Fail the request. */
printk ("%s: tray open\n", drive->name);
do_end_request = 1;
} else {
struct cdrom_info *info = drive->driver_data;
/* allow the drive 5 seconds to recover, some
* devices will return this error while flushing
* data from cache */
if (!rq->errors)
info->write_timeout = jiffies + ATAPI_WAIT_WRITE_BUSY;
rq->errors = 1;
if (time_after(jiffies, info->write_timeout))
do_end_request = 1;
else {
unsigned long flags;
/*
* take a breather relying on the
* unplug timer to kick us again
*/
spin_lock_irqsave(&ide_lock, flags);
blk_plug_device(drive->queue);
spin_unlock_irqrestore(&ide_lock,flags);
return 1;
}
}
} else if (sense_key == UNIT_ATTENTION) {
/* Media change. */
cdrom_saw_media_change (drive);
/* Arrange to retry the request.
But be sure to give up if we've retried
too many times. */
if (++rq->errors > ERROR_MAX)
do_end_request = 1;
} else if (sense_key == ILLEGAL_REQUEST ||
sense_key == DATA_PROTECT) {
/* No point in retrying after an illegal
request or data protect error.*/
ide_dump_status_no_sense (drive, "command error", stat);
do_end_request = 1;
} else if (sense_key == MEDIUM_ERROR) {
/* No point in re-trying a zillion times on a bad
* sector... If we got here the error is not correctable */
ide_dump_status_no_sense (drive, "media error (bad sector)", stat);
do_end_request = 1;
} else if (sense_key == BLANK_CHECK) {
/* Disk appears blank ?? */
ide_dump_status_no_sense (drive, "media error (blank)", stat);
do_end_request = 1;
} else if ((err & ~ABRT_ERR) != 0) {
/* Go to the default handler
for other errors. */
ide_error(drive, "cdrom_decode_status", stat);
return 1;
} else if ((++rq->errors > ERROR_MAX)) {
/* We've racked up too many retries. Abort. */
do_end_request = 1;
}
/* End a request through request sense analysis when we have
sense data. We need this in order to perform end of media
processing */
if (do_end_request) {
if (stat & ERR_STAT) {
unsigned long flags;
spin_lock_irqsave(&ide_lock, flags);
blkdev_dequeue_request(rq);
HWGROUP(drive)->rq = NULL;
spin_unlock_irqrestore(&ide_lock, flags);
cdrom_queue_request_sense(drive, rq->sense, rq);
} else
cdrom_end_request(drive, 0);
} else {
/* If we got a CHECK_CONDITION status,
queue a request sense command. */
if (stat & ERR_STAT)
cdrom_queue_request_sense(drive, NULL, NULL);
}
} else {
blk_dump_rq_flags(rq, "ide-cd: bad rq");
cdrom_end_request(drive, 0);
}
/* Retry, or handle the next request. */
return 1;
}
static int cdrom_timer_expiry(ide_drive_t *drive)
{
struct request *rq = HWGROUP(drive)->rq;
unsigned long wait = 0;
/*
* Some commands are *slow* and normally take a long time to
* complete. Usually we can use the ATAPI "disconnect" to bypass
* this, but not all commands/drives support that. Let
* ide_timer_expiry keep polling us for these.
*/
switch (rq->cmd[0]) {
case GPCMD_BLANK:
case GPCMD_FORMAT_UNIT:
case GPCMD_RESERVE_RZONE_TRACK:
case GPCMD_CLOSE_TRACK:
case GPCMD_FLUSH_CACHE:
wait = ATAPI_WAIT_PC;
break;
default:
if (!(rq->flags & REQ_QUIET))
printk(KERN_INFO "ide-cd: cmd 0x%x timed out\n", rq->cmd[0]);
wait = 0;
break;
}
return wait;
}
/* Set up the device registers for transferring a packet command on DEV,
expecting to later transfer XFERLEN bytes. HANDLER is the routine
which actually transfers the command to the drive. If this is a
drq_interrupt device, this routine will arrange for HANDLER to be
called when the interrupt from the drive arrives. Otherwise, HANDLER
will be called immediately after the drive is prepared for the transfer. */
static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive,
int xferlen,
ide_handler_t *handler)
{
ide_startstop_t startstop;
struct cdrom_info *info = drive->driver_data;
ide_hwif_t *hwif = drive->hwif;
/* Wait for the controller to be idle. */
if (ide_wait_stat(&startstop, drive, 0, BUSY_STAT, WAIT_READY))
return startstop;
if (info->dma)
info->dma = !hwif->dma_setup(drive);
/* Set up the controller registers. */
/* FIXME: for Virtual DMA we must check harder */
HWIF(drive)->OUTB(info->dma, IDE_FEATURE_REG);
HWIF(drive)->OUTB(0, IDE_IREASON_REG);
HWIF(drive)->OUTB(0, IDE_SECTOR_REG);
HWIF(drive)->OUTB(xferlen & 0xff, IDE_BCOUNTL_REG);
HWIF(drive)->OUTB(xferlen >> 8 , IDE_BCOUNTH_REG);
if (IDE_CONTROL_REG)
HWIF(drive)->OUTB(drive->ctl, IDE_CONTROL_REG);
if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) {
/* packet command */
ide_execute_command(drive, WIN_PACKETCMD, handler, ATAPI_WAIT_PC, cdrom_timer_expiry);
return ide_started;
} else {
unsigned long flags;
/* packet command */
spin_lock_irqsave(&ide_lock, flags);
hwif->OUTBSYNC(drive, WIN_PACKETCMD, IDE_COMMAND_REG);
ndelay(400);
spin_unlock_irqrestore(&ide_lock, flags);
return (*handler) (drive);
}
}
/* Send a packet command to DRIVE described by CMD_BUF and CMD_LEN.
The device registers must have already been prepared
by cdrom_start_packet_command.
HANDLER is the interrupt handler to call when the command completes
or there's data ready. */
/*
* changed 5 parameters to 3 for dvd-ram
* struct packet_command *pc; now packet_command_t *pc;
*/
#define ATAPI_MIN_CDB_BYTES 12
static ide_startstop_t cdrom_transfer_packet_command (ide_drive_t *drive,
struct request *rq,
ide_handler_t *handler)
{
ide_hwif_t *hwif = drive->hwif;
int cmd_len;
struct cdrom_info *info = drive->driver_data;
ide_startstop_t startstop;
if (CDROM_CONFIG_FLAGS(drive)->drq_interrupt) {
/* Here we should have been called after receiving an interrupt
from the device. DRQ should how be set. */
/* Check for errors. */
if (cdrom_decode_status(drive, DRQ_STAT, NULL))
return ide_stopped;
} else {
/* Otherwise, we must wait for DRQ to get set. */
if (ide_wait_stat(&startstop, drive, DRQ_STAT,
BUSY_STAT, WAIT_READY))
return startstop;
}
/* Arm the interrupt handler. */
ide_set_handler(drive, handler, rq->timeout, cdrom_timer_expiry);
/* ATAPI commands get padded out to 12 bytes minimum */
cmd_len = COMMAND_SIZE(rq->cmd[0]);
if (cmd_len < ATAPI_MIN_CDB_BYTES)
cmd_len = ATAPI_MIN_CDB_BYTES;
/* Send the command to the device. */
HWIF(drive)->atapi_output_bytes(drive, rq->cmd, cmd_len);
/* Start the DMA if need be */
if (info->dma)
hwif->dma_start(drive);
return ide_started;
}
/****************************************************************************
* Block read functions.
*/
/*
* Buffer up to SECTORS_TO_TRANSFER sectors from the drive in our sector
* buffer. Once the first sector is added, any subsequent sectors are
* assumed to be continuous (until the buffer is cleared). For the first