|
|
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: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.