1 #include <linux/kernel.h> 2 #include <linux/sched.h> 5 #include <asm/uaccess.h> 6 #include <linux/errno.h> 7 #include <linux/string.h> 12 #include <scsi/scsi_ioctl.h> 14 #include <linux/cdrom.h> 15 #include <linux/ucdrom.h> 18 externvoidget_sectorsize(int); 20 #define IOCTL_RETRIES 3 21 /* The CDROM is fairly slow, so we need a little extra time */ 22 /* In fact, it is very slow if it has to spin up first */ 23 #define IOCTL_TIMEOUT 3000 25 static voidsr_ioctl_done(Scsi_Cmnd
* SCpnt
) 29 req
= &SCpnt
->request
; 30 req
->rq_status
= RQ_SCSI_DONE
;/* Busy, but indicate request done */ 32 if(req
->sem
!= NULL
) { 37 /* We do our own retries because we want to know what the specific 38 error code is. Normally the UNIT_ATTENTION code will automatically 39 clear after one error */ 41 intsr_do_ioctl(int target
,unsigned char* sr_cmd
,void* buffer
,unsigned buflength
) 46 SCpnt
=allocate_device(NULL
, scsi_CDs
[target
].device
,1); 48 struct semaphore sem
= MUTEX_LOCKED
; 49 SCpnt
->request
.sem
= &sem
; 51 (void*) sr_cmd
, buffer
, buflength
, sr_ioctl_done
, 52 IOCTL_TIMEOUT
, IOCTL_RETRIES
); 56 result
= SCpnt
->result
; 58 /* Minimal error checking. Ignore cases we know about, and report the rest. */ 59 if(driver_byte(result
) !=0) 60 switch(SCpnt
->sense_buffer
[2] &0xf) { 62 scsi_CDs
[target
].device
->changed
=1; 63 printk("Disc change detected.\n"); 65 case NOT_READY
:/* This happens if there is no disc in drive */ 66 printk(KERN_INFO
"CDROM not ready. Make sure there is a disc in the drive.\n"); 69 printk("CDROM (ioctl) reports ILLEGAL REQUEST.\n"); 72 print_sense("sr", SCpnt
); 75 result
= SCpnt
->result
; 76 SCpnt
->request
.rq_status
= RQ_INACTIVE
;/* Deallocate */ 77 wake_up(&SCpnt
->device
->device_wait
); 78 /* Wake up a process waiting for device*/ 82 /* ---------------------------------------------------------------------- */ 83 /* interface to cdrom.c */ 85 intsr_tray_move(struct cdrom_device_info
*cdi
,int pos
) 89 sr_cmd
[0] = START_STOP
; 90 sr_cmd
[1] = ((scsi_CDs
[MINOR(cdi
->dev
)].device
-> lun
) <<5); 91 sr_cmd
[2] = sr_cmd
[3] = sr_cmd
[5] =0; 92 sr_cmd
[4] = (pos
==0) ?0x03/* close */:0x02/* eject */; 94 returnsr_do_ioctl(MINOR(cdi
->dev
), sr_cmd
, NULL
,255); 97 intsr_lock_door(struct cdrom_device_info
*cdi
,int lock
) 99 returnscsi_ioctl(scsi_CDs
[MINOR(cdi
->dev
)].device
, 100 lock
? SCSI_IOCTL_DOORLOCK
: SCSI_IOCTL_DOORUNLOCK
, 104 intsr_drive_status(struct cdrom_device_info
*cdi
,int slot
) 106 if(CDSL_CURRENT
!= slot
) { 107 /* we have no changer support */ 111 if(!scsi_ioctl(scsi_CDs
[MINOR(cdi
->dev
)].device
, 112 SCSI_IOCTL_TEST_UNIT_READY
,0)) 116 /* Tell tray is open if the drive is not ready. Seems there is 117 * no way to check whenever the tray is really open, but this way 118 * we get auto-close-on-open work. And it seems to have no ill 119 * effects with caddy drives... */ 120 return CDS_TRAY_OPEN
; 126 intsr_disk_status(struct cdrom_device_info
*cdi
) 128 struct cdrom_tochdr toc_h
; 129 struct cdrom_tocentry toc_e
; 132 if(scsi_ioctl(scsi_CDs
[MINOR(cdi
->dev
)].device
,SCSI_IOCTL_TEST_UNIT_READY
,0)) 135 /* if the xa-bit is on, we tell it is XA... */ 136 if(scsi_CDs
[MINOR(cdi
->dev
)].xa_flag
) 139 /* ...else we look for data tracks */ 140 if(sr_audio_ioctl(cdi
, CDROMREADTOCHDR
, &toc_h
)) 142 for(i
= toc_h
.cdth_trk0
; i
<= toc_h
.cdth_trk1
; i
++) { 143 toc_e
.cdte_track
= i
; 144 toc_e
.cdte_format
= CDROM_LBA
; 145 if(sr_audio_ioctl(cdi
, CDROMREADTOCENTRY
, &toc_e
)) 147 if(toc_e
.cdte_ctrl
& CDROM_DATA_TRACK
) 150 if(i
== toc_h
.cdth_trk0
&& toc_e
.cdte_addr
.lba
>100) 151 /* guess: looks like a "hidden track" CD */ 158 intsr_get_last_session(struct cdrom_device_info
*cdi
, 159 struct cdrom_multisession
* ms_info
) 161 ms_info
->addr
.lba
=scsi_CDs
[MINOR(cdi
->dev
)].ms_offset
; 162 ms_info
->xa_flag
=scsi_CDs
[MINOR(cdi
->dev
)].xa_flag
|| 163 scsi_CDs
[MINOR(cdi
->dev
)].ms_offset
>0; 168 intsr_get_mcn(struct cdrom_device_info
*cdi
,struct cdrom_mcn
*mcn
) 174 sr_cmd
[0] = SCMD_READ_SUBCHANNEL
; 175 sr_cmd
[1] = ((scsi_CDs
[MINOR(cdi
->dev
)].device
->lun
) <<5); 176 sr_cmd
[2] =0x40;/* I do want the subchannel info */ 177 sr_cmd
[3] =0x02;/* Give me medium catalog number info */ 178 sr_cmd
[4] = sr_cmd
[5] =0; 184 buffer
= (unsigned char*)scsi_malloc(512); 185 if(!buffer
)return-ENOMEM
; 187 result
=sr_do_ioctl(MINOR(cdi
->dev
), sr_cmd
, buffer
,24); 189 memcpy(mcn
->medium_catalog_number
, buffer
+9,13); 190 mcn
->medium_catalog_number
[13] =0; 192 scsi_free(buffer
,512); 197 intsr_reset(struct cdrom_device_info
*cdi
) 199 invalidate_buffers(cdi
->dev
); 203 /* ----------------------------------------------------------------------- */ 204 /* this is called by the generic cdrom driver. arg is a _kernel_ pointer, */ 205 /* becauce the generic cdrom driver does the user access stuff for us. */ 207 intsr_audio_ioctl(struct cdrom_device_info
*cdi
,unsigned int cmd
,void* arg
) 212 target
=MINOR(cdi
->dev
); 219 sr_cmd
[0] = SCMD_PAUSE_RESUME
; 220 sr_cmd
[1] = scsi_CDs
[target
].device
->lun
<<5; 221 sr_cmd
[2] = sr_cmd
[3] = sr_cmd
[4] =0; 222 sr_cmd
[5] = sr_cmd
[6] = sr_cmd
[7] =0; 226 result
=sr_do_ioctl(target
, sr_cmd
, NULL
,255); 231 sr_cmd
[0] = SCMD_PAUSE_RESUME
; 232 sr_cmd
[1] = scsi_CDs
[target
].device
->lun
<<5; 233 sr_cmd
[2] = sr_cmd
[3] = sr_cmd
[4] =0; 234 sr_cmd
[5] = sr_cmd
[6] = sr_cmd
[7] =0; 238 result
=sr_do_ioctl(target
, sr_cmd
, NULL
,255); 243 struct cdrom_msf
* msf
= (struct cdrom_msf
*)arg
; 245 sr_cmd
[0] = SCMD_PLAYAUDIO_MSF
; 246 sr_cmd
[1] = scsi_CDs
[target
].device
->lun
<<5; 248 sr_cmd
[3] = msf
->cdmsf_min0
; 249 sr_cmd
[4] = msf
->cdmsf_sec0
; 250 sr_cmd
[5] = msf
->cdmsf_frame0
; 251 sr_cmd
[6] = msf
->cdmsf_min1
; 252 sr_cmd
[7] = msf
->cdmsf_sec1
; 253 sr_cmd
[8] = msf
->cdmsf_frame1
; 256 result
=sr_do_ioctl(target
, sr_cmd
, NULL
,255); 262 struct cdrom_blk
* blk
= (struct cdrom_blk
*)arg
; 264 sr_cmd
[0] = SCMD_PLAYAUDIO10
; 265 sr_cmd
[1] = scsi_CDs
[target
].device
->lun
<<5; 266 sr_cmd
[2] = blk
->from
>>24; 267 sr_cmd
[3] = blk
->from
>>16; 268 sr_cmd
[4] = blk
->from
>>8; 269 sr_cmd
[5] = blk
->from
; 271 sr_cmd
[7] = blk
->len
>>8; 272 sr_cmd
[8] = blk
->len
; 275 result
=sr_do_ioctl(target
, sr_cmd
, NULL
,255); 279 case CDROMPLAYTRKIND
: 281 struct cdrom_ti
* ti
= (struct cdrom_ti
*)arg
; 283 sr_cmd
[0] = SCMD_PLAYAUDIO_TI
; 284 sr_cmd
[1] = scsi_CDs
[target
].device
->lun
<<5; 287 sr_cmd
[4] = ti
->cdti_trk0
; 288 sr_cmd
[5] = ti
->cdti_ind0
; 290 sr_cmd
[7] = ti
->cdti_trk1
; 291 sr_cmd
[8] = ti
->cdti_ind1
; 294 result
=sr_do_ioctl(target
, sr_cmd
, NULL
,255); 298 case CDROMREADTOCHDR
: 300 struct cdrom_tochdr
* tochdr
= (struct cdrom_tochdr
*)arg
; 303 sr_cmd
[0] = SCMD_READ_TOC
; 304 sr_cmd
[1] = ((scsi_CDs
[target
].device
->lun
) <<5); 305 sr_cmd
[2] = sr_cmd
[3] = sr_cmd
[4] = sr_cmd
[5] =0; 307 sr_cmd
[7] =0;/* MSB of length (12) */ 308 sr_cmd
[8] =12;/* LSB of length */ 311 buffer
= (unsigned char*)scsi_malloc(512); 312 if(!buffer
)return-ENOMEM
; 314 result
=sr_do_ioctl(target
, sr_cmd
, buffer
,12); 316 tochdr
->cdth_trk0
= buffer
[2]; 317 tochdr
->cdth_trk1
= buffer
[3]; 319 scsi_free(buffer
,512); 323 case CDROMREADTOCENTRY
: 325 struct cdrom_tocentry
* tocentry
= (struct cdrom_tocentry
*)arg
; 326 unsigned char* buffer
; 328 sr_cmd
[0] = SCMD_READ_TOC
; 329 sr_cmd
[1] = ((scsi_CDs
[target
].device
->lun
) <<5) | 330 (tocentry
->cdte_format
== CDROM_MSF
?0x02:0); 331 sr_cmd
[2] = sr_cmd
[3] = sr_cmd
[4] = sr_cmd
[5] =0; 332 sr_cmd
[6] = tocentry
->cdte_track
; 333 sr_cmd
[7] =0;/* MSB of length (12) */ 334 sr_cmd
[8] =12;/* LSB of length */ 337 buffer
= (unsigned char*)scsi_malloc(512); 338 if(!buffer
)return-ENOMEM
; 340 result
=sr_do_ioctl(target
, sr_cmd
, buffer
,12); 342 tocentry
->cdte_ctrl
= buffer
[5] &0xf; 343 tocentry
->cdte_adr
= buffer
[5] >>4; 344 tocentry
->cdte_datamode
= (tocentry
->cdte_ctrl
&0x04) ?1:0; 345 if(tocentry
->cdte_format
== CDROM_MSF
) { 346 tocentry
->cdte_addr
.msf
.minute
= buffer
[9]; 347 tocentry
->cdte_addr
.msf
.second
= buffer
[10]; 348 tocentry
->cdte_addr
.msf
.frame
= buffer
[11]; 350 tocentry
->cdte_addr
.lba
= (((((buffer
[8] <<8) + buffer
[9]) <<8) 351 + buffer
[10]) <<8) + buffer
[11]; 353 scsi_free(buffer
,512); 358 sr_cmd
[0] = START_STOP
; 359 sr_cmd
[1] = ((scsi_CDs
[target
].device
->lun
) <<5) |1; 360 sr_cmd
[2] = sr_cmd
[3] = sr_cmd
[5] =0; 363 result
=sr_do_ioctl(target
, sr_cmd
, NULL
,255); 367 sr_cmd
[0] = START_STOP
; 368 sr_cmd
[1] = ((scsi_CDs
[target
].device
->lun
) <<5) |1; 369 sr_cmd
[2] = sr_cmd
[3] = sr_cmd
[5] =0; 372 result
=sr_do_ioctl(target
, sr_cmd
, NULL
,255); 377 char* buffer
, * mask
; 378 struct cdrom_volctrl
* volctrl
= (struct cdrom_volctrl
*)arg
; 380 /* First we get the current params so we can just twiddle the volume */ 382 sr_cmd
[0] = MODE_SENSE
; 383 sr_cmd
[1] = (scsi_CDs
[target
].device
-> lun
) <<5; 384 sr_cmd
[2] =0xe;/* Want mode page 0xe, CDROM audio params */ 389 buffer
= (unsigned char*)scsi_malloc(512); 390 if(!buffer
)return-ENOMEM
; 392 if((result
=sr_do_ioctl(target
, sr_cmd
, buffer
,28))) { 393 printk("Hosed while obtaining audio mode page\n"); 394 scsi_free(buffer
,512); 398 sr_cmd
[0] = MODE_SENSE
; 399 sr_cmd
[1] = (scsi_CDs
[target
].device
-> lun
) <<5; 400 sr_cmd
[2] =0x4e;/* Want the mask for mode page 0xe */ 405 mask
= (unsigned char*)scsi_malloc(512); 407 scsi_free(buffer
,512); 412 if((result
=sr_do_ioctl(target
, sr_cmd
, mask
,28))) { 413 printk("Hosed while obtaining mask for audio mode page\n"); 414 scsi_free(buffer
,512); 419 /* Now mask and substitute our own volume and reuse the rest */ 420 buffer
[0] =0;/* Clear reserved field */ 422 buffer
[21] = volctrl
->channel0
& mask
[21]; 423 buffer
[23] = volctrl
->channel1
& mask
[23]; 424 buffer
[25] = volctrl
->channel2
& mask
[25]; 425 buffer
[27] = volctrl
->channel3
& mask
[27]; 427 sr_cmd
[0] = MODE_SELECT
; 428 sr_cmd
[1] = ((scsi_CDs
[target
].device
-> lun
) <<5) |0x10;/* Params are SCSI-2 */ 429 sr_cmd
[2] = sr_cmd
[3] =0; 433 result
=sr_do_ioctl(target
, sr_cmd
, buffer
,28); 434 scsi_free(buffer
,512); 442 struct cdrom_volctrl
* volctrl
= (struct cdrom_volctrl
*)arg
; 444 /* Get the current params */ 446 sr_cmd
[0] = MODE_SENSE
; 447 sr_cmd
[1] = (scsi_CDs
[target
].device
-> lun
) <<5; 448 sr_cmd
[2] =0xe;/* Want mode page 0xe, CDROM audio params */ 453 buffer
= (unsigned char*)scsi_malloc(512); 454 if(!buffer
)return-ENOMEM
; 456 if((result
=sr_do_ioctl(target
, sr_cmd
, buffer
,28))) { 457 printk("(CDROMVOLREAD) Hosed while obtaining audio mode page\n"); 458 scsi_free(buffer
,512); 462 volctrl
->channel0
= buffer
[21]; 463 volctrl
->channel1
= buffer
[23]; 464 volctrl
->channel2
= buffer
[25]; 465 volctrl
->channel3
= buffer
[27]; 467 scsi_free(buffer
,512); 473 struct cdrom_subchnl
* subchnl
= (struct cdrom_subchnl
*)arg
; 476 sr_cmd
[0] = SCMD_READ_SUBCHANNEL
; 477 sr_cmd
[1] = ((scsi_CDs
[target
].device
->lun
) <<5) |0x02;/* MSF format */ 478 sr_cmd
[2] =0x40;/* I do want the subchannel info */ 479 sr_cmd
[3] =0x01;/* Give me current position info */ 480 sr_cmd
[4] = sr_cmd
[5] =0; 486 buffer
= (unsigned char*)scsi_malloc(512); 487 if(!buffer
)return-ENOMEM
; 489 result
=sr_do_ioctl(target
, sr_cmd
, buffer
,16); 491 subchnl
->cdsc_audiostatus
= buffer
[1]; 492 subchnl
->cdsc_format
= CDROM_MSF
; 493 subchnl
->cdsc_ctrl
= buffer
[5] &0xf; 494 subchnl
->cdsc_trk
= buffer
[6]; 495 subchnl
->cdsc_ind
= buffer
[7]; 497 subchnl
->cdsc_reladdr
.msf
.minute
= buffer
[13]; 498 subchnl
->cdsc_reladdr
.msf
.second
= buffer
[14]; 499 subchnl
->cdsc_reladdr
.msf
.frame
= buffer
[15]; 500 subchnl
->cdsc_absaddr
.msf
.minute
= buffer
[9]; 501 subchnl
->cdsc_absaddr
.msf
.second
= buffer
[10]; 502 subchnl
->cdsc_absaddr
.msf
.frame
= buffer
[11]; 504 scsi_free(buffer
,512); 513 printk("DEBUG: sr_audio: result for ioctl %x: %x\n",cmd
,result
); 519 intsr_dev_ioctl(struct cdrom_device_info
*cdi
, 520 unsigned int cmd
,unsigned long arg
) 524 target
=MINOR(cdi
->dev
); 527 /* these are compatible with the ide-cd driver */ 532 #if CONFIG_BLK_DEV_SR_VENDOR 535 struct cdrom_msf msf
; 536 int blocksize
, lba
, rc
; 538 if(cmd
== CDROMREADMODE1
) 539 blocksize
= CD_FRAMESIZE
;/* 2048 */ 540 else if(cmd
== CDROMREADMODE2
) 541 blocksize
= CD_FRAMESIZE_RAW0
;/* 2336 */ 543 /* some SCSI drives do not allow this one */ 544 blocksize
= CD_FRAMESIZE_RAW
;/* 2352 */ 546 if(copy_from_user(&msf
,(void*)arg
,sizeof(msf
))) 548 if(!(raw
=scsi_malloc(2048+512))) 551 lba
= (((msf
.cdmsf_min0
* CD_SECS
) + msf
.cdmsf_sec0
) 552 * CD_FRAMES
+ msf
.cdmsf_frame0
) - CD_BLOCK_OFFSET
; 553 rc
=sr_read_sector(target
, lba
, blocksize
, raw
); 555 if(copy_to_user((void*)arg
, raw
, blocksize
)) 558 scsi_free(raw
,2048+512); 569 err
=verify_area(VERIFY_WRITE
, (long*) arg
,sizeof(long)); 572 put_user(read_ahead
[MAJOR(cdi
->dev
)], (long*) arg
); 582 read_ahead
[MAJOR(cdi
->dev
)] = arg
; 585 RO_IOCTLS(cdi
->dev
,arg
); 588 returnscsi_ioctl(scsi_CDs
[target
].device
,cmd
,(void*) arg
); 593 * Overrides for Emacs so that we follow Linus's tabbing style. 594 * Emacs will notice this stuff at the end of the file and automatically 595 * adjust the settings for this buffer only. This must remain at the end 597 * --------------------------------------------------------------------------- 600 * c-brace-imaginary-offset: 0 602 * c-argdecl-indent: 4 604 * c-continued-statement-offset: 4 605 * c-continued-brace-offset: 0 606 * indent-tabs-mode: nil