diff options
-rw-r--r-- | drivers/cdrom/cdrom.c | 7 | ||||
-rw-r--r-- | drivers/cdrom/cdu31a.c | 8 | ||||
-rw-r--r-- | drivers/cdrom/cm206.c | 44 | ||||
-rw-r--r-- | drivers/cdrom/sbpcd.c | 710 | ||||
-rw-r--r-- | drivers/cdrom/viocd.c | 2 | ||||
-rw-r--r-- | drivers/ide/ide-cd.c | 99 | ||||
-rw-r--r-- | drivers/scsi/sr.c | 37 | ||||
-rw-r--r-- | drivers/scsi/sr.h | 1 | ||||
-rw-r--r-- | drivers/scsi/sr_ioctl.c | 19 | ||||
-rw-r--r-- | include/linux/cdrom.h | 5 |
10 files changed, 450 insertions, 482 deletions
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index d6653fc03b92..a59876a0bfa1 100644 --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c | |||
@@ -407,7 +407,6 @@ int register_cdrom(struct cdrom_device_info *cdi) | |||
407 | ENSURE(get_mcn, CDC_MCN); | 407 | ENSURE(get_mcn, CDC_MCN); |
408 | ENSURE(reset, CDC_RESET); | 408 | ENSURE(reset, CDC_RESET); |
409 | ENSURE(audio_ioctl, CDC_PLAY_AUDIO); | 409 | ENSURE(audio_ioctl, CDC_PLAY_AUDIO); |
410 | ENSURE(dev_ioctl, CDC_IOCTLS); | ||
411 | ENSURE(generic_packet, CDC_GENERIC_PACKET); | 410 | ENSURE(generic_packet, CDC_GENERIC_PACKET); |
412 | cdi->mc_flags = 0; | 411 | cdi->mc_flags = 0; |
413 | cdo->n_minors = 0; | 412 | cdo->n_minors = 0; |
@@ -2776,12 +2775,6 @@ int cdrom_ioctl(struct file * file, struct cdrom_device_info *cdi, | |||
2776 | return cdrom_ioctl_audioctl(cdi, cmd); | 2775 | return cdrom_ioctl_audioctl(cdi, cmd); |
2777 | } | 2776 | } |
2778 | 2777 | ||
2779 | /* | ||
2780 | * Finally, do the device specific ioctls | ||
2781 | */ | ||
2782 | if (CDROM_CAN(CDC_IOCTLS)) | ||
2783 | return cdi->ops->dev_ioctl(cdi, cmd, arg); | ||
2784 | |||
2785 | return -ENOSYS; | 2778 | return -ENOSYS; |
2786 | } | 2779 | } |
2787 | 2780 | ||
diff --git a/drivers/cdrom/cdu31a.c b/drivers/cdrom/cdu31a.c index 378e88d20757..72ffd64e8b1e 100644 --- a/drivers/cdrom/cdu31a.c +++ b/drivers/cdrom/cdu31a.c | |||
@@ -2668,7 +2668,7 @@ static int scd_audio_ioctl(struct cdrom_device_info *cdi, | |||
2668 | return retval; | 2668 | return retval; |
2669 | } | 2669 | } |
2670 | 2670 | ||
2671 | static int scd_dev_ioctl(struct cdrom_device_info *cdi, | 2671 | static int scd_read_audio(struct cdrom_device_info *cdi, |
2672 | unsigned int cmd, unsigned long arg) | 2672 | unsigned int cmd, unsigned long arg) |
2673 | { | 2673 | { |
2674 | void __user *argp = (void __user *)arg; | 2674 | void __user *argp = (void __user *)arg; |
@@ -2894,11 +2894,10 @@ static struct cdrom_device_ops scd_dops = { | |||
2894 | .get_mcn = scd_get_mcn, | 2894 | .get_mcn = scd_get_mcn, |
2895 | .reset = scd_reset, | 2895 | .reset = scd_reset, |
2896 | .audio_ioctl = scd_audio_ioctl, | 2896 | .audio_ioctl = scd_audio_ioctl, |
2897 | .dev_ioctl = scd_dev_ioctl, | ||
2898 | .capability = CDC_OPEN_TRAY | CDC_CLOSE_TRAY | CDC_LOCK | | 2897 | .capability = CDC_OPEN_TRAY | CDC_CLOSE_TRAY | CDC_LOCK | |
2899 | CDC_SELECT_SPEED | CDC_MULTI_SESSION | | 2898 | CDC_SELECT_SPEED | CDC_MULTI_SESSION | |
2900 | CDC_MCN | CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO | | 2899 | CDC_MCN | CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO | |
2901 | CDC_RESET | CDC_IOCTLS | CDC_DRIVE_STATUS, | 2900 | CDC_RESET | CDC_DRIVE_STATUS, |
2902 | .n_minors = 1, | 2901 | .n_minors = 1, |
2903 | }; | 2902 | }; |
2904 | 2903 | ||
@@ -2936,6 +2935,9 @@ static int scd_block_ioctl(struct inode *inode, struct file *file, | |||
2936 | case CDROMCLOSETRAY: | 2935 | case CDROMCLOSETRAY: |
2937 | retval = scd_tray_move(&scd_info, 0); | 2936 | retval = scd_tray_move(&scd_info, 0); |
2938 | break; | 2937 | break; |
2938 | case CDROMREADAUDIO: | ||
2939 | retval = scd_read_audio(&scd_info, CDROMREADAUDIO, arg); | ||
2940 | break; | ||
2939 | default: | 2941 | default: |
2940 | retval = cdrom_ioctl(file, &scd_info, inode, cmd, arg); | 2942 | retval = cdrom_ioctl(file, &scd_info, inode, cmd, arg); |
2941 | } | 2943 | } |
diff --git a/drivers/cdrom/cm206.c b/drivers/cdrom/cm206.c index ce127f7ec0f6..fad27a87ce35 100644 --- a/drivers/cdrom/cm206.c +++ b/drivers/cdrom/cm206.c | |||
@@ -1157,32 +1157,6 @@ static int cm206_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, | |||
1157 | } | 1157 | } |
1158 | } | 1158 | } |
1159 | 1159 | ||
1160 | /* Ioctl. These ioctls are specific to the cm206 driver. I have made | ||
1161 | some driver statistics accessible through ioctl calls. | ||
1162 | */ | ||
1163 | |||
1164 | static int cm206_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, | ||
1165 | unsigned long arg) | ||
1166 | { | ||
1167 | switch (cmd) { | ||
1168 | #ifdef STATISTICS | ||
1169 | case CM206CTL_GET_STAT: | ||
1170 | if (arg >= NR_STATS) | ||
1171 | return -EINVAL; | ||
1172 | else | ||
1173 | return cd->stats[arg]; | ||
1174 | case CM206CTL_GET_LAST_STAT: | ||
1175 | if (arg >= NR_STATS) | ||
1176 | return -EINVAL; | ||
1177 | else | ||
1178 | return cd->last_stat[arg]; | ||
1179 | #endif | ||
1180 | default: | ||
1181 | debug(("Unknown ioctl call 0x%x\n", cmd)); | ||
1182 | return -EINVAL; | ||
1183 | } | ||
1184 | } | ||
1185 | |||
1186 | static int cm206_media_changed(struct cdrom_device_info *cdi, int disc_nr) | 1160 | static int cm206_media_changed(struct cdrom_device_info *cdi, int disc_nr) |
1187 | { | 1161 | { |
1188 | if (cd != NULL) { | 1162 | if (cd != NULL) { |
@@ -1321,11 +1295,10 @@ static struct cdrom_device_ops cm206_dops = { | |||
1321 | .get_mcn = cm206_get_upc, | 1295 | .get_mcn = cm206_get_upc, |
1322 | .reset = cm206_reset, | 1296 | .reset = cm206_reset, |
1323 | .audio_ioctl = cm206_audio_ioctl, | 1297 | .audio_ioctl = cm206_audio_ioctl, |
1324 | .dev_ioctl = cm206_ioctl, | ||
1325 | .capability = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK | | 1298 | .capability = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK | |
1326 | CDC_MULTI_SESSION | CDC_MEDIA_CHANGED | | 1299 | CDC_MULTI_SESSION | CDC_MEDIA_CHANGED | |
1327 | CDC_MCN | CDC_PLAY_AUDIO | CDC_SELECT_SPEED | | 1300 | CDC_MCN | CDC_PLAY_AUDIO | CDC_SELECT_SPEED | |
1328 | CDC_IOCTLS | CDC_DRIVE_STATUS, | 1301 | CDC_DRIVE_STATUS, |
1329 | .n_minors = 1, | 1302 | .n_minors = 1, |
1330 | }; | 1303 | }; |
1331 | 1304 | ||
@@ -1350,6 +1323,21 @@ static int cm206_block_release(struct inode *inode, struct file *file) | |||
1350 | static int cm206_block_ioctl(struct inode *inode, struct file *file, | 1323 | static int cm206_block_ioctl(struct inode *inode, struct file *file, |
1351 | unsigned cmd, unsigned long arg) | 1324 | unsigned cmd, unsigned long arg) |
1352 | { | 1325 | { |
1326 | switch (cmd) { | ||
1327 | #ifdef STATISTICS | ||
1328 | case CM206CTL_GET_STAT: | ||
1329 | if (arg >= NR_STATS) | ||
1330 | return -EINVAL; | ||
1331 | return cd->stats[arg]; | ||
1332 | case CM206CTL_GET_LAST_STAT: | ||
1333 | if (arg >= NR_STATS) | ||
1334 | return -EINVAL; | ||
1335 | return cd->last_stat[arg]; | ||
1336 | #endif | ||
1337 | default: | ||
1338 | break; | ||
1339 | } | ||
1340 | |||
1353 | return cdrom_ioctl(file, &cm206_info, inode, cmd, arg); | 1341 | return cdrom_ioctl(file, &cm206_info, inode, cmd, arg); |
1354 | } | 1342 | } |
1355 | 1343 | ||
diff --git a/drivers/cdrom/sbpcd.c b/drivers/cdrom/sbpcd.c index 466e9c2974bd..4760f515f591 100644 --- a/drivers/cdrom/sbpcd.c +++ b/drivers/cdrom/sbpcd.c | |||
@@ -4160,332 +4160,6 @@ static int sbpcd_get_last_session(struct cdrom_device_info *cdi, struct cdrom_mu | |||
4160 | return 0; | 4160 | return 0; |
4161 | } | 4161 | } |
4162 | 4162 | ||
4163 | /*==========================================================================*/ | ||
4164 | /*==========================================================================*/ | ||
4165 | /* | ||
4166 | * ioctl support | ||
4167 | */ | ||
4168 | static int sbpcd_dev_ioctl(struct cdrom_device_info *cdi, u_int cmd, | ||
4169 | u_long arg) | ||
4170 | { | ||
4171 | struct sbpcd_drive *p = cdi->handle; | ||
4172 | int i; | ||
4173 | |||
4174 | msg(DBG_IO2,"ioctl(%s, 0x%08lX, 0x%08lX)\n", cdi->name, cmd, arg); | ||
4175 | if (p->drv_id==-1) { | ||
4176 | msg(DBG_INF, "ioctl: bad device: %s\n", cdi->name); | ||
4177 | return (-ENXIO); /* no such drive */ | ||
4178 | } | ||
4179 | down(&ioctl_read_sem); | ||
4180 | if (p != current_drive) | ||
4181 | switch_drive(p); | ||
4182 | |||
4183 | msg(DBG_IO2,"ioctl: device %s, request %04X\n",cdi->name,cmd); | ||
4184 | switch (cmd) /* Sun-compatible */ | ||
4185 | { | ||
4186 | case DDIOCSDBG: /* DDI Debug */ | ||
4187 | if (!capable(CAP_SYS_ADMIN)) RETURN_UP(-EPERM); | ||
4188 | i=sbpcd_dbg_ioctl(arg,1); | ||
4189 | RETURN_UP(i); | ||
4190 | case CDROMRESET: /* hard reset the drive */ | ||
4191 | msg(DBG_IOC,"ioctl: CDROMRESET entered.\n"); | ||
4192 | i=DriveReset(); | ||
4193 | current_drive->audio_state=0; | ||
4194 | RETURN_UP(i); | ||
4195 | |||
4196 | case CDROMREADMODE1: | ||
4197 | msg(DBG_IOC,"ioctl: CDROMREADMODE1 requested.\n"); | ||
4198 | #ifdef SAFE_MIXED | ||
4199 | if (current_drive->has_data>1) RETURN_UP(-EBUSY); | ||
4200 | #endif /* SAFE_MIXED */ | ||
4201 | cc_ModeSelect(CD_FRAMESIZE); | ||
4202 | cc_ModeSense(); | ||
4203 | current_drive->mode=READ_M1; | ||
4204 | RETURN_UP(0); | ||
4205 | |||
4206 | case CDROMREADMODE2: /* not usable at the moment */ | ||
4207 | msg(DBG_IOC,"ioctl: CDROMREADMODE2 requested.\n"); | ||
4208 | #ifdef SAFE_MIXED | ||
4209 | if (current_drive->has_data>1) RETURN_UP(-EBUSY); | ||
4210 | #endif /* SAFE_MIXED */ | ||
4211 | cc_ModeSelect(CD_FRAMESIZE_RAW1); | ||
4212 | cc_ModeSense(); | ||
4213 | current_drive->mode=READ_M2; | ||
4214 | RETURN_UP(0); | ||
4215 | |||
4216 | case CDROMAUDIOBUFSIZ: /* configure the audio buffer size */ | ||
4217 | msg(DBG_IOC,"ioctl: CDROMAUDIOBUFSIZ entered.\n"); | ||
4218 | if (current_drive->sbp_audsiz>0) | ||
4219 | vfree(current_drive->aud_buf); | ||
4220 | current_drive->aud_buf=NULL; | ||
4221 | current_drive->sbp_audsiz=arg; | ||
4222 | |||
4223 | if (current_drive->sbp_audsiz>16) | ||
4224 | { | ||
4225 | current_drive->sbp_audsiz = 0; | ||
4226 | RETURN_UP(current_drive->sbp_audsiz); | ||
4227 | } | ||
4228 | |||
4229 | if (current_drive->sbp_audsiz>0) | ||
4230 | { | ||
4231 | current_drive->aud_buf=(u_char *) vmalloc(current_drive->sbp_audsiz*CD_FRAMESIZE_RAW); | ||
4232 | if (current_drive->aud_buf==NULL) | ||
4233 | { | ||
4234 | msg(DBG_INF,"audio buffer (%d frames) not available.\n",current_drive->sbp_audsiz); | ||
4235 | current_drive->sbp_audsiz=0; | ||
4236 | } | ||
4237 | else msg(DBG_INF,"audio buffer size: %d frames.\n",current_drive->sbp_audsiz); | ||
4238 | } | ||
4239 | RETURN_UP(current_drive->sbp_audsiz); | ||
4240 | |||
4241 | case CDROMREADAUDIO: | ||
4242 | { /* start of CDROMREADAUDIO */ | ||
4243 | int i=0, j=0, frame, block=0; | ||
4244 | u_int try=0; | ||
4245 | u_long timeout; | ||
4246 | u_char *p; | ||
4247 | u_int data_tries = 0; | ||
4248 | u_int data_waits = 0; | ||
4249 | u_int data_retrying = 0; | ||
4250 | int status_tries; | ||
4251 | int error_flag; | ||
4252 | |||
4253 | msg(DBG_IOC,"ioctl: CDROMREADAUDIO entered.\n"); | ||
4254 | if (fam0_drive) RETURN_UP(-EINVAL); | ||
4255 | if (famL_drive) RETURN_UP(-EINVAL); | ||
4256 | if (famV_drive) RETURN_UP(-EINVAL); | ||
4257 | if (famT_drive) RETURN_UP(-EINVAL); | ||
4258 | #ifdef SAFE_MIXED | ||
4259 | if (current_drive->has_data>1) RETURN_UP(-EBUSY); | ||
4260 | #endif /* SAFE_MIXED */ | ||
4261 | if (current_drive->aud_buf==NULL) RETURN_UP(-EINVAL); | ||
4262 | if (copy_from_user(&read_audio, (void __user *)arg, | ||
4263 | sizeof(struct cdrom_read_audio))) | ||
4264 | RETURN_UP(-EFAULT); | ||
4265 | if (read_audio.nframes < 0 || read_audio.nframes>current_drive->sbp_audsiz) RETURN_UP(-EINVAL); | ||
4266 | if (!access_ok(VERIFY_WRITE, read_audio.buf, | ||
4267 | read_audio.nframes*CD_FRAMESIZE_RAW)) | ||
4268 | RETURN_UP(-EFAULT); | ||
4269 | |||
4270 | if (read_audio.addr_format==CDROM_MSF) /* MSF-bin specification of where to start */ | ||
4271 | block=msf2lba(&read_audio.addr.msf.minute); | ||
4272 | else if (read_audio.addr_format==CDROM_LBA) /* lba specification of where to start */ | ||
4273 | block=read_audio.addr.lba; | ||
4274 | else RETURN_UP(-EINVAL); | ||
4275 | #if 000 | ||
4276 | i=cc_SetSpeed(speed_150,0,0); | ||
4277 | if (i) msg(DBG_AUD,"read_audio: SetSpeed error %d\n", i); | ||
4278 | #endif | ||
4279 | msg(DBG_AUD,"read_audio: lba: %d, msf: %06X\n", | ||
4280 | block, blk2msf(block)); | ||
4281 | msg(DBG_AUD,"read_audio: before cc_ReadStatus.\n"); | ||
4282 | #if OLD_BUSY | ||
4283 | while (busy_data) sbp_sleep(HZ/10); /* wait a bit */ | ||
4284 | busy_audio=1; | ||
4285 | #endif /* OLD_BUSY */ | ||
4286 | error_flag=0; | ||
4287 | for (data_tries=5; data_tries>0; data_tries--) | ||
4288 | { | ||
4289 | msg(DBG_AUD,"data_tries=%d ...\n", data_tries); | ||
4290 | current_drive->mode=READ_AU; | ||
4291 | cc_ModeSelect(CD_FRAMESIZE_RAW); | ||
4292 | cc_ModeSense(); | ||
4293 | for (status_tries=3; status_tries > 0; status_tries--) | ||
4294 | { | ||
4295 | flags_cmd_out |= f_respo3; | ||
4296 | cc_ReadStatus(); | ||
4297 | if (sbp_status() != 0) break; | ||
4298 | if (st_check) cc_ReadError(); | ||
4299 | sbp_sleep(1); /* wait a bit, try again */ | ||
4300 | } | ||
4301 | if (status_tries == 0) | ||
4302 | { | ||
4303 | msg(DBG_AUD,"read_audio: sbp_status: failed after 3 tries in line %d.\n", __LINE__); | ||
4304 | continue; | ||
4305 | } | ||
4306 | msg(DBG_AUD,"read_audio: sbp_status: ok.\n"); | ||
4307 | |||
4308 | flags_cmd_out = f_putcmd | f_respo2 | f_ResponseStatus | f_obey_p_check; | ||
4309 | if (fam0L_drive) | ||
4310 | { | ||
4311 | flags_cmd_out |= f_lopsta | f_getsta | f_bit1; | ||
4312 | cmd_type=READ_M2; | ||
4313 | drvcmd[0]=CMD0_READ_XA; /* "read XA frames", old drives */ | ||
4314 | drvcmd[1]=(block>>16)&0x000000ff; | ||
4315 | drvcmd[2]=(block>>8)&0x000000ff; | ||
4316 | drvcmd[3]=block&0x000000ff; | ||
4317 | drvcmd[4]=0; | ||
4318 | drvcmd[5]=read_audio.nframes; /* # of frames */ | ||
4319 | drvcmd[6]=0; | ||
4320 | } | ||
4321 | else if (fam1_drive) | ||
4322 | { | ||
4323 | drvcmd[0]=CMD1_READ; /* "read frames", new drives */ | ||
4324 | lba2msf(block,&drvcmd[1]); /* msf-bin format required */ | ||
4325 | drvcmd[4]=0; | ||
4326 | drvcmd[5]=0; | ||
4327 | drvcmd[6]=read_audio.nframes; /* # of frames */ | ||
4328 | } | ||
4329 | else if (fam2_drive) | ||
4330 | { | ||
4331 | drvcmd[0]=CMD2_READ_XA2; | ||
4332 | lba2msf(block,&drvcmd[1]); /* msf-bin format required */ | ||
4333 | drvcmd[4]=0; | ||
4334 | drvcmd[5]=read_audio.nframes; /* # of frames */ | ||
4335 | drvcmd[6]=0x11; /* raw mode */ | ||
4336 | } | ||
4337 | else if (famT_drive) /* CD-55A: not tested yet */ | ||
4338 | { | ||
4339 | } | ||
4340 | msg(DBG_AUD,"read_audio: before giving \"read\" command.\n"); | ||
4341 | flags_cmd_out=f_putcmd; | ||
4342 | response_count=0; | ||
4343 | i=cmd_out(); | ||
4344 | if (i<0) msg(DBG_INF,"error giving READ AUDIO command: %0d\n", i); | ||
4345 | sbp_sleep(0); | ||
4346 | msg(DBG_AUD,"read_audio: after giving \"read\" command.\n"); | ||
4347 | for (frame=1;frame<2 && !error_flag; frame++) | ||
4348 | { | ||
4349 | try=maxtim_data; | ||
4350 | for (timeout=jiffies+9*HZ; ; ) | ||
4351 | { | ||
4352 | for ( ; try!=0;try--) | ||
4353 | { | ||
4354 | j=inb(CDi_status); | ||
4355 | if (!(j&s_not_data_ready)) break; | ||
4356 | if (!(j&s_not_result_ready)) break; | ||
4357 | if (fam0L_drive) if (j&s_attention) break; | ||
4358 | } | ||
4359 | if (try != 0 || time_after_eq(jiffies, timeout)) break; | ||
4360 | if (data_retrying == 0) data_waits++; | ||
4361 | data_retrying = 1; | ||
4362 | sbp_sleep(1); | ||
4363 | try = 1; | ||
4364 | } | ||
4365 | if (try==0) | ||
4366 | { | ||
4367 | msg(DBG_INF,"read_audio: sbp_data: CDi_status timeout.\n"); | ||
4368 | error_flag++; | ||
4369 | break; | ||
4370 | } | ||
4371 | msg(DBG_AUD,"read_audio: sbp_data: CDi_status ok.\n"); | ||
4372 | if (j&s_not_data_ready) | ||
4373 | { | ||
4374 | msg(DBG_INF, "read_audio: sbp_data: DATA_READY timeout.\n"); | ||
4375 | error_flag++; | ||
4376 | break; | ||
4377 | } | ||
4378 | msg(DBG_AUD,"read_audio: before reading data.\n"); | ||
4379 | error_flag=0; | ||
4380 | p = current_drive->aud_buf; | ||
4381 | if (sbpro_type==1) OUT(CDo_sel_i_d,1); | ||
4382 | if (do_16bit) | ||
4383 | { | ||
4384 | u_short *p2 = (u_short *) p; | ||
4385 | |||
4386 | for (; (u_char *) p2 < current_drive->aud_buf + read_audio.nframes*CD_FRAMESIZE_RAW;) | ||
4387 | { | ||
4388 | if ((inb_p(CDi_status)&s_not_data_ready)) continue; | ||
4389 | |||
4390 | /* get one sample */ | ||
4391 | *p2++ = inw_p(CDi_data); | ||
4392 | *p2++ = inw_p(CDi_data); | ||
4393 | } | ||
4394 | } else { | ||
4395 | for (; p < current_drive->aud_buf + read_audio.nframes*CD_FRAMESIZE_RAW;) | ||
4396 | { | ||
4397 | if ((inb_p(CDi_status)&s_not_data_ready)) continue; | ||
4398 | |||
4399 | /* get one sample */ | ||
4400 | *p++ = inb_p(CDi_data); | ||
4401 | *p++ = inb_p(CDi_data); | ||
4402 | *p++ = inb_p(CDi_data); | ||
4403 | *p++ = inb_p(CDi_data); | ||
4404 | } | ||
4405 | } | ||
4406 | if (sbpro_type==1) OUT(CDo_sel_i_d,0); | ||
4407 | data_retrying = 0; | ||
4408 | } | ||
4409 | msg(DBG_AUD,"read_audio: after reading data.\n"); | ||
4410 | if (error_flag) /* must have been spurious D_RDY or (ATTN&&!D_RDY) */ | ||
4411 | { | ||
4412 | msg(DBG_AUD,"read_audio: read aborted by drive\n"); | ||
4413 | #if 0000 | ||
4414 | i=cc_DriveReset(); /* ugly fix to prevent a hang */ | ||
4415 | #else | ||
4416 | i=cc_ReadError(); | ||
4417 | #endif | ||
4418 | continue; | ||
4419 | } | ||
4420 | if (fam0L_drive) | ||
4421 | { | ||
4422 | i=maxtim_data; | ||
4423 | for (timeout=jiffies+9*HZ; time_before(jiffies, timeout); timeout--) | ||
4424 | { | ||
4425 | for ( ;i!=0;i--) | ||
4426 | { | ||
4427 | j=inb(CDi_status); | ||
4428 | if (!(j&s_not_data_ready)) break; | ||
4429 | if (!(j&s_not_result_ready)) break; | ||
4430 | if (j&s_attention) break; | ||
4431 | } | ||
4432 | if (i != 0 || time_after_eq(jiffies, timeout)) break; | ||
4433 | sbp_sleep(0); | ||
4434 | i = 1; | ||
4435 | } | ||
4436 | if (i==0) msg(DBG_AUD,"read_audio: STATUS TIMEOUT AFTER READ"); | ||
4437 | if (!(j&s_attention)) | ||
4438 | { | ||
4439 | msg(DBG_AUD,"read_audio: sbp_data: timeout waiting DRV_ATTN - retrying\n"); | ||
4440 | i=cc_DriveReset(); /* ugly fix to prevent a hang */ | ||
4441 | continue; | ||
4442 | } | ||
4443 | } | ||
4444 | do | ||
4445 | { | ||
4446 | if (fam0L_drive) cc_ReadStatus(); | ||
4447 | i=ResponseStatus(); /* builds status_bits, returns orig. status (old) or faked p_success (new) */ | ||
4448 | if (i<0) { msg(DBG_AUD, | ||
4449 | "read_audio: cc_ReadStatus error after read: %02X\n", | ||
4450 | current_drive->status_bits); | ||
4451 | continue; /* FIXME */ | ||
4452 | } | ||
4453 | } | ||
4454 | while ((fam0L_drive)&&(!st_check)&&(!(i&p_success))); | ||
4455 | if (st_check) | ||
4456 | { | ||
4457 | i=cc_ReadError(); | ||
4458 | msg(DBG_AUD,"read_audio: cc_ReadError was necessary after read: %02X\n",i); | ||
4459 | continue; | ||
4460 | } | ||
4461 | if (copy_to_user(read_audio.buf, | ||
4462 | current_drive->aud_buf, | ||
4463 | read_audio.nframes * CD_FRAMESIZE_RAW)) | ||
4464 | RETURN_UP(-EFAULT); | ||
4465 | msg(DBG_AUD,"read_audio: copy_to_user done.\n"); | ||
4466 | break; | ||
4467 | } | ||
4468 | cc_ModeSelect(CD_FRAMESIZE); | ||
4469 | cc_ModeSense(); | ||
4470 | current_drive->mode=READ_M1; | ||
4471 | #if OLD_BUSY | ||
4472 | busy_audio=0; | ||
4473 | #endif /* OLD_BUSY */ | ||
4474 | if (data_tries == 0) | ||
4475 | { | ||
4476 | msg(DBG_AUD,"read_audio: failed after 5 tries in line %d.\n", __LINE__); | ||
4477 | RETURN_UP(-EIO); | ||
4478 | } | ||
4479 | msg(DBG_AUD,"read_audio: successful return.\n"); | ||
4480 | RETURN_UP(0); | ||
4481 | } /* end of CDROMREADAUDIO */ | ||
4482 | |||
4483 | default: | ||
4484 | msg(DBG_IOC,"ioctl: unknown function request %04X\n", cmd); | ||
4485 | RETURN_UP(-EINVAL); | ||
4486 | } /* end switch(cmd) */ | ||
4487 | } | ||
4488 | |||
4489 | static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd, | 4163 | static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd, |
4490 | void * arg) | 4164 | void * arg) |
4491 | { | 4165 | { |
@@ -4530,7 +4204,7 @@ static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd, | |||
4530 | default: | 4204 | default: |
4531 | RETURN_UP(-EINVAL); | 4205 | RETURN_UP(-EINVAL); |
4532 | } | 4206 | } |
4533 | 4207 | ||
4534 | case CDROMRESUME: /* resume paused audio play */ | 4208 | case CDROMRESUME: /* resume paused audio play */ |
4535 | msg(DBG_IOC,"ioctl: CDROMRESUME entered.\n"); | 4209 | msg(DBG_IOC,"ioctl: CDROMRESUME entered.\n"); |
4536 | /* resume playing audio tracks when a previous PLAY AUDIO call has */ | 4210 | /* resume playing audio tracks when a previous PLAY AUDIO call has */ |
@@ -4544,12 +4218,12 @@ static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd, | |||
4544 | if (i<0) RETURN_UP(-EIO); | 4218 | if (i<0) RETURN_UP(-EIO); |
4545 | current_drive->audio_state=audio_playing; | 4219 | current_drive->audio_state=audio_playing; |
4546 | RETURN_UP(0); | 4220 | RETURN_UP(0); |
4547 | 4221 | ||
4548 | case CDROMPLAYMSF: | 4222 | case CDROMPLAYMSF: |
4549 | msg(DBG_IOC,"ioctl: CDROMPLAYMSF entered.\n"); | 4223 | msg(DBG_IOC,"ioctl: CDROMPLAYMSF entered.\n"); |
4550 | #ifdef SAFE_MIXED | 4224 | #ifdef SAFE_MIXED |
4551 | if (current_drive->has_data>1) RETURN_UP(-EBUSY); | 4225 | if (current_drive->has_data>1) RETURN_UP(-EBUSY); |
4552 | #endif /* SAFE_MIXED */ | 4226 | #endif /* SAFE_MIXED */ |
4553 | if (current_drive->audio_state==audio_playing) | 4227 | if (current_drive->audio_state==audio_playing) |
4554 | { | 4228 | { |
4555 | i=cc_Pause_Resume(1); | 4229 | i=cc_Pause_Resume(1); |
@@ -4584,7 +4258,7 @@ static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd, | |||
4584 | msg(DBG_IOC,"ioctl: CDROMPLAYTRKIND entered.\n"); | 4258 | msg(DBG_IOC,"ioctl: CDROMPLAYTRKIND entered.\n"); |
4585 | #ifdef SAFE_MIXED | 4259 | #ifdef SAFE_MIXED |
4586 | if (current_drive->has_data>1) RETURN_UP(-EBUSY); | 4260 | if (current_drive->has_data>1) RETURN_UP(-EBUSY); |
4587 | #endif /* SAFE_MIXED */ | 4261 | #endif /* SAFE_MIXED */ |
4588 | if (current_drive->audio_state==audio_playing) | 4262 | if (current_drive->audio_state==audio_playing) |
4589 | { | 4263 | { |
4590 | msg(DBG_IOX,"CDROMPLAYTRKIND: already audio_playing.\n"); | 4264 | msg(DBG_IOX,"CDROMPLAYTRKIND: already audio_playing.\n"); |
@@ -4654,13 +4328,13 @@ static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd, | |||
4654 | cc_DriveReset(); | 4328 | cc_DriveReset(); |
4655 | #endif | 4329 | #endif |
4656 | RETURN_UP(i); | 4330 | RETURN_UP(i); |
4657 | 4331 | ||
4658 | case CDROMSTART: /* Spin up the drive */ | 4332 | case CDROMSTART: /* Spin up the drive */ |
4659 | msg(DBG_IOC,"ioctl: CDROMSTART entered.\n"); | 4333 | msg(DBG_IOC,"ioctl: CDROMSTART entered.\n"); |
4660 | cc_SpinUp(); | 4334 | cc_SpinUp(); |
4661 | current_drive->audio_state=0; | 4335 | current_drive->audio_state=0; |
4662 | RETURN_UP(0); | 4336 | RETURN_UP(0); |
4663 | 4337 | ||
4664 | case CDROMVOLCTRL: /* Volume control */ | 4338 | case CDROMVOLCTRL: /* Volume control */ |
4665 | msg(DBG_IOC,"ioctl: CDROMVOLCTRL entered.\n"); | 4339 | msg(DBG_IOC,"ioctl: CDROMVOLCTRL entered.\n"); |
4666 | memcpy(&volctrl,(char *) arg,sizeof(volctrl)); | 4340 | memcpy(&volctrl,(char *) arg,sizeof(volctrl)); |
@@ -4670,7 +4344,7 @@ static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd, | |||
4670 | current_drive->vol_ctrl1=volctrl.channel1; | 4344 | current_drive->vol_ctrl1=volctrl.channel1; |
4671 | i=cc_SetVolume(); | 4345 | i=cc_SetVolume(); |
4672 | RETURN_UP(0); | 4346 | RETURN_UP(0); |
4673 | 4347 | ||
4674 | case CDROMVOLREAD: /* read Volume settings from drive */ | 4348 | case CDROMVOLREAD: /* read Volume settings from drive */ |
4675 | msg(DBG_IOC,"ioctl: CDROMVOLREAD entered.\n"); | 4349 | msg(DBG_IOC,"ioctl: CDROMVOLREAD entered.\n"); |
4676 | st=cc_GetVolume(); | 4350 | st=cc_GetVolume(); |
@@ -4694,7 +4368,7 @@ static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd, | |||
4694 | if (i<0) { | 4368 | if (i<0) { |
4695 | j=cc_ReadError(); /* clear out error status from drive */ | 4369 | j=cc_ReadError(); /* clear out error status from drive */ |
4696 | current_drive->audio_state=CDROM_AUDIO_NO_STATUS; | 4370 | current_drive->audio_state=CDROM_AUDIO_NO_STATUS; |
4697 | /* get and set the disk state here, | 4371 | /* get and set the disk state here, |
4698 | probably not the right place, but who cares! | 4372 | probably not the right place, but who cares! |
4699 | It makes it work properly! --AJK */ | 4373 | It makes it work properly! --AJK */ |
4700 | if (current_drive->CD_changed==0xFF) { | 4374 | if (current_drive->CD_changed==0xFF) { |
@@ -4715,8 +4389,8 @@ static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd, | |||
4715 | } | 4389 | } |
4716 | } | 4390 | } |
4717 | memcpy(&SC, (void *) arg, sizeof(struct cdrom_subchnl)); | 4391 | memcpy(&SC, (void *) arg, sizeof(struct cdrom_subchnl)); |
4718 | /* | 4392 | /* |
4719 | This virtual crap is very bogus! | 4393 | This virtual crap is very bogus! |
4720 | It doesn't detect when the cd is done playing audio! | 4394 | It doesn't detect when the cd is done playing audio! |
4721 | Lets do this right with proper hardware register reading! | 4395 | Lets do this right with proper hardware register reading! |
4722 | */ | 4396 | */ |
@@ -4775,7 +4449,7 @@ static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd, | |||
4775 | SC.cdsc_trk,SC.cdsc_ind, | 4449 | SC.cdsc_trk,SC.cdsc_ind, |
4776 | SC.cdsc_absaddr,SC.cdsc_reladdr); | 4450 | SC.cdsc_absaddr,SC.cdsc_reladdr); |
4777 | RETURN_UP(0); | 4451 | RETURN_UP(0); |
4778 | 4452 | ||
4779 | default: | 4453 | default: |
4780 | msg(DBG_IOC,"ioctl: unknown function request %04X\n", cmd); | 4454 | msg(DBG_IOC,"ioctl: unknown function request %04X\n", cmd); |
4781 | RETURN_UP(-EINVAL); | 4455 | RETURN_UP(-EINVAL); |
@@ -4788,7 +4462,7 @@ static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd, | |||
4788 | static void sbp_transfer(struct request *req) | 4462 | static void sbp_transfer(struct request *req) |
4789 | { | 4463 | { |
4790 | long offs; | 4464 | long offs; |
4791 | 4465 | ||
4792 | while ( (req->nr_sectors > 0) && | 4466 | while ( (req->nr_sectors > 0) && |
4793 | (req->sector/4 >= current_drive->sbp_first_frame) && | 4467 | (req->sector/4 >= current_drive->sbp_first_frame) && |
4794 | (req->sector/4 <= current_drive->sbp_last_frame) ) | 4468 | (req->sector/4 <= current_drive->sbp_last_frame) ) |
@@ -4807,11 +4481,11 @@ static void sbp_transfer(struct request *req) | |||
4807 | * | 4481 | * |
4808 | * This is a kludge so we don't need to modify end_request. | 4482 | * This is a kludge so we don't need to modify end_request. |
4809 | * We put the req we take out after INIT_REQUEST in the requests list, | 4483 | * We put the req we take out after INIT_REQUEST in the requests list, |
4810 | * so that end_request will discard it. | 4484 | * so that end_request will discard it. |
4811 | * | 4485 | * |
4812 | * The bug could be present in other block devices, perhaps we | 4486 | * The bug could be present in other block devices, perhaps we |
4813 | * should modify INIT_REQUEST and end_request instead, and | 4487 | * should modify INIT_REQUEST and end_request instead, and |
4814 | * change every block device.. | 4488 | * change every block device.. |
4815 | * | 4489 | * |
4816 | * Could be a race here?? Could e.g. a timer interrupt schedule() us? | 4490 | * Could be a race here?? Could e.g. a timer interrupt schedule() us? |
4817 | * If so, we should copy end_request here, and do it right.. (or | 4491 | * If so, we should copy end_request here, and do it right.. (or |
@@ -4883,19 +4557,19 @@ static void do_sbpcd_request(request_queue_t * q) | |||
4883 | while (busy_audio) sbp_sleep(HZ); /* wait a bit */ | 4557 | while (busy_audio) sbp_sleep(HZ); /* wait a bit */ |
4884 | busy_data=1; | 4558 | busy_data=1; |
4885 | #endif /* OLD_BUSY */ | 4559 | #endif /* OLD_BUSY */ |
4886 | 4560 | ||
4887 | if (p->audio_state==audio_playing) goto err_done; | 4561 | if (p->audio_state==audio_playing) goto err_done; |
4888 | if (p != current_drive) | 4562 | if (p != current_drive) |
4889 | switch_drive(p); | 4563 | switch_drive(p); |
4890 | 4564 | ||
4891 | block = req->sector; /* always numbered as 512-byte-pieces */ | 4565 | block = req->sector; /* always numbered as 512-byte-pieces */ |
4892 | nsect = req->nr_sectors; /* always counted as 512-byte-pieces */ | 4566 | nsect = req->nr_sectors; /* always counted as 512-byte-pieces */ |
4893 | 4567 | ||
4894 | msg(DBG_BSZ,"read sector %d (%d sectors)\n", block, nsect); | 4568 | msg(DBG_BSZ,"read sector %d (%d sectors)\n", block, nsect); |
4895 | #if 0 | 4569 | #if 0 |
4896 | msg(DBG_MUL,"read LBA %d\n", block/4); | 4570 | msg(DBG_MUL,"read LBA %d\n", block/4); |
4897 | #endif | 4571 | #endif |
4898 | 4572 | ||
4899 | sbp_transfer(req); | 4573 | sbp_transfer(req); |
4900 | /* if we satisfied the request from the buffer, we're done. */ | 4574 | /* if we satisfied the request from the buffer, we're done. */ |
4901 | if (req->nr_sectors == 0) | 4575 | if (req->nr_sectors == 0) |
@@ -4914,10 +4588,10 @@ static void do_sbpcd_request(request_queue_t * q) | |||
4914 | i=prepare(0,0); /* at moment not really a hassle check, but ... */ | 4588 | i=prepare(0,0); /* at moment not really a hassle check, but ... */ |
4915 | if (i!=0) | 4589 | if (i!=0) |
4916 | msg(DBG_INF,"\"prepare\" tells error %d -- ignored\n", i); | 4590 | msg(DBG_INF,"\"prepare\" tells error %d -- ignored\n", i); |
4917 | #endif /* FUTURE */ | 4591 | #endif /* FUTURE */ |
4918 | 4592 | ||
4919 | if (!st_spinning) cc_SpinUp(); | 4593 | if (!st_spinning) cc_SpinUp(); |
4920 | 4594 | ||
4921 | for (data_tries=n_retries; data_tries > 0; data_tries--) | 4595 | for (data_tries=n_retries; data_tries > 0; data_tries--) |
4922 | { | 4596 | { |
4923 | for (status_tries=3; status_tries > 0; status_tries--) | 4597 | for (status_tries=3; status_tries > 0; status_tries--) |
@@ -4940,7 +4614,7 @@ static void do_sbpcd_request(request_queue_t * q) | |||
4940 | { | 4614 | { |
4941 | #ifdef SAFE_MIXED | 4615 | #ifdef SAFE_MIXED |
4942 | current_drive->has_data=2; /* is really a data disk */ | 4616 | current_drive->has_data=2; /* is really a data disk */ |
4943 | #endif /* SAFE_MIXED */ | 4617 | #endif /* SAFE_MIXED */ |
4944 | #ifdef DEBUG_GTL | 4618 | #ifdef DEBUG_GTL |
4945 | printk(" do_sbpcd_request[%do](%p:%ld+%ld) end 3, Time:%li\n", | 4619 | printk(" do_sbpcd_request[%do](%p:%ld+%ld) end 3, Time:%li\n", |
4946 | xnr, req, req->sector, req->nr_sectors, jiffies); | 4620 | xnr, req, req->sector, req->nr_sectors, jiffies); |
@@ -4951,7 +4625,7 @@ static void do_sbpcd_request(request_queue_t * q) | |||
4951 | goto request_loop; | 4625 | goto request_loop; |
4952 | } | 4626 | } |
4953 | } | 4627 | } |
4954 | 4628 | ||
4955 | err_done: | 4629 | err_done: |
4956 | #if OLD_BUSY | 4630 | #if OLD_BUSY |
4957 | busy_data=0; | 4631 | busy_data=0; |
@@ -4976,7 +4650,7 @@ static void sbp_read_cmd(struct request *req) | |||
4976 | 4650 | ||
4977 | int i; | 4651 | int i; |
4978 | int block; | 4652 | int block; |
4979 | 4653 | ||
4980 | current_drive->sbp_first_frame=current_drive->sbp_last_frame=-1; /* purge buffer */ | 4654 | current_drive->sbp_first_frame=current_drive->sbp_last_frame=-1; /* purge buffer */ |
4981 | current_drive->sbp_current = 0; | 4655 | current_drive->sbp_current = 0; |
4982 | block=req->sector/4; | 4656 | block=req->sector/4; |
@@ -4993,7 +4667,7 @@ static void sbp_read_cmd(struct request *req) | |||
4993 | current_drive->sbp_read_frames=1; | 4667 | current_drive->sbp_read_frames=1; |
4994 | } | 4668 | } |
4995 | } | 4669 | } |
4996 | 4670 | ||
4997 | flags_cmd_out = f_putcmd | f_respo2 | f_ResponseStatus | f_obey_p_check; | 4671 | flags_cmd_out = f_putcmd | f_respo2 | f_ResponseStatus | f_obey_p_check; |
4998 | clr_cmdbuf(); | 4672 | clr_cmdbuf(); |
4999 | if (famV_drive) | 4673 | if (famV_drive) |
@@ -5092,7 +4766,7 @@ static int sbp_data(struct request *req) | |||
5092 | int success; | 4766 | int success; |
5093 | int wait; | 4767 | int wait; |
5094 | int duration; | 4768 | int duration; |
5095 | 4769 | ||
5096 | error_flag=0; | 4770 | error_flag=0; |
5097 | success=0; | 4771 | success=0; |
5098 | #if LONG_TIMING | 4772 | #if LONG_TIMING |
@@ -5105,12 +4779,12 @@ static int sbp_data(struct request *req) | |||
5105 | for (frame=0;frame<current_drive->sbp_read_frames&&!error_flag; frame++) | 4779 | for (frame=0;frame<current_drive->sbp_read_frames&&!error_flag; frame++) |
5106 | { | 4780 | { |
5107 | SBPCD_CLI; | 4781 | SBPCD_CLI; |
5108 | 4782 | ||
5109 | del_timer(&data_timer); | 4783 | del_timer(&data_timer); |
5110 | data_timer.expires=jiffies+max_latency; | 4784 | data_timer.expires=jiffies+max_latency; |
5111 | timed_out_data=0; | 4785 | timed_out_data=0; |
5112 | add_timer(&data_timer); | 4786 | add_timer(&data_timer); |
5113 | while (!timed_out_data) | 4787 | while (!timed_out_data) |
5114 | { | 4788 | { |
5115 | if (current_drive->f_multisession) try=maxtim_data*4; | 4789 | if (current_drive->f_multisession) try=maxtim_data*4; |
5116 | else try=maxtim_data; | 4790 | else try=maxtim_data; |
@@ -5207,9 +4881,9 @@ static int sbp_data(struct request *req) | |||
5207 | else | 4881 | else |
5208 | { | 4882 | { |
5209 | sbp_sleep(1); | 4883 | sbp_sleep(1); |
5210 | OUT(CDo_sel_i_d,0); | 4884 | OUT(CDo_sel_i_d,0); |
5211 | i=inb(CDi_status); | 4885 | i=inb(CDi_status); |
5212 | } | 4886 | } |
5213 | if (!(i&s_not_data_ready)) | 4887 | if (!(i&s_not_data_ready)) |
5214 | { | 4888 | { |
5215 | OUT(CDo_sel_i_d,1); | 4889 | OUT(CDo_sel_i_d,1); |
@@ -5311,7 +4985,7 @@ static int sbp_data(struct request *req) | |||
5311 | } | 4985 | } |
5312 | SBPCD_STI; | 4986 | SBPCD_STI; |
5313 | } | 4987 | } |
5314 | 4988 | ||
5315 | #if 0 | 4989 | #if 0 |
5316 | if (!success) | 4990 | if (!success) |
5317 | #endif | 4991 | #endif |
@@ -5370,7 +5044,326 @@ static int sbpcd_block_ioctl(struct inode *inode, struct file *file, | |||
5370 | unsigned cmd, unsigned long arg) | 5044 | unsigned cmd, unsigned long arg) |
5371 | { | 5045 | { |
5372 | struct sbpcd_drive *p = inode->i_bdev->bd_disk->private_data; | 5046 | struct sbpcd_drive *p = inode->i_bdev->bd_disk->private_data; |
5373 | return cdrom_ioctl(file, p->sbpcd_infop, inode, cmd, arg); | 5047 | struct cdrom_device_info *cdi = p->sbpcd_infop; |
5048 | int ret, i; | ||
5049 | |||
5050 | ret = cdrom_ioctl(file, p->sbpcd_infop, inode, cmd, arg); | ||
5051 | if (ret != -ENOSYS) | ||
5052 | return ret; | ||
5053 | |||
5054 | msg(DBG_IO2,"ioctl(%s, 0x%08lX, 0x%08lX)\n", cdi->name, cmd, arg); | ||
5055 | if (p->drv_id==-1) { | ||
5056 | msg(DBG_INF, "ioctl: bad device: %s\n", cdi->name); | ||
5057 | return (-ENXIO); /* no such drive */ | ||
5058 | } | ||
5059 | down(&ioctl_read_sem); | ||
5060 | if (p != current_drive) | ||
5061 | switch_drive(p); | ||
5062 | |||
5063 | msg(DBG_IO2,"ioctl: device %s, request %04X\n",cdi->name,cmd); | ||
5064 | switch (cmd) /* Sun-compatible */ | ||
5065 | { | ||
5066 | case DDIOCSDBG: /* DDI Debug */ | ||
5067 | if (!capable(CAP_SYS_ADMIN)) RETURN_UP(-EPERM); | ||
5068 | i=sbpcd_dbg_ioctl(arg,1); | ||
5069 | RETURN_UP(i); | ||
5070 | case CDROMRESET: /* hard reset the drive */ | ||
5071 | msg(DBG_IOC,"ioctl: CDROMRESET entered.\n"); | ||
5072 | i=DriveReset(); | ||
5073 | current_drive->audio_state=0; | ||
5074 | RETURN_UP(i); | ||
5075 | |||
5076 | case CDROMREADMODE1: | ||
5077 | msg(DBG_IOC,"ioctl: CDROMREADMODE1 requested.\n"); | ||
5078 | #ifdef SAFE_MIXED | ||
5079 | if (current_drive->has_data>1) RETURN_UP(-EBUSY); | ||
5080 | #endif /* SAFE_MIXED */ | ||
5081 | cc_ModeSelect(CD_FRAMESIZE); | ||
5082 | cc_ModeSense(); | ||
5083 | current_drive->mode=READ_M1; | ||
5084 | RETURN_UP(0); | ||
5085 | |||
5086 | case CDROMREADMODE2: /* not usable at the moment */ | ||
5087 | msg(DBG_IOC,"ioctl: CDROMREADMODE2 requested.\n"); | ||
5088 | #ifdef SAFE_MIXED | ||
5089 | if (current_drive->has_data>1) RETURN_UP(-EBUSY); | ||
5090 | #endif /* SAFE_MIXED */ | ||
5091 | cc_ModeSelect(CD_FRAMESIZE_RAW1); | ||
5092 | cc_ModeSense(); | ||
5093 | current_drive->mode=READ_M2; | ||
5094 | RETURN_UP(0); | ||
5095 | |||
5096 | case CDROMAUDIOBUFSIZ: /* configure the audio buffer size */ | ||
5097 | msg(DBG_IOC,"ioctl: CDROMAUDIOBUFSIZ entered.\n"); | ||
5098 | if (current_drive->sbp_audsiz>0) | ||
5099 | vfree(current_drive->aud_buf); | ||
5100 | current_drive->aud_buf=NULL; | ||
5101 | current_drive->sbp_audsiz=arg; | ||
5102 | |||
5103 | if (current_drive->sbp_audsiz>16) | ||
5104 | { | ||
5105 | current_drive->sbp_audsiz = 0; | ||
5106 | RETURN_UP(current_drive->sbp_audsiz); | ||
5107 | } | ||
5108 | |||
5109 | if (current_drive->sbp_audsiz>0) | ||
5110 | { | ||
5111 | current_drive->aud_buf=(u_char *) vmalloc(current_drive->sbp_audsiz*CD_FRAMESIZE_RAW); | ||
5112 | if (current_drive->aud_buf==NULL) | ||
5113 | { | ||
5114 | msg(DBG_INF,"audio buffer (%d frames) not available.\n",current_drive->sbp_audsiz); | ||
5115 | current_drive->sbp_audsiz=0; | ||
5116 | } | ||
5117 | else msg(DBG_INF,"audio buffer size: %d frames.\n",current_drive->sbp_audsiz); | ||
5118 | } | ||
5119 | RETURN_UP(current_drive->sbp_audsiz); | ||
5120 | |||
5121 | case CDROMREADAUDIO: | ||
5122 | { /* start of CDROMREADAUDIO */ | ||
5123 | int i=0, j=0, frame, block=0; | ||
5124 | u_int try=0; | ||
5125 | u_long timeout; | ||
5126 | u_char *p; | ||
5127 | u_int data_tries = 0; | ||
5128 | u_int data_waits = 0; | ||
5129 | u_int data_retrying = 0; | ||
5130 | int status_tries; | ||
5131 | int error_flag; | ||
5132 | |||
5133 | msg(DBG_IOC,"ioctl: CDROMREADAUDIO entered.\n"); | ||
5134 | if (fam0_drive) RETURN_UP(-EINVAL); | ||
5135 | if (famL_drive) RETURN_UP(-EINVAL); | ||
5136 | if (famV_drive) RETURN_UP(-EINVAL); | ||
5137 | if (famT_drive) RETURN_UP(-EINVAL); | ||
5138 | #ifdef SAFE_MIXED | ||
5139 | if (current_drive->has_data>1) RETURN_UP(-EBUSY); | ||
5140 | #endif /* SAFE_MIXED */ | ||
5141 | if (current_drive->aud_buf==NULL) RETURN_UP(-EINVAL); | ||
5142 | if (copy_from_user(&read_audio, (void __user *)arg, | ||
5143 | sizeof(struct cdrom_read_audio))) | ||
5144 | RETURN_UP(-EFAULT); | ||
5145 | if (read_audio.nframes < 0 || read_audio.nframes>current_drive->sbp_audsiz) RETURN_UP(-EINVAL); | ||
5146 | if (!access_ok(VERIFY_WRITE, read_audio.buf, | ||
5147 | read_audio.nframes*CD_FRAMESIZE_RAW)) | ||
5148 | RETURN_UP(-EFAULT); | ||
5149 | |||
5150 | if (read_audio.addr_format==CDROM_MSF) /* MSF-bin specification of where to start */ | ||
5151 | block=msf2lba(&read_audio.addr.msf.minute); | ||
5152 | else if (read_audio.addr_format==CDROM_LBA) /* lba specification of where to start */ | ||
5153 | block=read_audio.addr.lba; | ||
5154 | else RETURN_UP(-EINVAL); | ||
5155 | #if 000 | ||
5156 | i=cc_SetSpeed(speed_150,0,0); | ||
5157 | if (i) msg(DBG_AUD,"read_audio: SetSpeed error %d\n", i); | ||
5158 | #endif | ||
5159 | msg(DBG_AUD,"read_audio: lba: %d, msf: %06X\n", | ||
5160 | block, blk2msf(block)); | ||
5161 | msg(DBG_AUD,"read_audio: before cc_ReadStatus.\n"); | ||
5162 | #if OLD_BUSY | ||
5163 | while (busy_data) sbp_sleep(HZ/10); /* wait a bit */ | ||
5164 | busy_audio=1; | ||
5165 | #endif /* OLD_BUSY */ | ||
5166 | error_flag=0; | ||
5167 | for (data_tries=5; data_tries>0; data_tries--) | ||
5168 | { | ||
5169 | msg(DBG_AUD,"data_tries=%d ...\n", data_tries); | ||
5170 | current_drive->mode=READ_AU; | ||
5171 | cc_ModeSelect(CD_FRAMESIZE_RAW); | ||
5172 | cc_ModeSense(); | ||
5173 | for (status_tries=3; status_tries > 0; status_tries--) | ||
5174 | { | ||
5175 | flags_cmd_out |= f_respo3; | ||
5176 | cc_ReadStatus(); | ||
5177 | if (sbp_status() != 0) break; | ||
5178 | if (st_check) cc_ReadError(); | ||
5179 | sbp_sleep(1); /* wait a bit, try again */ | ||
5180 | } | ||
5181 | if (status_tries == 0) | ||
5182 | { | ||
5183 | msg(DBG_AUD,"read_audio: sbp_status: failed after 3 tries in line %d.\n", __LINE__); | ||
5184 | continue; | ||
5185 | } | ||
5186 | msg(DBG_AUD,"read_audio: sbp_status: ok.\n"); | ||
5187 | |||
5188 | flags_cmd_out = f_putcmd | f_respo2 | f_ResponseStatus | f_obey_p_check; | ||
5189 | if (fam0L_drive) | ||
5190 | { | ||
5191 | flags_cmd_out |= f_lopsta | f_getsta | f_bit1; | ||
5192 | cmd_type=READ_M2; | ||
5193 | drvcmd[0]=CMD0_READ_XA; /* "read XA frames", old drives */ | ||
5194 | drvcmd[1]=(block>>16)&0x000000ff; | ||
5195 | drvcmd[2]=(block>>8)&0x000000ff; | ||
5196 | drvcmd[3]=block&0x000000ff; | ||
5197 | drvcmd[4]=0; | ||
5198 | drvcmd[5]=read_audio.nframes; /* # of frames */ | ||
5199 | drvcmd[6]=0; | ||
5200 | } | ||
5201 | else if (fam1_drive) | ||
5202 | { | ||
5203 | drvcmd[0]=CMD1_READ; /* "read frames", new drives */ | ||
5204 | lba2msf(block,&drvcmd[1]); /* msf-bin format required */ | ||
5205 | drvcmd[4]=0; | ||
5206 | drvcmd[5]=0; | ||
5207 | drvcmd[6]=read_audio.nframes; /* # of frames */ | ||
5208 | } | ||
5209 | else if (fam2_drive) | ||
5210 | { | ||
5211 | drvcmd[0]=CMD2_READ_XA2; | ||
5212 | lba2msf(block,&drvcmd[1]); /* msf-bin format required */ | ||
5213 | drvcmd[4]=0; | ||
5214 | drvcmd[5]=read_audio.nframes; /* # of frames */ | ||
5215 | drvcmd[6]=0x11; /* raw mode */ | ||
5216 | } | ||
5217 | else if (famT_drive) /* CD-55A: not tested yet */ | ||
5218 | { | ||
5219 | } | ||
5220 | msg(DBG_AUD,"read_audio: before giving \"read\" command.\n"); | ||
5221 | flags_cmd_out=f_putcmd; | ||
5222 | response_count=0; | ||
5223 | i=cmd_out(); | ||
5224 | if (i<0) msg(DBG_INF,"error giving READ AUDIO command: %0d\n", i); | ||
5225 | sbp_sleep(0); | ||
5226 | msg(DBG_AUD,"read_audio: after giving \"read\" command.\n"); | ||
5227 | for (frame=1;frame<2 && !error_flag; frame++) | ||
5228 | { | ||
5229 | try=maxtim_data; | ||
5230 | for (timeout=jiffies+9*HZ; ; ) | ||
5231 | { | ||
5232 | for ( ; try!=0;try--) | ||
5233 | { | ||
5234 | j=inb(CDi_status); | ||
5235 | if (!(j&s_not_data_ready)) break; | ||
5236 | if (!(j&s_not_result_ready)) break; | ||
5237 | if (fam0L_drive) if (j&s_attention) break; | ||
5238 | } | ||
5239 | if (try != 0 || time_after_eq(jiffies, timeout)) break; | ||
5240 | if (data_retrying == 0) data_waits++; | ||
5241 | data_retrying = 1; | ||
5242 | sbp_sleep(1); | ||
5243 | try = 1; | ||
5244 | } | ||
5245 | if (try==0) | ||
5246 | { | ||
5247 | msg(DBG_INF,"read_audio: sbp_data: CDi_status timeout.\n"); | ||
5248 | error_flag++; | ||
5249 | break; | ||
5250 | } | ||
5251 | msg(DBG_AUD,"read_audio: sbp_data: CDi_status ok.\n"); | ||
5252 | if (j&s_not_data_ready) | ||
5253 | { | ||
5254 | msg(DBG_INF, "read_audio: sbp_data: DATA_READY timeout.\n"); | ||
5255 | error_flag++; | ||
5256 | break; | ||
5257 | } | ||
5258 | msg(DBG_AUD,"read_audio: before reading data.\n"); | ||
5259 | error_flag=0; | ||
5260 | p = current_drive->aud_buf; | ||
5261 | if (sbpro_type==1) OUT(CDo_sel_i_d,1); | ||
5262 | if (do_16bit) | ||
5263 | { | ||
5264 | u_short *p2 = (u_short *) p; | ||
5265 | |||
5266 | for (; (u_char *) p2 < current_drive->aud_buf + read_audio.nframes*CD_FRAMESIZE_RAW;) | ||
5267 | { | ||
5268 | if ((inb_p(CDi_status)&s_not_data_ready)) continue; | ||
5269 | |||
5270 | /* get one sample */ | ||
5271 | *p2++ = inw_p(CDi_data); | ||
5272 | *p2++ = inw_p(CDi_data); | ||
5273 | } | ||
5274 | } else { | ||
5275 | for (; p < current_drive->aud_buf + read_audio.nframes*CD_FRAMESIZE_RAW;) | ||
5276 | { | ||
5277 | if ((inb_p(CDi_status)&s_not_data_ready)) continue; | ||
5278 | |||
5279 | /* get one sample */ | ||
5280 | *p++ = inb_p(CDi_data); | ||
5281 | *p++ = inb_p(CDi_data); | ||
5282 | *p++ = inb_p(CDi_data); | ||
5283 | *p++ = inb_p(CDi_data); | ||
5284 | } | ||
5285 | } | ||
5286 | if (sbpro_type==1) OUT(CDo_sel_i_d,0); | ||
5287 | data_retrying = 0; | ||
5288 | } | ||
5289 | msg(DBG_AUD,"read_audio: after reading data.\n"); | ||
5290 | if (error_flag) /* must have been spurious D_RDY or (ATTN&&!D_RDY) */ | ||
5291 | { | ||
5292 | msg(DBG_AUD,"read_audio: read aborted by drive\n"); | ||
5293 | #if 0000 | ||
5294 | i=cc_DriveReset(); /* ugly fix to prevent a hang */ | ||
5295 | #else | ||
5296 | i=cc_ReadError(); | ||
5297 | #endif | ||
5298 | continue; | ||
5299 | } | ||
5300 | if (fam0L_drive) | ||
5301 | { | ||
5302 | i=maxtim_data; | ||
5303 | for (timeout=jiffies+9*HZ; time_before(jiffies, timeout); timeout--) | ||
5304 | { | ||
5305 | for ( ;i!=0;i--) | ||
5306 | { | ||
5307 | j=inb(CDi_status); | ||
5308 | if (!(j&s_not_data_ready)) break; | ||
5309 | if (!(j&s_not_result_ready)) break; | ||
5310 | if (j&s_attention) break; | ||
5311 | } | ||
5312 | if (i != 0 || time_after_eq(jiffies, timeout)) break; | ||
5313 | sbp_sleep(0); | ||
5314 | i = 1; | ||
5315 | } | ||
5316 | if (i==0) msg(DBG_AUD,"read_audio: STATUS TIMEOUT AFTER READ"); | ||
5317 | if (!(j&s_attention)) | ||
5318 | { | ||
5319 | msg(DBG_AUD,"read_audio: sbp_data: timeout waiting DRV_ATTN - retrying\n"); | ||
5320 | i=cc_DriveReset(); /* ugly fix to prevent a hang */ | ||
5321 | continue; | ||
5322 | } | ||
5323 | } | ||
5324 | do | ||
5325 | { | ||
5326 | if (fam0L_drive) cc_ReadStatus(); | ||
5327 | i=ResponseStatus(); /* builds status_bits, returns orig. status (old) or faked p_success (new) */ | ||
5328 | if (i<0) { msg(DBG_AUD, | ||
5329 | "read_audio: cc_ReadStatus error after read: %02X\n", | ||
5330 | current_drive->status_bits); | ||
5331 | continue; /* FIXME */ | ||
5332 | } | ||
5333 | } | ||
5334 | while ((fam0L_drive)&&(!st_check)&&(!(i&p_success))); | ||
5335 | if (st_check) | ||
5336 | { | ||
5337 | i=cc_ReadError(); | ||
5338 | msg(DBG_AUD,"read_audio: cc_ReadError was necessary after read: %02X\n",i); | ||
5339 | continue; | ||
5340 | } | ||
5341 | if (copy_to_user(read_audio.buf, | ||
5342 | current_drive->aud_buf, | ||
5343 | read_audio.nframes * CD_FRAMESIZE_RAW)) | ||
5344 | RETURN_UP(-EFAULT); | ||
5345 | msg(DBG_AUD,"read_audio: copy_to_user done.\n"); | ||
5346 | break; | ||
5347 | } | ||
5348 | cc_ModeSelect(CD_FRAMESIZE); | ||
5349 | cc_ModeSense(); | ||
5350 | current_drive->mode=READ_M1; | ||
5351 | #if OLD_BUSY | ||
5352 | busy_audio=0; | ||
5353 | #endif /* OLD_BUSY */ | ||
5354 | if (data_tries == 0) | ||
5355 | { | ||
5356 | msg(DBG_AUD,"read_audio: failed after 5 tries in line %d.\n", __LINE__); | ||
5357 | RETURN_UP(-EIO); | ||
5358 | } | ||
5359 | msg(DBG_AUD,"read_audio: successful return.\n"); | ||
5360 | RETURN_UP(0); | ||
5361 | } /* end of CDROMREADAUDIO */ | ||
5362 | |||
5363 | default: | ||
5364 | msg(DBG_IOC,"ioctl: unknown function request %04X\n", cmd); | ||
5365 | RETURN_UP(-EINVAL); | ||
5366 | } /* end switch(cmd) */ | ||
5374 | } | 5367 | } |
5375 | 5368 | ||
5376 | static int sbpcd_block_media_changed(struct gendisk *disk) | 5369 | static int sbpcd_block_media_changed(struct gendisk *disk) |
@@ -5478,10 +5471,9 @@ static struct cdrom_device_ops sbpcd_dops = { | |||
5478 | .get_mcn = sbpcd_get_mcn, | 5471 | .get_mcn = sbpcd_get_mcn, |
5479 | .reset = sbpcd_reset, | 5472 | .reset = sbpcd_reset, |
5480 | .audio_ioctl = sbpcd_audio_ioctl, | 5473 | .audio_ioctl = sbpcd_audio_ioctl, |
5481 | .dev_ioctl = sbpcd_dev_ioctl, | ||
5482 | .capability = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK | | 5474 | .capability = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK | |
5483 | CDC_MULTI_SESSION | CDC_MEDIA_CHANGED | | 5475 | CDC_MULTI_SESSION | CDC_MEDIA_CHANGED | |
5484 | CDC_MCN | CDC_PLAY_AUDIO | CDC_IOCTLS, | 5476 | CDC_MCN | CDC_PLAY_AUDIO, |
5485 | .n_minors = 1, | 5477 | .n_minors = 1, |
5486 | }; | 5478 | }; |
5487 | 5479 | ||
diff --git a/drivers/cdrom/viocd.c b/drivers/cdrom/viocd.c index e27617259552..c0f817ba7adb 100644 --- a/drivers/cdrom/viocd.c +++ b/drivers/cdrom/viocd.c | |||
@@ -627,7 +627,7 @@ static struct cdrom_device_ops viocd_dops = { | |||
627 | .media_changed = viocd_media_changed, | 627 | .media_changed = viocd_media_changed, |
628 | .lock_door = viocd_lock_door, | 628 | .lock_door = viocd_lock_door, |
629 | .generic_packet = viocd_packet, | 629 | .generic_packet = viocd_packet, |
630 | .capability = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK | CDC_SELECT_SPEED | CDC_SELECT_DISC | CDC_MULTI_SESSION | CDC_MCN | CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO | CDC_RESET | CDC_IOCTLS | CDC_DRIVE_STATUS | CDC_GENERIC_PACKET | CDC_CD_R | CDC_CD_RW | CDC_DVD | CDC_DVD_R | CDC_DVD_RAM | CDC_RAM | 630 | .capability = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK | CDC_SELECT_SPEED | CDC_SELECT_DISC | CDC_MULTI_SESSION | CDC_MCN | CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO | CDC_RESET | CDC_DRIVE_STATUS | CDC_GENERIC_PACKET | CDC_CD_R | CDC_CD_RW | CDC_DVD | CDC_DVD_R | CDC_DVD_RAM | CDC_RAM |
631 | }; | 631 | }; |
632 | 632 | ||
633 | static int __init find_capability(const char *type) | 633 | static int __init find_capability(const char *type) |
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 3325660f7248..430d8af35cb1 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
@@ -2471,52 +2471,6 @@ static int ide_cdrom_packet(struct cdrom_device_info *cdi, | |||
2471 | } | 2471 | } |
2472 | 2472 | ||
2473 | static | 2473 | static |
2474 | int ide_cdrom_dev_ioctl (struct cdrom_device_info *cdi, | ||
2475 | unsigned int cmd, unsigned long arg) | ||
2476 | { | ||
2477 | struct packet_command cgc; | ||
2478 | char buffer[16]; | ||
2479 | int stat; | ||
2480 | |||
2481 | init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_UNKNOWN); | ||
2482 | |||
2483 | /* These will be moved into the Uniform layer shortly... */ | ||
2484 | switch (cmd) { | ||
2485 | case CDROMSETSPINDOWN: { | ||
2486 | char spindown; | ||
2487 | |||
2488 | if (copy_from_user(&spindown, (void __user *) arg, sizeof(char))) | ||
2489 | return -EFAULT; | ||
2490 | |||
2491 | if ((stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CDROM_PAGE, 0))) | ||
2492 | return stat; | ||
2493 | |||
2494 | buffer[11] = (buffer[11] & 0xf0) | (spindown & 0x0f); | ||
2495 | |||
2496 | return cdrom_mode_select(cdi, &cgc); | ||
2497 | } | ||
2498 | |||
2499 | case CDROMGETSPINDOWN: { | ||
2500 | char spindown; | ||
2501 | |||
2502 | if ((stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CDROM_PAGE, 0))) | ||
2503 | return stat; | ||
2504 | |||
2505 | spindown = buffer[11] & 0x0f; | ||
2506 | |||
2507 | if (copy_to_user((void __user *) arg, &spindown, sizeof (char))) | ||
2508 | return -EFAULT; | ||
2509 | |||
2510 | return 0; | ||
2511 | } | ||
2512 | |||
2513 | default: | ||
2514 | return -EINVAL; | ||
2515 | } | ||
2516 | |||
2517 | } | ||
2518 | |||
2519 | static | ||
2520 | int ide_cdrom_audio_ioctl (struct cdrom_device_info *cdi, | 2474 | int ide_cdrom_audio_ioctl (struct cdrom_device_info *cdi, |
2521 | unsigned int cmd, void *arg) | 2475 | unsigned int cmd, void *arg) |
2522 | 2476 | ||
@@ -2852,12 +2806,11 @@ static struct cdrom_device_ops ide_cdrom_dops = { | |||
2852 | .get_mcn = ide_cdrom_get_mcn, | 2806 | .get_mcn = ide_cdrom_get_mcn, |
2853 | .reset = ide_cdrom_reset, | 2807 | .reset = ide_cdrom_reset, |
2854 | .audio_ioctl = ide_cdrom_audio_ioctl, | 2808 | .audio_ioctl = ide_cdrom_audio_ioctl, |
2855 | .dev_ioctl = ide_cdrom_dev_ioctl, | ||
2856 | .capability = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK | | 2809 | .capability = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK | |
2857 | CDC_SELECT_SPEED | CDC_SELECT_DISC | | 2810 | CDC_SELECT_SPEED | CDC_SELECT_DISC | |
2858 | CDC_MULTI_SESSION | CDC_MCN | | 2811 | CDC_MULTI_SESSION | CDC_MCN | |
2859 | CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO | CDC_RESET | | 2812 | CDC_MEDIA_CHANGED | CDC_PLAY_AUDIO | CDC_RESET | |
2860 | CDC_IOCTLS | CDC_DRIVE_STATUS | CDC_CD_R | | 2813 | CDC_DRIVE_STATUS | CDC_CD_R | |
2861 | CDC_CD_RW | CDC_DVD | CDC_DVD_R| CDC_DVD_RAM | | 2814 | CDC_CD_RW | CDC_DVD | CDC_DVD_R| CDC_DVD_RAM | |
2862 | CDC_GENERIC_PACKET | CDC_MO_DRIVE | CDC_MRW | | 2815 | CDC_GENERIC_PACKET | CDC_MO_DRIVE | CDC_MRW | |
2863 | CDC_MRW_W | CDC_RAM, | 2816 | CDC_MRW_W | CDC_RAM, |
@@ -3367,6 +3320,45 @@ static int idecd_release(struct inode * inode, struct file * file) | |||
3367 | return 0; | 3320 | return 0; |
3368 | } | 3321 | } |
3369 | 3322 | ||
3323 | static int idecd_set_spindown(struct cdrom_device_info *cdi, unsigned long arg) | ||
3324 | { | ||
3325 | struct packet_command cgc; | ||
3326 | char buffer[16]; | ||
3327 | int stat; | ||
3328 | char spindown; | ||
3329 | |||
3330 | if (copy_from_user(&spindown, (void __user *)arg, sizeof(char))) | ||
3331 | return -EFAULT; | ||
3332 | |||
3333 | init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_UNKNOWN); | ||
3334 | |||
3335 | stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CDROM_PAGE, 0); | ||
3336 | if (stat) | ||
3337 | return stat; | ||
3338 | |||
3339 | buffer[11] = (buffer[11] & 0xf0) | (spindown & 0x0f); | ||
3340 | return cdrom_mode_select(cdi, &cgc); | ||
3341 | } | ||
3342 | |||
3343 | static int idecd_get_spindown(struct cdrom_device_info *cdi, unsigned long arg) | ||
3344 | { | ||
3345 | struct packet_command cgc; | ||
3346 | char buffer[16]; | ||
3347 | int stat; | ||
3348 | char spindown; | ||
3349 | |||
3350 | init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_UNKNOWN); | ||
3351 | |||
3352 | stat = cdrom_mode_sense(cdi, &cgc, GPMODE_CDROM_PAGE, 0); | ||
3353 | if (stat) | ||
3354 | return stat; | ||
3355 | |||
3356 | spindown = buffer[11] & 0x0f; | ||
3357 | if (copy_to_user((void __user *)arg, &spindown, sizeof (char))) | ||
3358 | return -EFAULT; | ||
3359 | return 0; | ||
3360 | } | ||
3361 | |||
3370 | static int idecd_ioctl (struct inode *inode, struct file *file, | 3362 | static int idecd_ioctl (struct inode *inode, struct file *file, |
3371 | unsigned int cmd, unsigned long arg) | 3363 | unsigned int cmd, unsigned long arg) |
3372 | { | 3364 | { |
@@ -3374,7 +3366,16 @@ static int idecd_ioctl (struct inode *inode, struct file *file, | |||
3374 | struct cdrom_info *info = ide_cd_g(bdev->bd_disk); | 3366 | struct cdrom_info *info = ide_cd_g(bdev->bd_disk); |
3375 | int err; | 3367 | int err; |
3376 | 3368 | ||
3377 | err = generic_ide_ioctl(info->drive, file, bdev, cmd, arg); | 3369 | switch (cmd) { |
3370 | case CDROMSETSPINDOWN: | ||
3371 | return idecd_set_spindown(&info->devinfo, arg); | ||
3372 | case CDROMGETSPINDOWN: | ||
3373 | return idecd_get_spindown(&info->devinfo, arg); | ||
3374 | default: | ||
3375 | break; | ||
3376 | } | ||
3377 | |||
3378 | err = generic_ide_ioctl(info->drive, file, bdev, cmd, arg); | ||
3378 | if (err == -EINVAL) | 3379 | if (err == -EINVAL) |
3379 | err = cdrom_ioctl(file, &info->devinfo, inode, cmd, arg); | 3380 | err = cdrom_ioctl(file, &info->devinfo, inode, cmd, arg); |
3380 | 3381 | ||
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index f9c1192dc15e..7c80711e18ed 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c | |||
@@ -71,7 +71,7 @@ MODULE_ALIAS_BLOCKDEV_MAJOR(SCSI_CDROM_MAJOR); | |||
71 | #define SR_CAPABILITIES \ | 71 | #define SR_CAPABILITIES \ |
72 | (CDC_CLOSE_TRAY|CDC_OPEN_TRAY|CDC_LOCK|CDC_SELECT_SPEED| \ | 72 | (CDC_CLOSE_TRAY|CDC_OPEN_TRAY|CDC_LOCK|CDC_SELECT_SPEED| \ |
73 | CDC_SELECT_DISC|CDC_MULTI_SESSION|CDC_MCN|CDC_MEDIA_CHANGED| \ | 73 | CDC_SELECT_DISC|CDC_MULTI_SESSION|CDC_MCN|CDC_MEDIA_CHANGED| \ |
74 | CDC_PLAY_AUDIO|CDC_RESET|CDC_IOCTLS|CDC_DRIVE_STATUS| \ | 74 | CDC_PLAY_AUDIO|CDC_RESET|CDC_DRIVE_STATUS| \ |
75 | CDC_CD_R|CDC_CD_RW|CDC_DVD|CDC_DVD_R|CDC_DVD_RAM|CDC_GENERIC_PACKET| \ | 75 | CDC_CD_R|CDC_CD_RW|CDC_DVD|CDC_DVD_R|CDC_DVD_RAM|CDC_GENERIC_PACKET| \ |
76 | CDC_MRW|CDC_MRW_W|CDC_RAM) | 76 | CDC_MRW|CDC_MRW_W|CDC_RAM) |
77 | 77 | ||
@@ -118,7 +118,6 @@ static struct cdrom_device_ops sr_dops = { | |||
118 | .get_mcn = sr_get_mcn, | 118 | .get_mcn = sr_get_mcn, |
119 | .reset = sr_reset, | 119 | .reset = sr_reset, |
120 | .audio_ioctl = sr_audio_ioctl, | 120 | .audio_ioctl = sr_audio_ioctl, |
121 | .dev_ioctl = sr_dev_ioctl, | ||
122 | .capability = SR_CAPABILITIES, | 121 | .capability = SR_CAPABILITIES, |
123 | .generic_packet = sr_packet, | 122 | .generic_packet = sr_packet, |
124 | }; | 123 | }; |
@@ -456,17 +455,33 @@ static int sr_block_ioctl(struct inode *inode, struct file *file, unsigned cmd, | |||
456 | { | 455 | { |
457 | struct scsi_cd *cd = scsi_cd(inode->i_bdev->bd_disk); | 456 | struct scsi_cd *cd = scsi_cd(inode->i_bdev->bd_disk); |
458 | struct scsi_device *sdev = cd->device; | 457 | struct scsi_device *sdev = cd->device; |
458 | void __user *argp = (void __user *)arg; | ||
459 | int ret; | ||
459 | 460 | ||
460 | /* | 461 | /* |
461 | * Send SCSI addressing ioctls directly to mid level, send other | 462 | * Send SCSI addressing ioctls directly to mid level, send other |
462 | * ioctls to cdrom/block level. | 463 | * ioctls to cdrom/block level. |
463 | */ | 464 | */ |
464 | switch (cmd) { | 465 | switch (cmd) { |
465 | case SCSI_IOCTL_GET_IDLUN: | 466 | case SCSI_IOCTL_GET_IDLUN: |
466 | case SCSI_IOCTL_GET_BUS_NUMBER: | 467 | case SCSI_IOCTL_GET_BUS_NUMBER: |
467 | return scsi_ioctl(sdev, cmd, (void __user *)arg); | 468 | return scsi_ioctl(sdev, cmd, argp); |
468 | } | 469 | } |
469 | return cdrom_ioctl(file, &cd->cdi, inode, cmd, arg); | 470 | |
471 | ret = cdrom_ioctl(file, &cd->cdi, inode, cmd, arg); | ||
472 | if (ret != ENOSYS) | ||
473 | return ret; | ||
474 | |||
475 | /* | ||
476 | * ENODEV means that we didn't recognise the ioctl, or that we | ||
477 | * cannot execute it in the current device state. In either | ||
478 | * case fall through to scsi_ioctl, which will return ENDOEV again | ||
479 | * if it doesn't recognise the ioctl | ||
480 | */ | ||
481 | ret = scsi_nonblockable_ioctl(sdev, cmd, argp, NULL); | ||
482 | if (ret != -ENODEV) | ||
483 | return ret; | ||
484 | return scsi_ioctl(sdev, cmd, argp); | ||
470 | } | 485 | } |
471 | 486 | ||
472 | static int sr_block_media_changed(struct gendisk *disk) | 487 | static int sr_block_media_changed(struct gendisk *disk) |
diff --git a/drivers/scsi/sr.h b/drivers/scsi/sr.h index d2bcd99c272f..d65de9621b27 100644 --- a/drivers/scsi/sr.h +++ b/drivers/scsi/sr.h | |||
@@ -55,7 +55,6 @@ int sr_get_mcn(struct cdrom_device_info *, struct cdrom_mcn *); | |||
55 | int sr_reset(struct cdrom_device_info *); | 55 | int sr_reset(struct cdrom_device_info *); |
56 | int sr_select_speed(struct cdrom_device_info *cdi, int speed); | 56 | int sr_select_speed(struct cdrom_device_info *cdi, int speed); |
57 | int sr_audio_ioctl(struct cdrom_device_info *, unsigned int, void *); | 57 | int sr_audio_ioctl(struct cdrom_device_info *, unsigned int, void *); |
58 | int sr_dev_ioctl(struct cdrom_device_info *, unsigned int, unsigned long); | ||
59 | 58 | ||
60 | int sr_is_xa(Scsi_CD *); | 59 | int sr_is_xa(Scsi_CD *); |
61 | 60 | ||
diff --git a/drivers/scsi/sr_ioctl.c b/drivers/scsi/sr_ioctl.c index b65462f76484..d1268cb46837 100644 --- a/drivers/scsi/sr_ioctl.c +++ b/drivers/scsi/sr_ioctl.c | |||
@@ -562,22 +562,3 @@ int sr_is_xa(Scsi_CD *cd) | |||
562 | #endif | 562 | #endif |
563 | return is_xa; | 563 | return is_xa; |
564 | } | 564 | } |
565 | |||
566 | int sr_dev_ioctl(struct cdrom_device_info *cdi, | ||
567 | unsigned int cmd, unsigned long arg) | ||
568 | { | ||
569 | Scsi_CD *cd = cdi->handle; | ||
570 | int ret; | ||
571 | |||
572 | ret = scsi_nonblockable_ioctl(cd->device, cmd, | ||
573 | (void __user *)arg, NULL); | ||
574 | /* | ||
575 | * ENODEV means that we didn't recognise the ioctl, or that we | ||
576 | * cannot execute it in the current device state. In either | ||
577 | * case fall through to scsi_ioctl, which will return ENDOEV again | ||
578 | * if it doesn't recognise the ioctl | ||
579 | */ | ||
580 | if (ret != -ENODEV) | ||
581 | return ret; | ||
582 | return scsi_ioctl(cd->device, cmd, (void __user *)arg); | ||
583 | } | ||
diff --git a/include/linux/cdrom.h b/include/linux/cdrom.h index b68fdf1f3156..3c9b0bc05123 100644 --- a/include/linux/cdrom.h +++ b/include/linux/cdrom.h | |||
@@ -378,7 +378,6 @@ struct cdrom_generic_command | |||
378 | #define CDC_MEDIA_CHANGED 0x80 /* media changed */ | 378 | #define CDC_MEDIA_CHANGED 0x80 /* media changed */ |
379 | #define CDC_PLAY_AUDIO 0x100 /* audio functions */ | 379 | #define CDC_PLAY_AUDIO 0x100 /* audio functions */ |
380 | #define CDC_RESET 0x200 /* hard reset device */ | 380 | #define CDC_RESET 0x200 /* hard reset device */ |
381 | #define CDC_IOCTLS 0x400 /* driver has non-standard ioctls */ | ||
382 | #define CDC_DRIVE_STATUS 0x800 /* driver implements drive status */ | 381 | #define CDC_DRIVE_STATUS 0x800 /* driver implements drive status */ |
383 | #define CDC_GENERIC_PACKET 0x1000 /* driver implements generic packets */ | 382 | #define CDC_GENERIC_PACKET 0x1000 /* driver implements generic packets */ |
384 | #define CDC_CD_R 0x2000 /* drive is a CD-R */ | 383 | #define CDC_CD_R 0x2000 /* drive is a CD-R */ |
@@ -974,9 +973,7 @@ struct cdrom_device_ops { | |||
974 | int (*reset) (struct cdrom_device_info *); | 973 | int (*reset) (struct cdrom_device_info *); |
975 | /* play stuff */ | 974 | /* play stuff */ |
976 | int (*audio_ioctl) (struct cdrom_device_info *,unsigned int, void *); | 975 | int (*audio_ioctl) (struct cdrom_device_info *,unsigned int, void *); |
977 | /* dev-specific */ | 976 | |
978 | int (*dev_ioctl) (struct cdrom_device_info *, | ||
979 | unsigned int, unsigned long); | ||
980 | /* driver specifications */ | 977 | /* driver specifications */ |
981 | const int capability; /* capability flags */ | 978 | const int capability; /* capability flags */ |
982 | int n_minors; /* number of active minor devices */ | 979 | int n_minors; /* number of active minor devices */ |