diff options
Diffstat (limited to 'drivers/cdrom/sbpcd.c')
| -rw-r--r-- | drivers/cdrom/sbpcd.c | 710 |
1 files changed, 351 insertions, 359 deletions
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 | ||
