Annotation of Gnu-Mach/i386/i386at/gpl/linux/block/ide-cd.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * linux/drivers/block/ide-cd.c
        !             3:  *
        !             4:  * 1.00  Oct 31, 1994 -- Initial version.
        !             5:  * 1.01  Nov  2, 1994 -- Fixed problem with starting request in
        !             6:  *                       cdrom_check_status.
        !             7:  * 1.03  Nov 25, 1994 -- leaving unmask_intr[] as a user-setting (as for disks)
        !             8:  * (from mlord)       -- minor changes to cdrom_setup()
        !             9:  *                    -- renamed ide_dev_s to ide_drive_t, enable irq on command
        !            10:  * 2.00  Nov 27, 1994 -- Generalize packet command interface;
        !            11:  *                       add audio ioctls.
        !            12:  * 2.01  Dec  3, 1994 -- Rework packet command interface to handle devices
        !            13:  *                       which send an interrupt when ready for a command.
        !            14:  * 2.02  Dec 11, 1994 -- Cache the TOC in the driver.
        !            15:  *                       Don't use SCMD_PLAYAUDIO_TI; it's not included
        !            16:  *                       in the current version of ATAPI.
        !            17:  *                       Try to use LBA instead of track or MSF addressing
        !            18:  *                       when possible.
        !            19:  *                       Don't wait for READY_STAT.
        !            20:  * 2.03  Jan 10, 1995 -- Rewrite block read routines to handle block sizes
        !            21:  *                       other than 2k and to move multiple sectors in a
        !            22:  *                       single transaction.
        !            23:  * 2.04  Apr 21, 1995 -- Add work-around for Creative Labs CD220E drives.
        !            24:  *                       Thanks to Nick Saw <[email protected]> for
        !            25:  *                       help in figuring this out.  Ditto for Acer and
        !            26:  *                       Aztech drives, which seem to have the same problem.
        !            27:  * 2.04b May 30, 1995 -- Fix to match changes in ide.c version 3.16 -ml
        !            28:  * 2.05  Jun  8, 1995 -- Don't attempt to retry after an illegal request
        !            29:  *                        or data protect error.
        !            30:  *                       Use HWIF and DEV_HWIF macros as in ide.c.
        !            31:  *                       Always try to do a request_sense after
        !            32:  *                        a failed command.
        !            33:  *                       Include an option to give textual descriptions
        !            34:  *                        of ATAPI errors.
        !            35:  *                       Fix a bug in handling the sector cache which
        !            36:  *                        showed up if the drive returned data in 512 byte
        !            37:  *                        blocks (like Pioneer drives).  Thanks to
        !            38:  *                        Richard Hirst <[email protected]> for diagnosing this.
        !            39:  *                       Properly supply the page number field in the
        !            40:  *                        MODE_SELECT command.
        !            41:  *                       PLAYAUDIO12 is broken on the Aztech; work around it.
        !            42:  * 2.05x Aug 11, 1995 -- lots of data structure renaming/restructuring in ide.c
        !            43:  *                       (my apologies to Scott, but now ide-cd.c is independent)
        !            44:  * 3.00  Aug 22, 1995 -- Implement CDROMMULTISESSION ioctl.
        !            45:  *                       Implement CDROMREADAUDIO ioctl (UNTESTED).
        !            46:  *                       Use input_ide_data() and output_ide_data().
        !            47:  *                       Add door locking.
        !            48:  *                       Fix usage count leak in cdrom_open, which happened
        !            49:  *                        when a read-write mount was attempted.
        !            50:  *                       Try to load the disk on open.
        !            51:  *                       Implement CDROMEJECT_SW ioctl (off by default).
        !            52:  *                       Read total cdrom capacity during open.
        !            53:  *                       Rearrange logic in cdrom_decode_status.  Issue
        !            54:  *                        request sense commands for failed packet commands
        !            55:  *                        from here instead of from cdrom_queue_packet_command.
        !            56:  *                        Fix a race condition in retrieving error information.
        !            57:  *                       Suppress printing normal unit attention errors and
        !            58:  *                        some drive not ready errors.
        !            59:  *                       Implement CDROMVOLREAD ioctl.
        !            60:  *                       Implement CDROMREADMODE1/2 ioctls.
        !            61:  *                       Fix race condition in setting up interrupt handlers
        !            62:  *                        when the `serialize' option is used.
        !            63:  * 3.01  Sep  2, 1995 -- Fix ordering of reenabling interrupts in
        !            64:  *                        cdrom_queue_request.
        !            65:  *                       Another try at using ide_[input,output]_data.
        !            66:  * 3.02  Sep 16, 1995 -- Stick total disk capacity in partition table as well.
        !            67:  *                       Make VERBOSE_IDE_CD_ERRORS dump failed command again.
        !            68:  *                       Dump out more information for ILLEGAL REQUEST errs.
        !            69:  *                       Fix handling of errors occuring before the
        !            70:  *                        packet command is transferred.
        !            71:  *                       Fix transfers with odd bytelengths.
        !            72:  * 3.03  Oct 27, 1995 -- Some Creative drives have an id of just `CD'.
        !            73:  *                       `DCI-2S10' drives are broken too.
        !            74:  * 3.04  Nov 20, 1995 -- So are Vertos drives.
        !            75:  * 3.05  Dec  1, 1995 -- Changes to go with overhaul of ide.c and ide-tape.c
        !            76:  * 3.06  Dec 16, 1995 -- Add support needed for partitions.
        !            77:  *                       More workarounds for Vertos bugs (based on patches
        !            78:  *                        from Holger Dietze <[email protected]>).
        !            79:  *                       Try to eliminate byteorder assumptions.
        !            80:  *                       Use atapi_cdrom_subchnl struct definition.
        !            81:  *                       Add STANDARD_ATAPI compilation option.
        !            82:  * 3.07  Jan 29, 1996 -- More twiddling for broken drives: Sony 55D,
        !            83:  *                        Vertos 300.
        !            84:  *                       Add NO_DOOR_LOCKING configuration option.
        !            85:  *                       Handle drive_cmd requests w/NULL args (for hdparm -t).
        !            86:  *                       Work around sporadic Sony55e audio play problem.
        !            87:  * 3.07a Feb 11, 1996 -- check drive->id for NULL before dereferencing, to fix
        !            88:  *                        problem with "hde=cdrom" with no drive present.  -ml
        !            89:  *
        !            90:  * NOTE: Direct audio reads will only work on some types of drive.
        !            91:  * So far, i've received reports of success for Sony and Toshiba drives.
        !            92:  *
        !            93:  * ATAPI cd-rom driver.  To be used with ide.c.
        !            94:  *
        !            95:  * Copyright (C) 1994, 1995, 1996  scott snyder  <[email protected]>
        !            96:  * May be copied or modified under the terms of the GNU General Public License
        !            97:  * (../../COPYING).
        !            98:  */
        !            99: 
        !           100: 
        !           101: /***************************************************************************/
        !           102: 
        !           103: #include <linux/types.h>
        !           104: #include <linux/kernel.h>
        !           105: #include <linux/delay.h>
        !           106: #include <linux/timer.h>
        !           107: #include <linux/malloc.h>
        !           108: #include <linux/ioport.h>
        !           109: #include <linux/interrupt.h>
        !           110: #include <linux/blkdev.h>
        !           111: #include <linux/errno.h>
        !           112: #include <linux/hdreg.h>
        !           113: #include <linux/cdrom.h>
        !           114: #include <asm/irq.h>
        !           115: #include <asm/io.h>
        !           116: #include <asm/byteorder.h>
        !           117: #include <asm/segment.h>
        !           118: #ifdef __alpha__
        !           119: # include <asm/unaligned.h>
        !           120: #endif
        !           121: 
        !           122: #include "ide.h"
        !           123: 
        !           124: 
        !           125: 
        !           126: /* Turn this on to have the driver print out the meanings of the
        !           127:    ATAPI error codes.  This will use up additional kernel-space
        !           128:    memory, though. */
        !           129: 
        !           130: #ifndef VERBOSE_IDE_CD_ERRORS
        !           131: #define VERBOSE_IDE_CD_ERRORS 0
        !           132: #endif
        !           133: 
        !           134: 
        !           135: /* Turning this on will remove code to work around various nonstandard
        !           136:    ATAPI implementations.  If you know your drive follows the standard,
        !           137:    this will give you a slightly smaller kernel. */
        !           138: 
        !           139: #ifndef STANDARD_ATAPI
        !           140: #define STANDARD_ATAPI 0
        !           141: #endif
        !           142: 
        !           143: 
        !           144: /* Turning this on will disable the door-locking functionality.
        !           145:    This is apparently needed for supermount. */
        !           146: 
        !           147: #ifndef NO_DOOR_LOCKING
        !           148: #define NO_DOOR_LOCKING 0
        !           149: #endif
        !           150: 
        !           151: 
        !           152: /************************************************************************/
        !           153: 
        !           154: #define SECTOR_SIZE 512
        !           155: #define SECTOR_BITS 9
        !           156: #define SECTORS_PER_FRAME (CD_FRAMESIZE / SECTOR_SIZE)
        !           157: 
        !           158: #define MIN(a,b) ((a) < (b) ? (a) : (b))
        !           159: 
        !           160: /* special command codes for strategy routine. */
        !           161: #define PACKET_COMMAND        4315
        !           162: #define REQUEST_SENSE_COMMAND 4316
        !           163: #define RESET_DRIVE_COMMAND   4317
        !           164: 
        !           165: /* Some ATAPI command opcodes (just like SCSI).
        !           166:    (Some other cdrom-specific codes are in cdrom.h.) */
        !           167: #define TEST_UNIT_READY         0x00
        !           168: #define REQUEST_SENSE           0x03
        !           169: #define START_STOP              0x1b
        !           170: #define ALLOW_MEDIUM_REMOVAL    0x1e
        !           171: #define READ_CAPACITY          0x25
        !           172: #define READ_10                 0x28
        !           173: #define MODE_SENSE_10           0x5a
        !           174: #define MODE_SELECT_10          0x55
        !           175: #define READ_CD                 0xbe
        !           176: 
        !           177: 
        !           178: /* ATAPI sense keys (mostly copied from scsi.h). */
        !           179: 
        !           180: #define NO_SENSE                0x00
        !           181: #define RECOVERED_ERROR         0x01
        !           182: #define NOT_READY               0x02
        !           183: #define MEDIUM_ERROR            0x03
        !           184: #define HARDWARE_ERROR          0x04
        !           185: #define ILLEGAL_REQUEST         0x05
        !           186: #define UNIT_ATTENTION          0x06
        !           187: #define DATA_PROTECT            0x07
        !           188: #define ABORTED_COMMAND         0x0b
        !           189: #define MISCOMPARE              0x0e
        !           190: 
        !           191: /* We want some additional flags for cd-rom drives.
        !           192:    To save space in the ide_drive_t struct, use some fields which
        !           193:    doesn't make sense for cd-roms -- `bios_sect' and `bios_head'. */
        !           194: 
        !           195: /* Configuration flags.  These describe the capabilities of the drive.
        !           196:    They generally do not change after initialization, unless we learn
        !           197:    more about the drive from stuff failing. */
        !           198: struct ide_cd_config_flags {
        !           199:   __u8 drq_interrupt : 1; /* Device sends an interrupt when ready
        !           200:                                  for a packet command. */
        !           201:   __u8 no_doorlock   : 1; /* Drive cannot lock the door. */
        !           202: #if ! STANDARD_ATAPI
        !           203:   __u8 no_playaudio12: 1; /* The PLAYAUDIO12 command is not supported. */
        !           204:  
        !           205:   __u8 no_lba_toc    : 1; /* Drive cannot return TOC info in LBA format. */
        !           206:   __u8 playmsf_uses_bcd : 1; /* Drive uses BCD in PLAYAUDIO_MSF. */
        !           207:   __u8 old_readcd    : 1; /* Drive uses old READ CD opcode. */
        !           208:   __u8 vertos_lossage: 1; /* Drive is a Vertos 300,
        !           209:                                 and likes to speak BCD. */
        !           210: #endif  /* not STANDARD_ATAPI */
        !           211:   __u8 reserved : 1;
        !           212: };
        !           213: #define CDROM_CONFIG_FLAGS(drive) ((struct ide_cd_config_flags *)&((drive)->bios_sect))
        !           214: 
        !           215:  
        !           216: /* State flags.  These give information about the current state of the
        !           217:    drive, and will change during normal operation. */
        !           218: struct ide_cd_state_flags {
        !           219:   __u8 media_changed : 1; /* Driver has noticed a media change. */
        !           220:   __u8 toc_valid     : 1; /* Saved TOC information is current. */
        !           221:   __u8 door_locked   : 1; /* We think that the drive door is locked. */
        !           222:   __u8 eject_on_close: 1; /* Drive should eject when device is closed. */
        !           223:   __u8 reserved : 4;
        !           224: };
        !           225: #define CDROM_STATE_FLAGS(drive)  ((struct ide_cd_state_flags *)&((drive)->bios_head))
        !           226: 
        !           227: 
        !           228: #define SECTOR_BUFFER_SIZE CD_FRAMESIZE
        !           229: 
        !           230: 
        !           231: 
        !           232: /****************************************************************************
        !           233:  * Routines to read and write data from/to the drive, using
        !           234:  * the routines input_ide_data() and output_ide_data() from ide.c.
        !           235:  *
        !           236:  * These routines will round up any request for an odd number of bytes,
        !           237:  * so if an odd bytecount is specified, be sure that there's at least one
        !           238:  * extra byte allocated for the buffer.
        !           239:  */
        !           240: 
        !           241: 
        !           242: static inline
        !           243: void cdrom_in_bytes (ide_drive_t *drive, void *buffer, uint bytecount)
        !           244: {
        !           245:   ++bytecount;
        !           246:   ide_input_data (drive, buffer, bytecount / 4);
        !           247:   if ((bytecount & 0x03) >= 2)
        !           248:     {
        !           249:       insw (IDE_DATA_REG, ((byte *)buffer) + (bytecount & ~0x03), 1);
        !           250:     }
        !           251: }
        !           252: 
        !           253: 
        !           254: static inline
        !           255: void cdrom_out_bytes (ide_drive_t *drive, void *buffer, uint bytecount)
        !           256: {
        !           257:   ++bytecount;
        !           258:   ide_output_data (drive, buffer, bytecount / 4);
        !           259:   if ((bytecount & 0x03) >= 2)
        !           260:     {
        !           261:       outsw (IDE_DATA_REG, ((byte *)buffer) + (bytecount & ~0x03), 1);
        !           262:     }
        !           263: }
        !           264: 
        !           265: 
        !           266: 
        !           267: /****************************************************************************
        !           268:  * Descriptions of ATAPI error codes.
        !           269:  */
        !           270: 
        !           271: #define ARY_LEN(a) ((sizeof(a) / sizeof(a[0])))
        !           272: 
        !           273: #if VERBOSE_IDE_CD_ERRORS
        !           274: 
        !           275: /* From Table 124 of the ATAPI 1.2 spec. */
        !           276: 
        !           277: char *sense_key_texts[16] = {
        !           278:   "No sense data",
        !           279:   "Recovered error",
        !           280:   "Not ready",
        !           281:   "Medium error",
        !           282:   "Hardware error",
        !           283:   "Illegal request",
        !           284:   "Unit attention",
        !           285:   "Data protect",
        !           286:   "(reserved)",
        !           287:   "(reserved)",
        !           288:   "(reserved)",
        !           289:   "Aborted command",
        !           290:   "(reserved)",
        !           291:   "(reserved)",
        !           292:   "Miscompare",
        !           293:   "(reserved)",
        !           294: };
        !           295: 
        !           296: 
        !           297: /* From Table 125 of the ATAPI 1.2 spec. */
        !           298: 
        !           299: struct {
        !           300:   short asc_ascq;
        !           301:   char *text;
        !           302: } sense_data_texts[] = {
        !           303:   { 0x0000, "No additional sense information" },
        !           304:   { 0x0011, "Audio play operation in progress" },
        !           305:   { 0x0012, "Audio play operation paused" },
        !           306:   { 0x0013, "Audio play operation successfully completed" },
        !           307:   { 0x0014, "Audio play operation stopped due to error" },
        !           308:   { 0x0015, "No current audio status to return" },
        !           309: 
        !           310:   { 0x0200, "No seek complete" },
        !           311: 
        !           312:   { 0x0400, "Logical unit not ready - cause not reportable" },
        !           313:   { 0x0401, "Logical unit not ready - in progress (sic) of becoming ready" },
        !           314:   { 0x0402, "Logical unit not ready - initializing command required" },
        !           315:   { 0x0403, "Logical unit not ready - manual intervention required" },
        !           316: 
        !           317:   { 0x0600, "No reference position found" },
        !           318: 
        !           319:   { 0x0900, "Track following error" },
        !           320:   { 0x0901, "Tracking servo failure" },
        !           321:   { 0x0902, "Focus servo failure" },
        !           322:   { 0x0903, "Spindle servo failure" },
        !           323: 
        !           324:   { 0x1100, "Unrecovered read error" },
        !           325:   { 0x1106, "CIRC unrecovered error" },
        !           326: 
        !           327:   { 0x1500, "Random positioning error" },
        !           328:   { 0x1501, "Mechanical positioning error" },
        !           329:   { 0x1502, "Positioning error detected by read of medium" },
        !           330: 
        !           331:   { 0x1700, "Recovered data with no error correction applied" },
        !           332:   { 0x1701, "Recovered data with retries" },
        !           333:   { 0x1702, "Recovered data with positive head offset" },
        !           334:   { 0x1703, "Recovered data with negative head offset" },
        !           335:   { 0x1704, "Recovered data with retries and/or CIRC applied" },
        !           336:   { 0x1705, "Recovered data using previous sector ID" },
        !           337: 
        !           338:   { 0x1800, "Recovered data with error correction applied" },
        !           339:   { 0x1801, "Recovered data with error correction and retries applied" },
        !           340:   { 0x1802, "Recovered data - the data was auto-reallocated" },
        !           341:   { 0x1803, "Recovered data with CIRC" },
        !           342:   { 0x1804, "Recovered data with L-EC" },
        !           343:   { 0x1805, "Recovered data - recommend reassignment" },
        !           344:   { 0x1806, "Recovered data - recommend rewrite" },
        !           345: 
        !           346:   { 0x1a00, "Parameter list length error" },
        !           347: 
        !           348:   { 0x2000, "Invalid command operation code" },
        !           349: 
        !           350:   { 0x2100, "Logical block address out of range" },
        !           351: 
        !           352:   { 0x2400, "Invalid field in command packet" },
        !           353: 
        !           354:   { 0x2600, "Invalid field in parameter list" },
        !           355:   { 0x2601, "Parameter not supported" },
        !           356:   { 0x2602, "Parameter value invalid" },
        !           357:   { 0x2603, "Threshold parameters not supported" },
        !           358: 
        !           359:   { 0x2800, "Not ready to ready transition, medium may have changed" },
        !           360: 
        !           361:   { 0x2900, "Power on, reset or bus device reset occurred" },
        !           362: 
        !           363:   { 0x2a00, "Parameters changed" },
        !           364:   { 0x2a01, "Mode parameters changed" },
        !           365: 
        !           366:   { 0x3000, "Incompatible medium installed" },
        !           367:   { 0x3001, "Cannot read medium - unknown format" },
        !           368:   { 0x3002, "Cannot read medium - incompatible format" },
        !           369: 
        !           370:   { 0x3700, "Rounded parameter" },
        !           371: 
        !           372:   { 0x3900, "Saving parameters not supported" },
        !           373: 
        !           374:   { 0x3a00, "Medium not present" },
        !           375: 
        !           376:   { 0x3f00, "ATAPI CD-ROM drive operating conditions have changed" },
        !           377:   { 0x3f01, "Microcode has been changed" },
        !           378:   { 0x3f02, "Changed operating definition" },
        !           379:   { 0x3f03, "Inquiry data has changed" },
        !           380: 
        !           381:   { 0x4000, "Diagnostic failure on component (ASCQ)" },
        !           382: 
        !           383:   { 0x4400, "Internal ATAPI CD-ROM drive failure" },
        !           384: 
        !           385:   { 0x4e00, "Overlapped commands attempted" },
        !           386: 
        !           387:   { 0x5300, "Media load or eject failed" },
        !           388:   { 0x5302, "Medium removal prevented" },
        !           389: 
        !           390:   { 0x5700, "Unable to recover table of contents" },
        !           391: 
        !           392:   { 0x5a00, "Operator request or state change input (unspecified)" },
        !           393:   { 0x5a01, "Operator medium removal request" },
        !           394: 
        !           395:   { 0x5b00, "Threshold condition met" },
        !           396: 
        !           397:   { 0x5c00, "Status change" },
        !           398: 
        !           399:   { 0x6300, "End of user area encountered on this track" },
        !           400: 
        !           401:   { 0x6400, "Illegal mode for this track" },
        !           402: 
        !           403:   { 0xbf00, "Loss of streaming" },
        !           404: };
        !           405: #endif
        !           406: 
        !           407: 
        !           408: 
        !           409: /****************************************************************************
        !           410:  * Generic packet command support and error handling routines.
        !           411:  */
        !           412: 
        !           413: 
        !           414: static
        !           415: void cdrom_analyze_sense_data (ide_drive_t *drive, 
        !           416:                               struct atapi_request_sense *reqbuf,
        !           417:                               struct packet_command *failed_command)
        !           418: {
        !           419:   /* Don't print not ready or unit attention errors for READ_SUBCHANNEL.
        !           420:      Workman (and probably other programs) uses this command to poll
        !           421:      the drive, and we don't want to fill the syslog with useless errors. */
        !           422:   if (failed_command &&
        !           423:       failed_command->c[0] == SCMD_READ_SUBCHANNEL &&
        !           424:       (reqbuf->sense_key == NOT_READY || reqbuf->sense_key == UNIT_ATTENTION))
        !           425:     return;
        !           426: 
        !           427: #if VERBOSE_IDE_CD_ERRORS
        !           428:   {
        !           429:     int i;
        !           430:     char *s;
        !           431:     char buf[80];
        !           432: 
        !           433:     printk ("ATAPI device %s:\n", drive->name);
        !           434: 
        !           435:     printk ("  Error code: 0x%02x\n", reqbuf->error_code);
        !           436: 
        !           437:     if (reqbuf->sense_key >= 0 &&
        !           438:        reqbuf->sense_key < ARY_LEN (sense_key_texts))
        !           439:       s = sense_key_texts[reqbuf->sense_key];
        !           440:     else
        !           441:       s = "(bad sense key)";
        !           442: 
        !           443:     printk ("  Sense key: 0x%02x - %s\n", reqbuf->sense_key, s);
        !           444: 
        !           445:     if (reqbuf->asc == 0x40) {
        !           446:       sprintf (buf, "Diagnostic failure on component 0x%02x", reqbuf->ascq);
        !           447:       s = buf;
        !           448:     }
        !           449: 
        !           450:     else {
        !           451:       int lo, hi;
        !           452:       int key = (reqbuf->asc << 8);
        !           453:       if ( ! (reqbuf->ascq >= 0x80 && reqbuf->ascq <= 0xdd) )
        !           454:        key |= reqbuf->ascq;
        !           455: 
        !           456:       lo = 0;
        !           457:       hi = ARY_LEN (sense_data_texts);
        !           458:       s = NULL;
        !           459: 
        !           460:       while (hi > lo) {
        !           461:        int mid = (lo + hi) / 2;
        !           462:        if (sense_data_texts[mid].asc_ascq == key) {
        !           463:          s = sense_data_texts[mid].text;
        !           464:          break;
        !           465:        }
        !           466:        else if (sense_data_texts[mid].asc_ascq > key)
        !           467:          hi = mid;
        !           468:        else
        !           469:          lo = mid+1;
        !           470:       }
        !           471:     }
        !           472: 
        !           473:     if (s == NULL) {
        !           474:       if (reqbuf->asc > 0x80)
        !           475:        s = "(vendor-specific error)";
        !           476:       else
        !           477:        s = "(reserved error code)";
        !           478:     }
        !           479: 
        !           480:     printk ("  Additional sense data: 0x%02x, 0x%02x  - %s\n",
        !           481:            reqbuf->asc, reqbuf->ascq, s);
        !           482: 
        !           483:     if (failed_command != NULL) {
        !           484:       printk ("  Failed packet command: ");
        !           485:       for (i=0; i<sizeof (failed_command->c); i++)
        !           486:        printk ("%02x ", failed_command->c[i]);
        !           487:       printk ("\n");
        !           488:     }
        !           489: 
        !           490:     if (reqbuf->sense_key == ILLEGAL_REQUEST &&
        !           491:        (reqbuf->sense_key_specific[0] & 0x80) != 0)
        !           492:       {
        !           493:        printk ("  Error in %s byte %d",
        !           494:                (reqbuf->sense_key_specific[0] & 0x40) != 0
        !           495:                  ? "command packet"
        !           496:                  : "command data",
        !           497:                (reqbuf->sense_key_specific[1] << 8) +
        !           498:                reqbuf->sense_key_specific[2]);
        !           499: 
        !           500:        if ((reqbuf->sense_key_specific[0] & 0x40) != 0)
        !           501:          {
        !           502:            printk (" bit %d", reqbuf->sense_key_specific[0] & 0x07);
        !           503:          }
        !           504: 
        !           505:        printk ("\n");
        !           506:       }
        !           507:   }
        !           508: 
        !           509: #else
        !           510: 
        !           511:   /* Suppress printing unit attention and `in progress of becoming ready'
        !           512:      errors when we're not being verbose. */
        !           513: 
        !           514:   if (reqbuf->sense_key == UNIT_ATTENTION ||
        !           515:       (reqbuf->sense_key == NOT_READY && (reqbuf->asc == 4 ||
        !           516:                                          reqbuf->asc == 0x3a)))
        !           517:     return;
        !           518: 
        !           519:   printk ("%s: code: 0x%02x  key: 0x%02x  asc: 0x%02x  ascq: 0x%02x\n",
        !           520:          drive->name,
        !           521:          reqbuf->error_code, reqbuf->sense_key, reqbuf->asc, reqbuf->ascq);
        !           522: #endif
        !           523: }
        !           524: 
        !           525: 
        !           526: /* Fix up a possibly partially-processed request so that we can
        !           527:    start it over entirely, or even put it back on the request queue. */
        !           528: static void restore_request (struct request *rq)
        !           529: {
        !           530:   if (rq->buffer != rq->bh->b_data)
        !           531:     {
        !           532:       int n = (rq->buffer - rq->bh->b_data) / SECTOR_SIZE;
        !           533:       rq->buffer = rq->bh->b_data;
        !           534:       rq->nr_sectors += n;
        !           535:       rq->sector -= n;
        !           536:     }
        !           537:   rq->current_nr_sectors = rq->bh->b_size >> SECTOR_BITS;
        !           538: }
        !           539: 
        !           540: 
        !           541: static void cdrom_queue_request_sense (ide_drive_t *drive, 
        !           542:                                       struct semaphore *sem,
        !           543:                                       struct atapi_request_sense *reqbuf,
        !           544:                                       struct packet_command *failed_command)
        !           545: {
        !           546:   struct request *rq;
        !           547:   struct packet_command *pc;
        !           548:   int len;
        !           549: 
        !           550:   /* If the request didn't explicitly specify where to put the sense data,
        !           551:      use the statically allocated structure. */
        !           552:   if (reqbuf == NULL)
        !           553:     reqbuf = &drive->cdrom_info.sense_data;
        !           554: 
        !           555:   /* Make up a new request to retrieve sense information. */
        !           556: 
        !           557:   pc = &HWIF(drive)->request_sense_pc;
        !           558:   memset (pc, 0, sizeof (*pc));
        !           559: 
        !           560:   /* The request_sense structure has an odd number of (16-bit) words,
        !           561:      which won't work well with 32-bit transfers.  However, we don't care
        !           562:      about the last two bytes, so just truncate the structure down
        !           563:      to an even length. */
        !           564:   len = sizeof (*reqbuf) / 4;
        !           565:   len *= 4;
        !           566: 
        !           567:   pc->c[0] = REQUEST_SENSE;
        !           568:   pc->c[4] = len;
        !           569:   pc->buffer = (char *)reqbuf;
        !           570:   pc->buflen = len;
        !           571:   pc->sense_data = (struct atapi_request_sense *)failed_command;
        !           572: 
        !           573:   /* stuff the sense request in front of our current request */
        !           574: 
        !           575:   rq = &HWIF(drive)->request_sense_request;
        !           576:   ide_init_drive_cmd (rq);
        !           577:   rq->cmd = REQUEST_SENSE_COMMAND;
        !           578:   rq->buffer = (char *)pc;
        !           579:   rq->sem = sem;
        !           580:   (void) ide_do_drive_cmd (drive, rq, ide_preempt);
        !           581: }
        !           582: 
        !           583: 
        !           584: static void cdrom_end_request (int uptodate, ide_drive_t *drive)
        !           585: {
        !           586:   struct request *rq = HWGROUP(drive)->rq;
        !           587: 
        !           588:   /* The code in blk.h can screw us up on error recovery if the block
        !           589:      size is larger than 1k.  Fix that up here. */
        !           590:   if (!uptodate && rq->bh != 0)
        !           591:     {
        !           592:       int adj = rq->current_nr_sectors - 1;
        !           593:       rq->current_nr_sectors -= adj;
        !           594:       rq->sector += adj;
        !           595:     }
        !           596: 
        !           597:   if (rq->cmd == REQUEST_SENSE_COMMAND && uptodate)
        !           598:     {
        !           599:       struct packet_command *pc = (struct packet_command *)rq->buffer;
        !           600:       cdrom_analyze_sense_data (drive,
        !           601:                                (struct atapi_request_sense *)(pc->buffer - pc->c[4]), 
        !           602:                                (struct packet_command *)pc->sense_data);
        !           603:     }
        !           604: 
        !           605:   ide_end_request (uptodate, HWGROUP(drive));
        !           606: }
        !           607: 
        !           608: 
        !           609: /* Mark that we've seen a media change, and invalidate our internal
        !           610:    buffers. */
        !           611: static void cdrom_saw_media_change (ide_drive_t *drive)
        !           612: {
        !           613:   CDROM_STATE_FLAGS (drive)->media_changed = 1;
        !           614:   CDROM_STATE_FLAGS (drive)->toc_valid = 0;
        !           615:   drive->cdrom_info.nsectors_buffered = 0;
        !           616: }
        !           617: 
        !           618: 
        !           619: /* Returns 0 if the request should be continued.
        !           620:    Returns 1 if the request was ended. */
        !           621: static int cdrom_decode_status (ide_drive_t *drive, int good_stat, int *stat_ret)
        !           622: {
        !           623:   struct request *rq = HWGROUP(drive)->rq;
        !           624:   int stat, err, sense_key, cmd;
        !           625: 
        !           626:   /* Check for errors. */
        !           627:   stat = GET_STAT();
        !           628:   *stat_ret = stat;
        !           629: 
        !           630:   if (OK_STAT (stat, good_stat, BAD_R_STAT))
        !           631:     return 0;
        !           632: 
        !           633:   /* Got an error. */
        !           634:   err = IN_BYTE (IDE_ERROR_REG);
        !           635:   sense_key = err >> 4;
        !           636: 
        !           637:   if (rq == NULL)
        !           638:     printk ("%s : missing request in cdrom_decode_status\n", drive->name);
        !           639:   else
        !           640:     {
        !           641:       cmd = rq->cmd;
        !           642: 
        !           643:       if (cmd == REQUEST_SENSE_COMMAND)
        !           644:        {
        !           645:          /* We got an error trying to get sense info from the drive
        !           646:             (probably while trying to recover from a former error).
        !           647:             Just give up. */
        !           648: 
        !           649:          struct packet_command *pc = (struct packet_command *)rq->buffer;
        !           650:          pc->stat = 1;
        !           651:          cdrom_end_request (1, drive);
        !           652:          ide_error (drive, "request sense failure", stat);
        !           653:          return 1;
        !           654:        }
        !           655: 
        !           656:       else if (cmd == PACKET_COMMAND)
        !           657:        {
        !           658:          /* All other functions, except for READ. */
        !           659: 
        !           660:          struct packet_command *pc = (struct packet_command *)rq->buffer;
        !           661:          struct semaphore *sem = NULL;
        !           662: 
        !           663:          /* Check for tray open. */
        !           664:          if (sense_key == NOT_READY)
        !           665:            {
        !           666:              cdrom_saw_media_change (drive);
        !           667: 
        !           668:              /* Print an error message to the syslog.
        !           669:                 Exception: don't print anything if this is a read subchannel
        !           670:                 command.  This is because workman constantly polls the drive
        !           671:                 with this command, and we don't want to uselessly fill up
        !           672:                 the syslog. */
        !           673:              if (pc->c[0] != SCMD_READ_SUBCHANNEL)
        !           674:                printk ("%s : tray open or drive not ready\n", drive->name);
        !           675:            }
        !           676: 
        !           677:          /* Check for media change. */
        !           678:          else if (sense_key == UNIT_ATTENTION)
        !           679:            {
        !           680:              cdrom_saw_media_change (drive);
        !           681:              printk ("%s: media changed\n", drive->name);
        !           682:            }
        !           683: 
        !           684:          /* Otherwise, print an error. */
        !           685:          else
        !           686:            {
        !           687:              ide_dump_status (drive, "packet command error", stat);
        !           688:            }
        !           689: 
        !           690:          /* Set the error flag and complete the request.
        !           691:             Then, if we have a CHECK CONDITION status, queue a request
        !           692:             sense command.  We must be careful, though: we don't want
        !           693:             the thread in cdrom_queue_packet_command to wake up until
        !           694:             the request sense has completed.  We do this by transferring
        !           695:             the semaphore from the packet command request to the
        !           696:             request sense request. */
        !           697: 
        !           698:          if ((stat & ERR_STAT) != 0)
        !           699:            {
        !           700:              sem = rq->sem;
        !           701:              rq->sem = NULL;
        !           702:            }
        !           703: 
        !           704:          pc->stat = 1;
        !           705:          cdrom_end_request (1, drive);
        !           706: 
        !           707:          if ((stat & ERR_STAT) != 0)
        !           708:            cdrom_queue_request_sense (drive, sem, pc->sense_data, pc);
        !           709:        }
        !           710: 
        !           711:       else
        !           712:        {
        !           713:          /* Handle errors from READ requests. */
        !           714: 
        !           715:          /* Check for tray open. */
        !           716:          if (sense_key == NOT_READY)
        !           717:            {
        !           718:              cdrom_saw_media_change (drive);
        !           719: 
        !           720:              /* Fail the request. */
        !           721:              printk ("%s : tray open\n", drive->name);
        !           722:              cdrom_end_request (0, drive);
        !           723:            }
        !           724: 
        !           725:          /* Check for media change. */
        !           726:          else if (sense_key == UNIT_ATTENTION)
        !           727:            {
        !           728:              cdrom_saw_media_change (drive);
        !           729: 
        !           730:              /* Arrange to retry the request.
        !           731:                 But be sure to give up if we've retried too many times. */
        !           732:              if (++rq->errors > ERROR_MAX)
        !           733:                {
        !           734:                  cdrom_end_request (0, drive);
        !           735:                }
        !           736:            }
        !           737:          /* No point in retrying after an illegal request or
        !           738:             data protect error.*/
        !           739:          else if (sense_key == ILLEGAL_REQUEST || sense_key == DATA_PROTECT)
        !           740:            {
        !           741:              ide_dump_status (drive, "command error", stat);
        !           742:              cdrom_end_request (0, drive);
        !           743:            }
        !           744: 
        !           745:          /* If there were other errors, go to the default handler. */
        !           746:          else if ((err & ~ABRT_ERR) != 0)
        !           747:            {
        !           748:              ide_error (drive, "cdrom_decode_status", stat);
        !           749:              return 1;
        !           750:            }
        !           751: 
        !           752:          /* Else, abort if we've racked up too many retries. */
        !           753:          else if ((++rq->errors > ERROR_MAX))
        !           754:            {
        !           755:              cdrom_end_request (0, drive);
        !           756:            }
        !           757: 
        !           758:          /* If we got a CHECK_CONDITION status, queue a request sense
        !           759:             command. */
        !           760:          if ((stat & ERR_STAT) != 0)
        !           761:            cdrom_queue_request_sense (drive, NULL, NULL, NULL);
        !           762:        }
        !           763:     }
        !           764: 
        !           765:   /* Retry, or handle the next request. */
        !           766:   return 1;
        !           767: }
        !           768: 
        !           769: 
        !           770: /* Set up the device registers for transferring a packet command on DEV,
        !           771:    expecting to later transfer XFERLEN bytes.  HANDLER is the routine
        !           772:    which actually transfers the command to the drive.  If this is a
        !           773:    drq_interrupt device, this routine will arrange for HANDLER to be
        !           774:    called when the interrupt from the drive arrives.  Otherwise, HANDLER
        !           775:    will be called immediately after the drive is prepared for the transfer. */
        !           776: 
        !           777: static int cdrom_start_packet_command (ide_drive_t *drive, int xferlen,
        !           778:                                       ide_handler_t *handler)
        !           779: {
        !           780:   /* Wait for the controller to be idle. */
        !           781:   if (ide_wait_stat (drive, 0, BUSY_STAT, WAIT_READY)) return 1;
        !           782: 
        !           783:   /* Set up the controller registers. */
        !           784:   OUT_BYTE (0, IDE_FEATURE_REG);
        !           785:   OUT_BYTE (0, IDE_NSECTOR_REG);
        !           786:   OUT_BYTE (0, IDE_SECTOR_REG);
        !           787: 
        !           788:   OUT_BYTE (xferlen & 0xff, IDE_LCYL_REG);
        !           789:   OUT_BYTE (xferlen >> 8  , IDE_HCYL_REG);
        !           790:   OUT_BYTE (drive->ctl, IDE_CONTROL_REG);
        !           791: 
        !           792:   if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt)
        !           793:     {
        !           794:       ide_set_handler (drive, handler, WAIT_CMD);
        !           795:       OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */
        !           796:     }
        !           797:   else
        !           798:     {
        !           799:       OUT_BYTE (WIN_PACKETCMD, IDE_COMMAND_REG); /* packet command */
        !           800:       (*handler) (drive);
        !           801:     }
        !           802: 
        !           803:   return 0;
        !           804: }
        !           805: 
        !           806: 
        !           807: /* Send a packet command to DRIVE described by CMD_BUF and CMD_LEN.
        !           808:    The device registers must have already been prepared
        !           809:    by cdrom_start_packet_command.
        !           810:    HANDLER is the interrupt handler to call when the command completes
        !           811:    or there's data ready. */
        !           812: static int cdrom_transfer_packet_command (ide_drive_t *drive,
        !           813:                                           char *cmd_buf, int cmd_len,
        !           814:                                          ide_handler_t *handler)
        !           815: {
        !           816:   if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt)
        !           817:     {
        !           818:       /* Here we should have been called after receiving an interrupt
        !           819:          from the device.  DRQ should how be set. */
        !           820:       int stat_dum;
        !           821: 
        !           822:       /* Check for errors. */
        !           823:       if (cdrom_decode_status (drive, DRQ_STAT, &stat_dum)) return 1;
        !           824:     }
        !           825:   else
        !           826:     {
        !           827:       /* Otherwise, we must wait for DRQ to get set. */
        !           828:       if (ide_wait_stat (drive, DRQ_STAT, BUSY_STAT, WAIT_READY)) return 1;
        !           829:     }
        !           830: 
        !           831:   /* Arm the interrupt handler. */
        !           832:   ide_set_handler (drive, handler, WAIT_CMD);
        !           833: 
        !           834:   /* Send the command to the device. */
        !           835:   cdrom_out_bytes (drive, cmd_buf, cmd_len);
        !           836: 
        !           837:   return 0;
        !           838: }
        !           839: 
        !           840: 
        !           841: 
        !           842: /****************************************************************************
        !           843:  * Block read functions.
        !           844:  */
        !           845: 
        !           846: /*
        !           847:  * Buffer up to SECTORS_TO_TRANSFER sectors from the drive in our sector
        !           848:  * buffer.  Once the first sector is added, any subsequent sectors are
        !           849:  * assumed to be continuous (until the buffer is cleared).  For the first
        !           850:  * sector added, SECTOR is its sector number.  (SECTOR is then ignored until
        !           851:  * the buffer is cleared.)
        !           852:  */
        !           853: static void cdrom_buffer_sectors (ide_drive_t *drive, unsigned long sector,
        !           854:                                   int sectors_to_transfer)
        !           855: {
        !           856:   struct cdrom_info *info = &drive->cdrom_info;
        !           857: 
        !           858:   /* Number of sectors to read into the buffer. */
        !           859:   int sectors_to_buffer = MIN (sectors_to_transfer,
        !           860:                                (SECTOR_BUFFER_SIZE >> SECTOR_BITS) -
        !           861:                                  info->nsectors_buffered);
        !           862: 
        !           863:   char *dest;
        !           864: 
        !           865:   /* If we don't yet have a sector buffer, try to allocate one.
        !           866:      If we can't get one atomically, it's not fatal -- we'll just throw
        !           867:      the data away rather than caching it. */
        !           868:   if (info->sector_buffer == NULL)
        !           869:     {
        !           870:       info->sector_buffer = (char *) kmalloc (SECTOR_BUFFER_SIZE, GFP_ATOMIC);
        !           871: 
        !           872:       /* If we couldn't get a buffer, don't try to buffer anything... */
        !           873:       if (info->sector_buffer == NULL)
        !           874:         sectors_to_buffer = 0;
        !           875:     }
        !           876: 
        !           877:   /* If this is the first sector in the buffer, remember its number. */
        !           878:   if (info->nsectors_buffered == 0)
        !           879:     info->sector_buffered = sector;
        !           880: 
        !           881:   /* Read the data into the buffer. */
        !           882:   dest = info->sector_buffer + info->nsectors_buffered * SECTOR_SIZE;
        !           883:   while (sectors_to_buffer > 0)
        !           884:     {
        !           885:       cdrom_in_bytes (drive, dest, SECTOR_SIZE);
        !           886:       --sectors_to_buffer;
        !           887:       --sectors_to_transfer;
        !           888:       ++info->nsectors_buffered;
        !           889:       dest += SECTOR_SIZE;
        !           890:     }
        !           891: 
        !           892:   /* Throw away any remaining data. */
        !           893:   while (sectors_to_transfer > 0)
        !           894:     {
        !           895:       char dum[SECTOR_SIZE];
        !           896:       cdrom_in_bytes (drive, dum, sizeof (dum));
        !           897:       --sectors_to_transfer;
        !           898:     }
        !           899: }
        !           900: 
        !           901: 
        !           902: /*
        !           903:  * Check the contents of the interrupt reason register from the cdrom
        !           904:  * and attempt to recover if there are problems.  Returns  0 if everything's
        !           905:  * ok; nonzero if the request has been terminated.
        !           906:  */
        !           907: static inline
        !           908: int cdrom_read_check_ireason (ide_drive_t *drive, int len, int ireason)
        !           909: {
        !           910:   ireason &= 3;
        !           911:   if (ireason == 2) return 0;
        !           912: 
        !           913:   if (ireason == 0)
        !           914:     {
        !           915:       /* Whoops... The drive is expecting to receive data from us! */
        !           916:       printk ("%s: cdrom_read_intr: "
        !           917:               "Drive wants to transfer data the wrong way!\n",
        !           918:               drive->name);
        !           919: 
        !           920:       /* Throw some data at the drive so it doesn't hang
        !           921:          and quit this request. */
        !           922:       while (len > 0)
        !           923:         {
        !           924:           int dum = 0;
        !           925:          cdrom_out_bytes (drive, &dum, sizeof (dum));
        !           926:           len -= sizeof (dum);
        !           927:         }
        !           928:     }
        !           929: 
        !           930:   else
        !           931:     {
        !           932:       /* Drive wants a command packet, or invalid ireason... */
        !           933:       printk ("%s: cdrom_read_intr: bad interrupt reason %d\n",
        !           934:               drive->name, ireason);
        !           935:     }
        !           936: 
        !           937:   cdrom_end_request (0, drive);
        !           938:   return -1;
        !           939: }
        !           940: 
        !           941: 
        !           942: /*
        !           943:  * Interrupt routine.  Called when a read request has completed.
        !           944:  */
        !           945: static void cdrom_read_intr (ide_drive_t *drive)
        !           946: {
        !           947:   int stat;
        !           948:   int ireason, len, sectors_to_transfer, nskip;
        !           949: 
        !           950:   struct request *rq = HWGROUP(drive)->rq;
        !           951: 
        !           952:   /* Check for errors. */
        !           953:   if (cdrom_decode_status (drive, 0, &stat)) return;
        !           954: 
        !           955:   /* Read the interrupt reason and the transfer length. */
        !           956:   ireason = IN_BYTE (IDE_NSECTOR_REG);
        !           957:   len = IN_BYTE (IDE_LCYL_REG) + 256 * IN_BYTE (IDE_HCYL_REG);
        !           958: 
        !           959:   /* If DRQ is clear, the command has completed. */
        !           960:   if ((stat & DRQ_STAT) == 0)
        !           961:     {
        !           962:       /* If we're not done filling the current buffer, complain.
        !           963:          Otherwise, complete the command normally. */
        !           964:       if (rq->current_nr_sectors > 0)
        !           965:         {
        !           966:           printk ("%s: cdrom_read_intr: data underrun (%ld blocks)\n",
        !           967:                   drive->name, rq->current_nr_sectors);
        !           968:           cdrom_end_request (0, drive);
        !           969:         }
        !           970:       else
        !           971:         cdrom_end_request (1, drive);
        !           972: 
        !           973:       return;
        !           974:     }
        !           975: 
        !           976:   /* Check that the drive is expecting to do the same thing that we are. */
        !           977:   if (cdrom_read_check_ireason (drive, len, ireason)) return;
        !           978: 
        !           979:   /* Assume that the drive will always provide data in multiples of at least
        !           980:      SECTOR_SIZE, as it gets hairy to keep track of the transfers otherwise. */
        !           981:   if ((len % SECTOR_SIZE) != 0)
        !           982:     {
        !           983:       printk ("%s: cdrom_read_intr: Bad transfer size %d\n",
        !           984:               drive->name, len);
        !           985:       printk ("  This drive is not supported by this version of the driver\n");
        !           986:       cdrom_end_request (0, drive);
        !           987:       return;
        !           988:     }
        !           989: 
        !           990:   /* The number of sectors we need to read from the drive. */
        !           991:   sectors_to_transfer = len / SECTOR_SIZE;
        !           992: 
        !           993:   /* First, figure out if we need to bit-bucket any of the leading sectors. */
        !           994:   nskip = MIN ((int)(rq->current_nr_sectors - (rq->bh->b_size >> SECTOR_BITS)),
        !           995:                sectors_to_transfer);
        !           996: 
        !           997:   while (nskip > 0)
        !           998:     {
        !           999:       /* We need to throw away a sector. */
        !          1000:       char dum[SECTOR_SIZE];
        !          1001:       cdrom_in_bytes (drive, dum, sizeof (dum));
        !          1002: 
        !          1003:       --rq->current_nr_sectors;
        !          1004:       --nskip;
        !          1005:       --sectors_to_transfer;
        !          1006:     }
        !          1007: 
        !          1008:   /* Now loop while we still have data to read from the drive. */
        !          1009:   while (sectors_to_transfer > 0)
        !          1010:     {
        !          1011:       int this_transfer;
        !          1012: 
        !          1013:       /* If we've filled the present buffer but there's another chained
        !          1014:          buffer after it, move on. */
        !          1015:       if (rq->current_nr_sectors == 0 &&
        !          1016:           rq->nr_sectors > 0)
        !          1017:         cdrom_end_request (1, drive);
        !          1018: 
        !          1019:       /* If the buffers are full, cache the rest of the data in our
        !          1020:          internal buffer. */
        !          1021:       if (rq->current_nr_sectors == 0)
        !          1022:         {
        !          1023:           cdrom_buffer_sectors (drive, rq->sector, sectors_to_transfer);
        !          1024:           sectors_to_transfer = 0;
        !          1025:         }
        !          1026:       else
        !          1027:         {
        !          1028:           /* Transfer data to the buffers.
        !          1029:              Figure out how many sectors we can transfer
        !          1030:              to the current buffer. */
        !          1031:           this_transfer = MIN (sectors_to_transfer,
        !          1032:                                rq->current_nr_sectors);
        !          1033: 
        !          1034:           /* Read this_transfer sectors into the current buffer. */
        !          1035:           while (this_transfer > 0)
        !          1036:             {
        !          1037:               cdrom_in_bytes (drive, rq->buffer, SECTOR_SIZE);
        !          1038:               rq->buffer += SECTOR_SIZE;
        !          1039:               --rq->nr_sectors;
        !          1040:               --rq->current_nr_sectors;
        !          1041:               ++rq->sector;
        !          1042:               --this_transfer;
        !          1043:               --sectors_to_transfer;
        !          1044:             }
        !          1045:         }
        !          1046:     }
        !          1047: 
        !          1048:   /* Done moving data!
        !          1049:      Wait for another interrupt. */
        !          1050:   ide_set_handler (drive, &cdrom_read_intr, WAIT_CMD);
        !          1051: }
        !          1052: 
        !          1053: 
        !          1054: /*
        !          1055:  * Try to satisfy some of the current read request from our cached data.
        !          1056:  * Returns nonzero if the request has been completed, zero otherwise.
        !          1057:  */
        !          1058: static int cdrom_read_from_buffer (ide_drive_t *drive)
        !          1059: {
        !          1060:   struct cdrom_info *info = &drive->cdrom_info;
        !          1061:   struct request *rq = HWGROUP(drive)->rq;
        !          1062: 
        !          1063:   /* Can't do anything if there's no buffer. */
        !          1064:   if (info->sector_buffer == NULL) return 0;
        !          1065: 
        !          1066:   /* Loop while this request needs data and the next block is present
        !          1067:      in our cache. */
        !          1068:   while (rq->nr_sectors > 0 &&
        !          1069:          rq->sector >= info->sector_buffered &&
        !          1070:          rq->sector < info->sector_buffered + info->nsectors_buffered)
        !          1071:     {
        !          1072:       if (rq->current_nr_sectors == 0)
        !          1073:         cdrom_end_request (1, drive);
        !          1074: 
        !          1075:       memcpy (rq->buffer,
        !          1076:               info->sector_buffer +
        !          1077:                 (rq->sector - info->sector_buffered) * SECTOR_SIZE,
        !          1078:               SECTOR_SIZE);
        !          1079:       rq->buffer += SECTOR_SIZE;
        !          1080:       --rq->current_nr_sectors;
        !          1081:       --rq->nr_sectors;
        !          1082:       ++rq->sector;
        !          1083:     }
        !          1084: 
        !          1085:   /* If we've satisfied the current request, terminate it successfully. */
        !          1086:   if (rq->nr_sectors == 0)
        !          1087:     {
        !          1088:       cdrom_end_request (1, drive);
        !          1089:       return -1;
        !          1090:     }
        !          1091: 
        !          1092:   /* Move on to the next buffer if needed. */
        !          1093:   if (rq->current_nr_sectors == 0)
        !          1094:     cdrom_end_request (1, drive);
        !          1095: 
        !          1096:   /* If this condition does not hold, then the kluge i use to
        !          1097:      represent the number of sectors to skip at the start of a transfer
        !          1098:      will fail.  I think that this will never happen, but let's be
        !          1099:      paranoid and check. */
        !          1100:   if (rq->current_nr_sectors < (rq->bh->b_size >> SECTOR_BITS) &&
        !          1101:       (rq->sector % SECTORS_PER_FRAME) != 0)
        !          1102:     {
        !          1103:       printk ("%s: cdrom_read_from_buffer: buffer botch (%ld)\n",
        !          1104:               drive->name, rq->sector);
        !          1105:       cdrom_end_request (0, drive);
        !          1106:       return -1;
        !          1107:     }
        !          1108: 
        !          1109:   return 0;
        !          1110: }
        !          1111: 
        !          1112: 
        !          1113: 
        !          1114: /*
        !          1115:  * Routine to send a read packet command to the drive.
        !          1116:  * This is usually called directly from cdrom_start_read.
        !          1117:  * However, for drq_interrupt devices, it is called from an interrupt
        !          1118:  * when the drive is ready to accept the command.
        !          1119:  */
        !          1120: static void cdrom_start_read_continuation (ide_drive_t *drive)
        !          1121: {
        !          1122:   struct packet_command pc;
        !          1123:   struct request *rq = HWGROUP(drive)->rq;
        !          1124: 
        !          1125:   int nsect, sector, nframes, frame, nskip;
        !          1126: 
        !          1127:   /* Number of sectors to transfer. */
        !          1128:   nsect = rq->nr_sectors;
        !          1129: 
        !          1130:   /* Starting sector. */
        !          1131:   sector = rq->sector;
        !          1132: 
        !          1133:   /* If the requested sector doesn't start on a cdrom block boundary,
        !          1134:      we must adjust the start of the transfer so that it does,
        !          1135:      and remember to skip the first few sectors.  If the CURRENT_NR_SECTORS
        !          1136:      field is larger than the size of the buffer, it will mean that
        !          1137:      we're to skip a number of sectors equal to the amount by which
        !          1138:      CURRENT_NR_SECTORS is larger than the buffer size. */
        !          1139:   nskip = (sector % SECTORS_PER_FRAME);
        !          1140:   if (nskip > 0)
        !          1141:     {
        !          1142:       /* Sanity check... */
        !          1143:       if (rq->current_nr_sectors != (rq->bh->b_size >> SECTOR_BITS))
        !          1144:         {
        !          1145:           printk ("%s: cdrom_start_read_continuation: buffer botch (%ld)\n",
        !          1146:                   drive->name, rq->current_nr_sectors);
        !          1147:           cdrom_end_request (0, drive);
        !          1148:           return;
        !          1149:         }
        !          1150: 
        !          1151:       sector -= nskip;
        !          1152:       nsect += nskip;
        !          1153:       rq->current_nr_sectors += nskip;
        !          1154:     }
        !          1155: 
        !          1156:   /* Convert from sectors to cdrom blocks, rounding up the transfer
        !          1157:      length if needed. */
        !          1158:   nframes = (nsect + SECTORS_PER_FRAME-1) / SECTORS_PER_FRAME;
        !          1159:   frame = sector / SECTORS_PER_FRAME;
        !          1160: 
        !          1161:   /* Largest number of frames was can transfer at once is 64k-1. */
        !          1162:   nframes = MIN (nframes, 65535);
        !          1163: 
        !          1164:   /* Set up the command */
        !          1165:   memset (&pc.c, 0, sizeof (pc.c));
        !          1166:   pc.c[0] = READ_10;
        !          1167:   pc.c[7] = (nframes >> 8);
        !          1168:   pc.c[8] = (nframes & 0xff);
        !          1169: #ifdef __alpha__
        !          1170:   stl_u (htonl (frame), (unsigned int *) &pc.c[2]);
        !          1171: #else
        !          1172:   *(int *)(&pc.c[2]) = htonl (frame);
        !          1173: #endif
        !          1174: 
        !          1175:   /* Send the command to the drive and return. */
        !          1176:   (void) cdrom_transfer_packet_command (drive, pc.c, sizeof (pc.c),
        !          1177:                                        &cdrom_read_intr);
        !          1178: }
        !          1179: 
        !          1180: 
        !          1181: /*
        !          1182:  * Start a read request from the CD-ROM.
        !          1183:  */
        !          1184: static void cdrom_start_read (ide_drive_t *drive, unsigned int block)
        !          1185: {
        !          1186:   struct request *rq = HWGROUP(drive)->rq;
        !          1187:   int minor = MINOR (rq->rq_dev);
        !          1188: 
        !          1189:   /* If the request is relative to a partition, fix it up to refer to the
        !          1190:      absolute address.  */
        !          1191:   if ((minor & PARTN_MASK) != 0) {
        !          1192:     rq->sector = block;
        !          1193:     minor &= ~PARTN_MASK;
        !          1194:     rq->rq_dev = MKDEV (MAJOR(rq->rq_dev), minor);
        !          1195:   }
        !          1196: 
        !          1197:   /* We may be retrying this request after an error.
        !          1198:      Fix up any weirdness which might be present in the request packet. */
        !          1199:   restore_request (rq);
        !          1200: 
        !          1201:   /* Satisfy whatever we can of this request from our cached sector. */
        !          1202:   if (cdrom_read_from_buffer (drive))
        !          1203:     return;
        !          1204: 
        !          1205:   /* Clear the local sector buffer. */
        !          1206:   drive->cdrom_info.nsectors_buffered = 0;
        !          1207: 
        !          1208:   /* Start sending the read request to the drive. */
        !          1209:   cdrom_start_packet_command (drive, 32768, cdrom_start_read_continuation);
        !          1210: }
        !          1211: 
        !          1212: 
        !          1213: 
        !          1214: 
        !          1215: /****************************************************************************
        !          1216:  * Execute all other packet commands.
        !          1217:  */
        !          1218: 
        !          1219: /* Forward declarations. */
        !          1220: static int
        !          1221: cdrom_lockdoor (ide_drive_t *drive, int lockflag,
        !          1222:                struct atapi_request_sense *reqbuf);
        !          1223: 
        !          1224: 
        !          1225: 
        !          1226: /* Interrupt routine for packet command completion. */
        !          1227: static void cdrom_pc_intr (ide_drive_t *drive)
        !          1228: {
        !          1229:   int ireason, len, stat, thislen;
        !          1230:   struct request *rq = HWGROUP(drive)->rq;
        !          1231:   struct packet_command *pc = (struct packet_command *)rq->buffer;
        !          1232: 
        !          1233:   /* Check for errors. */
        !          1234:   if (cdrom_decode_status (drive, 0, &stat)) return;
        !          1235: 
        !          1236:   /* Read the interrupt reason and the transfer length. */
        !          1237:   ireason = IN_BYTE (IDE_NSECTOR_REG);
        !          1238:   len = IN_BYTE (IDE_LCYL_REG) + 256 * IN_BYTE (IDE_HCYL_REG);
        !          1239: 
        !          1240:   /* If DRQ is clear, the command has completed.
        !          1241:      Complain if we still have data left to transfer. */
        !          1242:   if ((stat & DRQ_STAT) == 0)
        !          1243:     {
        !          1244:       /* Some of the trailing request sense fields are optional, and
        !          1245:         some drives don't send them.  Sigh. */
        !          1246:       if (pc->c[0] == REQUEST_SENSE && pc->buflen > 0 && pc->buflen <= 5) {
        !          1247:        while (pc->buflen > 0) {
        !          1248:          *pc->buffer++ = 0;
        !          1249:          --pc->buflen;
        !          1250:        }
        !          1251:       }
        !          1252: 
        !          1253:       if (pc->buflen == 0)
        !          1254:         cdrom_end_request (1, drive);
        !          1255:       else
        !          1256:         {
        !          1257:           printk ("%s: cdrom_pc_intr: data underrun %d\n",
        !          1258:                   drive->name, pc->buflen);
        !          1259:           pc->stat = 1;
        !          1260:           cdrom_end_request (1, drive);
        !          1261:         }
        !          1262:       return;
        !          1263:     }
        !          1264: 
        !          1265:   /* Figure out how much data to transfer. */
        !          1266:   thislen = pc->buflen;
        !          1267:   if (thislen < 0) thislen = -thislen;
        !          1268:   if (thislen > len) thislen = len;
        !          1269: 
        !          1270:   /* The drive wants to be written to. */
        !          1271:   if ((ireason & 3) == 0)
        !          1272:     {
        !          1273:       /* Check that we want to write. */
        !          1274:       if (pc->buflen > 0)
        !          1275:         {
        !          1276:           printk ("%s: cdrom_pc_intr: Drive wants to transfer data the wrong way!\n",
        !          1277:                   drive->name);
        !          1278:           pc->stat = 1;
        !          1279:           thislen = 0;
        !          1280:         }
        !          1281: 
        !          1282:       /* Transfer the data. */
        !          1283:       cdrom_out_bytes (drive, pc->buffer, thislen);
        !          1284: 
        !          1285:       /* If we haven't moved enough data to satisfy the drive,
        !          1286:          add some padding. */
        !          1287:       while (len > thislen)
        !          1288:         {
        !          1289:           int dum = 0;
        !          1290:          cdrom_out_bytes (drive, &dum, sizeof (dum));
        !          1291:           len -= sizeof (dum);
        !          1292:         }
        !          1293: 
        !          1294:       /* Keep count of how much data we've moved. */
        !          1295:       pc->buffer += thislen;
        !          1296:       pc->buflen += thislen;
        !          1297:     }
        !          1298: 
        !          1299:   /* Same drill for reading. */
        !          1300:   else if ((ireason & 3) == 2)
        !          1301:     {
        !          1302:       /* Check that we want to read. */
        !          1303:       if (pc->buflen < 0)
        !          1304:         {
        !          1305:           printk ("%s: cdrom_pc_intr: Drive wants to transfer data the wrong way!\n",
        !          1306:                   drive->name);
        !          1307:           pc->stat = 1;
        !          1308:           thislen = 0;
        !          1309:         }
        !          1310: 
        !          1311:       /* Transfer the data. */
        !          1312:       cdrom_in_bytes (drive, pc->buffer, thislen);
        !          1313: 
        !          1314:       /* If we haven't moved enough data to satisfy the drive,
        !          1315:          add some padding. */
        !          1316:       while (len > thislen)
        !          1317:         {
        !          1318:           int dum = 0;
        !          1319:          cdrom_in_bytes (drive, &dum, sizeof (dum));
        !          1320:           len -= sizeof (dum);
        !          1321:         }
        !          1322: 
        !          1323:       /* Keep count of how much data we've moved. */
        !          1324:       pc->buffer += thislen;
        !          1325:       pc->buflen -= thislen;
        !          1326:     }
        !          1327: 
        !          1328:   else
        !          1329:     {
        !          1330:       printk ("%s: cdrom_pc_intr: The drive appears confused (ireason = 0x%2x)\n",
        !          1331:               drive->name, ireason);
        !          1332:       pc->stat = 1;
        !          1333:     }
        !          1334: 
        !          1335:   /* Now we wait for another interrupt. */
        !          1336:   ide_set_handler (drive, &cdrom_pc_intr, WAIT_CMD);
        !          1337: }
        !          1338: 
        !          1339: 
        !          1340: static void cdrom_do_pc_continuation (ide_drive_t *drive)
        !          1341: {
        !          1342:   struct request *rq = HWGROUP(drive)->rq;
        !          1343:   struct packet_command *pc = (struct packet_command *)rq->buffer;
        !          1344: 
        !          1345:   /* Send the command to the drive and return. */
        !          1346:   cdrom_transfer_packet_command (drive, pc->c, sizeof (pc->c), &cdrom_pc_intr);
        !          1347: }
        !          1348: 
        !          1349: 
        !          1350: static void cdrom_do_packet_command (ide_drive_t *drive)
        !          1351: {
        !          1352:   int len;
        !          1353:   struct request *rq = HWGROUP(drive)->rq;
        !          1354:   struct packet_command *pc = (struct packet_command *)rq->buffer;
        !          1355: 
        !          1356:   len = pc->buflen;
        !          1357:   if (len < 0) len = -len;
        !          1358: 
        !          1359:   pc->stat = 0;
        !          1360: 
        !          1361:   /* Start sending the command to the drive. */
        !          1362:   cdrom_start_packet_command (drive, len, cdrom_do_pc_continuation);
        !          1363: }
        !          1364: 
        !          1365: #ifndef MACH
        !          1366: /* Sleep for TIME jiffies.
        !          1367:    Not to be called from an interrupt handler. */
        !          1368: static
        !          1369: void cdrom_sleep (int time)
        !          1370: {
        !          1371:   current->state = TASK_INTERRUPTIBLE;
        !          1372:   current->timeout = jiffies + time;
        !          1373:   schedule ();
        !          1374: }
        !          1375: #endif
        !          1376: 
        !          1377: static
        !          1378: int cdrom_queue_packet_command (ide_drive_t *drive, struct packet_command *pc)
        !          1379: {
        !          1380:   struct atapi_request_sense my_reqbuf;
        !          1381:   int retries = 10;
        !          1382:   struct request req;
        !          1383: 
        !          1384:   /* If our caller has not provided a place to stick any sense data,
        !          1385:      use our own area. */
        !          1386:   if (pc->sense_data == NULL)
        !          1387:     pc->sense_data = &my_reqbuf;
        !          1388:   pc->sense_data->sense_key = 0;
        !          1389: 
        !          1390:   /* Start of retry loop. */
        !          1391:   do {
        !          1392:     ide_init_drive_cmd (&req);
        !          1393:     req.cmd = PACKET_COMMAND;
        !          1394:     req.buffer = (char *)pc;
        !          1395:     (void) ide_do_drive_cmd (drive, &req, ide_wait);
        !          1396: 
        !          1397:     if (pc->stat != 0)
        !          1398:       {
        !          1399:        /* The request failed.  Retry if it was due to a unit attention status
        !          1400:           (usually means media was changed). */
        !          1401:        struct atapi_request_sense *reqbuf = pc->sense_data;
        !          1402: 
        !          1403:        if (reqbuf->sense_key == UNIT_ATTENTION)
        !          1404:          ;
        !          1405: 
        !          1406:        /* Also retry if the drive is in the process of loading a disk.
        !          1407:           This time, however, wait a little between retries to give
        !          1408:           the drive time. */
        !          1409:        else if (reqbuf->sense_key == NOT_READY && reqbuf->asc == 4)
        !          1410:          {
        !          1411:            cdrom_sleep (HZ);
        !          1412:          }
        !          1413: 
        !          1414:        /* Otherwise, don't retry. */
        !          1415:        else
        !          1416:          retries = 0;
        !          1417: 
        !          1418:        --retries;
        !          1419:       }
        !          1420: 
        !          1421:     /* End of retry loop. */
        !          1422:   } while (pc->stat != 0 && retries >= 0);
        !          1423: 
        !          1424: 
        !          1425:   /* Return an error if the command failed. */
        !          1426:   if (pc->stat != 0)
        !          1427:     return -EIO;
        !          1428: 
        !          1429:   else
        !          1430:     {
        !          1431:       /* The command succeeded.  If it was anything other than a request sense,
        !          1432:         eject, or door lock command, and we think that the door is presently
        !          1433:         unlocked, lock it again.  (The door was probably unlocked via
        !          1434:         an explicit CDROMEJECT ioctl.) */
        !          1435:       if (CDROM_STATE_FLAGS (drive)->door_locked == 0 &&
        !          1436:          (pc->c[0] != REQUEST_SENSE &&
        !          1437:           pc->c[0] != ALLOW_MEDIUM_REMOVAL &&
        !          1438:           pc->c[0] != START_STOP))
        !          1439:        {
        !          1440:          (void) cdrom_lockdoor (drive, 1, NULL);
        !          1441:        }
        !          1442:       return 0;
        !          1443:     }
        !          1444: }
        !          1445: 
        !          1446: 
        !          1447: 
        !          1448: /****************************************************************************
        !          1449:  * drive_cmd handling.
        !          1450:  *
        !          1451:  * Most of the functions accessed via drive_cmd are not valid for ATAPI
        !          1452:  * devices.  Only attempt to execute those which actually should be valid.
        !          1453:  */
        !          1454: 
        !          1455: static
        !          1456: void cdrom_do_drive_cmd (ide_drive_t *drive)
        !          1457: {
        !          1458:   struct request *rq = HWGROUP(drive)->rq;
        !          1459:   byte *args = rq->buffer;
        !          1460: 
        !          1461:   if (args)
        !          1462:     {
        !          1463: #if 0  /* This bit isn't done yet... */
        !          1464:       if (args[0] == WIN_SETFEATURES &&
        !          1465:          (args[2] == 0x66 || args[2] == 0xcc || args[2] == 0x02 ||
        !          1466:           args[2] == 0xdd || args[2] == 0x5d))
        !          1467:        {
        !          1468:          OUT_BYTE (args[2], io_base + IDE_FEATURE_OFFSET);
        !          1469:          <send cmd>
        !          1470:        }
        !          1471:       else
        !          1472: #endif
        !          1473:        {
        !          1474:          printk ("%s: Unsupported drive command %02x %02x %02x\n",
        !          1475:                  drive->name, args[0], args[1], args[2]);
        !          1476:          rq->errors = 1;
        !          1477:        }
        !          1478:     }
        !          1479: 
        !          1480:   cdrom_end_request (1, drive);
        !          1481: }
        !          1482: 
        !          1483: 
        !          1484: 
        !          1485: /****************************************************************************
        !          1486:  * cdrom driver request routine.
        !          1487:  */
        !          1488: 
        !          1489: void ide_do_rw_cdrom (ide_drive_t *drive, unsigned long block)
        !          1490: {
        !          1491:   struct request *rq = HWGROUP(drive)->rq;
        !          1492: 
        !          1493:   if (rq -> cmd == PACKET_COMMAND || rq -> cmd == REQUEST_SENSE_COMMAND)
        !          1494:     cdrom_do_packet_command (drive);
        !          1495: 
        !          1496:   else if (rq -> cmd == RESET_DRIVE_COMMAND)
        !          1497:     {
        !          1498:       cdrom_end_request (1, drive);
        !          1499:       ide_do_reset (drive);
        !          1500:       return;
        !          1501:     }
        !          1502: 
        !          1503:   else if (rq -> cmd == IDE_DRIVE_CMD)
        !          1504:     cdrom_do_drive_cmd (drive);
        !          1505: 
        !          1506:   else if (rq -> cmd != READ)
        !          1507:     {
        !          1508:       printk ("ide-cd: bad cmd %d\n", rq -> cmd);
        !          1509:       cdrom_end_request (0, drive);
        !          1510:     }
        !          1511:   else
        !          1512:     cdrom_start_read (drive, block);
        !          1513: }
        !          1514: 
        !          1515: 
        !          1516: 
        !          1517: /****************************************************************************
        !          1518:  * Ioctl handling.
        !          1519:  *
        !          1520:  * Routines which queue packet commands take as a final argument a pointer
        !          1521:  * to an atapi_request_sense struct.  If execution of the command results
        !          1522:  * in an error with a CHECK CONDITION status, this structure will be filled
        !          1523:  * with the results of the subsequent request sense command.  The pointer
        !          1524:  * can also be NULL, in which case no sense information is returned.
        !          1525:  */
        !          1526: 
        !          1527: #if ! STANDARD_ATAPI
        !          1528: static
        !          1529: int bin2bcd (int x)
        !          1530: {
        !          1531:   return (x%10) | ((x/10) << 4);
        !          1532: }
        !          1533: 
        !          1534: 
        !          1535: static
        !          1536: int bcd2bin (int x)
        !          1537: {
        !          1538:   return (x >> 4) * 10 + (x & 0x0f);
        !          1539: }
        !          1540: #endif /* not STANDARD_ATAPI */
        !          1541: 
        !          1542: 
        !          1543: static inline
        !          1544: void lba_to_msf (int lba, byte *m, byte *s, byte *f)
        !          1545: {
        !          1546:   lba += CD_BLOCK_OFFSET;
        !          1547:   lba &= 0xffffff;  /* negative lbas use only 24 bits */
        !          1548:   *m = lba / (CD_SECS * CD_FRAMES);
        !          1549:   lba %= (CD_SECS * CD_FRAMES);
        !          1550:   *s = lba / CD_FRAMES;
        !          1551:   *f = lba % CD_FRAMES;
        !          1552: }
        !          1553: 
        !          1554: 
        !          1555: static inline
        !          1556: int msf_to_lba (byte m, byte s, byte f)
        !          1557: {
        !          1558:   return (((m * CD_SECS) + s) * CD_FRAMES + f) - CD_BLOCK_OFFSET;
        !          1559: }
        !          1560: 
        !          1561: 
        !          1562: static int
        !          1563: cdrom_check_status (ide_drive_t  *drive,
        !          1564:                    struct atapi_request_sense *reqbuf)
        !          1565: {
        !          1566:   struct packet_command pc;
        !          1567: 
        !          1568:   memset (&pc, 0, sizeof (pc));
        !          1569: 
        !          1570:   pc.sense_data = reqbuf;
        !          1571:   pc.c[0] = TEST_UNIT_READY;
        !          1572: 
        !          1573:   return cdrom_queue_packet_command (drive, &pc);
        !          1574: }
        !          1575: 
        !          1576: 
        !          1577: /* Lock the door if LOCKFLAG is nonzero; unlock it otherwise. */
        !          1578: static int
        !          1579: cdrom_lockdoor (ide_drive_t *drive, int lockflag,
        !          1580:                struct atapi_request_sense *reqbuf)
        !          1581: {
        !          1582:   struct atapi_request_sense my_reqbuf;
        !          1583:   int stat;
        !          1584:   struct packet_command pc;
        !          1585: 
        !          1586:   if (reqbuf == NULL)
        !          1587:     reqbuf = &my_reqbuf;
        !          1588: 
        !          1589:   /* If the drive cannot lock the door, just pretend. */
        !          1590:   if (CDROM_CONFIG_FLAGS (drive)->no_doorlock)
        !          1591:     stat = 0;
        !          1592:   else
        !          1593:     {
        !          1594:       memset (&pc, 0, sizeof (pc));
        !          1595:       pc.sense_data = reqbuf;
        !          1596: 
        !          1597:       pc.c[0] = ALLOW_MEDIUM_REMOVAL;
        !          1598:       pc.c[4] = (lockflag != 0);
        !          1599:       stat = cdrom_queue_packet_command (drive, &pc);
        !          1600:     }
        !          1601: 
        !          1602:   if (stat == 0)
        !          1603:     CDROM_STATE_FLAGS (drive)->door_locked = lockflag;
        !          1604:   else
        !          1605:     {
        !          1606:       /* If we got an illegal field error, the drive
        !          1607:         probably cannot lock the door. */
        !          1608:       if (reqbuf->sense_key == ILLEGAL_REQUEST && reqbuf->asc == 0x24)
        !          1609:        {
        !          1610:          printk ("%s: door locking not supported\n", drive->name);
        !          1611:          CDROM_CONFIG_FLAGS (drive)->no_doorlock = 1;
        !          1612:          stat = 0;
        !          1613:          CDROM_STATE_FLAGS (drive)->door_locked = lockflag;
        !          1614:        }
        !          1615:     }
        !          1616:   return stat;
        !          1617: }
        !          1618: 
        !          1619: 
        !          1620: /* Eject the disk if EJECTFLAG is 0.
        !          1621:    If EJECTFLAG is 1, try to reload the disk. */
        !          1622: static int
        !          1623: cdrom_eject (ide_drive_t *drive, int ejectflag,
        !          1624:             struct atapi_request_sense *reqbuf)
        !          1625: {
        !          1626:   struct packet_command pc;
        !          1627: 
        !          1628:   memset (&pc, 0, sizeof (pc));
        !          1629:   pc.sense_data = reqbuf;
        !          1630: 
        !          1631:   pc.c[0] = START_STOP;
        !          1632:   pc.c[4] = 2 + (ejectflag != 0);
        !          1633:   return cdrom_queue_packet_command (drive, &pc);
        !          1634: }
        !          1635: 
        !          1636: 
        !          1637: static int
        !          1638: cdrom_pause (ide_drive_t *drive, int pauseflag,
        !          1639:             struct atapi_request_sense *reqbuf)
        !          1640: {
        !          1641:   struct packet_command pc;
        !          1642: 
        !          1643:   memset (&pc, 0, sizeof (pc));
        !          1644:   pc.sense_data = reqbuf;
        !          1645: 
        !          1646:   pc.c[0] = SCMD_PAUSE_RESUME;
        !          1647:   pc.c[8] = !pauseflag;
        !          1648:   return cdrom_queue_packet_command (drive, &pc);
        !          1649: }
        !          1650: 
        !          1651: 
        !          1652: static int
        !          1653: cdrom_startstop (ide_drive_t *drive, int startflag,
        !          1654:                 struct atapi_request_sense *reqbuf)
        !          1655: {
        !          1656:   struct packet_command pc;
        !          1657: 
        !          1658:   memset (&pc, 0, sizeof (pc));
        !          1659:   pc.sense_data = reqbuf;
        !          1660: 
        !          1661:   pc.c[0] = START_STOP;
        !          1662:   pc.c[1] = 1;
        !          1663:   pc.c[4] = startflag;
        !          1664:   return cdrom_queue_packet_command (drive, &pc);
        !          1665: }
        !          1666: 
        !          1667: 
        !          1668: static int
        !          1669: cdrom_read_capacity (ide_drive_t *drive, unsigned *capacity,
        !          1670:                     struct atapi_request_sense *reqbuf)
        !          1671: {
        !          1672:   struct {
        !          1673:     unsigned lba;
        !          1674:     unsigned blocklen;
        !          1675:   } capbuf;
        !          1676: 
        !          1677:   int stat;
        !          1678:   struct packet_command pc;
        !          1679: 
        !          1680:   memset (&pc, 0, sizeof (pc));
        !          1681:   pc.sense_data = reqbuf;
        !          1682: 
        !          1683:   pc.c[0] = READ_CAPACITY;
        !          1684:   pc.buffer = (char *)&capbuf;
        !          1685:   pc.buflen = sizeof (capbuf);
        !          1686: 
        !          1687:   stat = cdrom_queue_packet_command (drive, &pc);
        !          1688:   if (stat == 0)
        !          1689:     {
        !          1690:       *capacity = ntohl (capbuf.lba);
        !          1691:     }
        !          1692: 
        !          1693:   return stat;
        !          1694: }
        !          1695: 
        !          1696: 
        !          1697: static int
        !          1698: cdrom_read_tocentry (ide_drive_t *drive, int trackno, int msf_flag,
        !          1699:                      int format, char *buf, int buflen,
        !          1700:                     struct atapi_request_sense *reqbuf)
        !          1701: {
        !          1702:   struct packet_command pc;
        !          1703: 
        !          1704:   memset (&pc, 0, sizeof (pc));
        !          1705:   pc.sense_data = reqbuf;
        !          1706: 
        !          1707:   pc.buffer =  buf;
        !          1708:   pc.buflen = buflen;
        !          1709:   pc.c[0] = SCMD_READ_TOC;
        !          1710:   pc.c[6] = trackno;
        !          1711:   pc.c[7] = (buflen >> 8);
        !          1712:   pc.c[8] = (buflen & 0xff);
        !          1713:   pc.c[9] = (format << 6);
        !          1714:   if (msf_flag) pc.c[1] = 2;
        !          1715:   return cdrom_queue_packet_command (drive, &pc);
        !          1716: }
        !          1717: 
        !          1718: 
        !          1719: /* Try to read the entire TOC for the disk into our internal buffer. */
        !          1720: static int
        !          1721: cdrom_read_toc (ide_drive_t *drive,
        !          1722:                struct atapi_request_sense *reqbuf)
        !          1723: {
        !          1724:   int msf_flag;
        !          1725:   int stat, ntracks, i;
        !          1726:   struct atapi_toc *toc = drive->cdrom_info.toc;
        !          1727:   struct {
        !          1728:     struct atapi_toc_header hdr;
        !          1729:     struct atapi_toc_entry  ent;
        !          1730:   } ms_tmp;
        !          1731: 
        !          1732:   if (toc == NULL)
        !          1733:     {
        !          1734:       /* Try to allocate space. */
        !          1735:       toc = (struct atapi_toc *) kmalloc (sizeof (struct atapi_toc),
        !          1736:                                           GFP_KERNEL);
        !          1737:       drive->cdrom_info.toc = toc;
        !          1738:     }
        !          1739: 
        !          1740:   if (toc == NULL)
        !          1741:     {
        !          1742:       printk ("%s: No cdrom TOC buffer!\n", drive->name);
        !          1743:       return -EIO;
        !          1744:     }
        !          1745: 
        !          1746:   /* Check to see if the existing data is still valid.
        !          1747:      If it is, just return. */
        !          1748:   if (CDROM_STATE_FLAGS (drive)->toc_valid)
        !          1749:     (void) cdrom_check_status (drive, NULL);
        !          1750: 
        !          1751:   if (CDROM_STATE_FLAGS (drive)->toc_valid) return 0;
        !          1752: 
        !          1753: #if STANDARD_ATAPI
        !          1754:   msf_flag = 0;
        !          1755: #else  /* not STANDARD_ATAPI */
        !          1756:   /* Some drives can't return TOC data in LBA format. */
        !          1757:   msf_flag = (CDROM_CONFIG_FLAGS (drive)->no_lba_toc);
        !          1758: #endif  /* not STANDARD_ATAPI */
        !          1759: 
        !          1760:   /* First read just the header, so we know how long the TOC is. */
        !          1761:   stat = cdrom_read_tocentry (drive, 0, msf_flag, 0, (char *)&toc->hdr,
        !          1762:                               sizeof (struct atapi_toc_header) +
        !          1763:                               sizeof (struct atapi_toc_entry),
        !          1764:                              reqbuf);
        !          1765:   if (stat) return stat;
        !          1766: 
        !          1767: #if ! STANDARD_ATAPI
        !          1768:   if (CDROM_CONFIG_FLAGS (drive)->vertos_lossage)
        !          1769:     {
        !          1770:       toc->hdr.first_track = bcd2bin (toc->hdr.first_track);
        !          1771:       toc->hdr.last_track  = bcd2bin (toc->hdr.last_track);
        !          1772:       /* hopefully the length is not BCD, too ;-| */
        !          1773:     }
        !          1774: #endif  /* not STANDARD_ATAPI */
        !          1775: 
        !          1776:   ntracks = toc->hdr.last_track - toc->hdr.first_track + 1;
        !          1777:   if (ntracks <= 0) return -EIO;
        !          1778:   if (ntracks > MAX_TRACKS) ntracks = MAX_TRACKS;
        !          1779: 
        !          1780:   /* Now read the whole schmeer. */
        !          1781:   stat = cdrom_read_tocentry (drive, 0, msf_flag, 0, (char *)&toc->hdr,
        !          1782:                               sizeof (struct atapi_toc_header) +
        !          1783:                               (ntracks+1) * sizeof (struct atapi_toc_entry),
        !          1784:                              reqbuf);
        !          1785:   if (stat) return stat;
        !          1786:   toc->hdr.toc_length = ntohs (toc->hdr.toc_length);
        !          1787: 
        !          1788: #if ! STANDARD_ATAPI
        !          1789:   if (CDROM_CONFIG_FLAGS (drive)->vertos_lossage)
        !          1790:     {
        !          1791:       toc->hdr.first_track = bcd2bin (toc->hdr.first_track);
        !          1792:       toc->hdr.last_track  = bcd2bin (toc->hdr.last_track);
        !          1793:       /* hopefully the length is not BCD, too ;-| */
        !          1794:     }
        !          1795: #endif  /* not STANDARD_ATAPI */
        !          1796: 
        !          1797:   for (i=0; i<=ntracks; i++)
        !          1798:     {
        !          1799: #if ! STANDARD_ATAPI
        !          1800:       if (msf_flag)
        !          1801:        {
        !          1802:          if (CDROM_CONFIG_FLAGS (drive)->vertos_lossage)
        !          1803:            {
        !          1804:              toc->ent[i].track = bcd2bin (toc->ent[i].track);
        !          1805:              toc->ent[i].addr.msf.m = bcd2bin (toc->ent[i].addr.msf.m);
        !          1806:              toc->ent[i].addr.msf.s = bcd2bin (toc->ent[i].addr.msf.s);
        !          1807:              toc->ent[i].addr.msf.f = bcd2bin (toc->ent[i].addr.msf.f);
        !          1808:            }
        !          1809:          toc->ent[i].addr.lba = msf_to_lba (toc->ent[i].addr.msf.m,
        !          1810:                                             toc->ent[i].addr.msf.s,
        !          1811:                                             toc->ent[i].addr.msf.f);
        !          1812:        }
        !          1813:       else
        !          1814: #endif  /* not STANDARD_ATAPI */
        !          1815:        toc->ent[i].addr.lba = ntohl (toc->ent[i].addr.lba);
        !          1816:     }
        !          1817: 
        !          1818:   /* Read the multisession information. */
        !          1819:   stat = cdrom_read_tocentry (drive, 0, msf_flag, 1,
        !          1820:                              (char *)&ms_tmp, sizeof (ms_tmp),
        !          1821:                              reqbuf);
        !          1822:   if (stat) return stat;
        !          1823: #if ! STANDARD_ATAPI
        !          1824:   if (msf_flag)
        !          1825:     toc->last_session_lba = msf_to_lba (ms_tmp.ent.addr.msf.m,
        !          1826:                                        ms_tmp.ent.addr.msf.s,
        !          1827:                                        ms_tmp.ent.addr.msf.f);
        !          1828:   else
        !          1829: #endif  /* not STANDARD_ATAPI */
        !          1830:     toc->last_session_lba = ntohl (ms_tmp.ent.addr.lba);
        !          1831: 
        !          1832:   toc->xa_flag = (ms_tmp.hdr.first_track != ms_tmp.hdr.last_track);
        !          1833: 
        !          1834:   /* Now try to get the total cdrom capacity. */
        !          1835:   stat = cdrom_read_capacity (drive, &toc->capacity, reqbuf);
        !          1836:   if (stat) toc->capacity = 0x1fffff;
        !          1837: 
        !          1838:   HWIF(drive)->gd->sizes[drive->select.b.unit << PARTN_BITS]
        !          1839:     = toc->capacity * SECTORS_PER_FRAME;
        !          1840:   drive->part[0].nr_sects = toc->capacity * SECTORS_PER_FRAME;
        !          1841: 
        !          1842:   /* Remember that we've read this stuff. */
        !          1843:   CDROM_STATE_FLAGS (drive)->toc_valid = 1;
        !          1844: 
        !          1845:   return 0;
        !          1846: }
        !          1847: 
        !          1848: 
        !          1849: static int
        !          1850: cdrom_read_subchannel (ide_drive_t *drive,
        !          1851:                        char *buf, int buflen,
        !          1852:                       struct atapi_request_sense *reqbuf)
        !          1853: {
        !          1854:   struct packet_command pc;
        !          1855: 
        !          1856:   memset (&pc, 0, sizeof (pc));
        !          1857:   pc.sense_data = reqbuf;
        !          1858: 
        !          1859:   pc.buffer =  buf;
        !          1860:   pc.buflen = buflen;
        !          1861:   pc.c[0] = SCMD_READ_SUBCHANNEL;
        !          1862:   pc.c[2] = 0x40;  /* request subQ data */
        !          1863:   pc.c[3] = 0x01;  /* Format 1: current position */
        !          1864:   pc.c[7] = (buflen >> 8);
        !          1865:   pc.c[8] = (buflen & 0xff);
        !          1866:   return cdrom_queue_packet_command (drive, &pc);
        !          1867: }
        !          1868: 
        !          1869: 
        !          1870: /* modeflag: 0 = current, 1 = changeable mask, 2 = default, 3 = saved */
        !          1871: static int
        !          1872: cdrom_mode_sense (ide_drive_t *drive, int pageno, int modeflag,
        !          1873:                   char *buf, int buflen,
        !          1874:                  struct atapi_request_sense *reqbuf)
        !          1875: {
        !          1876:   struct packet_command pc;
        !          1877: 
        !          1878:   memset (&pc, 0, sizeof (pc));
        !          1879:   pc.sense_data = reqbuf;
        !          1880: 
        !          1881:   pc.buffer =  buf;
        !          1882:   pc.buflen = buflen;
        !          1883:   pc.c[0] = MODE_SENSE_10;
        !          1884:   pc.c[2] = pageno | (modeflag << 6);
        !          1885:   pc.c[7] = (buflen >> 8);
        !          1886:   pc.c[8] = (buflen & 0xff);
        !          1887:   return cdrom_queue_packet_command (drive, &pc);
        !          1888: }
        !          1889: 
        !          1890: 
        !          1891: static int
        !          1892: cdrom_mode_select (ide_drive_t *drive, int pageno, char *buf, int buflen,
        !          1893:                   struct atapi_request_sense *reqbuf)
        !          1894: {
        !          1895:   struct packet_command pc;
        !          1896: 
        !          1897:   memset (&pc, 0, sizeof (pc));
        !          1898:   pc.sense_data = reqbuf;
        !          1899: 
        !          1900:   pc.buffer =  buf;
        !          1901:   pc.buflen = - buflen;
        !          1902:   pc.c[0] = MODE_SELECT_10;
        !          1903:   pc.c[1] = 0x10;
        !          1904:   pc.c[2] = pageno;
        !          1905:   pc.c[7] = (buflen >> 8);
        !          1906:   pc.c[8] = (buflen & 0xff);
        !          1907:   return cdrom_queue_packet_command (drive, &pc);
        !          1908: }
        !          1909: 
        !          1910: 
        !          1911: static int
        !          1912: cdrom_play_lba_range_play12 (ide_drive_t *drive, int lba_start, int lba_end,
        !          1913:                             struct atapi_request_sense *reqbuf)
        !          1914: {
        !          1915:   struct packet_command pc;
        !          1916: 
        !          1917:   memset (&pc, 0, sizeof (pc));
        !          1918:   pc.sense_data = reqbuf;
        !          1919: 
        !          1920:   pc.c[0] = SCMD_PLAYAUDIO12;
        !          1921: #ifdef __alpha__
        !          1922:   stq_u(((long) htonl (lba_end - lba_start) << 32) | htonl(lba_start),
        !          1923:        (unsigned long *) &pc.c[2]);
        !          1924: #else
        !          1925:   *(int *)(&pc.c[2]) = htonl (lba_start);
        !          1926:   *(int *)(&pc.c[6]) = htonl (lba_end - lba_start);
        !          1927: #endif
        !          1928: 
        !          1929:   return cdrom_queue_packet_command (drive, &pc);
        !          1930: }
        !          1931: 
        !          1932: 
        !          1933: #if !  STANDARD_ATAPI
        !          1934: static int
        !          1935: cdrom_play_lba_range_msf (ide_drive_t *drive, int lba_start, int lba_end,
        !          1936:                          struct atapi_request_sense *reqbuf)
        !          1937: {
        !          1938:   struct packet_command pc;
        !          1939: 
        !          1940:   memset (&pc, 0, sizeof (pc));
        !          1941:   pc.sense_data = reqbuf;
        !          1942: 
        !          1943:   pc.c[0] = SCMD_PLAYAUDIO_MSF;
        !          1944:   lba_to_msf (lba_start, &pc.c[3], &pc.c[4], &pc.c[5]);
        !          1945:   lba_to_msf (lba_end-1, &pc.c[6], &pc.c[7], &pc.c[8]);
        !          1946: 
        !          1947:   if (CDROM_CONFIG_FLAGS (drive)->playmsf_uses_bcd)
        !          1948:     {
        !          1949:       pc.c[3] = bin2bcd (pc.c[3]);
        !          1950:       pc.c[4] = bin2bcd (pc.c[4]);
        !          1951:       pc.c[5] = bin2bcd (pc.c[5]);
        !          1952:       pc.c[6] = bin2bcd (pc.c[6]);
        !          1953:       pc.c[7] = bin2bcd (pc.c[7]);
        !          1954:       pc.c[8] = bin2bcd (pc.c[8]);
        !          1955:     }
        !          1956: 
        !          1957:   return cdrom_queue_packet_command (drive, &pc);
        !          1958: }
        !          1959: #endif  /* not STANDARD_ATAPI */
        !          1960: 
        !          1961: 
        !          1962: static int
        !          1963: cdrom_play_lba_range_1 (ide_drive_t *drive, int lba_start, int lba_end,
        !          1964:                        struct atapi_request_sense *reqbuf)
        !          1965: {
        !          1966:   /* This is rather annoying.
        !          1967:      My NEC-260 won't recognize group 5 commands such as PLAYAUDIO12;
        !          1968:      the only way to get it to play more than 64k of blocks at once
        !          1969:      seems to be the PLAYAUDIO_MSF command.  However, the parameters
        !          1970:      the NEC 260 wants for the PLAYMSF command are incompatible with
        !          1971:      the new version of the spec.
        !          1972: 
        !          1973:      So what i'll try is this.  First try for PLAYAUDIO12.  If it works,
        !          1974:      great.  Otherwise, if the drive reports an illegal command code,
        !          1975:      try PLAYAUDIO_MSF using the NEC 260-style bcd parameters. */
        !          1976: 
        !          1977: #if ! STANDARD_ATAPI
        !          1978:   if (CDROM_CONFIG_FLAGS (drive)->no_playaudio12)
        !          1979:     return cdrom_play_lba_range_msf (drive, lba_start, lba_end, reqbuf);
        !          1980:   else
        !          1981: #endif  /* not STANDARD_ATAPI */
        !          1982:     {
        !          1983:       int stat;
        !          1984:       struct atapi_request_sense my_reqbuf;
        !          1985: 
        !          1986:       if (reqbuf == NULL)
        !          1987:        reqbuf = &my_reqbuf;
        !          1988: 
        !          1989:       stat = cdrom_play_lba_range_play12 (drive, lba_start, lba_end, reqbuf);
        !          1990:       if (stat == 0) return 0;
        !          1991: 
        !          1992: #if ! STANDARD_ATAPI
        !          1993:       /* It failed.  Try to find out why. */
        !          1994:       if (reqbuf->sense_key == ILLEGAL_REQUEST && reqbuf->asc == 0x20)
        !          1995:         {
        !          1996:           /* The drive didn't recognize the command.
        !          1997:              Retry with the MSF variant. */
        !          1998:           printk ("%s: Drive does not support PLAYAUDIO12; "
        !          1999:                   "trying PLAYAUDIO_MSF\n", drive->name);
        !          2000:           CDROM_CONFIG_FLAGS (drive)->no_playaudio12 = 1;
        !          2001:           CDROM_CONFIG_FLAGS (drive)->playmsf_uses_bcd = 1;
        !          2002:           return cdrom_play_lba_range_msf (drive, lba_start, lba_end, reqbuf);
        !          2003:         }
        !          2004: #endif  /* not STANDARD_ATAPI */
        !          2005: 
        !          2006:       /* Failed for some other reason.  Give up. */
        !          2007:       return stat;
        !          2008:     }
        !          2009: }
        !          2010: 
        !          2011: 
        !          2012: /* Play audio starting at LBA LBA_START and finishing with the
        !          2013:    LBA before LBA_END. */
        !          2014: static int
        !          2015: cdrom_play_lba_range (ide_drive_t *drive, int lba_start, int lba_end,
        !          2016:                      struct atapi_request_sense *reqbuf)
        !          2017: {
        !          2018:   int i, stat;
        !          2019:   struct atapi_request_sense my_reqbuf;
        !          2020: 
        !          2021:   if (reqbuf == NULL)
        !          2022:     reqbuf = &my_reqbuf;
        !          2023: 
        !          2024:   /* Some drives, will, for certain audio cds,
        !          2025:      give an error if you ask them to play the entire cd using the
        !          2026:      values which are returned in the TOC.  The play will succeed, however,
        !          2027:      if the ending address is adjusted downwards by a few frames. */
        !          2028:   for (i=0; i<75; i++)
        !          2029:     {
        !          2030:       stat = cdrom_play_lba_range_1 (drive, lba_start, lba_end, reqbuf);
        !          2031: 
        !          2032:       if (stat == 0 ||
        !          2033:           !(reqbuf->sense_key == ILLEGAL_REQUEST && reqbuf->asc == 0x24))
        !          2034:        return stat;
        !          2035: 
        !          2036:       --lba_end;
        !          2037:       if (lba_end <= lba_start) break;
        !          2038:     }
        !          2039: 
        !          2040:   return stat;
        !          2041: }
        !          2042: 
        !          2043: 
        !          2044: static
        !          2045: int cdrom_get_toc_entry (ide_drive_t *drive, int track,
        !          2046:                          struct atapi_toc_entry **ent,
        !          2047:                         struct atapi_request_sense *reqbuf)
        !          2048: {
        !          2049:   int stat, ntracks;
        !          2050:   struct atapi_toc *toc;
        !          2051: 
        !          2052:   /* Make sure our saved TOC is valid. */
        !          2053:   stat = cdrom_read_toc (drive, reqbuf);
        !          2054:   if (stat) return stat;
        !          2055: 
        !          2056:   toc = drive->cdrom_info.toc;
        !          2057: 
        !          2058:   /* Check validity of requested track number. */
        !          2059:   ntracks = toc->hdr.last_track - toc->hdr.first_track + 1;
        !          2060:   if (track == CDROM_LEADOUT)
        !          2061:     *ent = &toc->ent[ntracks];
        !          2062:   else if (track < toc->hdr.first_track ||
        !          2063:            track > toc->hdr.last_track)
        !          2064:     return -EINVAL;
        !          2065:   else
        !          2066:     *ent = &toc->ent[track - toc->hdr.first_track];
        !          2067: 
        !          2068:   return 0;
        !          2069: }
        !          2070: 
        !          2071: 
        !          2072: static int
        !          2073: cdrom_read_block (ide_drive_t *drive, int format, int lba,
        !          2074:                  char *buf, int buflen,
        !          2075:                  struct atapi_request_sense *reqbuf)
        !          2076: {
        !          2077:   struct packet_command pc;
        !          2078:   struct atapi_request_sense my_reqbuf;
        !          2079:   int stat;
        !          2080: 
        !          2081:   if (reqbuf == NULL)
        !          2082:     reqbuf = &my_reqbuf;
        !          2083: 
        !          2084:   memset (&pc, 0, sizeof (pc));
        !          2085:   pc.sense_data = reqbuf;
        !          2086: 
        !          2087:   pc.buffer = buf;
        !          2088:   pc.buflen = buflen;
        !          2089: 
        !          2090: #if ! STANDARD_ATAPI
        !          2091:   if (CDROM_CONFIG_FLAGS (drive)->old_readcd)
        !          2092:     pc.c[0] = 0xd4;
        !          2093:   else
        !          2094: #endif  /* not STANDARD_ATAPI */
        !          2095:     pc.c[0] = READ_CD;
        !          2096: 
        !          2097:   pc.c[1] = (format << 2);
        !          2098: #ifdef __alpha__
        !          2099:   stl_u(htonl (lba), (unsigned int *) &pc.c[2]);
        !          2100: #else
        !          2101:   *(int *)(&pc.c[2]) = htonl (lba);
        !          2102: #endif
        !          2103:   pc.c[8] = 1;  /* one block */
        !          2104:   pc.c[9] = 0x10;
        !          2105: 
        !          2106:   stat = cdrom_queue_packet_command (drive, &pc);
        !          2107: 
        !          2108: #if ! STANDARD_ATAPI
        !          2109:   /* If the drive doesn't recognize the READ CD opcode, retry the command
        !          2110:      with an older opcode for that command. */
        !          2111:   if (stat && reqbuf->sense_key == ILLEGAL_REQUEST && reqbuf->asc == 0x20 &&
        !          2112:       CDROM_CONFIG_FLAGS (drive)->old_readcd == 0)
        !          2113:     {
        !          2114:       printk ("%s: Drive does not recognize READ_CD; trying opcode 0xd4\n",
        !          2115:              drive->name);
        !          2116:       CDROM_CONFIG_FLAGS (drive)->old_readcd = 1;
        !          2117:       return cdrom_read_block (drive, format, lba, buf, buflen, reqbuf);
        !          2118:     }
        !          2119: #endif  /* not STANDARD_ATAPI */
        !          2120: 
        !          2121:   return stat;
        !          2122: }
        !          2123: 
        !          2124: 
        !          2125: int ide_cdrom_ioctl (ide_drive_t *drive, struct inode *inode,
        !          2126:                     struct file *file, unsigned int cmd, unsigned long arg)
        !          2127: {
        !          2128:   switch (cmd)
        !          2129:     {
        !          2130:     case CDROMEJECT:
        !          2131:       {
        !          2132:        int stat;
        !          2133: 
        !          2134:        if (drive->usage > 1)
        !          2135:          return -EBUSY;
        !          2136: 
        !          2137:        stat = cdrom_lockdoor (drive, 0, NULL);
        !          2138:        if (stat) return stat;
        !          2139: 
        !          2140:        return cdrom_eject (drive, 0, NULL);
        !          2141:       }
        !          2142: 
        !          2143:     case CDROMEJECT_SW:
        !          2144:       {
        !          2145:        CDROM_STATE_FLAGS (drive)->eject_on_close = arg;
        !          2146:        return 0;
        !          2147:       }
        !          2148: 
        !          2149:     case CDROMPAUSE:
        !          2150:       return cdrom_pause (drive, 1, NULL);
        !          2151: 
        !          2152:     case CDROMRESUME:
        !          2153:       return cdrom_pause (drive, 0, NULL);
        !          2154: 
        !          2155:     case CDROMSTART:
        !          2156:       return cdrom_startstop (drive, 1, NULL);
        !          2157: 
        !          2158:     case CDROMSTOP:
        !          2159:       {
        !          2160:        int stat;
        !          2161: 
        !          2162:        stat = cdrom_startstop (drive, 0, NULL);
        !          2163:        if (stat) return stat;
        !          2164:        /* pit says the Dolphin needs this. */
        !          2165:        return cdrom_eject (drive, 1, NULL);
        !          2166:       }
        !          2167: 
        !          2168:     case CDROMPLAYMSF:
        !          2169:       {
        !          2170:         struct cdrom_msf msf;
        !          2171:         int stat, lba_start, lba_end;
        !          2172: 
        !          2173:         stat = verify_area (VERIFY_READ, (void *)arg, sizeof (msf));
        !          2174:         if (stat) return stat;
        !          2175: 
        !          2176:         memcpy_fromfs (&msf, (void *) arg, sizeof(msf));
        !          2177: 
        !          2178:         lba_start = msf_to_lba (msf.cdmsf_min0, msf.cdmsf_sec0,
        !          2179:                                 msf.cdmsf_frame0);
        !          2180:         lba_end = msf_to_lba (msf.cdmsf_min1, msf.cdmsf_sec1,
        !          2181:                               msf.cdmsf_frame1) + 1;
        !          2182: 
        !          2183:         if (lba_end <= lba_start) return -EINVAL;
        !          2184: 
        !          2185:         return cdrom_play_lba_range (drive, lba_start, lba_end, NULL);
        !          2186:       }
        !          2187: 
        !          2188:     /* Like just about every other Linux cdrom driver, we ignore the
        !          2189:        index part of the request here. */
        !          2190:     case CDROMPLAYTRKIND:
        !          2191:       {
        !          2192:         int stat, lba_start, lba_end;
        !          2193:         struct cdrom_ti ti;
        !          2194:         struct atapi_toc_entry *first_toc, *last_toc;
        !          2195: 
        !          2196:         stat = verify_area (VERIFY_READ, (void *)arg, sizeof (ti));
        !          2197:         if (stat) return stat;
        !          2198: 
        !          2199:         memcpy_fromfs (&ti, (void *) arg, sizeof(ti));
        !          2200: 
        !          2201:         stat = cdrom_get_toc_entry (drive, ti.cdti_trk0, &first_toc, NULL);
        !          2202:         if (stat) return stat;
        !          2203:         stat = cdrom_get_toc_entry (drive, ti.cdti_trk1, &last_toc, NULL);
        !          2204:         if (stat) return stat;
        !          2205: 
        !          2206:         if (ti.cdti_trk1 != CDROM_LEADOUT) ++last_toc;
        !          2207:         lba_start = first_toc->addr.lba;
        !          2208:         lba_end   = last_toc->addr.lba;
        !          2209: 
        !          2210:         if (lba_end <= lba_start) return -EINVAL;
        !          2211: 
        !          2212:         return cdrom_play_lba_range (drive, lba_start, lba_end, NULL);
        !          2213:       }
        !          2214: 
        !          2215:     case CDROMREADTOCHDR:
        !          2216:       {
        !          2217:         int stat;
        !          2218:         struct cdrom_tochdr tochdr;
        !          2219:         struct atapi_toc *toc;
        !          2220: 
        !          2221:         stat = verify_area (VERIFY_WRITE, (void *) arg, sizeof (tochdr));
        !          2222:         if (stat) return stat;
        !          2223: 
        !          2224:         /* Make sure our saved TOC is valid. */
        !          2225:         stat = cdrom_read_toc (drive, NULL);
        !          2226:         if (stat) return stat;
        !          2227: 
        !          2228:         toc = drive->cdrom_info.toc;
        !          2229:         tochdr.cdth_trk0 = toc->hdr.first_track;
        !          2230:         tochdr.cdth_trk1 = toc->hdr.last_track;
        !          2231: 
        !          2232:         memcpy_tofs ((void *) arg, &tochdr, sizeof (tochdr));
        !          2233: 
        !          2234:         return stat;
        !          2235:       }
        !          2236: 
        !          2237:     case CDROMREADTOCENTRY:
        !          2238:       {
        !          2239:         int stat;
        !          2240:         struct cdrom_tocentry tocentry;
        !          2241:         struct atapi_toc_entry *toce;
        !          2242: 
        !          2243:         stat = verify_area (VERIFY_READ, (void *) arg, sizeof (tocentry));
        !          2244:         if (stat) return stat;
        !          2245:         stat = verify_area (VERIFY_WRITE, (void *) arg, sizeof (tocentry));
        !          2246:         if (stat) return stat;
        !          2247: 
        !          2248:         memcpy_fromfs (&tocentry, (void *) arg, sizeof (tocentry));
        !          2249: 
        !          2250:         stat = cdrom_get_toc_entry (drive, tocentry.cdte_track, &toce, NULL);
        !          2251:         if (stat) return stat;
        !          2252: 
        !          2253:         tocentry.cdte_ctrl = toce->control;
        !          2254:         tocentry.cdte_adr  = toce->adr;
        !          2255: 
        !          2256:         if (tocentry.cdte_format == CDROM_MSF)
        !          2257:           {
        !          2258:             /* convert to MSF */
        !          2259:             lba_to_msf (toce->addr.lba,
        !          2260:                         &tocentry.cdte_addr.msf.minute,
        !          2261:                         &tocentry.cdte_addr.msf.second,
        !          2262:                         &tocentry.cdte_addr.msf.frame);
        !          2263:           }
        !          2264:         else
        !          2265:           tocentry.cdte_addr.lba = toce->addr.lba;
        !          2266: 
        !          2267:         memcpy_tofs ((void *) arg, &tocentry, sizeof (tocentry));
        !          2268: 
        !          2269:         return stat;
        !          2270:       }
        !          2271: 
        !          2272:     case CDROMSUBCHNL:
        !          2273:       {
        !          2274:         struct atapi_cdrom_subchnl scbuf;
        !          2275:         int stat, abs_lba, rel_lba;
        !          2276:         struct cdrom_subchnl subchnl;
        !          2277: 
        !          2278:         stat = verify_area (VERIFY_WRITE, (void *) arg, sizeof (subchnl));
        !          2279:         if (stat) return stat;
        !          2280:         stat = verify_area (VERIFY_READ, (void *) arg, sizeof (subchnl));
        !          2281:         if (stat) return stat;
        !          2282: 
        !          2283:         memcpy_fromfs (&subchnl, (void *) arg, sizeof (subchnl));
        !          2284: 
        !          2285:         stat = cdrom_read_subchannel (drive, (char *)&scbuf, sizeof (scbuf),
        !          2286:                                      NULL);
        !          2287:         if (stat) return stat;
        !          2288: 
        !          2289: #if ! STANDARD_ATAPI
        !          2290:        if (CDROM_CONFIG_FLAGS (drive)->vertos_lossage)
        !          2291:          {
        !          2292:            abs_lba = msf_to_lba (bcd2bin (scbuf.acdsc_absaddr.msf.minute),
        !          2293:                                  bcd2bin (scbuf.acdsc_absaddr.msf.second),
        !          2294:                                  bcd2bin (scbuf.acdsc_absaddr.msf.frame));
        !          2295:            rel_lba = msf_to_lba (bcd2bin (scbuf.acdsc_reladdr.msf.minute),
        !          2296:                                  bcd2bin (scbuf.acdsc_reladdr.msf.second),
        !          2297:                                  bcd2bin (scbuf.acdsc_reladdr.msf.frame));
        !          2298:            scbuf.acdsc_trk = bcd2bin (scbuf.acdsc_trk);
        !          2299:          }
        !          2300:        else
        !          2301: #endif /* not STANDARD_ATAPI */
        !          2302:          {
        !          2303:            abs_lba = ntohl (scbuf.acdsc_absaddr.lba);
        !          2304:            rel_lba = ntohl (scbuf.acdsc_reladdr.lba);
        !          2305:          }
        !          2306: 
        !          2307:         if (subchnl.cdsc_format == CDROM_MSF)
        !          2308:           {
        !          2309:             lba_to_msf (abs_lba,
        !          2310:                         &subchnl.cdsc_absaddr.msf.minute,
        !          2311:                         &subchnl.cdsc_absaddr.msf.second,
        !          2312:                         &subchnl.cdsc_absaddr.msf.frame);
        !          2313:             lba_to_msf (rel_lba,
        !          2314:                         &subchnl.cdsc_reladdr.msf.minute,
        !          2315:                         &subchnl.cdsc_reladdr.msf.second,
        !          2316:                         &subchnl.cdsc_reladdr.msf.frame);
        !          2317:           }
        !          2318:         else
        !          2319:           {
        !          2320:             subchnl.cdsc_absaddr.lba = abs_lba;
        !          2321:             subchnl.cdsc_reladdr.lba = rel_lba;
        !          2322:           }
        !          2323: 
        !          2324:         subchnl.cdsc_audiostatus = scbuf.acdsc_audiostatus;
        !          2325:         subchnl.cdsc_ctrl = scbuf.acdsc_ctrl;
        !          2326:         subchnl.cdsc_trk  = scbuf.acdsc_trk;
        !          2327:         subchnl.cdsc_ind  = scbuf.acdsc_ind;
        !          2328: 
        !          2329:         memcpy_tofs ((void *) arg, &subchnl, sizeof (subchnl));
        !          2330: 
        !          2331:         return stat;
        !          2332:       }
        !          2333: 
        !          2334:     case CDROMVOLCTRL:
        !          2335:       {
        !          2336:         struct cdrom_volctrl volctrl;
        !          2337:         char buffer[24], mask[24];
        !          2338:         int stat;
        !          2339: 
        !          2340:         stat = verify_area (VERIFY_READ, (void *) arg, sizeof (volctrl));
        !          2341:         if (stat) return stat;
        !          2342:         memcpy_fromfs (&volctrl, (void *) arg, sizeof (volctrl));
        !          2343: 
        !          2344:         stat = cdrom_mode_sense (drive, 0x0e, 0, buffer, sizeof (buffer),NULL);
        !          2345:         if (stat) return stat;
        !          2346:         stat = cdrom_mode_sense (drive, 0x0e, 1, mask  , sizeof (buffer),NULL);
        !          2347:         if (stat) return stat;
        !          2348: 
        !          2349:         buffer[1] = buffer[2] = 0;
        !          2350: 
        !          2351:         buffer[17] = volctrl.channel0 & mask[17];
        !          2352:         buffer[19] = volctrl.channel1 & mask[19];
        !          2353:         buffer[21] = volctrl.channel2 & mask[21];
        !          2354:         buffer[23] = volctrl.channel3 & mask[23];
        !          2355: 
        !          2356:         return cdrom_mode_select (drive, 0x0e, buffer, sizeof (buffer), NULL);
        !          2357:       }
        !          2358: 
        !          2359:     case CDROMVOLREAD:
        !          2360:       {
        !          2361:         struct cdrom_volctrl volctrl;
        !          2362:         char buffer[24];
        !          2363:         int stat;
        !          2364: 
        !          2365:         stat = verify_area (VERIFY_WRITE, (void *) arg, sizeof (volctrl));
        !          2366:         if (stat) return stat;
        !          2367: 
        !          2368:         stat = cdrom_mode_sense (drive, 0x0e, 0, buffer, sizeof (buffer), NULL);
        !          2369:         if (stat) return stat;
        !          2370: 
        !          2371:         volctrl.channel0 = buffer[17];
        !          2372:         volctrl.channel1 = buffer[19];
        !          2373:         volctrl.channel2 = buffer[21];
        !          2374:         volctrl.channel3 = buffer[23];
        !          2375: 
        !          2376:         memcpy_tofs ((void *) arg, &volctrl, sizeof (volctrl));
        !          2377: 
        !          2378:        return 0;
        !          2379:       }
        !          2380: 
        !          2381:     case CDROMMULTISESSION:
        !          2382:       {
        !          2383:        struct cdrom_multisession ms_info;
        !          2384:        struct atapi_toc *toc;
        !          2385:        int stat;
        !          2386: 
        !          2387:        stat = verify_area (VERIFY_READ,  (void *)arg, sizeof (ms_info));
        !          2388:         if (stat) return stat;
        !          2389:        stat = verify_area (VERIFY_WRITE, (void *)arg, sizeof (ms_info));
        !          2390:         if (stat) return stat;
        !          2391: 
        !          2392:        memcpy_fromfs (&ms_info, (void *)arg, sizeof (ms_info));
        !          2393: 
        !          2394:        /* Make sure the TOC information is valid. */
        !          2395:        stat = cdrom_read_toc (drive, NULL);
        !          2396:        if (stat) return stat;
        !          2397: 
        !          2398:        toc = drive->cdrom_info.toc;
        !          2399: 
        !          2400:        if (ms_info.addr_format == CDROM_MSF)
        !          2401:          lba_to_msf (toc->last_session_lba,
        !          2402:                      &ms_info.addr.msf.minute,
        !          2403:                      &ms_info.addr.msf.second,
        !          2404:                      &ms_info.addr.msf.frame);
        !          2405: 
        !          2406:        else if (ms_info.addr_format == CDROM_LBA)
        !          2407:          ms_info.addr.lba = toc->last_session_lba;
        !          2408: 
        !          2409:        else
        !          2410:          return -EINVAL;
        !          2411: 
        !          2412:        ms_info.xa_flag = toc->xa_flag;
        !          2413: 
        !          2414:        memcpy_tofs ((void *)arg, &ms_info, sizeof (ms_info));
        !          2415: 
        !          2416:        return 0;
        !          2417:       }
        !          2418: 
        !          2419:     /* Read 2352 byte blocks from audio tracks. */
        !          2420:     case CDROMREADAUDIO:
        !          2421:       {
        !          2422:        int stat, lba;
        !          2423:        struct atapi_toc *toc;
        !          2424:        struct cdrom_read_audio ra;
        !          2425:        char buf[CD_FRAMESIZE_RAW];
        !          2426: 
        !          2427:        /* Make sure the TOC is up to date. */
        !          2428:        stat = cdrom_read_toc (drive, NULL);
        !          2429:        if (stat) return stat;
        !          2430: 
        !          2431:        toc = drive->cdrom_info.toc;
        !          2432: 
        !          2433:        stat = verify_area (VERIFY_READ, (char *)arg, sizeof (ra));
        !          2434:        if (stat) return stat;
        !          2435: 
        !          2436:        memcpy_fromfs (&ra, (void *)arg, sizeof (ra));
        !          2437: 
        !          2438:        if (ra.nframes < 0 || ra.nframes > toc->capacity)
        !          2439:          return -EINVAL;
        !          2440:        else if (ra.nframes == 0)
        !          2441:          return 0;
        !          2442: 
        !          2443:        stat = verify_area (VERIFY_WRITE, (char *)ra.buf,
        !          2444:                                          ra.nframes * CD_FRAMESIZE_RAW);
        !          2445:        if (stat) return stat;
        !          2446: 
        !          2447:        if (ra.addr_format == CDROM_MSF)
        !          2448:          lba = msf_to_lba (ra.addr.msf.minute, ra.addr.msf.second,
        !          2449:                            ra.addr.msf.frame);
        !          2450:        
        !          2451:        else if (ra.addr_format == CDROM_LBA)
        !          2452:          lba = ra.addr.lba;
        !          2453: 
        !          2454:        else
        !          2455:          return -EINVAL;
        !          2456: 
        !          2457:        if (lba < 0 || lba >= toc->capacity)
        !          2458:          return -EINVAL;
        !          2459: 
        !          2460:        while (ra.nframes > 0)
        !          2461:          {
        !          2462:            stat = cdrom_read_block (drive, 1, lba, buf,
        !          2463:                                     CD_FRAMESIZE_RAW, NULL);
        !          2464:            if (stat) return stat;
        !          2465:            memcpy_tofs (ra.buf, buf, CD_FRAMESIZE_RAW);
        !          2466:            ra.buf += CD_FRAMESIZE_RAW;
        !          2467:            --ra.nframes;
        !          2468:            ++lba;
        !          2469:          }
        !          2470: 
        !          2471:        return 0;
        !          2472:       }
        !          2473: 
        !          2474:     case CDROMREADMODE1:
        !          2475:     case CDROMREADMODE2:
        !          2476:       {
        !          2477:        struct cdrom_msf msf;
        !          2478:        int blocksize, format, stat, lba;
        !          2479:        struct atapi_toc *toc;
        !          2480:        char buf[CD_FRAMESIZE_RAW0];
        !          2481: 
        !          2482:        if (cmd == CDROMREADMODE1)
        !          2483:          {
        !          2484:            blocksize = CD_FRAMESIZE;
        !          2485:            format = 2;
        !          2486:          }
        !          2487:        else
        !          2488:          {
        !          2489:            blocksize = CD_FRAMESIZE_RAW0;
        !          2490:            format = 3;
        !          2491:          }
        !          2492: 
        !          2493:        stat = verify_area (VERIFY_READ, (char *)arg, sizeof (msf));
        !          2494:        if (stat) return stat;
        !          2495:        stat = verify_area (VERIFY_WRITE, (char *)arg, blocksize);
        !          2496:        if (stat) return stat;
        !          2497: 
        !          2498:        memcpy_fromfs (&msf, (void *)arg, sizeof (msf));
        !          2499: 
        !          2500:        lba = msf_to_lba (msf.cdmsf_min0, msf.cdmsf_sec0, msf.cdmsf_frame0);
        !          2501:        
        !          2502:        /* Make sure the TOC is up to date. */
        !          2503:        stat = cdrom_read_toc (drive, NULL);
        !          2504:        if (stat) return stat;
        !          2505: 
        !          2506:        toc = drive->cdrom_info.toc;
        !          2507: 
        !          2508:        if (lba < 0 || lba >= toc->capacity)
        !          2509:          return -EINVAL;
        !          2510: 
        !          2511:        stat = cdrom_read_block (drive, format, lba, buf, blocksize, NULL);
        !          2512:        if (stat) return stat;
        !          2513: 
        !          2514:        memcpy_tofs ((char *)arg, buf, blocksize);
        !          2515:        return 0;
        !          2516:       }
        !          2517: 
        !          2518: #if 0 /* Doesn't work reliably yet. */
        !          2519:     case CDROMRESET:
        !          2520:       {
        !          2521:        struct request req;
        !          2522:        ide_init_drive_cmd (&req);
        !          2523:        req.cmd = RESET_DRIVE_COMMAND;
        !          2524:        return ide_do_drive_cmd (drive, &req, ide_wait);
        !          2525:       }
        !          2526: #endif
        !          2527: 
        !          2528:  
        !          2529: #ifdef TEST
        !          2530:     case 0x1234:
        !          2531:       {
        !          2532:         int stat;
        !          2533:         struct packet_command pc;
        !          2534:        int len, lena;
        !          2535: 
        !          2536:         memset (&pc, 0, sizeof (pc));
        !          2537: 
        !          2538:         stat = verify_area (VERIFY_READ, (void *) arg, sizeof (pc.c));
        !          2539:         if (stat) return stat;
        !          2540:         memcpy_fromfs (&pc.c, (void *) arg, sizeof (pc.c));
        !          2541:        arg += sizeof (pc.c);
        !          2542: 
        !          2543:        stat = verify_area (VERIFY_READ, (void *) arg, sizeof (len));
        !          2544:         if (stat) return stat;
        !          2545:         memcpy_fromfs (&len, (void *) arg , sizeof (len));
        !          2546:        arg += sizeof (len);
        !          2547: 
        !          2548:        if (len > 0) {
        !          2549:          stat = verify_area (VERIFY_WRITE, (void *) arg, len);
        !          2550:          if (stat) return stat;
        !          2551:        }
        !          2552: 
        !          2553:        lena = len;
        !          2554:        if (lena  < 0) lena = 0;
        !          2555: 
        !          2556:        {
        !          2557:          char buf[lena];
        !          2558:          if (len > 0) {
        !          2559:            pc.buflen = len;
        !          2560:            pc.buffer = buf;
        !          2561:          }
        !          2562: 
        !          2563:          stat = cdrom_queue_packet_command (drive, &pc);
        !          2564: 
        !          2565:          if (len > 0)
        !          2566:            memcpy_tofs ((void *)arg, buf, len);
        !          2567:        }
        !          2568: 
        !          2569:         return stat;
        !          2570:       }
        !          2571: #endif
        !          2572: 
        !          2573:     default:
        !          2574:       return -EPERM;
        !          2575:     }
        !          2576: 
        !          2577: }
        !          2578: 
        !          2579: 
        !          2580: 
        !          2581: /****************************************************************************
        !          2582:  * Other driver requests (open, close, check media change).
        !          2583:  */
        !          2584: 
        !          2585: int ide_cdrom_check_media_change (ide_drive_t *drive)
        !          2586: {
        !          2587:   int retval;
        !          2588: 
        !          2589:   (void) cdrom_check_status (drive, NULL);
        !          2590: 
        !          2591:   retval = CDROM_STATE_FLAGS (drive)->media_changed;
        !          2592:   CDROM_STATE_FLAGS (drive)->media_changed = 0;
        !          2593: 
        !          2594:   return retval;
        !          2595: }
        !          2596: 
        !          2597: 
        !          2598: int ide_cdrom_open (struct inode *ip, struct file *fp, ide_drive_t *drive)
        !          2599: {
        !          2600:   /* no write access */
        !          2601:   if (fp->f_mode & 2)
        !          2602:     {
        !          2603:       --drive->usage;
        !          2604:       return -EROFS;
        !          2605:     }
        !          2606: 
        !          2607:   /* If this is the first open, check the drive status. */
        !          2608:   if (drive->usage == 1)
        !          2609:     {
        !          2610:       int stat;
        !          2611:       struct atapi_request_sense my_reqbuf;
        !          2612:       my_reqbuf.sense_key = 0;
        !          2613: 
        !          2614:       /* Get the drive status. */
        !          2615:       stat = cdrom_check_status (drive, &my_reqbuf);
        !          2616: 
        !          2617:       /* If the tray is open, try to close it. */
        !          2618:       if (stat && my_reqbuf.sense_key == NOT_READY)
        !          2619:        {
        !          2620:          cdrom_eject (drive, 1, &my_reqbuf);
        !          2621:          stat = cdrom_check_status (drive, &my_reqbuf);
        !          2622:        }
        !          2623: 
        !          2624:       /* Return an error if there are still problems. */
        !          2625:       if (stat && my_reqbuf.sense_key != UNIT_ATTENTION)
        !          2626:        {
        !          2627:          --drive->usage;
        !          2628:          return -ENXIO;
        !          2629:        }
        !          2630: 
        !          2631:       /* Now lock the door. */
        !          2632:       (void) cdrom_lockdoor (drive, 1, &my_reqbuf);
        !          2633: 
        !          2634:       /* And try to read the TOC information now. */
        !          2635:       (void) cdrom_read_toc (drive, &my_reqbuf);
        !          2636:     }
        !          2637: 
        !          2638:   return 0;
        !          2639: }
        !          2640: 
        !          2641: 
        !          2642: /*
        !          2643:  * Close down the device.  Invalidate all cached blocks.
        !          2644:  */
        !          2645: 
        !          2646: void ide_cdrom_release (struct inode *inode, struct file *file, ide_drive_t *drive)
        !          2647: {
        !          2648:   if (drive->usage == 0)
        !          2649:     {
        !          2650:       invalidate_buffers (inode->i_rdev);
        !          2651: 
        !          2652:       /* Unlock the door. */
        !          2653:       (void) cdrom_lockdoor (drive, 0, NULL);
        !          2654: 
        !          2655:       /* Do an eject if we were requested to do so. */
        !          2656:       if (CDROM_STATE_FLAGS (drive)->eject_on_close)
        !          2657:        (void) cdrom_eject (drive, 0, NULL);
        !          2658:     }
        !          2659: }
        !          2660: 
        !          2661: 
        !          2662: 
        !          2663: /****************************************************************************
        !          2664:  * Device initialization.
        !          2665:  */
        !          2666: 
        !          2667: void ide_cdrom_setup (ide_drive_t *drive)
        !          2668: {
        !          2669:   blksize_size[HWIF(drive)->major][drive->select.b.unit << PARTN_BITS] = CD_FRAMESIZE;
        !          2670: 
        !          2671:   drive->special.all = 0;
        !          2672:   drive->ready_stat = 0;
        !          2673: 
        !          2674:   CDROM_STATE_FLAGS (drive)->media_changed = 0;
        !          2675:   CDROM_STATE_FLAGS (drive)->toc_valid     = 0;
        !          2676:   CDROM_STATE_FLAGS (drive)->door_locked   = 0;
        !          2677: 
        !          2678:   /* Turn this off by default, since many people don't like it. */
        !          2679:   CDROM_STATE_FLAGS (drive)->eject_on_close= 0;
        !          2680: 
        !          2681: #if NO_DOOR_LOCKING
        !          2682:   CDROM_CONFIG_FLAGS (drive)->no_doorlock = 1;
        !          2683: #else
        !          2684:   CDROM_CONFIG_FLAGS (drive)->no_doorlock = 0;
        !          2685: #endif
        !          2686: 
        !          2687:   if (drive->id != NULL) {
        !          2688:     CDROM_CONFIG_FLAGS (drive)->drq_interrupt =
        !          2689:       ((drive->id->config & 0x0060) == 0x20);
        !          2690:   } else {
        !          2691:     CDROM_CONFIG_FLAGS (drive)->drq_interrupt = 0;
        !          2692:   }
        !          2693: 
        !          2694: #if ! STANDARD_ATAPI
        !          2695:   CDROM_CONFIG_FLAGS (drive)->no_playaudio12 = 0;
        !          2696:   CDROM_CONFIG_FLAGS (drive)->old_readcd = 0;
        !          2697:   CDROM_CONFIG_FLAGS (drive)->no_lba_toc = 0;
        !          2698:   CDROM_CONFIG_FLAGS (drive)->playmsf_uses_bcd = 0;
        !          2699:   CDROM_CONFIG_FLAGS (drive)->vertos_lossage = 0;
        !          2700: 
        !          2701:   if (drive->id != NULL) {
        !          2702:     /* Accommodate some broken drives... */
        !          2703:     if (strcmp (drive->id->model, "CD220E") == 0 ||
        !          2704:         strcmp (drive->id->model, "CD")     == 0)        /* Creative Labs */
        !          2705:       CDROM_CONFIG_FLAGS (drive)->no_lba_toc = 1;
        !          2706: 
        !          2707:     else if (strcmp (drive->id->model, "TO-ICSLYAL") == 0 ||  /* Acer CD525E */
        !          2708:              strcmp (drive->id->model, "OTI-SCYLLA") == 0)
        !          2709:       CDROM_CONFIG_FLAGS (drive)->no_lba_toc = 1;
        !          2710: 
        !          2711:     /* I don't know who makes this.
        !          2712:        Francesco Messineo <[email protected]> says this one's broken too. */
        !          2713:     else if (strcmp (drive->id->model, "DCI-2S10") == 0)
        !          2714:       CDROM_CONFIG_FLAGS (drive)->no_lba_toc = 1;
        !          2715: 
        !          2716:     else if (strcmp (drive->id->model, "CDA26803I SE") == 0) /* Aztech */
        !          2717:       {
        !          2718:         CDROM_CONFIG_FLAGS (drive)->no_lba_toc = 1;
        !          2719: 
        !          2720:         /* This drive _also_ does not implement PLAYAUDIO12 correctly. */
        !          2721:         CDROM_CONFIG_FLAGS (drive)->no_playaudio12 = 1;
        !          2722:       }
        !          2723: 
        !          2724:     /* Vertos 300.
        !          2725:        There seem to be at least two different, incompatible versions
        !          2726:        of this drive floating around.  Luckily, they appear to return their
        !          2727:        id strings with different byte orderings. */
        !          2728:     else if (strcmp (drive->id->model, "V003S0DS") == 0)
        !          2729:       {
        !          2730:         CDROM_CONFIG_FLAGS (drive)->vertos_lossage = 1;
        !          2731:         CDROM_CONFIG_FLAGS (drive)->playmsf_uses_bcd = 1;
        !          2732:         CDROM_CONFIG_FLAGS (drive)->no_lba_toc = 1;
        !          2733:       }
        !          2734:     else if (strcmp (drive->id->model, "0V300SSD") == 0 ||
        !          2735:           strcmp (drive->id->model, "V003M0DP") == 0)
        !          2736:       CDROM_CONFIG_FLAGS (drive)->no_lba_toc = 1;
        !          2737: 
        !          2738:     /* Vertos 400. */
        !          2739:     else if (strcmp (drive->id->model, "V004E0DT") == 0 ||
        !          2740:           strcmp (drive->id->model, "0V400ETD") == 0)
        !          2741:       CDROM_CONFIG_FLAGS (drive)->no_lba_toc = 1;
        !          2742: 
        !          2743:     else if ( strcmp (drive->id->model, "CD-ROM CDU55D") == 0) /*sony cdu55d */
        !          2744:       CDROM_CONFIG_FLAGS (drive)->no_playaudio12 = 1;
        !          2745: 
        !          2746:    else if (strcmp (drive->id->model, "CD-ROM CDU55E") == 0)
        !          2747:        CDROM_CONFIG_FLAGS (drive)->no_playaudio12 = 1;
        !          2748:   } /* drive-id != NULL */
        !          2749: #endif  /* not STANDARD_ATAPI */
        !          2750: 
        !          2751:   drive->cdrom_info.toc               = NULL;
        !          2752:   drive->cdrom_info.sector_buffer     = NULL;
        !          2753:   drive->cdrom_info.sector_buffered   = 0;
        !          2754:   drive->cdrom_info.nsectors_buffered = 0;
        !          2755: }
        !          2756: 
        !          2757: 
        !          2758: 
        !          2759: /*
        !          2760:  * TODO:
        !          2761:  *  CDROM_GET_UPC
        !          2762:  *  CDROMRESET
        !          2763:  *  Lock the door when a read request completes successfully and the
        !          2764:  *   door is not already locked.  Also try to reorganize to reduce
        !          2765:  *   duplicated functionality between read and ioctl paths?
        !          2766:  *  Establish interfaces for an IDE port driver, and break out the cdrom
        !          2767:  *   code into a loadable module.
        !          2768:  *  Support changers.
        !          2769:  *  Write some real documentation.
        !          2770:  */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.