1*1da177e4SLinus Torvalds #include <linux/kernel.h> 2*1da177e4SLinus Torvalds #include <linux/sched.h> 3*1da177e4SLinus Torvalds #include <linux/mm.h> 4*1da177e4SLinus Torvalds #include <linux/fs.h> 5*1da177e4SLinus Torvalds #include <linux/errno.h> 6*1da177e4SLinus Torvalds #include <linux/string.h> 7*1da177e4SLinus Torvalds #include <linux/blkdev.h> 8*1da177e4SLinus Torvalds #include <linux/blkpg.h> 9*1da177e4SLinus Torvalds #include <linux/cdrom.h> 10*1da177e4SLinus Torvalds #include <linux/delay.h> 11*1da177e4SLinus Torvalds #include <asm/io.h> 12*1da177e4SLinus Torvalds #include <asm/uaccess.h> 13*1da177e4SLinus Torvalds 14*1da177e4SLinus Torvalds #include <scsi/scsi.h> 15*1da177e4SLinus Torvalds #include <scsi/scsi_dbg.h> 16*1da177e4SLinus Torvalds #include <scsi/scsi_device.h> 17*1da177e4SLinus Torvalds #include <scsi/scsi_eh.h> 18*1da177e4SLinus Torvalds #include <scsi/scsi_host.h> 19*1da177e4SLinus Torvalds #include <scsi/scsi_ioctl.h> 20*1da177e4SLinus Torvalds #include <scsi/scsi_request.h> 21*1da177e4SLinus Torvalds 22*1da177e4SLinus Torvalds #include "sr.h" 23*1da177e4SLinus Torvalds 24*1da177e4SLinus Torvalds #if 0 25*1da177e4SLinus Torvalds #define DEBUG 26*1da177e4SLinus Torvalds #endif 27*1da177e4SLinus Torvalds 28*1da177e4SLinus Torvalds /* The sr_is_xa() seems to trigger firmware bugs with some drives :-( 29*1da177e4SLinus Torvalds * It is off by default and can be turned on with this module parameter */ 30*1da177e4SLinus Torvalds static int xa_test = 0; 31*1da177e4SLinus Torvalds 32*1da177e4SLinus Torvalds module_param(xa_test, int, S_IRUGO | S_IWUSR); 33*1da177e4SLinus Torvalds 34*1da177e4SLinus Torvalds 35*1da177e4SLinus Torvalds #define IOCTL_RETRIES 3 36*1da177e4SLinus Torvalds 37*1da177e4SLinus Torvalds /* ATAPI drives don't have a SCMD_PLAYAUDIO_TI command. When these drives 38*1da177e4SLinus Torvalds are emulating a SCSI device via the idescsi module, they need to have 39*1da177e4SLinus Torvalds CDROMPLAYTRKIND commands translated into CDROMPLAYMSF commands for them */ 40*1da177e4SLinus Torvalds 41*1da177e4SLinus Torvalds static int sr_fake_playtrkind(struct cdrom_device_info *cdi, struct cdrom_ti *ti) 42*1da177e4SLinus Torvalds { 43*1da177e4SLinus Torvalds struct cdrom_tocentry trk0_te, trk1_te; 44*1da177e4SLinus Torvalds struct cdrom_tochdr tochdr; 45*1da177e4SLinus Torvalds struct packet_command cgc; 46*1da177e4SLinus Torvalds int ntracks, ret; 47*1da177e4SLinus Torvalds 48*1da177e4SLinus Torvalds if ((ret = sr_audio_ioctl(cdi, CDROMREADTOCHDR, &tochdr))) 49*1da177e4SLinus Torvalds return ret; 50*1da177e4SLinus Torvalds 51*1da177e4SLinus Torvalds ntracks = tochdr.cdth_trk1 - tochdr.cdth_trk0 + 1; 52*1da177e4SLinus Torvalds 53*1da177e4SLinus Torvalds if (ti->cdti_trk1 == ntracks) 54*1da177e4SLinus Torvalds ti->cdti_trk1 = CDROM_LEADOUT; 55*1da177e4SLinus Torvalds else if (ti->cdti_trk1 != CDROM_LEADOUT) 56*1da177e4SLinus Torvalds ti->cdti_trk1 ++; 57*1da177e4SLinus Torvalds 58*1da177e4SLinus Torvalds trk0_te.cdte_track = ti->cdti_trk0; 59*1da177e4SLinus Torvalds trk0_te.cdte_format = CDROM_MSF; 60*1da177e4SLinus Torvalds trk1_te.cdte_track = ti->cdti_trk1; 61*1da177e4SLinus Torvalds trk1_te.cdte_format = CDROM_MSF; 62*1da177e4SLinus Torvalds 63*1da177e4SLinus Torvalds if ((ret = sr_audio_ioctl(cdi, CDROMREADTOCENTRY, &trk0_te))) 64*1da177e4SLinus Torvalds return ret; 65*1da177e4SLinus Torvalds if ((ret = sr_audio_ioctl(cdi, CDROMREADTOCENTRY, &trk1_te))) 66*1da177e4SLinus Torvalds return ret; 67*1da177e4SLinus Torvalds 68*1da177e4SLinus Torvalds memset(&cgc, 0, sizeof(struct packet_command)); 69*1da177e4SLinus Torvalds cgc.cmd[0] = GPCMD_PLAY_AUDIO_MSF; 70*1da177e4SLinus Torvalds cgc.cmd[3] = trk0_te.cdte_addr.msf.minute; 71*1da177e4SLinus Torvalds cgc.cmd[4] = trk0_te.cdte_addr.msf.second; 72*1da177e4SLinus Torvalds cgc.cmd[5] = trk0_te.cdte_addr.msf.frame; 73*1da177e4SLinus Torvalds cgc.cmd[6] = trk1_te.cdte_addr.msf.minute; 74*1da177e4SLinus Torvalds cgc.cmd[7] = trk1_te.cdte_addr.msf.second; 75*1da177e4SLinus Torvalds cgc.cmd[8] = trk1_te.cdte_addr.msf.frame; 76*1da177e4SLinus Torvalds cgc.data_direction = DMA_NONE; 77*1da177e4SLinus Torvalds cgc.timeout = IOCTL_TIMEOUT; 78*1da177e4SLinus Torvalds return sr_do_ioctl(cdi->handle, &cgc); 79*1da177e4SLinus Torvalds } 80*1da177e4SLinus Torvalds 81*1da177e4SLinus Torvalds /* We do our own retries because we want to know what the specific 82*1da177e4SLinus Torvalds error code is. Normally the UNIT_ATTENTION code will automatically 83*1da177e4SLinus Torvalds clear after one error */ 84*1da177e4SLinus Torvalds 85*1da177e4SLinus Torvalds int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc) 86*1da177e4SLinus Torvalds { 87*1da177e4SLinus Torvalds struct scsi_request *SRpnt; 88*1da177e4SLinus Torvalds struct scsi_device *SDev; 89*1da177e4SLinus Torvalds struct request *req; 90*1da177e4SLinus Torvalds int result, err = 0, retries = 0; 91*1da177e4SLinus Torvalds 92*1da177e4SLinus Torvalds SDev = cd->device; 93*1da177e4SLinus Torvalds SRpnt = scsi_allocate_request(SDev, GFP_KERNEL); 94*1da177e4SLinus Torvalds if (!SRpnt) { 95*1da177e4SLinus Torvalds printk(KERN_ERR "Unable to allocate SCSI request in sr_do_ioctl"); 96*1da177e4SLinus Torvalds err = -ENOMEM; 97*1da177e4SLinus Torvalds goto out; 98*1da177e4SLinus Torvalds } 99*1da177e4SLinus Torvalds SRpnt->sr_data_direction = cgc->data_direction; 100*1da177e4SLinus Torvalds 101*1da177e4SLinus Torvalds retry: 102*1da177e4SLinus Torvalds if (!scsi_block_when_processing_errors(SDev)) { 103*1da177e4SLinus Torvalds err = -ENODEV; 104*1da177e4SLinus Torvalds goto out_free; 105*1da177e4SLinus Torvalds } 106*1da177e4SLinus Torvalds 107*1da177e4SLinus Torvalds scsi_wait_req(SRpnt, cgc->cmd, cgc->buffer, cgc->buflen, 108*1da177e4SLinus Torvalds cgc->timeout, IOCTL_RETRIES); 109*1da177e4SLinus Torvalds 110*1da177e4SLinus Torvalds req = SRpnt->sr_request; 111*1da177e4SLinus Torvalds if (SRpnt->sr_buffer && req->buffer && SRpnt->sr_buffer != req->buffer) { 112*1da177e4SLinus Torvalds memcpy(req->buffer, SRpnt->sr_buffer, SRpnt->sr_bufflen); 113*1da177e4SLinus Torvalds kfree(SRpnt->sr_buffer); 114*1da177e4SLinus Torvalds SRpnt->sr_buffer = req->buffer; 115*1da177e4SLinus Torvalds } 116*1da177e4SLinus Torvalds 117*1da177e4SLinus Torvalds result = SRpnt->sr_result; 118*1da177e4SLinus Torvalds 119*1da177e4SLinus Torvalds /* Minimal error checking. Ignore cases we know about, and report the rest. */ 120*1da177e4SLinus Torvalds if (driver_byte(result) != 0) { 121*1da177e4SLinus Torvalds switch (SRpnt->sr_sense_buffer[2] & 0xf) { 122*1da177e4SLinus Torvalds case UNIT_ATTENTION: 123*1da177e4SLinus Torvalds SDev->changed = 1; 124*1da177e4SLinus Torvalds if (!cgc->quiet) 125*1da177e4SLinus Torvalds printk(KERN_INFO "%s: disc change detected.\n", cd->cdi.name); 126*1da177e4SLinus Torvalds if (retries++ < 10) 127*1da177e4SLinus Torvalds goto retry; 128*1da177e4SLinus Torvalds err = -ENOMEDIUM; 129*1da177e4SLinus Torvalds break; 130*1da177e4SLinus Torvalds case NOT_READY: /* This happens if there is no disc in drive */ 131*1da177e4SLinus Torvalds if (SRpnt->sr_sense_buffer[12] == 0x04 && 132*1da177e4SLinus Torvalds SRpnt->sr_sense_buffer[13] == 0x01) { 133*1da177e4SLinus Torvalds /* sense: Logical unit is in process of becoming ready */ 134*1da177e4SLinus Torvalds if (!cgc->quiet) 135*1da177e4SLinus Torvalds printk(KERN_INFO "%s: CDROM not ready yet.\n", cd->cdi.name); 136*1da177e4SLinus Torvalds if (retries++ < 10) { 137*1da177e4SLinus Torvalds /* sleep 2 sec and try again */ 138*1da177e4SLinus Torvalds ssleep(2); 139*1da177e4SLinus Torvalds goto retry; 140*1da177e4SLinus Torvalds } else { 141*1da177e4SLinus Torvalds /* 20 secs are enough? */ 142*1da177e4SLinus Torvalds err = -ENOMEDIUM; 143*1da177e4SLinus Torvalds break; 144*1da177e4SLinus Torvalds } 145*1da177e4SLinus Torvalds } 146*1da177e4SLinus Torvalds if (!cgc->quiet) 147*1da177e4SLinus Torvalds printk(KERN_INFO "%s: CDROM not ready. Make sure there is a disc in the drive.\n", cd->cdi.name); 148*1da177e4SLinus Torvalds #ifdef DEBUG 149*1da177e4SLinus Torvalds scsi_print_req_sense("sr", SRpnt); 150*1da177e4SLinus Torvalds #endif 151*1da177e4SLinus Torvalds err = -ENOMEDIUM; 152*1da177e4SLinus Torvalds break; 153*1da177e4SLinus Torvalds case ILLEGAL_REQUEST: 154*1da177e4SLinus Torvalds err = -EIO; 155*1da177e4SLinus Torvalds if (SRpnt->sr_sense_buffer[12] == 0x20 && 156*1da177e4SLinus Torvalds SRpnt->sr_sense_buffer[13] == 0x00) 157*1da177e4SLinus Torvalds /* sense: Invalid command operation code */ 158*1da177e4SLinus Torvalds err = -EDRIVE_CANT_DO_THIS; 159*1da177e4SLinus Torvalds #ifdef DEBUG 160*1da177e4SLinus Torvalds __scsi_print_command(cgc->cmd); 161*1da177e4SLinus Torvalds scsi_print_req_sense("sr", SRpnt); 162*1da177e4SLinus Torvalds #endif 163*1da177e4SLinus Torvalds break; 164*1da177e4SLinus Torvalds default: 165*1da177e4SLinus Torvalds printk(KERN_ERR "%s: CDROM (ioctl) error, command: ", cd->cdi.name); 166*1da177e4SLinus Torvalds __scsi_print_command(cgc->cmd); 167*1da177e4SLinus Torvalds scsi_print_req_sense("sr", SRpnt); 168*1da177e4SLinus Torvalds err = -EIO; 169*1da177e4SLinus Torvalds } 170*1da177e4SLinus Torvalds } 171*1da177e4SLinus Torvalds 172*1da177e4SLinus Torvalds if (cgc->sense) 173*1da177e4SLinus Torvalds memcpy(cgc->sense, SRpnt->sr_sense_buffer, sizeof(*cgc->sense)); 174*1da177e4SLinus Torvalds 175*1da177e4SLinus Torvalds /* Wake up a process waiting for device */ 176*1da177e4SLinus Torvalds out_free: 177*1da177e4SLinus Torvalds scsi_release_request(SRpnt); 178*1da177e4SLinus Torvalds SRpnt = NULL; 179*1da177e4SLinus Torvalds out: 180*1da177e4SLinus Torvalds cgc->stat = err; 181*1da177e4SLinus Torvalds return err; 182*1da177e4SLinus Torvalds } 183*1da177e4SLinus Torvalds 184*1da177e4SLinus Torvalds /* ---------------------------------------------------------------------- */ 185*1da177e4SLinus Torvalds /* interface to cdrom.c */ 186*1da177e4SLinus Torvalds 187*1da177e4SLinus Torvalds static int test_unit_ready(Scsi_CD *cd) 188*1da177e4SLinus Torvalds { 189*1da177e4SLinus Torvalds struct packet_command cgc; 190*1da177e4SLinus Torvalds 191*1da177e4SLinus Torvalds memset(&cgc, 0, sizeof(struct packet_command)); 192*1da177e4SLinus Torvalds cgc.cmd[0] = GPCMD_TEST_UNIT_READY; 193*1da177e4SLinus Torvalds cgc.quiet = 1; 194*1da177e4SLinus Torvalds cgc.data_direction = DMA_NONE; 195*1da177e4SLinus Torvalds cgc.timeout = IOCTL_TIMEOUT; 196*1da177e4SLinus Torvalds return sr_do_ioctl(cd, &cgc); 197*1da177e4SLinus Torvalds } 198*1da177e4SLinus Torvalds 199*1da177e4SLinus Torvalds int sr_tray_move(struct cdrom_device_info *cdi, int pos) 200*1da177e4SLinus Torvalds { 201*1da177e4SLinus Torvalds Scsi_CD *cd = cdi->handle; 202*1da177e4SLinus Torvalds struct packet_command cgc; 203*1da177e4SLinus Torvalds 204*1da177e4SLinus Torvalds memset(&cgc, 0, sizeof(struct packet_command)); 205*1da177e4SLinus Torvalds cgc.cmd[0] = GPCMD_START_STOP_UNIT; 206*1da177e4SLinus Torvalds cgc.cmd[4] = (pos == 0) ? 0x03 /* close */ : 0x02 /* eject */ ; 207*1da177e4SLinus Torvalds cgc.data_direction = DMA_NONE; 208*1da177e4SLinus Torvalds cgc.timeout = IOCTL_TIMEOUT; 209*1da177e4SLinus Torvalds return sr_do_ioctl(cd, &cgc); 210*1da177e4SLinus Torvalds } 211*1da177e4SLinus Torvalds 212*1da177e4SLinus Torvalds int sr_lock_door(struct cdrom_device_info *cdi, int lock) 213*1da177e4SLinus Torvalds { 214*1da177e4SLinus Torvalds Scsi_CD *cd = cdi->handle; 215*1da177e4SLinus Torvalds 216*1da177e4SLinus Torvalds return scsi_set_medium_removal(cd->device, lock ? 217*1da177e4SLinus Torvalds SCSI_REMOVAL_PREVENT : SCSI_REMOVAL_ALLOW); 218*1da177e4SLinus Torvalds } 219*1da177e4SLinus Torvalds 220*1da177e4SLinus Torvalds int sr_drive_status(struct cdrom_device_info *cdi, int slot) 221*1da177e4SLinus Torvalds { 222*1da177e4SLinus Torvalds if (CDSL_CURRENT != slot) { 223*1da177e4SLinus Torvalds /* we have no changer support */ 224*1da177e4SLinus Torvalds return -EINVAL; 225*1da177e4SLinus Torvalds } 226*1da177e4SLinus Torvalds if (0 == test_unit_ready(cdi->handle)) 227*1da177e4SLinus Torvalds return CDS_DISC_OK; 228*1da177e4SLinus Torvalds 229*1da177e4SLinus Torvalds return CDS_TRAY_OPEN; 230*1da177e4SLinus Torvalds } 231*1da177e4SLinus Torvalds 232*1da177e4SLinus Torvalds int sr_disk_status(struct cdrom_device_info *cdi) 233*1da177e4SLinus Torvalds { 234*1da177e4SLinus Torvalds Scsi_CD *cd = cdi->handle; 235*1da177e4SLinus Torvalds struct cdrom_tochdr toc_h; 236*1da177e4SLinus Torvalds struct cdrom_tocentry toc_e; 237*1da177e4SLinus Torvalds int i, rc, have_datatracks = 0; 238*1da177e4SLinus Torvalds 239*1da177e4SLinus Torvalds /* look for data tracks */ 240*1da177e4SLinus Torvalds if (0 != (rc = sr_audio_ioctl(cdi, CDROMREADTOCHDR, &toc_h))) 241*1da177e4SLinus Torvalds return (rc == -ENOMEDIUM) ? CDS_NO_DISC : CDS_NO_INFO; 242*1da177e4SLinus Torvalds 243*1da177e4SLinus Torvalds for (i = toc_h.cdth_trk0; i <= toc_h.cdth_trk1; i++) { 244*1da177e4SLinus Torvalds toc_e.cdte_track = i; 245*1da177e4SLinus Torvalds toc_e.cdte_format = CDROM_LBA; 246*1da177e4SLinus Torvalds if (sr_audio_ioctl(cdi, CDROMREADTOCENTRY, &toc_e)) 247*1da177e4SLinus Torvalds return CDS_NO_INFO; 248*1da177e4SLinus Torvalds if (toc_e.cdte_ctrl & CDROM_DATA_TRACK) { 249*1da177e4SLinus Torvalds have_datatracks = 1; 250*1da177e4SLinus Torvalds break; 251*1da177e4SLinus Torvalds } 252*1da177e4SLinus Torvalds } 253*1da177e4SLinus Torvalds if (!have_datatracks) 254*1da177e4SLinus Torvalds return CDS_AUDIO; 255*1da177e4SLinus Torvalds 256*1da177e4SLinus Torvalds if (cd->xa_flag) 257*1da177e4SLinus Torvalds return CDS_XA_2_1; 258*1da177e4SLinus Torvalds else 259*1da177e4SLinus Torvalds return CDS_DATA_1; 260*1da177e4SLinus Torvalds } 261*1da177e4SLinus Torvalds 262*1da177e4SLinus Torvalds int sr_get_last_session(struct cdrom_device_info *cdi, 263*1da177e4SLinus Torvalds struct cdrom_multisession *ms_info) 264*1da177e4SLinus Torvalds { 265*1da177e4SLinus Torvalds Scsi_CD *cd = cdi->handle; 266*1da177e4SLinus Torvalds 267*1da177e4SLinus Torvalds ms_info->addr.lba = cd->ms_offset; 268*1da177e4SLinus Torvalds ms_info->xa_flag = cd->xa_flag || cd->ms_offset > 0; 269*1da177e4SLinus Torvalds 270*1da177e4SLinus Torvalds return 0; 271*1da177e4SLinus Torvalds } 272*1da177e4SLinus Torvalds 273*1da177e4SLinus Torvalds /* primitive to determine whether we need to have GFP_DMA set based on 274*1da177e4SLinus Torvalds * the status of the unchecked_isa_dma flag in the host structure */ 275*1da177e4SLinus Torvalds #define SR_GFP_DMA(cd) (((cd)->device->host->unchecked_isa_dma) ? GFP_DMA : 0) 276*1da177e4SLinus Torvalds 277*1da177e4SLinus Torvalds int sr_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn) 278*1da177e4SLinus Torvalds { 279*1da177e4SLinus Torvalds Scsi_CD *cd = cdi->handle; 280*1da177e4SLinus Torvalds struct packet_command cgc; 281*1da177e4SLinus Torvalds char *buffer = kmalloc(32, GFP_KERNEL | SR_GFP_DMA(cd)); 282*1da177e4SLinus Torvalds int result; 283*1da177e4SLinus Torvalds 284*1da177e4SLinus Torvalds memset(&cgc, 0, sizeof(struct packet_command)); 285*1da177e4SLinus Torvalds cgc.cmd[0] = GPCMD_READ_SUBCHANNEL; 286*1da177e4SLinus Torvalds cgc.cmd[2] = 0x40; /* I do want the subchannel info */ 287*1da177e4SLinus Torvalds cgc.cmd[3] = 0x02; /* Give me medium catalog number info */ 288*1da177e4SLinus Torvalds cgc.cmd[8] = 24; 289*1da177e4SLinus Torvalds cgc.buffer = buffer; 290*1da177e4SLinus Torvalds cgc.buflen = 24; 291*1da177e4SLinus Torvalds cgc.data_direction = DMA_FROM_DEVICE; 292*1da177e4SLinus Torvalds cgc.timeout = IOCTL_TIMEOUT; 293*1da177e4SLinus Torvalds result = sr_do_ioctl(cd, &cgc); 294*1da177e4SLinus Torvalds 295*1da177e4SLinus Torvalds memcpy(mcn->medium_catalog_number, buffer + 9, 13); 296*1da177e4SLinus Torvalds mcn->medium_catalog_number[13] = 0; 297*1da177e4SLinus Torvalds 298*1da177e4SLinus Torvalds kfree(buffer); 299*1da177e4SLinus Torvalds return result; 300*1da177e4SLinus Torvalds } 301*1da177e4SLinus Torvalds 302*1da177e4SLinus Torvalds int sr_reset(struct cdrom_device_info *cdi) 303*1da177e4SLinus Torvalds { 304*1da177e4SLinus Torvalds return 0; 305*1da177e4SLinus Torvalds } 306*1da177e4SLinus Torvalds 307*1da177e4SLinus Torvalds int sr_select_speed(struct cdrom_device_info *cdi, int speed) 308*1da177e4SLinus Torvalds { 309*1da177e4SLinus Torvalds Scsi_CD *cd = cdi->handle; 310*1da177e4SLinus Torvalds struct packet_command cgc; 311*1da177e4SLinus Torvalds 312*1da177e4SLinus Torvalds if (speed == 0) 313*1da177e4SLinus Torvalds speed = 0xffff; /* set to max */ 314*1da177e4SLinus Torvalds else 315*1da177e4SLinus Torvalds speed *= 177; /* Nx to kbyte/s */ 316*1da177e4SLinus Torvalds 317*1da177e4SLinus Torvalds memset(&cgc, 0, sizeof(struct packet_command)); 318*1da177e4SLinus Torvalds cgc.cmd[0] = GPCMD_SET_SPEED; /* SET CD SPEED */ 319*1da177e4SLinus Torvalds cgc.cmd[2] = (speed >> 8) & 0xff; /* MSB for speed (in kbytes/sec) */ 320*1da177e4SLinus Torvalds cgc.cmd[3] = speed & 0xff; /* LSB */ 321*1da177e4SLinus Torvalds cgc.data_direction = DMA_NONE; 322*1da177e4SLinus Torvalds cgc.timeout = IOCTL_TIMEOUT; 323*1da177e4SLinus Torvalds 324*1da177e4SLinus Torvalds if (sr_do_ioctl(cd, &cgc)) 325*1da177e4SLinus Torvalds return -EIO; 326*1da177e4SLinus Torvalds return 0; 327*1da177e4SLinus Torvalds } 328*1da177e4SLinus Torvalds 329*1da177e4SLinus Torvalds /* ----------------------------------------------------------------------- */ 330*1da177e4SLinus Torvalds /* this is called by the generic cdrom driver. arg is a _kernel_ pointer, */ 331*1da177e4SLinus Torvalds /* because the generic cdrom driver does the user access stuff for us. */ 332*1da177e4SLinus Torvalds /* only cdromreadtochdr and cdromreadtocentry are left - for use with the */ 333*1da177e4SLinus Torvalds /* sr_disk_status interface for the generic cdrom driver. */ 334*1da177e4SLinus Torvalds 335*1da177e4SLinus Torvalds int sr_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, void *arg) 336*1da177e4SLinus Torvalds { 337*1da177e4SLinus Torvalds Scsi_CD *cd = cdi->handle; 338*1da177e4SLinus Torvalds struct packet_command cgc; 339*1da177e4SLinus Torvalds int result; 340*1da177e4SLinus Torvalds unsigned char *buffer = kmalloc(32, GFP_KERNEL | SR_GFP_DMA(cd)); 341*1da177e4SLinus Torvalds 342*1da177e4SLinus Torvalds if (!buffer) 343*1da177e4SLinus Torvalds return -ENOMEM; 344*1da177e4SLinus Torvalds 345*1da177e4SLinus Torvalds memset(&cgc, 0, sizeof(struct packet_command)); 346*1da177e4SLinus Torvalds cgc.timeout = IOCTL_TIMEOUT; 347*1da177e4SLinus Torvalds 348*1da177e4SLinus Torvalds switch (cmd) { 349*1da177e4SLinus Torvalds case CDROMREADTOCHDR: 350*1da177e4SLinus Torvalds { 351*1da177e4SLinus Torvalds struct cdrom_tochdr *tochdr = (struct cdrom_tochdr *) arg; 352*1da177e4SLinus Torvalds 353*1da177e4SLinus Torvalds cgc.cmd[0] = GPCMD_READ_TOC_PMA_ATIP; 354*1da177e4SLinus Torvalds cgc.cmd[8] = 12; /* LSB of length */ 355*1da177e4SLinus Torvalds cgc.buffer = buffer; 356*1da177e4SLinus Torvalds cgc.buflen = 12; 357*1da177e4SLinus Torvalds cgc.quiet = 1; 358*1da177e4SLinus Torvalds cgc.data_direction = DMA_FROM_DEVICE; 359*1da177e4SLinus Torvalds 360*1da177e4SLinus Torvalds result = sr_do_ioctl(cd, &cgc); 361*1da177e4SLinus Torvalds 362*1da177e4SLinus Torvalds tochdr->cdth_trk0 = buffer[2]; 363*1da177e4SLinus Torvalds tochdr->cdth_trk1 = buffer[3]; 364*1da177e4SLinus Torvalds 365*1da177e4SLinus Torvalds break; 366*1da177e4SLinus Torvalds } 367*1da177e4SLinus Torvalds 368*1da177e4SLinus Torvalds case CDROMREADTOCENTRY: 369*1da177e4SLinus Torvalds { 370*1da177e4SLinus Torvalds struct cdrom_tocentry *tocentry = (struct cdrom_tocentry *) arg; 371*1da177e4SLinus Torvalds 372*1da177e4SLinus Torvalds cgc.cmd[0] = GPCMD_READ_TOC_PMA_ATIP; 373*1da177e4SLinus Torvalds cgc.cmd[1] |= (tocentry->cdte_format == CDROM_MSF) ? 0x02 : 0; 374*1da177e4SLinus Torvalds cgc.cmd[6] = tocentry->cdte_track; 375*1da177e4SLinus Torvalds cgc.cmd[8] = 12; /* LSB of length */ 376*1da177e4SLinus Torvalds cgc.buffer = buffer; 377*1da177e4SLinus Torvalds cgc.buflen = 12; 378*1da177e4SLinus Torvalds cgc.data_direction = DMA_FROM_DEVICE; 379*1da177e4SLinus Torvalds 380*1da177e4SLinus Torvalds result = sr_do_ioctl(cd, &cgc); 381*1da177e4SLinus Torvalds 382*1da177e4SLinus Torvalds tocentry->cdte_ctrl = buffer[5] & 0xf; 383*1da177e4SLinus Torvalds tocentry->cdte_adr = buffer[5] >> 4; 384*1da177e4SLinus Torvalds tocentry->cdte_datamode = (tocentry->cdte_ctrl & 0x04) ? 1 : 0; 385*1da177e4SLinus Torvalds if (tocentry->cdte_format == CDROM_MSF) { 386*1da177e4SLinus Torvalds tocentry->cdte_addr.msf.minute = buffer[9]; 387*1da177e4SLinus Torvalds tocentry->cdte_addr.msf.second = buffer[10]; 388*1da177e4SLinus Torvalds tocentry->cdte_addr.msf.frame = buffer[11]; 389*1da177e4SLinus Torvalds } else 390*1da177e4SLinus Torvalds tocentry->cdte_addr.lba = (((((buffer[8] << 8) + buffer[9]) << 8) 391*1da177e4SLinus Torvalds + buffer[10]) << 8) + buffer[11]; 392*1da177e4SLinus Torvalds 393*1da177e4SLinus Torvalds break; 394*1da177e4SLinus Torvalds } 395*1da177e4SLinus Torvalds 396*1da177e4SLinus Torvalds case CDROMPLAYTRKIND: { 397*1da177e4SLinus Torvalds struct cdrom_ti* ti = (struct cdrom_ti*)arg; 398*1da177e4SLinus Torvalds 399*1da177e4SLinus Torvalds cgc.cmd[0] = GPCMD_PLAYAUDIO_TI; 400*1da177e4SLinus Torvalds cgc.cmd[4] = ti->cdti_trk0; 401*1da177e4SLinus Torvalds cgc.cmd[5] = ti->cdti_ind0; 402*1da177e4SLinus Torvalds cgc.cmd[7] = ti->cdti_trk1; 403*1da177e4SLinus Torvalds cgc.cmd[8] = ti->cdti_ind1; 404*1da177e4SLinus Torvalds cgc.data_direction = DMA_NONE; 405*1da177e4SLinus Torvalds 406*1da177e4SLinus Torvalds result = sr_do_ioctl(cd, &cgc); 407*1da177e4SLinus Torvalds if (result == -EDRIVE_CANT_DO_THIS) 408*1da177e4SLinus Torvalds result = sr_fake_playtrkind(cdi, ti); 409*1da177e4SLinus Torvalds 410*1da177e4SLinus Torvalds break; 411*1da177e4SLinus Torvalds } 412*1da177e4SLinus Torvalds 413*1da177e4SLinus Torvalds default: 414*1da177e4SLinus Torvalds result = -EINVAL; 415*1da177e4SLinus Torvalds } 416*1da177e4SLinus Torvalds 417*1da177e4SLinus Torvalds #if 0 418*1da177e4SLinus Torvalds if (result) 419*1da177e4SLinus Torvalds printk("DEBUG: sr_audio: result for ioctl %x: %x\n", cmd, result); 420*1da177e4SLinus Torvalds #endif 421*1da177e4SLinus Torvalds 422*1da177e4SLinus Torvalds kfree(buffer); 423*1da177e4SLinus Torvalds return result; 424*1da177e4SLinus Torvalds } 425*1da177e4SLinus Torvalds 426*1da177e4SLinus Torvalds /* ----------------------------------------------------------------------- 427*1da177e4SLinus Torvalds * a function to read all sorts of funny cdrom sectors using the READ_CD 428*1da177e4SLinus Torvalds * scsi-3 mmc command 429*1da177e4SLinus Torvalds * 430*1da177e4SLinus Torvalds * lba: linear block address 431*1da177e4SLinus Torvalds * format: 0 = data (anything) 432*1da177e4SLinus Torvalds * 1 = audio 433*1da177e4SLinus Torvalds * 2 = data (mode 1) 434*1da177e4SLinus Torvalds * 3 = data (mode 2) 435*1da177e4SLinus Torvalds * 4 = data (mode 2 form1) 436*1da177e4SLinus Torvalds * 5 = data (mode 2 form2) 437*1da177e4SLinus Torvalds * blksize: 2048 | 2336 | 2340 | 2352 438*1da177e4SLinus Torvalds */ 439*1da177e4SLinus Torvalds 440*1da177e4SLinus Torvalds static int sr_read_cd(Scsi_CD *cd, unsigned char *dest, int lba, int format, int blksize) 441*1da177e4SLinus Torvalds { 442*1da177e4SLinus Torvalds struct packet_command cgc; 443*1da177e4SLinus Torvalds 444*1da177e4SLinus Torvalds #ifdef DEBUG 445*1da177e4SLinus Torvalds printk("%s: sr_read_cd lba=%d format=%d blksize=%d\n", 446*1da177e4SLinus Torvalds cd->cdi.name, lba, format, blksize); 447*1da177e4SLinus Torvalds #endif 448*1da177e4SLinus Torvalds 449*1da177e4SLinus Torvalds memset(&cgc, 0, sizeof(struct packet_command)); 450*1da177e4SLinus Torvalds cgc.cmd[0] = GPCMD_READ_CD; /* READ_CD */ 451*1da177e4SLinus Torvalds cgc.cmd[1] = ((format & 7) << 2); 452*1da177e4SLinus Torvalds cgc.cmd[2] = (unsigned char) (lba >> 24) & 0xff; 453*1da177e4SLinus Torvalds cgc.cmd[3] = (unsigned char) (lba >> 16) & 0xff; 454*1da177e4SLinus Torvalds cgc.cmd[4] = (unsigned char) (lba >> 8) & 0xff; 455*1da177e4SLinus Torvalds cgc.cmd[5] = (unsigned char) lba & 0xff; 456*1da177e4SLinus Torvalds cgc.cmd[8] = 1; 457*1da177e4SLinus Torvalds switch (blksize) { 458*1da177e4SLinus Torvalds case 2336: 459*1da177e4SLinus Torvalds cgc.cmd[9] = 0x58; 460*1da177e4SLinus Torvalds break; 461*1da177e4SLinus Torvalds case 2340: 462*1da177e4SLinus Torvalds cgc.cmd[9] = 0x78; 463*1da177e4SLinus Torvalds break; 464*1da177e4SLinus Torvalds case 2352: 465*1da177e4SLinus Torvalds cgc.cmd[9] = 0xf8; 466*1da177e4SLinus Torvalds break; 467*1da177e4SLinus Torvalds default: 468*1da177e4SLinus Torvalds cgc.cmd[9] = 0x10; 469*1da177e4SLinus Torvalds break; 470*1da177e4SLinus Torvalds } 471*1da177e4SLinus Torvalds cgc.buffer = dest; 472*1da177e4SLinus Torvalds cgc.buflen = blksize; 473*1da177e4SLinus Torvalds cgc.data_direction = DMA_FROM_DEVICE; 474*1da177e4SLinus Torvalds cgc.timeout = IOCTL_TIMEOUT; 475*1da177e4SLinus Torvalds return sr_do_ioctl(cd, &cgc); 476*1da177e4SLinus Torvalds } 477*1da177e4SLinus Torvalds 478*1da177e4SLinus Torvalds /* 479*1da177e4SLinus Torvalds * read sectors with blocksizes other than 2048 480*1da177e4SLinus Torvalds */ 481*1da177e4SLinus Torvalds 482*1da177e4SLinus Torvalds static int sr_read_sector(Scsi_CD *cd, int lba, int blksize, unsigned char *dest) 483*1da177e4SLinus Torvalds { 484*1da177e4SLinus Torvalds struct packet_command cgc; 485*1da177e4SLinus Torvalds int rc; 486*1da177e4SLinus Torvalds 487*1da177e4SLinus Torvalds /* we try the READ CD command first... */ 488*1da177e4SLinus Torvalds if (cd->readcd_known) { 489*1da177e4SLinus Torvalds rc = sr_read_cd(cd, dest, lba, 0, blksize); 490*1da177e4SLinus Torvalds if (-EDRIVE_CANT_DO_THIS != rc) 491*1da177e4SLinus Torvalds return rc; 492*1da177e4SLinus Torvalds cd->readcd_known = 0; 493*1da177e4SLinus Torvalds printk("CDROM does'nt support READ CD (0xbe) command\n"); 494*1da177e4SLinus Torvalds /* fall & retry the other way */ 495*1da177e4SLinus Torvalds } 496*1da177e4SLinus Torvalds /* ... if this fails, we switch the blocksize using MODE SELECT */ 497*1da177e4SLinus Torvalds if (blksize != cd->device->sector_size) { 498*1da177e4SLinus Torvalds if (0 != (rc = sr_set_blocklength(cd, blksize))) 499*1da177e4SLinus Torvalds return rc; 500*1da177e4SLinus Torvalds } 501*1da177e4SLinus Torvalds #ifdef DEBUG 502*1da177e4SLinus Torvalds printk("%s: sr_read_sector lba=%d blksize=%d\n", cd->cdi.name, lba, blksize); 503*1da177e4SLinus Torvalds #endif 504*1da177e4SLinus Torvalds 505*1da177e4SLinus Torvalds memset(&cgc, 0, sizeof(struct packet_command)); 506*1da177e4SLinus Torvalds cgc.cmd[0] = GPCMD_READ_10; 507*1da177e4SLinus Torvalds cgc.cmd[2] = (unsigned char) (lba >> 24) & 0xff; 508*1da177e4SLinus Torvalds cgc.cmd[3] = (unsigned char) (lba >> 16) & 0xff; 509*1da177e4SLinus Torvalds cgc.cmd[4] = (unsigned char) (lba >> 8) & 0xff; 510*1da177e4SLinus Torvalds cgc.cmd[5] = (unsigned char) lba & 0xff; 511*1da177e4SLinus Torvalds cgc.cmd[8] = 1; 512*1da177e4SLinus Torvalds cgc.buffer = dest; 513*1da177e4SLinus Torvalds cgc.buflen = blksize; 514*1da177e4SLinus Torvalds cgc.data_direction = DMA_FROM_DEVICE; 515*1da177e4SLinus Torvalds cgc.timeout = IOCTL_TIMEOUT; 516*1da177e4SLinus Torvalds rc = sr_do_ioctl(cd, &cgc); 517*1da177e4SLinus Torvalds 518*1da177e4SLinus Torvalds return rc; 519*1da177e4SLinus Torvalds } 520*1da177e4SLinus Torvalds 521*1da177e4SLinus Torvalds /* 522*1da177e4SLinus Torvalds * read a sector in raw mode to check the sector format 523*1da177e4SLinus Torvalds * ret: 1 == mode2 (XA), 0 == mode1, <0 == error 524*1da177e4SLinus Torvalds */ 525*1da177e4SLinus Torvalds 526*1da177e4SLinus Torvalds int sr_is_xa(Scsi_CD *cd) 527*1da177e4SLinus Torvalds { 528*1da177e4SLinus Torvalds unsigned char *raw_sector; 529*1da177e4SLinus Torvalds int is_xa; 530*1da177e4SLinus Torvalds 531*1da177e4SLinus Torvalds if (!xa_test) 532*1da177e4SLinus Torvalds return 0; 533*1da177e4SLinus Torvalds 534*1da177e4SLinus Torvalds raw_sector = (unsigned char *) kmalloc(2048, GFP_KERNEL | SR_GFP_DMA(cd)); 535*1da177e4SLinus Torvalds if (!raw_sector) 536*1da177e4SLinus Torvalds return -ENOMEM; 537*1da177e4SLinus Torvalds if (0 == sr_read_sector(cd, cd->ms_offset + 16, 538*1da177e4SLinus Torvalds CD_FRAMESIZE_RAW1, raw_sector)) { 539*1da177e4SLinus Torvalds is_xa = (raw_sector[3] == 0x02) ? 1 : 0; 540*1da177e4SLinus Torvalds } else { 541*1da177e4SLinus Torvalds /* read a raw sector failed for some reason. */ 542*1da177e4SLinus Torvalds is_xa = -1; 543*1da177e4SLinus Torvalds } 544*1da177e4SLinus Torvalds kfree(raw_sector); 545*1da177e4SLinus Torvalds #ifdef DEBUG 546*1da177e4SLinus Torvalds printk("%s: sr_is_xa: %d\n", cd->cdi.name, is_xa); 547*1da177e4SLinus Torvalds #endif 548*1da177e4SLinus Torvalds return is_xa; 549*1da177e4SLinus Torvalds } 550*1da177e4SLinus Torvalds 551*1da177e4SLinus Torvalds int sr_dev_ioctl(struct cdrom_device_info *cdi, 552*1da177e4SLinus Torvalds unsigned int cmd, unsigned long arg) 553*1da177e4SLinus Torvalds { 554*1da177e4SLinus Torvalds Scsi_CD *cd = cdi->handle; 555*1da177e4SLinus Torvalds int ret; 556*1da177e4SLinus Torvalds 557*1da177e4SLinus Torvalds ret = scsi_nonblockable_ioctl(cd->device, cmd, 558*1da177e4SLinus Torvalds (void __user *)arg, NULL); 559*1da177e4SLinus Torvalds /* 560*1da177e4SLinus Torvalds * ENODEV means that we didn't recognise the ioctl, or that we 561*1da177e4SLinus Torvalds * cannot execute it in the current device state. In either 562*1da177e4SLinus Torvalds * case fall through to scsi_ioctl, which will return ENDOEV again 563*1da177e4SLinus Torvalds * if it doesn't recognise the ioctl 564*1da177e4SLinus Torvalds */ 565*1da177e4SLinus Torvalds if (ret != -ENODEV) 566*1da177e4SLinus Torvalds return ret; 567*1da177e4SLinus Torvalds return scsi_ioctl(cd->device, cmd, (void __user *)arg); 568*1da177e4SLinus Torvalds } 569