aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cdrom
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/cdrom')
-rw-r--r--drivers/cdrom/cdrom.c874
-rw-r--r--drivers/cdrom/cdu31a.c8
-rw-r--r--drivers/cdrom/cm206.c44
-rw-r--r--drivers/cdrom/sbpcd.c710
-rw-r--r--drivers/cdrom/viocd.c2
5 files changed, 905 insertions, 733 deletions
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
index 879bbc26ce96..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;
@@ -2196,395 +2195,586 @@ retry:
2196 return cdrom_read_cdda_old(cdi, ubuf, lba, nframes); 2195 return cdrom_read_cdda_old(cdi, ubuf, lba, nframes);
2197} 2196}
2198 2197
2199/* Just about every imaginable ioctl is supported in the Uniform layer 2198static int cdrom_ioctl_multisession(struct cdrom_device_info *cdi,
2200 * these days. ATAPI / SCSI specific code now mainly resides in 2199 void __user *argp)
2201 * mmc_ioct().
2202 */
2203int cdrom_ioctl(struct file * file, struct cdrom_device_info *cdi,
2204 struct inode *ip, unsigned int cmd, unsigned long arg)
2205{ 2200{
2206 struct cdrom_device_ops *cdo = cdi->ops; 2201 struct cdrom_multisession ms_info;
2202 u8 requested_format;
2207 int ret; 2203 int ret;
2208 2204
2209 /* Try the generic SCSI command ioctl's first.. */ 2205 cdinfo(CD_DO_IOCTL, "entering CDROMMULTISESSION\n");
2210 ret = scsi_cmd_ioctl(file, ip->i_bdev->bd_disk, cmd, (void __user *)arg); 2206
2211 if (ret != -ENOTTY) 2207 if (!(cdi->ops->capability & CDC_MULTI_SESSION))
2208 return -ENOSYS;
2209
2210 if (copy_from_user(&ms_info, argp, sizeof(ms_info)))
2211 return -EFAULT;
2212
2213 requested_format = ms_info.addr_format;
2214 if (requested_format != CDROM_MSF && requested_format != CDROM_LBA)
2215 return -EINVAL;
2216 ms_info.addr_format = CDROM_LBA;
2217
2218 ret = cdi->ops->get_last_session(cdi, &ms_info);
2219 if (ret)
2212 return ret; 2220 return ret;
2213 2221
2214 /* the first few commands do not deal with audio drive_info, but 2222 sanitize_format(&ms_info.addr, &ms_info.addr_format, requested_format);
2215 only with routines in cdrom device operations. */ 2223
2216 switch (cmd) { 2224 if (copy_to_user(argp, &ms_info, sizeof(ms_info)))
2217 case CDROMMULTISESSION: { 2225 return -EFAULT;
2218 struct cdrom_multisession ms_info; 2226
2219 u_char requested_format; 2227 cdinfo(CD_DO_IOCTL, "CDROMMULTISESSION successful\n");
2220 cdinfo(CD_DO_IOCTL, "entering CDROMMULTISESSION\n"); 2228 return 0;
2221 if (!(cdo->capability & CDC_MULTI_SESSION)) 2229}
2222 return -ENOSYS; 2230
2223 IOCTL_IN(arg, struct cdrom_multisession, ms_info); 2231static int cdrom_ioctl_eject(struct cdrom_device_info *cdi)
2224 requested_format = ms_info.addr_format; 2232{
2225 if (!((requested_format == CDROM_MSF) || 2233 cdinfo(CD_DO_IOCTL, "entering CDROMEJECT\n");
2226 (requested_format == CDROM_LBA))) 2234
2227 return -EINVAL; 2235 if (!CDROM_CAN(CDC_OPEN_TRAY))
2228 ms_info.addr_format = CDROM_LBA; 2236 return -ENOSYS;
2229 if ((ret=cdo->get_last_session(cdi, &ms_info))) 2237 if (cdi->use_count != 1 || keeplocked)
2238 return -EBUSY;
2239 if (CDROM_CAN(CDC_LOCK)) {
2240 int ret = cdi->ops->lock_door(cdi, 0);
2241 if (ret)
2230 return ret; 2242 return ret;
2231 sanitize_format(&ms_info.addr, &ms_info.addr_format, 2243 }
2232 requested_format);
2233 IOCTL_OUT(arg, struct cdrom_multisession, ms_info);
2234 cdinfo(CD_DO_IOCTL, "CDROMMULTISESSION successful\n");
2235 return 0;
2236 }
2237 2244
2238 case CDROMEJECT: { 2245 return cdi->ops->tray_move(cdi, 1);
2239 cdinfo(CD_DO_IOCTL, "entering CDROMEJECT\n"); 2246}
2240 if (!CDROM_CAN(CDC_OPEN_TRAY))
2241 return -ENOSYS;
2242 if (cdi->use_count != 1 || keeplocked)
2243 return -EBUSY;
2244 if (CDROM_CAN(CDC_LOCK))
2245 if ((ret=cdo->lock_door(cdi, 0)))
2246 return ret;
2247 2247
2248 return cdo->tray_move(cdi, 1); 2248static int cdrom_ioctl_closetray(struct cdrom_device_info *cdi)
2249 } 2249{
2250 cdinfo(CD_DO_IOCTL, "entering CDROMCLOSETRAY\n");
2250 2251
2251 case CDROMCLOSETRAY: { 2252 if (!CDROM_CAN(CDC_CLOSE_TRAY))
2252 cdinfo(CD_DO_IOCTL, "entering CDROMCLOSETRAY\n"); 2253 return -ENOSYS;
2253 if (!CDROM_CAN(CDC_CLOSE_TRAY)) 2254 return cdi->ops->tray_move(cdi, 0);
2254 return -ENOSYS; 2255}
2255 return cdo->tray_move(cdi, 0);
2256 }
2257 2256
2258 case CDROMEJECT_SW: { 2257static int cdrom_ioctl_eject_sw(struct cdrom_device_info *cdi,
2259 cdinfo(CD_DO_IOCTL, "entering CDROMEJECT_SW\n"); 2258 unsigned long arg)
2260 if (!CDROM_CAN(CDC_OPEN_TRAY)) 2259{
2261 return -ENOSYS; 2260 cdinfo(CD_DO_IOCTL, "entering CDROMEJECT_SW\n");
2262 if (keeplocked)
2263 return -EBUSY;
2264 cdi->options &= ~(CDO_AUTO_CLOSE | CDO_AUTO_EJECT);
2265 if (arg)
2266 cdi->options |= CDO_AUTO_CLOSE | CDO_AUTO_EJECT;
2267 return 0;
2268 }
2269 2261
2270 case CDROM_MEDIA_CHANGED: { 2262 if (!CDROM_CAN(CDC_OPEN_TRAY))
2271 struct cdrom_changer_info *info; 2263 return -ENOSYS;
2272 int changed; 2264 if (keeplocked)
2265 return -EBUSY;
2273 2266
2274 cdinfo(CD_DO_IOCTL, "entering CDROM_MEDIA_CHANGED\n"); 2267 cdi->options &= ~(CDO_AUTO_CLOSE | CDO_AUTO_EJECT);
2275 if (!CDROM_CAN(CDC_MEDIA_CHANGED)) 2268 if (arg)
2276 return -ENOSYS; 2269 cdi->options |= CDO_AUTO_CLOSE | CDO_AUTO_EJECT;
2270 return 0;
2271}
2277 2272
2278 /* cannot select disc or select current disc */ 2273static int cdrom_ioctl_media_changed(struct cdrom_device_info *cdi,
2279 if (!CDROM_CAN(CDC_SELECT_DISC) || arg == CDSL_CURRENT) 2274 unsigned long arg)
2280 return media_changed(cdi, 1); 2275{
2276 struct cdrom_changer_info *info;
2277 int ret;
2281 2278
2282 if ((unsigned int)arg >= cdi->capacity) 2279 cdinfo(CD_DO_IOCTL, "entering CDROM_MEDIA_CHANGED\n");
2283 return -EINVAL;
2284 2280
2285 info = kmalloc(sizeof(*info), GFP_KERNEL); 2281 if (!CDROM_CAN(CDC_MEDIA_CHANGED))
2286 if (!info) 2282 return -ENOSYS;
2287 return -ENOMEM;
2288 2283
2289 if ((ret = cdrom_read_mech_status(cdi, info))) { 2284 /* cannot select disc or select current disc */
2290 kfree(info); 2285 if (!CDROM_CAN(CDC_SELECT_DISC) || arg == CDSL_CURRENT)
2291 return ret; 2286 return media_changed(cdi, 1);
2292 }
2293 2287
2294 changed = info->slots[arg].change; 2288 if ((unsigned int)arg >= cdi->capacity)
2295 kfree(info); 2289 return -EINVAL;
2296 return changed;
2297 }
2298 2290
2299 case CDROM_SET_OPTIONS: { 2291 info = kmalloc(sizeof(*info), GFP_KERNEL);
2300 cdinfo(CD_DO_IOCTL, "entering CDROM_SET_OPTIONS\n"); 2292 if (!info)
2301 /* options need to be in sync with capability. too late for 2293 return -ENOMEM;
2302 that, so we have to check each one separately... */
2303 switch (arg) {
2304 case CDO_USE_FFLAGS:
2305 case CDO_CHECK_TYPE:
2306 break;
2307 case CDO_LOCK:
2308 if (!CDROM_CAN(CDC_LOCK))
2309 return -ENOSYS;
2310 break;
2311 case 0:
2312 return cdi->options;
2313 /* default is basically CDO_[AUTO_CLOSE|AUTO_EJECT] */
2314 default:
2315 if (!CDROM_CAN(arg))
2316 return -ENOSYS;
2317 }
2318 cdi->options |= (int) arg;
2319 return cdi->options;
2320 }
2321 2294
2322 case CDROM_CLEAR_OPTIONS: { 2295 ret = cdrom_read_mech_status(cdi, info);
2323 cdinfo(CD_DO_IOCTL, "entering CDROM_CLEAR_OPTIONS\n"); 2296 if (!ret)
2324 cdi->options &= ~(int) arg; 2297 ret = info->slots[arg].change;
2325 return cdi->options; 2298 kfree(info);
2326 } 2299 return ret;
2300}
2327 2301
2328 case CDROM_SELECT_SPEED: { 2302static int cdrom_ioctl_set_options(struct cdrom_device_info *cdi,
2329 cdinfo(CD_DO_IOCTL, "entering CDROM_SELECT_SPEED\n"); 2303 unsigned long arg)
2330 if (!CDROM_CAN(CDC_SELECT_SPEED)) 2304{
2331 return -ENOSYS; 2305 cdinfo(CD_DO_IOCTL, "entering CDROM_SET_OPTIONS\n");
2332 return cdo->select_speed(cdi, arg);
2333 }
2334 2306
2335 case CDROM_SELECT_DISC: { 2307 /*
2336 cdinfo(CD_DO_IOCTL, "entering CDROM_SELECT_DISC\n"); 2308 * Options need to be in sync with capability.
2337 if (!CDROM_CAN(CDC_SELECT_DISC)) 2309 * Too late for that, so we have to check each one separately.
2310 */
2311 switch (arg) {
2312 case CDO_USE_FFLAGS:
2313 case CDO_CHECK_TYPE:
2314 break;
2315 case CDO_LOCK:
2316 if (!CDROM_CAN(CDC_LOCK))
2317 return -ENOSYS;
2318 break;
2319 case 0:
2320 return cdi->options;
2321 /* default is basically CDO_[AUTO_CLOSE|AUTO_EJECT] */
2322 default:
2323 if (!CDROM_CAN(arg))
2338 return -ENOSYS; 2324 return -ENOSYS;
2325 }
2326 cdi->options |= (int) arg;
2327 return cdi->options;
2328}
2339 2329
2340 if ((arg != CDSL_CURRENT) && (arg != CDSL_NONE)) 2330static int cdrom_ioctl_clear_options(struct cdrom_device_info *cdi,
2341 if ((int)arg >= cdi->capacity) 2331 unsigned long arg)
2342 return -EINVAL; 2332{
2343 2333 cdinfo(CD_DO_IOCTL, "entering CDROM_CLEAR_OPTIONS\n");
2344 /* cdo->select_disc is a hook to allow a driver-specific
2345 * way of seleting disc. However, since there is no
2346 * equiv hook for cdrom_slot_status this may not
2347 * actually be useful...
2348 */
2349 if (cdo->select_disc != NULL)
2350 return cdo->select_disc(cdi, arg);
2351
2352 /* no driver specific select_disc(), call our own */
2353 cdinfo(CD_CHANGER, "Using generic cdrom_select_disc()\n");
2354 return cdrom_select_disc(cdi, arg);
2355 }
2356 2334
2357 case CDROMRESET: { 2335 cdi->options &= ~(int) arg;
2358 if (!capable(CAP_SYS_ADMIN)) 2336 return cdi->options;
2359 return -EACCES; 2337}
2360 cdinfo(CD_DO_IOCTL, "entering CDROM_RESET\n");
2361 if (!CDROM_CAN(CDC_RESET))
2362 return -ENOSYS;
2363 invalidate_bdev(ip->i_bdev, 0);
2364 return cdo->reset(cdi);
2365 }
2366 2338
2367 case CDROM_LOCKDOOR: { 2339static int cdrom_ioctl_select_speed(struct cdrom_device_info *cdi,
2368 cdinfo(CD_DO_IOCTL, "%socking door.\n", arg ? "L" : "Unl"); 2340 unsigned long arg)
2369 if (!CDROM_CAN(CDC_LOCK)) 2341{
2370 return -EDRIVE_CANT_DO_THIS; 2342 cdinfo(CD_DO_IOCTL, "entering CDROM_SELECT_SPEED\n");
2371 keeplocked = arg ? 1 : 0;
2372 /* don't unlock the door on multiple opens,but allow root
2373 * to do so */
2374 if ((cdi->use_count != 1) && !arg && !capable(CAP_SYS_ADMIN))
2375 return -EBUSY;
2376 return cdo->lock_door(cdi, arg);
2377 }
2378 2343
2379 case CDROM_DEBUG: { 2344 if (!CDROM_CAN(CDC_SELECT_SPEED))
2380 if (!capable(CAP_SYS_ADMIN)) 2345 return -ENOSYS;
2381 return -EACCES; 2346 return cdi->ops->select_speed(cdi, arg);
2382 cdinfo(CD_DO_IOCTL, "%sabling debug.\n", arg ? "En" : "Dis"); 2347}
2383 debug = arg ? 1 : 0;
2384 return debug;
2385 }
2386 2348
2387 case CDROM_GET_CAPABILITY: { 2349static int cdrom_ioctl_select_disc(struct cdrom_device_info *cdi,
2388 cdinfo(CD_DO_IOCTL, "entering CDROM_GET_CAPABILITY\n"); 2350 unsigned long arg)
2389 return (cdo->capability & ~cdi->mask); 2351{
2390 } 2352 cdinfo(CD_DO_IOCTL, "entering CDROM_SELECT_DISC\n");
2353
2354 if (!CDROM_CAN(CDC_SELECT_DISC))
2355 return -ENOSYS;
2356
2357 if (arg != CDSL_CURRENT && arg != CDSL_NONE) {
2358 if ((int)arg >= cdi->capacity)
2359 return -EINVAL;
2360 }
2361
2362 /*
2363 * ->select_disc is a hook to allow a driver-specific way of
2364 * seleting disc. However, since there is no equivalent hook for
2365 * cdrom_slot_status this may not actually be useful...
2366 */
2367 if (cdi->ops->select_disc)
2368 return cdi->ops->select_disc(cdi, arg);
2369
2370 cdinfo(CD_CHANGER, "Using generic cdrom_select_disc()\n");
2371 return cdrom_select_disc(cdi, arg);
2372}
2373
2374static int cdrom_ioctl_reset(struct cdrom_device_info *cdi,
2375 struct block_device *bdev)
2376{
2377 cdinfo(CD_DO_IOCTL, "entering CDROM_RESET\n");
2378
2379 if (!capable(CAP_SYS_ADMIN))
2380 return -EACCES;
2381 if (!CDROM_CAN(CDC_RESET))
2382 return -ENOSYS;
2383 invalidate_bdev(bdev, 0);
2384 return cdi->ops->reset(cdi);
2385}
2386
2387static int cdrom_ioctl_lock_door(struct cdrom_device_info *cdi,
2388 unsigned long arg)
2389{
2390 cdinfo(CD_DO_IOCTL, "%socking door.\n", arg ? "L" : "Unl");
2391
2392 if (!CDROM_CAN(CDC_LOCK))
2393 return -EDRIVE_CANT_DO_THIS;
2394
2395 keeplocked = arg ? 1 : 0;
2396
2397 /*
2398 * Don't unlock the door on multiple opens by default, but allow
2399 * root to do so.
2400 */
2401 if (cdi->use_count != 1 && !arg && !capable(CAP_SYS_ADMIN))
2402 return -EBUSY;
2403 return cdi->ops->lock_door(cdi, arg);
2404}
2405
2406static int cdrom_ioctl_debug(struct cdrom_device_info *cdi,
2407 unsigned long arg)
2408{
2409 cdinfo(CD_DO_IOCTL, "%sabling debug.\n", arg ? "En" : "Dis");
2410
2411 if (!capable(CAP_SYS_ADMIN))
2412 return -EACCES;
2413 debug = arg ? 1 : 0;
2414 return debug;
2415}
2391 2416
2392/* The following function is implemented, although very few audio 2417static int cdrom_ioctl_get_capability(struct cdrom_device_info *cdi)
2418{
2419 cdinfo(CD_DO_IOCTL, "entering CDROM_GET_CAPABILITY\n");
2420 return (cdi->ops->capability & ~cdi->mask);
2421}
2422
2423/*
2424 * The following function is implemented, although very few audio
2393 * discs give Universal Product Code information, which should just be 2425 * discs give Universal Product Code information, which should just be
2394 * the Medium Catalog Number on the box. Note, that the way the code 2426 * the Medium Catalog Number on the box. Note, that the way the code
2395 * is written on the CD is /not/ uniform across all discs! 2427 * is written on the CD is /not/ uniform across all discs!
2396 */ 2428 */
2397 case CDROM_GET_MCN: { 2429static int cdrom_ioctl_get_mcn(struct cdrom_device_info *cdi,
2398 struct cdrom_mcn mcn; 2430 void __user *argp)
2399 cdinfo(CD_DO_IOCTL, "entering CDROM_GET_MCN\n"); 2431{
2400 if (!(cdo->capability & CDC_MCN)) 2432 struct cdrom_mcn mcn;
2401 return -ENOSYS; 2433 int ret;
2402 if ((ret=cdo->get_mcn(cdi, &mcn)))
2403 return ret;
2404 IOCTL_OUT(arg, struct cdrom_mcn, mcn);
2405 cdinfo(CD_DO_IOCTL, "CDROM_GET_MCN successful\n");
2406 return 0;
2407 }
2408 2434
2409 case CDROM_DRIVE_STATUS: { 2435 cdinfo(CD_DO_IOCTL, "entering CDROM_GET_MCN\n");
2410 cdinfo(CD_DO_IOCTL, "entering CDROM_DRIVE_STATUS\n");
2411 if (!(cdo->capability & CDC_DRIVE_STATUS))
2412 return -ENOSYS;
2413 if (!CDROM_CAN(CDC_SELECT_DISC))
2414 return cdo->drive_status(cdi, CDSL_CURRENT);
2415 if ((arg == CDSL_CURRENT) || (arg == CDSL_NONE))
2416 return cdo->drive_status(cdi, CDSL_CURRENT);
2417 if (((int)arg >= cdi->capacity))
2418 return -EINVAL;
2419 return cdrom_slot_status(cdi, arg);
2420 }
2421 2436
2422 /* Ok, this is where problems start. The current interface for the 2437 if (!(cdi->ops->capability & CDC_MCN))
2423 CDROM_DISC_STATUS ioctl is flawed. It makes the false assumption 2438 return -ENOSYS;
2424 that CDs are all CDS_DATA_1 or all CDS_AUDIO, etc. Unfortunatly, 2439 ret = cdi->ops->get_mcn(cdi, &mcn);
2425 while this is often the case, it is also very common for CDs to 2440 if (ret)
2426 have some tracks with data, and some tracks with audio. Just 2441 return ret;
2427 because I feel like it, I declare the following to be the best
2428 way to cope. If the CD has ANY data tracks on it, it will be
2429 returned as a data CD. If it has any XA tracks, I will return
2430 it as that. Now I could simplify this interface by combining these
2431 returns with the above, but this more clearly demonstrates
2432 the problem with the current interface. Too bad this wasn't
2433 designed to use bitmasks... -Erik
2434
2435 Well, now we have the option CDS_MIXED: a mixed-type CD.
2436 User level programmers might feel the ioctl is not very useful.
2437 ---david
2438 */
2439 case CDROM_DISC_STATUS: {
2440 tracktype tracks;
2441 cdinfo(CD_DO_IOCTL, "entering CDROM_DISC_STATUS\n");
2442 cdrom_count_tracks(cdi, &tracks);
2443 if (tracks.error)
2444 return(tracks.error);
2445
2446 /* Policy mode on */
2447 if (tracks.audio > 0) {
2448 if (tracks.data==0 && tracks.cdi==0 && tracks.xa==0)
2449 return CDS_AUDIO;
2450 else
2451 return CDS_MIXED;
2452 }
2453 if (tracks.cdi > 0) return CDS_XA_2_2;
2454 if (tracks.xa > 0) return CDS_XA_2_1;
2455 if (tracks.data > 0) return CDS_DATA_1;
2456 /* Policy mode off */
2457 2442
2458 cdinfo(CD_WARNING,"This disc doesn't have any tracks I recognize!\n"); 2443 if (copy_to_user(argp, &mcn, sizeof(mcn)))
2459 return CDS_NO_INFO; 2444 return -EFAULT;
2460 } 2445 cdinfo(CD_DO_IOCTL, "CDROM_GET_MCN successful\n");
2446 return 0;
2447}
2461 2448
2462 case CDROM_CHANGER_NSLOTS: { 2449static int cdrom_ioctl_drive_status(struct cdrom_device_info *cdi,
2463 cdinfo(CD_DO_IOCTL, "entering CDROM_CHANGER_NSLOTS\n"); 2450 unsigned long arg)
2464 return cdi->capacity; 2451{
2465 } 2452 cdinfo(CD_DO_IOCTL, "entering CDROM_DRIVE_STATUS\n");
2453
2454 if (!(cdi->ops->capability & CDC_DRIVE_STATUS))
2455 return -ENOSYS;
2456 if (!CDROM_CAN(CDC_SELECT_DISC) ||
2457 (arg == CDSL_CURRENT || arg == CDSL_NONE))
2458 return cdi->ops->drive_status(cdi, CDSL_CURRENT);
2459 if (((int)arg >= cdi->capacity))
2460 return -EINVAL;
2461 return cdrom_slot_status(cdi, arg);
2462}
2463
2464/*
2465 * Ok, this is where problems start. The current interface for the
2466 * CDROM_DISC_STATUS ioctl is flawed. It makes the false assumption that
2467 * CDs are all CDS_DATA_1 or all CDS_AUDIO, etc. Unfortunatly, while this
2468 * is often the case, it is also very common for CDs to have some tracks
2469 * with data, and some tracks with audio. Just because I feel like it,
2470 * I declare the following to be the best way to cope. If the CD has ANY
2471 * data tracks on it, it will be returned as a data CD. If it has any XA
2472 * tracks, I will return it as that. Now I could simplify this interface
2473 * by combining these returns with the above, but this more clearly
2474 * demonstrates the problem with the current interface. Too bad this
2475 * wasn't designed to use bitmasks... -Erik
2476 *
2477 * Well, now we have the option CDS_MIXED: a mixed-type CD.
2478 * User level programmers might feel the ioctl is not very useful.
2479 * ---david
2480 */
2481static int cdrom_ioctl_disc_status(struct cdrom_device_info *cdi)
2482{
2483 tracktype tracks;
2484
2485 cdinfo(CD_DO_IOCTL, "entering CDROM_DISC_STATUS\n");
2486
2487 cdrom_count_tracks(cdi, &tracks);
2488 if (tracks.error)
2489 return tracks.error;
2490
2491 /* Policy mode on */
2492 if (tracks.audio > 0) {
2493 if (!tracks.data && !tracks.cdi && !tracks.xa)
2494 return CDS_AUDIO;
2495 else
2496 return CDS_MIXED;
2466 } 2497 }
2467 2498
2468 /* use the ioctls that are implemented through the generic_packet() 2499 if (tracks.cdi > 0)
2469 interface. this may look at bit funny, but if -ENOTTY is 2500 return CDS_XA_2_2;
2470 returned that particular ioctl is not implemented and we 2501 if (tracks.xa > 0)
2471 let it go through the device specific ones. */ 2502 return CDS_XA_2_1;
2503 if (tracks.data > 0)
2504 return CDS_DATA_1;
2505 /* Policy mode off */
2506
2507 cdinfo(CD_WARNING,"This disc doesn't have any tracks I recognize!\n");
2508 return CDS_NO_INFO;
2509}
2510
2511static int cdrom_ioctl_changer_nslots(struct cdrom_device_info *cdi)
2512{
2513 cdinfo(CD_DO_IOCTL, "entering CDROM_CHANGER_NSLOTS\n");
2514 return cdi->capacity;
2515}
2516
2517static int cdrom_ioctl_get_subchnl(struct cdrom_device_info *cdi,
2518 void __user *argp)
2519{
2520 struct cdrom_subchnl q;
2521 u8 requested, back;
2522 int ret;
2523
2524 /* cdinfo(CD_DO_IOCTL,"entering CDROMSUBCHNL\n");*/
2525
2526 if (!CDROM_CAN(CDC_PLAY_AUDIO))
2527 return -ENOSYS;
2528 if (copy_from_user(&q, argp, sizeof(q)))
2529 return -EFAULT;
2530
2531 requested = q.cdsc_format;
2532 if (requested != CDROM_MSF && requested != CDROM_LBA)
2533 return -EINVAL;
2534 q.cdsc_format = CDROM_MSF;
2535
2536 ret = cdi->ops->audio_ioctl(cdi, CDROMSUBCHNL, &q);
2537 if (ret)
2538 return ret;
2539
2540 back = q.cdsc_format; /* local copy */
2541 sanitize_format(&q.cdsc_absaddr, &back, requested);
2542 sanitize_format(&q.cdsc_reladdr, &q.cdsc_format, requested);
2543
2544 if (copy_to_user(argp, &q, sizeof(q)))
2545 return -EFAULT;
2546 /* cdinfo(CD_DO_IOCTL, "CDROMSUBCHNL successful\n"); */
2547 return 0;
2548}
2549
2550static int cdrom_ioctl_read_tochdr(struct cdrom_device_info *cdi,
2551 void __user *argp)
2552{
2553 struct cdrom_tochdr header;
2554 int ret;
2555
2556 /* cdinfo(CD_DO_IOCTL, "entering CDROMREADTOCHDR\n"); */
2557
2558 if (!CDROM_CAN(CDC_PLAY_AUDIO))
2559 return -ENOSYS;
2560 if (copy_from_user(&header, argp, sizeof(header)))
2561 return -EFAULT;
2562
2563 ret = cdi->ops->audio_ioctl(cdi, CDROMREADTOCHDR, &header);
2564 if (ret)
2565 return ret;
2566
2567 if (copy_to_user(argp, &header, sizeof(header)))
2568 return -EFAULT;
2569 /* cdinfo(CD_DO_IOCTL, "CDROMREADTOCHDR successful\n"); */
2570 return 0;
2571}
2572
2573static int cdrom_ioctl_read_tocentry(struct cdrom_device_info *cdi,
2574 void __user *argp)
2575{
2576 struct cdrom_tocentry entry;
2577 u8 requested_format;
2578 int ret;
2579
2580 /* cdinfo(CD_DO_IOCTL, "entering CDROMREADTOCENTRY\n"); */
2581
2582 if (!CDROM_CAN(CDC_PLAY_AUDIO))
2583 return -ENOSYS;
2584 if (copy_from_user(&entry, argp, sizeof(entry)))
2585 return -EFAULT;
2586
2587 requested_format = entry.cdte_format;
2588 if (requested_format != CDROM_MSF && requested_format != CDROM_LBA)
2589 return -EINVAL;
2590 /* make interface to low-level uniform */
2591 entry.cdte_format = CDROM_MSF;
2592 ret = cdi->ops->audio_ioctl(cdi, CDROMREADTOCENTRY, &entry);
2593 if (ret)
2594 return ret;
2595 sanitize_format(&entry.cdte_addr, &entry.cdte_format, requested_format);
2596
2597 if (copy_to_user(argp, &entry, sizeof(entry)))
2598 return -EFAULT;
2599 /* cdinfo(CD_DO_IOCTL, "CDROMREADTOCENTRY successful\n"); */
2600 return 0;
2601}
2602
2603static int cdrom_ioctl_play_msf(struct cdrom_device_info *cdi,
2604 void __user *argp)
2605{
2606 struct cdrom_msf msf;
2607
2608 cdinfo(CD_DO_IOCTL, "entering CDROMPLAYMSF\n");
2609
2610 if (!CDROM_CAN(CDC_PLAY_AUDIO))
2611 return -ENOSYS;
2612 if (copy_from_user(&msf, argp, sizeof(msf)))
2613 return -EFAULT;
2614 return cdi->ops->audio_ioctl(cdi, CDROMPLAYMSF, &msf);
2615}
2616
2617static int cdrom_ioctl_play_trkind(struct cdrom_device_info *cdi,
2618 void __user *argp)
2619{
2620 struct cdrom_ti ti;
2621 int ret;
2622
2623 cdinfo(CD_DO_IOCTL, "entering CDROMPLAYTRKIND\n");
2624
2625 if (!CDROM_CAN(CDC_PLAY_AUDIO))
2626 return -ENOSYS;
2627 if (copy_from_user(&ti, argp, sizeof(ti)))
2628 return -EFAULT;
2629
2630 ret = check_for_audio_disc(cdi, cdi->ops);
2631 if (ret)
2632 return ret;
2633 return cdi->ops->audio_ioctl(cdi, CDROMPLAYTRKIND, &ti);
2634}
2635static int cdrom_ioctl_volctrl(struct cdrom_device_info *cdi,
2636 void __user *argp)
2637{
2638 struct cdrom_volctrl volume;
2639
2640 cdinfo(CD_DO_IOCTL, "entering CDROMVOLCTRL\n");
2641
2642 if (!CDROM_CAN(CDC_PLAY_AUDIO))
2643 return -ENOSYS;
2644 if (copy_from_user(&volume, argp, sizeof(volume)))
2645 return -EFAULT;
2646 return cdi->ops->audio_ioctl(cdi, CDROMVOLCTRL, &volume);
2647}
2648
2649static int cdrom_ioctl_volread(struct cdrom_device_info *cdi,
2650 void __user *argp)
2651{
2652 struct cdrom_volctrl volume;
2653 int ret;
2654
2655 cdinfo(CD_DO_IOCTL, "entering CDROMVOLREAD\n");
2656
2657 if (!CDROM_CAN(CDC_PLAY_AUDIO))
2658 return -ENOSYS;
2659
2660 ret = cdi->ops->audio_ioctl(cdi, CDROMVOLREAD, &volume);
2661 if (ret)
2662 return ret;
2663
2664 if (copy_to_user(argp, &volume, sizeof(volume)))
2665 return -EFAULT;
2666 return 0;
2667}
2668
2669static int cdrom_ioctl_audioctl(struct cdrom_device_info *cdi,
2670 unsigned int cmd)
2671{
2672 int ret;
2673
2674 cdinfo(CD_DO_IOCTL, "doing audio ioctl (start/stop/pause/resume)\n");
2675
2676 if (!CDROM_CAN(CDC_PLAY_AUDIO))
2677 return -ENOSYS;
2678 ret = check_for_audio_disc(cdi, cdi->ops);
2679 if (ret)
2680 return ret;
2681 return cdi->ops->audio_ioctl(cdi, cmd, NULL);
2682}
2683
2684/*
2685 * Just about every imaginable ioctl is supported in the Uniform layer
2686 * these days.
2687 * ATAPI / SCSI specific code now mainly resides in mmc_ioctl().
2688 */
2689int cdrom_ioctl(struct file * file, struct cdrom_device_info *cdi,
2690 struct inode *ip, unsigned int cmd, unsigned long arg)
2691{
2692 void __user *argp = (void __user *)arg;
2693 int ret;
2694
2695 /*
2696 * Try the generic SCSI command ioctl's first.
2697 */
2698 ret = scsi_cmd_ioctl(file, ip->i_bdev->bd_disk, cmd, argp);
2699 if (ret != -ENOTTY)
2700 return ret;
2701
2702 switch (cmd) {
2703 case CDROMMULTISESSION:
2704 return cdrom_ioctl_multisession(cdi, argp);
2705 case CDROMEJECT:
2706 return cdrom_ioctl_eject(cdi);
2707 case CDROMCLOSETRAY:
2708 return cdrom_ioctl_closetray(cdi);
2709 case CDROMEJECT_SW:
2710 return cdrom_ioctl_eject_sw(cdi, arg);
2711 case CDROM_MEDIA_CHANGED:
2712 return cdrom_ioctl_media_changed(cdi, arg);
2713 case CDROM_SET_OPTIONS:
2714 return cdrom_ioctl_set_options(cdi, arg);
2715 case CDROM_CLEAR_OPTIONS:
2716 return cdrom_ioctl_clear_options(cdi, arg);
2717 case CDROM_SELECT_SPEED:
2718 return cdrom_ioctl_select_speed(cdi, arg);
2719 case CDROM_SELECT_DISC:
2720 return cdrom_ioctl_select_disc(cdi, arg);
2721 case CDROMRESET:
2722 return cdrom_ioctl_reset(cdi, ip->i_bdev);
2723 case CDROM_LOCKDOOR:
2724 return cdrom_ioctl_lock_door(cdi, arg);
2725 case CDROM_DEBUG:
2726 return cdrom_ioctl_debug(cdi, arg);
2727 case CDROM_GET_CAPABILITY:
2728 return cdrom_ioctl_get_capability(cdi);
2729 case CDROM_GET_MCN:
2730 return cdrom_ioctl_get_mcn(cdi, argp);
2731 case CDROM_DRIVE_STATUS:
2732 return cdrom_ioctl_drive_status(cdi, arg);
2733 case CDROM_DISC_STATUS:
2734 return cdrom_ioctl_disc_status(cdi);
2735 case CDROM_CHANGER_NSLOTS:
2736 return cdrom_ioctl_changer_nslots(cdi);
2737 }
2738
2739 /*
2740 * Use the ioctls that are implemented through the generic_packet()
2741 * interface. this may look at bit funny, but if -ENOTTY is
2742 * returned that particular ioctl is not implemented and we
2743 * let it go through the device specific ones.
2744 */
2472 if (CDROM_CAN(CDC_GENERIC_PACKET)) { 2745 if (CDROM_CAN(CDC_GENERIC_PACKET)) {
2473 ret = mmc_ioctl(cdi, cmd, arg); 2746 ret = mmc_ioctl(cdi, cmd, arg);
2474 if (ret != -ENOTTY) { 2747 if (ret != -ENOTTY)
2475 return ret; 2748 return ret;
2476 }
2477 } 2749 }
2478 2750
2479 /* note: most of the cdinfo() calls are commented out here, 2751 /*
2480 because they fill up the sys log when CD players poll 2752 * Note: most of the cdinfo() calls are commented out here,
2481 the drive. */ 2753 * because they fill up the sys log when CD players poll
2754 * the drive.
2755 */
2482 switch (cmd) { 2756 switch (cmd) {
2483 case CDROMSUBCHNL: { 2757 case CDROMSUBCHNL:
2484 struct cdrom_subchnl q; 2758 return cdrom_ioctl_get_subchnl(cdi, argp);
2485 u_char requested, back; 2759 case CDROMREADTOCHDR:
2486 if (!CDROM_CAN(CDC_PLAY_AUDIO)) 2760 return cdrom_ioctl_read_tochdr(cdi, argp);
2487 return -ENOSYS; 2761 case CDROMREADTOCENTRY:
2488 /* cdinfo(CD_DO_IOCTL,"entering CDROMSUBCHNL\n");*/ 2762 return cdrom_ioctl_read_tocentry(cdi, argp);
2489 IOCTL_IN(arg, struct cdrom_subchnl, q); 2763 case CDROMPLAYMSF:
2490 requested = q.cdsc_format; 2764 return cdrom_ioctl_play_msf(cdi, argp);
2491 if (!((requested == CDROM_MSF) || 2765 case CDROMPLAYTRKIND:
2492 (requested == CDROM_LBA))) 2766 return cdrom_ioctl_play_trkind(cdi, argp);
2493 return -EINVAL; 2767 case CDROMVOLCTRL:
2494 q.cdsc_format = CDROM_MSF; 2768 return cdrom_ioctl_volctrl(cdi, argp);
2495 if ((ret=cdo->audio_ioctl(cdi, cmd, &q))) 2769 case CDROMVOLREAD:
2496 return ret; 2770 return cdrom_ioctl_volread(cdi, argp);
2497 back = q.cdsc_format; /* local copy */
2498 sanitize_format(&q.cdsc_absaddr, &back, requested);
2499 sanitize_format(&q.cdsc_reladdr, &q.cdsc_format, requested);
2500 IOCTL_OUT(arg, struct cdrom_subchnl, q);
2501 /* cdinfo(CD_DO_IOCTL, "CDROMSUBCHNL successful\n"); */
2502 return 0;
2503 }
2504 case CDROMREADTOCHDR: {
2505 struct cdrom_tochdr header;
2506 if (!CDROM_CAN(CDC_PLAY_AUDIO))
2507 return -ENOSYS;
2508 /* cdinfo(CD_DO_IOCTL, "entering CDROMREADTOCHDR\n"); */
2509 IOCTL_IN(arg, struct cdrom_tochdr, header);
2510 if ((ret=cdo->audio_ioctl(cdi, cmd, &header)))
2511 return ret;
2512 IOCTL_OUT(arg, struct cdrom_tochdr, header);
2513 /* cdinfo(CD_DO_IOCTL, "CDROMREADTOCHDR successful\n"); */
2514 return 0;
2515 }
2516 case CDROMREADTOCENTRY: {
2517 struct cdrom_tocentry entry;
2518 u_char requested_format;
2519 if (!CDROM_CAN(CDC_PLAY_AUDIO))
2520 return -ENOSYS;
2521 /* cdinfo(CD_DO_IOCTL, "entering CDROMREADTOCENTRY\n"); */
2522 IOCTL_IN(arg, struct cdrom_tocentry, entry);
2523 requested_format = entry.cdte_format;
2524 if (!((requested_format == CDROM_MSF) ||
2525 (requested_format == CDROM_LBA)))
2526 return -EINVAL;
2527 /* make interface to low-level uniform */
2528 entry.cdte_format = CDROM_MSF;
2529 if ((ret=cdo->audio_ioctl(cdi, cmd, &entry)))
2530 return ret;
2531 sanitize_format(&entry.cdte_addr,
2532 &entry.cdte_format, requested_format);
2533 IOCTL_OUT(arg, struct cdrom_tocentry, entry);
2534 /* cdinfo(CD_DO_IOCTL, "CDROMREADTOCENTRY successful\n"); */
2535 return 0;
2536 }
2537 case CDROMPLAYMSF: {
2538 struct cdrom_msf msf;
2539 if (!CDROM_CAN(CDC_PLAY_AUDIO))
2540 return -ENOSYS;
2541 cdinfo(CD_DO_IOCTL, "entering CDROMPLAYMSF\n");
2542 IOCTL_IN(arg, struct cdrom_msf, msf);
2543 return cdo->audio_ioctl(cdi, cmd, &msf);
2544 }
2545 case CDROMPLAYTRKIND: {
2546 struct cdrom_ti ti;
2547 if (!CDROM_CAN(CDC_PLAY_AUDIO))
2548 return -ENOSYS;
2549 cdinfo(CD_DO_IOCTL, "entering CDROMPLAYTRKIND\n");
2550 IOCTL_IN(arg, struct cdrom_ti, ti);
2551 CHECKAUDIO;
2552 return cdo->audio_ioctl(cdi, cmd, &ti);
2553 }
2554 case CDROMVOLCTRL: {
2555 struct cdrom_volctrl volume;
2556 if (!CDROM_CAN(CDC_PLAY_AUDIO))
2557 return -ENOSYS;
2558 cdinfo(CD_DO_IOCTL, "entering CDROMVOLCTRL\n");
2559 IOCTL_IN(arg, struct cdrom_volctrl, volume);
2560 return cdo->audio_ioctl(cdi, cmd, &volume);
2561 }
2562 case CDROMVOLREAD: {
2563 struct cdrom_volctrl volume;
2564 if (!CDROM_CAN(CDC_PLAY_AUDIO))
2565 return -ENOSYS;
2566 cdinfo(CD_DO_IOCTL, "entering CDROMVOLREAD\n");
2567 if ((ret=cdo->audio_ioctl(cdi, cmd, &volume)))
2568 return ret;
2569 IOCTL_OUT(arg, struct cdrom_volctrl, volume);
2570 return 0;
2571 }
2572 case CDROMSTART: 2771 case CDROMSTART:
2573 case CDROMSTOP: 2772 case CDROMSTOP:
2574 case CDROMPAUSE: 2773 case CDROMPAUSE:
2575 case CDROMRESUME: { 2774 case CDROMRESUME:
2576 if (!CDROM_CAN(CDC_PLAY_AUDIO)) 2775 return cdrom_ioctl_audioctl(cdi, cmd);
2577 return -ENOSYS; 2776 }
2578 cdinfo(CD_DO_IOCTL, "doing audio ioctl (start/stop/pause/resume)\n");
2579 CHECKAUDIO;
2580 return cdo->audio_ioctl(cdi, cmd, NULL);
2581 }
2582 } /* switch */
2583 2777
2584 /* do the device specific ioctls */
2585 if (CDROM_CAN(CDC_IOCTLS))
2586 return cdo->dev_ioctl(cdi, cmd, arg);
2587
2588 return -ENOSYS; 2778 return -ENOSYS;
2589} 2779}
2590 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
2671static int scd_dev_ioctl(struct cdrom_device_info *cdi, 2671static 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
1164static 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
1186static int cm206_media_changed(struct cdrom_device_info *cdi, int disc_nr) 1160static 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)
1350static int cm206_block_ioctl(struct inode *inode, struct file *file, 1323static 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 */
4168static 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
4489static int sbpcd_audio_ioctl(struct cdrom_device_info *cdi, u_int cmd, 4163static 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,
4788static void sbp_transfer(struct request *req) 4462static 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
5376static int sbpcd_block_media_changed(struct gendisk *disk) 5369static 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
633static int __init find_capability(const char *type) 633static int __init find_capability(const char *type)