Annotation of Gnu-Mach/linux/src/drivers/block/ide-cd.c, revision 1.1

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

unix.superglobalmegacorp.com

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