diff options
Diffstat (limited to 'drivers/cdrom/cdrom.c')
| -rw-r--r-- | drivers/cdrom/cdrom.c | 216 |
1 files changed, 125 insertions, 91 deletions
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index 3625a05bc3d3..aa5468f487ba 100644 --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c | |||
| @@ -302,7 +302,7 @@ module_param(lockdoor, bool, 0); | |||
| 302 | module_param(check_media_type, bool, 0); | 302 | module_param(check_media_type, bool, 0); |
| 303 | module_param(mrw_format_restart, bool, 0); | 303 | module_param(mrw_format_restart, bool, 0); |
| 304 | 304 | ||
| 305 | static DEFINE_SPINLOCK(cdrom_lock); | 305 | static DEFINE_MUTEX(cdrom_mutex); |
| 306 | 306 | ||
| 307 | static const char *mrw_format_status[] = { | 307 | static const char *mrw_format_status[] = { |
| 308 | "not mrw", | 308 | "not mrw", |
| @@ -438,10 +438,10 @@ int register_cdrom(struct cdrom_device_info *cdi) | |||
| 438 | cdo->generic_packet = cdrom_dummy_generic_packet; | 438 | cdo->generic_packet = cdrom_dummy_generic_packet; |
| 439 | 439 | ||
| 440 | cdinfo(CD_REG_UNREG, "drive \"/dev/%s\" registered\n", cdi->name); | 440 | cdinfo(CD_REG_UNREG, "drive \"/dev/%s\" registered\n", cdi->name); |
| 441 | spin_lock(&cdrom_lock); | 441 | mutex_lock(&cdrom_mutex); |
| 442 | cdi->next = topCdromPtr; | 442 | cdi->next = topCdromPtr; |
| 443 | topCdromPtr = cdi; | 443 | topCdromPtr = cdi; |
| 444 | spin_unlock(&cdrom_lock); | 444 | mutex_unlock(&cdrom_mutex); |
| 445 | return 0; | 445 | return 0; |
| 446 | } | 446 | } |
| 447 | #undef ENSURE | 447 | #undef ENSURE |
| @@ -452,7 +452,7 @@ int unregister_cdrom(struct cdrom_device_info *unreg) | |||
| 452 | cdinfo(CD_OPEN, "entering unregister_cdrom\n"); | 452 | cdinfo(CD_OPEN, "entering unregister_cdrom\n"); |
| 453 | 453 | ||
| 454 | prev = NULL; | 454 | prev = NULL; |
| 455 | spin_lock(&cdrom_lock); | 455 | mutex_lock(&cdrom_mutex); |
| 456 | cdi = topCdromPtr; | 456 | cdi = topCdromPtr; |
| 457 | while (cdi && cdi != unreg) { | 457 | while (cdi && cdi != unreg) { |
| 458 | prev = cdi; | 458 | prev = cdi; |
| @@ -460,7 +460,7 @@ int unregister_cdrom(struct cdrom_device_info *unreg) | |||
| 460 | } | 460 | } |
| 461 | 461 | ||
| 462 | if (cdi == NULL) { | 462 | if (cdi == NULL) { |
| 463 | spin_unlock(&cdrom_lock); | 463 | mutex_unlock(&cdrom_mutex); |
| 464 | return -2; | 464 | return -2; |
| 465 | } | 465 | } |
| 466 | if (prev) | 466 | if (prev) |
| @@ -468,7 +468,7 @@ int unregister_cdrom(struct cdrom_device_info *unreg) | |||
| 468 | else | 468 | else |
| 469 | topCdromPtr = cdi->next; | 469 | topCdromPtr = cdi->next; |
| 470 | 470 | ||
| 471 | spin_unlock(&cdrom_lock); | 471 | mutex_unlock(&cdrom_mutex); |
| 472 | 472 | ||
| 473 | if (cdi->exit) | 473 | if (cdi->exit) |
| 474 | cdi->exit(cdi); | 474 | cdi->exit(cdi); |
| @@ -3289,103 +3289,137 @@ static struct cdrom_sysctl_settings { | |||
| 3289 | int check; /* check media type */ | 3289 | int check; /* check media type */ |
| 3290 | } cdrom_sysctl_settings; | 3290 | } cdrom_sysctl_settings; |
| 3291 | 3291 | ||
| 3292 | enum cdrom_print_option { | ||
| 3293 | CTL_NAME, | ||
| 3294 | CTL_SPEED, | ||
| 3295 | CTL_SLOTS, | ||
| 3296 | CTL_CAPABILITY | ||
| 3297 | }; | ||
| 3298 | |||
| 3299 | static int cdrom_print_info(const char *header, int val, char *info, | ||
| 3300 | int *pos, enum cdrom_print_option option) | ||
| 3301 | { | ||
| 3302 | const int max_size = sizeof(cdrom_sysctl_settings.info); | ||
| 3303 | struct cdrom_device_info *cdi; | ||
| 3304 | int ret; | ||
| 3305 | |||
| 3306 | ret = scnprintf(info + *pos, max_size - *pos, header); | ||
| 3307 | if (!ret) | ||
| 3308 | return 1; | ||
| 3309 | |||
| 3310 | *pos += ret; | ||
| 3311 | |||
| 3312 | for (cdi = topCdromPtr; cdi; cdi = cdi->next) { | ||
| 3313 | switch (option) { | ||
| 3314 | case CTL_NAME: | ||
| 3315 | ret = scnprintf(info + *pos, max_size - *pos, | ||
| 3316 | "\t%s", cdi->name); | ||
| 3317 | break; | ||
| 3318 | case CTL_SPEED: | ||
| 3319 | ret = scnprintf(info + *pos, max_size - *pos, | ||
| 3320 | "\t%d", cdi->speed); | ||
| 3321 | break; | ||
| 3322 | case CTL_SLOTS: | ||
| 3323 | ret = scnprintf(info + *pos, max_size - *pos, | ||
| 3324 | "\t%d", cdi->capacity); | ||
| 3325 | break; | ||
| 3326 | case CTL_CAPABILITY: | ||
| 3327 | ret = scnprintf(info + *pos, max_size - *pos, | ||
| 3328 | "\t%d", CDROM_CAN(val) != 0); | ||
| 3329 | break; | ||
| 3330 | default: | ||
| 3331 | printk(KERN_INFO "cdrom: invalid option%d\n", option); | ||
| 3332 | return 1; | ||
| 3333 | } | ||
| 3334 | if (!ret) | ||
| 3335 | return 1; | ||
| 3336 | *pos += ret; | ||
| 3337 | } | ||
| 3338 | |||
| 3339 | return 0; | ||
| 3340 | } | ||
| 3341 | |||
| 3292 | static int cdrom_sysctl_info(ctl_table *ctl, int write, struct file * filp, | 3342 | static int cdrom_sysctl_info(ctl_table *ctl, int write, struct file * filp, |
| 3293 | void __user *buffer, size_t *lenp, loff_t *ppos) | 3343 | void __user *buffer, size_t *lenp, loff_t *ppos) |
| 3294 | { | 3344 | { |
| 3295 | int pos; | 3345 | int pos; |
| 3296 | struct cdrom_device_info *cdi; | ||
| 3297 | char *info = cdrom_sysctl_settings.info; | 3346 | char *info = cdrom_sysctl_settings.info; |
| 3347 | const int max_size = sizeof(cdrom_sysctl_settings.info); | ||
| 3298 | 3348 | ||
| 3299 | if (!*lenp || (*ppos && !write)) { | 3349 | if (!*lenp || (*ppos && !write)) { |
| 3300 | *lenp = 0; | 3350 | *lenp = 0; |
| 3301 | return 0; | 3351 | return 0; |
| 3302 | } | 3352 | } |
| 3303 | 3353 | ||
| 3354 | mutex_lock(&cdrom_mutex); | ||
| 3355 | |||
| 3304 | pos = sprintf(info, "CD-ROM information, " VERSION "\n"); | 3356 | pos = sprintf(info, "CD-ROM information, " VERSION "\n"); |
| 3305 | 3357 | ||
| 3306 | pos += sprintf(info+pos, "\ndrive name:\t"); | 3358 | if (cdrom_print_info("\ndrive name:\t", 0, info, &pos, CTL_NAME)) |
| 3307 | for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) | 3359 | goto done; |
| 3308 | pos += sprintf(info+pos, "\t%s", cdi->name); | 3360 | if (cdrom_print_info("\ndrive speed:\t", 0, info, &pos, CTL_SPEED)) |
| 3309 | 3361 | goto done; | |
| 3310 | pos += sprintf(info+pos, "\ndrive speed:\t"); | 3362 | if (cdrom_print_info("\ndrive # of slots:", 0, info, &pos, CTL_SLOTS)) |
| 3311 | for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) | 3363 | goto done; |
| 3312 | pos += sprintf(info+pos, "\t%d", cdi->speed); | 3364 | if (cdrom_print_info("\nCan close tray:\t", |
| 3313 | 3365 | CDC_CLOSE_TRAY, info, &pos, CTL_CAPABILITY)) | |
| 3314 | pos += sprintf(info+pos, "\ndrive # of slots:"); | 3366 | goto done; |
| 3315 | for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) | 3367 | if (cdrom_print_info("\nCan open tray:\t", |
| 3316 | pos += sprintf(info+pos, "\t%d", cdi->capacity); | 3368 | CDC_OPEN_TRAY, info, &pos, CTL_CAPABILITY)) |
| 3317 | 3369 | goto done; | |
| 3318 | pos += sprintf(info+pos, "\nCan close tray:\t"); | 3370 | if (cdrom_print_info("\nCan lock tray:\t", |
| 3319 | for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) | 3371 | CDC_LOCK, info, &pos, CTL_CAPABILITY)) |
| 3320 | pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_CLOSE_TRAY) != 0); | 3372 | goto done; |
| 3321 | 3373 | if (cdrom_print_info("\nCan change speed:", | |
| 3322 | pos += sprintf(info+pos, "\nCan open tray:\t"); | 3374 | CDC_SELECT_SPEED, info, &pos, CTL_CAPABILITY)) |
| 3323 | for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) | 3375 | goto done; |
| 3324 | pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_OPEN_TRAY) != 0); | 3376 | if (cdrom_print_info("\nCan select disk:", |
| 3325 | 3377 | CDC_SELECT_DISC, info, &pos, CTL_CAPABILITY)) | |
| 3326 | pos += sprintf(info+pos, "\nCan lock tray:\t"); | 3378 | goto done; |
| 3327 | for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) | 3379 | if (cdrom_print_info("\nCan read multisession:", |
| 3328 | pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_LOCK) != 0); | 3380 | CDC_MULTI_SESSION, info, &pos, CTL_CAPABILITY)) |
| 3329 | 3381 | goto done; | |
| 3330 | pos += sprintf(info+pos, "\nCan change speed:"); | 3382 | if (cdrom_print_info("\nCan read MCN:\t", |
| 3331 | for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) | 3383 | CDC_MCN, info, &pos, CTL_CAPABILITY)) |
| 3332 | pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_SELECT_SPEED) != 0); | 3384 | goto done; |
| 3333 | 3385 | if (cdrom_print_info("\nReports media changed:", | |
| 3334 | pos += sprintf(info+pos, "\nCan select disk:"); | 3386 | CDC_MEDIA_CHANGED, info, &pos, CTL_CAPABILITY)) |
| 3335 | for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) | 3387 | goto done; |
| 3336 | pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_SELECT_DISC) != 0); | 3388 | if (cdrom_print_info("\nCan play audio:\t", |
| 3337 | 3389 | CDC_PLAY_AUDIO, info, &pos, CTL_CAPABILITY)) | |
| 3338 | pos += sprintf(info+pos, "\nCan read multisession:"); | 3390 | goto done; |
| 3339 | for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) | 3391 | if (cdrom_print_info("\nCan write CD-R:\t", |
| 3340 | pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_MULTI_SESSION) != 0); | 3392 | CDC_CD_R, info, &pos, CTL_CAPABILITY)) |
| 3341 | 3393 | goto done; | |
| 3342 | pos += sprintf(info+pos, "\nCan read MCN:\t"); | 3394 | if (cdrom_print_info("\nCan write CD-RW:", |
| 3343 | for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) | 3395 | CDC_CD_RW, info, &pos, CTL_CAPABILITY)) |
| 3344 | pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_MCN) != 0); | 3396 | goto done; |
| 3345 | 3397 | if (cdrom_print_info("\nCan read DVD:\t", | |
| 3346 | pos += sprintf(info+pos, "\nReports media changed:"); | 3398 | CDC_DVD, info, &pos, CTL_CAPABILITY)) |
| 3347 | for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) | 3399 | goto done; |
| 3348 | pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_MEDIA_CHANGED) != 0); | 3400 | if (cdrom_print_info("\nCan write DVD-R:", |
| 3349 | 3401 | CDC_DVD_R, info, &pos, CTL_CAPABILITY)) | |
| 3350 | pos += sprintf(info+pos, "\nCan play audio:\t"); | 3402 | goto done; |
| 3351 | for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) | 3403 | if (cdrom_print_info("\nCan write DVD-RAM:", |
| 3352 | pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_PLAY_AUDIO) != 0); | 3404 | CDC_DVD_RAM, info, &pos, CTL_CAPABILITY)) |
| 3353 | 3405 | goto done; | |
| 3354 | pos += sprintf(info+pos, "\nCan write CD-R:\t"); | 3406 | if (cdrom_print_info("\nCan read MRW:\t", |
| 3355 | for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) | 3407 | CDC_MRW, info, &pos, CTL_CAPABILITY)) |
| 3356 | pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_CD_R) != 0); | 3408 | goto done; |
| 3357 | 3409 | if (cdrom_print_info("\nCan write MRW:\t", | |
| 3358 | pos += sprintf(info+pos, "\nCan write CD-RW:"); | 3410 | CDC_MRW_W, info, &pos, CTL_CAPABILITY)) |
| 3359 | for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) | 3411 | goto done; |
| 3360 | pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_CD_RW) != 0); | 3412 | if (cdrom_print_info("\nCan write RAM:\t", |
| 3361 | 3413 | CDC_RAM, info, &pos, CTL_CAPABILITY)) | |
| 3362 | pos += sprintf(info+pos, "\nCan read DVD:\t"); | 3414 | goto done; |
| 3363 | for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) | 3415 | if (!scnprintf(info + pos, max_size - pos, "\n\n")) |
| 3364 | pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_DVD) != 0); | 3416 | goto done; |
| 3365 | 3417 | doit: | |
| 3366 | pos += sprintf(info+pos, "\nCan write DVD-R:"); | 3418 | mutex_unlock(&cdrom_mutex); |
| 3367 | for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) | 3419 | return proc_dostring(ctl, write, filp, buffer, lenp, ppos); |
| 3368 | pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_DVD_R) != 0); | 3420 | done: |
| 3369 | 3421 | printk(KERN_INFO "cdrom: info buffer too small\n"); | |
| 3370 | pos += sprintf(info+pos, "\nCan write DVD-RAM:"); | 3422 | goto doit; |
| 3371 | for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) | ||
| 3372 | pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_DVD_RAM) != 0); | ||
| 3373 | |||
| 3374 | pos += sprintf(info+pos, "\nCan read MRW:\t"); | ||
| 3375 | for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) | ||
| 3376 | pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_MRW) != 0); | ||
| 3377 | |||
| 3378 | pos += sprintf(info+pos, "\nCan write MRW:\t"); | ||
| 3379 | for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) | ||
| 3380 | pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_MRW_W) != 0); | ||
| 3381 | |||
| 3382 | pos += sprintf(info+pos, "\nCan write RAM:\t"); | ||
| 3383 | for (cdi=topCdromPtr;cdi!=NULL;cdi=cdi->next) | ||
| 3384 | pos += sprintf(info+pos, "\t%d", CDROM_CAN(CDC_RAM) != 0); | ||
| 3385 | |||
| 3386 | strcpy(info+pos,"\n\n"); | ||
| 3387 | |||
| 3388 | return proc_dostring(ctl, write, filp, buffer, lenp, ppos); | ||
| 3389 | } | 3423 | } |
| 3390 | 3424 | ||
| 3391 | /* Unfortunately, per device settings are not implemented through | 3425 | /* Unfortunately, per device settings are not implemented through |
