diff options
Diffstat (limited to 'drivers/ide/ide-cd.c')
-rw-r--r-- | drivers/ide/ide-cd.c | 98 |
1 files changed, 61 insertions, 37 deletions
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index 2de76cc08f61..31fc76960a8f 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/delay.h> | 31 | #include <linux/delay.h> |
32 | #include <linux/timer.h> | 32 | #include <linux/timer.h> |
33 | #include <linux/seq_file.h> | 33 | #include <linux/seq_file.h> |
34 | #include <linux/smp_lock.h> | ||
34 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
35 | #include <linux/interrupt.h> | 36 | #include <linux/interrupt.h> |
36 | #include <linux/errno.h> | 37 | #include <linux/errno.h> |
@@ -176,7 +177,7 @@ static void cdrom_analyze_sense_data(ide_drive_t *drive, | |||
176 | if (!sense->valid) | 177 | if (!sense->valid) |
177 | break; | 178 | break; |
178 | if (failed_command == NULL || | 179 | if (failed_command == NULL || |
179 | !blk_fs_request(failed_command)) | 180 | failed_command->cmd_type != REQ_TYPE_FS) |
180 | break; | 181 | break; |
181 | sector = (sense->information[0] << 24) | | 182 | sector = (sense->information[0] << 24) | |
182 | (sense->information[1] << 16) | | 183 | (sense->information[1] << 16) | |
@@ -292,7 +293,7 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) | |||
292 | "stat 0x%x", | 293 | "stat 0x%x", |
293 | rq->cmd[0], rq->cmd_type, err, stat); | 294 | rq->cmd[0], rq->cmd_type, err, stat); |
294 | 295 | ||
295 | if (blk_sense_request(rq)) { | 296 | if (rq->cmd_type == REQ_TYPE_SENSE) { |
296 | /* | 297 | /* |
297 | * We got an error trying to get sense info from the drive | 298 | * We got an error trying to get sense info from the drive |
298 | * (probably while trying to recover from a former error). | 299 | * (probably while trying to recover from a former error). |
@@ -303,7 +304,7 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) | |||
303 | } | 304 | } |
304 | 305 | ||
305 | /* if we have an error, pass CHECK_CONDITION as the SCSI status byte */ | 306 | /* if we have an error, pass CHECK_CONDITION as the SCSI status byte */ |
306 | if (blk_pc_request(rq) && !rq->errors) | 307 | if (rq->cmd_type == REQ_TYPE_BLOCK_PC && !rq->errors) |
307 | rq->errors = SAM_STAT_CHECK_CONDITION; | 308 | rq->errors = SAM_STAT_CHECK_CONDITION; |
308 | 309 | ||
309 | if (blk_noretry_request(rq)) | 310 | if (blk_noretry_request(rq)) |
@@ -311,13 +312,14 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) | |||
311 | 312 | ||
312 | switch (sense_key) { | 313 | switch (sense_key) { |
313 | case NOT_READY: | 314 | case NOT_READY: |
314 | if (blk_fs_request(rq) && rq_data_dir(rq) == WRITE) { | 315 | if (rq->cmd_type == REQ_TYPE_FS && rq_data_dir(rq) == WRITE) { |
315 | if (ide_cd_breathe(drive, rq)) | 316 | if (ide_cd_breathe(drive, rq)) |
316 | return 1; | 317 | return 1; |
317 | } else { | 318 | } else { |
318 | cdrom_saw_media_change(drive); | 319 | cdrom_saw_media_change(drive); |
319 | 320 | ||
320 | if (blk_fs_request(rq) && !blk_rq_quiet(rq)) | 321 | if (rq->cmd_type == REQ_TYPE_FS && |
322 | !(rq->cmd_flags & REQ_QUIET)) | ||
321 | printk(KERN_ERR PFX "%s: tray open\n", | 323 | printk(KERN_ERR PFX "%s: tray open\n", |
322 | drive->name); | 324 | drive->name); |
323 | } | 325 | } |
@@ -326,7 +328,7 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) | |||
326 | case UNIT_ATTENTION: | 328 | case UNIT_ATTENTION: |
327 | cdrom_saw_media_change(drive); | 329 | cdrom_saw_media_change(drive); |
328 | 330 | ||
329 | if (blk_fs_request(rq) == 0) | 331 | if (rq->cmd_type != REQ_TYPE_FS) |
330 | return 0; | 332 | return 0; |
331 | 333 | ||
332 | /* | 334 | /* |
@@ -352,7 +354,7 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) | |||
352 | * No point in retrying after an illegal request or data | 354 | * No point in retrying after an illegal request or data |
353 | * protect error. | 355 | * protect error. |
354 | */ | 356 | */ |
355 | if (!blk_rq_quiet(rq)) | 357 | if (!(rq->cmd_flags & REQ_QUIET)) |
356 | ide_dump_status(drive, "command error", stat); | 358 | ide_dump_status(drive, "command error", stat); |
357 | do_end_request = 1; | 359 | do_end_request = 1; |
358 | break; | 360 | break; |
@@ -361,20 +363,20 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) | |||
361 | * No point in re-trying a zillion times on a bad sector. | 363 | * No point in re-trying a zillion times on a bad sector. |
362 | * If we got here the error is not correctable. | 364 | * If we got here the error is not correctable. |
363 | */ | 365 | */ |
364 | if (!blk_rq_quiet(rq)) | 366 | if (!(rq->cmd_flags & REQ_QUIET)) |
365 | ide_dump_status(drive, "media error " | 367 | ide_dump_status(drive, "media error " |
366 | "(bad sector)", stat); | 368 | "(bad sector)", stat); |
367 | do_end_request = 1; | 369 | do_end_request = 1; |
368 | break; | 370 | break; |
369 | case BLANK_CHECK: | 371 | case BLANK_CHECK: |
370 | /* disk appears blank? */ | 372 | /* disk appears blank? */ |
371 | if (!blk_rq_quiet(rq)) | 373 | if (!(rq->cmd_flags & REQ_QUIET)) |
372 | ide_dump_status(drive, "media error (blank)", | 374 | ide_dump_status(drive, "media error (blank)", |
373 | stat); | 375 | stat); |
374 | do_end_request = 1; | 376 | do_end_request = 1; |
375 | break; | 377 | break; |
376 | default: | 378 | default: |
377 | if (blk_fs_request(rq) == 0) | 379 | if (rq->cmd_type != REQ_TYPE_FS) |
378 | break; | 380 | break; |
379 | if (err & ~ATA_ABORTED) { | 381 | if (err & ~ATA_ABORTED) { |
380 | /* go to the default handler for other errors */ | 382 | /* go to the default handler for other errors */ |
@@ -385,7 +387,7 @@ static int cdrom_decode_status(ide_drive_t *drive, u8 stat) | |||
385 | do_end_request = 1; | 387 | do_end_request = 1; |
386 | } | 388 | } |
387 | 389 | ||
388 | if (blk_fs_request(rq) == 0) { | 390 | if (rq->cmd_type != REQ_TYPE_FS) { |
389 | rq->cmd_flags |= REQ_FAILED; | 391 | rq->cmd_flags |= REQ_FAILED; |
390 | do_end_request = 1; | 392 | do_end_request = 1; |
391 | } | 393 | } |
@@ -532,7 +534,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) | |||
532 | ide_expiry_t *expiry = NULL; | 534 | ide_expiry_t *expiry = NULL; |
533 | int dma_error = 0, dma, thislen, uptodate = 0; | 535 | int dma_error = 0, dma, thislen, uptodate = 0; |
534 | int write = (rq_data_dir(rq) == WRITE) ? 1 : 0, rc = 0; | 536 | int write = (rq_data_dir(rq) == WRITE) ? 1 : 0, rc = 0; |
535 | int sense = blk_sense_request(rq); | 537 | int sense = (rq->cmd_type == REQ_TYPE_SENSE); |
536 | unsigned int timeout; | 538 | unsigned int timeout; |
537 | u16 len; | 539 | u16 len; |
538 | u8 ireason, stat; | 540 | u8 ireason, stat; |
@@ -575,7 +577,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) | |||
575 | 577 | ||
576 | ide_read_bcount_and_ireason(drive, &len, &ireason); | 578 | ide_read_bcount_and_ireason(drive, &len, &ireason); |
577 | 579 | ||
578 | thislen = blk_fs_request(rq) ? len : cmd->nleft; | 580 | thislen = (rq->cmd_type == REQ_TYPE_FS) ? len : cmd->nleft; |
579 | if (thislen > len) | 581 | if (thislen > len) |
580 | thislen = len; | 582 | thislen = len; |
581 | 583 | ||
@@ -584,7 +586,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) | |||
584 | 586 | ||
585 | /* If DRQ is clear, the command has completed. */ | 587 | /* If DRQ is clear, the command has completed. */ |
586 | if ((stat & ATA_DRQ) == 0) { | 588 | if ((stat & ATA_DRQ) == 0) { |
587 | if (blk_fs_request(rq)) { | 589 | if (rq->cmd_type == REQ_TYPE_FS) { |
588 | /* | 590 | /* |
589 | * If we're not done reading/writing, complain. | 591 | * If we're not done reading/writing, complain. |
590 | * Otherwise, complete the command normally. | 592 | * Otherwise, complete the command normally. |
@@ -598,7 +600,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) | |||
598 | rq->cmd_flags |= REQ_FAILED; | 600 | rq->cmd_flags |= REQ_FAILED; |
599 | uptodate = 0; | 601 | uptodate = 0; |
600 | } | 602 | } |
601 | } else if (!blk_pc_request(rq)) { | 603 | } else if (rq->cmd_type != REQ_TYPE_BLOCK_PC) { |
602 | ide_cd_request_sense_fixup(drive, cmd); | 604 | ide_cd_request_sense_fixup(drive, cmd); |
603 | 605 | ||
604 | uptodate = cmd->nleft ? 0 : 1; | 606 | uptodate = cmd->nleft ? 0 : 1; |
@@ -647,7 +649,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) | |||
647 | 649 | ||
648 | /* pad, if necessary */ | 650 | /* pad, if necessary */ |
649 | if (len > 0) { | 651 | if (len > 0) { |
650 | if (blk_fs_request(rq) == 0 || write == 0) | 652 | if (rq->cmd_type != REQ_TYPE_FS || write == 0) |
651 | ide_pad_transfer(drive, write, len); | 653 | ide_pad_transfer(drive, write, len); |
652 | else { | 654 | else { |
653 | printk(KERN_ERR PFX "%s: confused, missing data\n", | 655 | printk(KERN_ERR PFX "%s: confused, missing data\n", |
@@ -656,11 +658,11 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) | |||
656 | } | 658 | } |
657 | } | 659 | } |
658 | 660 | ||
659 | if (blk_pc_request(rq)) { | 661 | if (rq->cmd_type == REQ_TYPE_BLOCK_PC) { |
660 | timeout = rq->timeout; | 662 | timeout = rq->timeout; |
661 | } else { | 663 | } else { |
662 | timeout = ATAPI_WAIT_PC; | 664 | timeout = ATAPI_WAIT_PC; |
663 | if (!blk_fs_request(rq)) | 665 | if (rq->cmd_type != REQ_TYPE_FS) |
664 | expiry = ide_cd_expiry; | 666 | expiry = ide_cd_expiry; |
665 | } | 667 | } |
666 | 668 | ||
@@ -669,7 +671,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive) | |||
669 | return ide_started; | 671 | return ide_started; |
670 | 672 | ||
671 | out_end: | 673 | out_end: |
672 | if (blk_pc_request(rq) && rc == 0) { | 674 | if (rq->cmd_type == REQ_TYPE_BLOCK_PC && rc == 0) { |
673 | rq->resid_len = 0; | 675 | rq->resid_len = 0; |
674 | blk_end_request_all(rq, 0); | 676 | blk_end_request_all(rq, 0); |
675 | hwif->rq = NULL; | 677 | hwif->rq = NULL; |
@@ -677,7 +679,7 @@ out_end: | |||
677 | if (sense && uptodate) | 679 | if (sense && uptodate) |
678 | ide_cd_complete_failed_rq(drive, rq); | 680 | ide_cd_complete_failed_rq(drive, rq); |
679 | 681 | ||
680 | if (blk_fs_request(rq)) { | 682 | if (rq->cmd_type == REQ_TYPE_FS) { |
681 | if (cmd->nleft == 0) | 683 | if (cmd->nleft == 0) |
682 | uptodate = 1; | 684 | uptodate = 1; |
683 | } else { | 685 | } else { |
@@ -690,7 +692,7 @@ out_end: | |||
690 | return ide_stopped; | 692 | return ide_stopped; |
691 | 693 | ||
692 | /* make sure it's fully ended */ | 694 | /* make sure it's fully ended */ |
693 | if (blk_fs_request(rq) == 0) { | 695 | if (rq->cmd_type != REQ_TYPE_FS) { |
694 | rq->resid_len -= cmd->nbytes - cmd->nleft; | 696 | rq->resid_len -= cmd->nbytes - cmd->nleft; |
695 | if (uptodate == 0 && (cmd->tf_flags & IDE_TFLAG_WRITE)) | 697 | if (uptodate == 0 && (cmd->tf_flags & IDE_TFLAG_WRITE)) |
696 | rq->resid_len += cmd->last_xfer_len; | 698 | rq->resid_len += cmd->last_xfer_len; |
@@ -750,7 +752,7 @@ static void cdrom_do_block_pc(ide_drive_t *drive, struct request *rq) | |||
750 | ide_debug_log(IDE_DBG_PC, "rq->cmd[0]: 0x%x, rq->cmd_type: 0x%x", | 752 | ide_debug_log(IDE_DBG_PC, "rq->cmd[0]: 0x%x, rq->cmd_type: 0x%x", |
751 | rq->cmd[0], rq->cmd_type); | 753 | rq->cmd[0], rq->cmd_type); |
752 | 754 | ||
753 | if (blk_pc_request(rq)) | 755 | if (rq->cmd_type == REQ_TYPE_BLOCK_PC) |
754 | rq->cmd_flags |= REQ_QUIET; | 756 | rq->cmd_flags |= REQ_QUIET; |
755 | else | 757 | else |
756 | rq->cmd_flags &= ~REQ_FAILED; | 758 | rq->cmd_flags &= ~REQ_FAILED; |
@@ -791,21 +793,26 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, | |||
791 | if (drive->debug_mask & IDE_DBG_RQ) | 793 | if (drive->debug_mask & IDE_DBG_RQ) |
792 | blk_dump_rq_flags(rq, "ide_cd_do_request"); | 794 | blk_dump_rq_flags(rq, "ide_cd_do_request"); |
793 | 795 | ||
794 | if (blk_fs_request(rq)) { | 796 | switch (rq->cmd_type) { |
797 | case REQ_TYPE_FS: | ||
795 | if (cdrom_start_rw(drive, rq) == ide_stopped) | 798 | if (cdrom_start_rw(drive, rq) == ide_stopped) |
796 | goto out_end; | 799 | goto out_end; |
797 | } else if (blk_sense_request(rq) || blk_pc_request(rq) || | 800 | break; |
798 | rq->cmd_type == REQ_TYPE_ATA_PC) { | 801 | case REQ_TYPE_SENSE: |
802 | case REQ_TYPE_BLOCK_PC: | ||
803 | case REQ_TYPE_ATA_PC: | ||
799 | if (!rq->timeout) | 804 | if (!rq->timeout) |
800 | rq->timeout = ATAPI_WAIT_PC; | 805 | rq->timeout = ATAPI_WAIT_PC; |
801 | 806 | ||
802 | cdrom_do_block_pc(drive, rq); | 807 | cdrom_do_block_pc(drive, rq); |
803 | } else if (blk_special_request(rq)) { | 808 | break; |
809 | case REQ_TYPE_SPECIAL: | ||
804 | /* right now this can only be a reset... */ | 810 | /* right now this can only be a reset... */ |
805 | uptodate = 1; | 811 | uptodate = 1; |
806 | goto out_end; | 812 | goto out_end; |
807 | } else | 813 | default: |
808 | BUG(); | 814 | BUG(); |
815 | } | ||
809 | 816 | ||
810 | /* prepare sense request for this command */ | 817 | /* prepare sense request for this command */ |
811 | ide_prep_sense(drive, rq); | 818 | ide_prep_sense(drive, rq); |
@@ -817,7 +824,7 @@ static ide_startstop_t ide_cd_do_request(ide_drive_t *drive, struct request *rq, | |||
817 | 824 | ||
818 | cmd.rq = rq; | 825 | cmd.rq = rq; |
819 | 826 | ||
820 | if (blk_fs_request(rq) || blk_rq_bytes(rq)) { | 827 | if (rq->cmd_type == REQ_TYPE_FS || blk_rq_bytes(rq)) { |
821 | ide_init_sg_cmd(&cmd, blk_rq_bytes(rq)); | 828 | ide_init_sg_cmd(&cmd, blk_rq_bytes(rq)); |
822 | ide_map_sg(drive, &cmd); | 829 | ide_map_sg(drive, &cmd); |
823 | } | 830 | } |
@@ -1373,9 +1380,9 @@ static int ide_cdrom_prep_pc(struct request *rq) | |||
1373 | 1380 | ||
1374 | static int ide_cdrom_prep_fn(struct request_queue *q, struct request *rq) | 1381 | static int ide_cdrom_prep_fn(struct request_queue *q, struct request *rq) |
1375 | { | 1382 | { |
1376 | if (blk_fs_request(rq)) | 1383 | if (rq->cmd_type == REQ_TYPE_FS) |
1377 | return ide_cdrom_prep_fs(q, rq); | 1384 | return ide_cdrom_prep_fs(q, rq); |
1378 | else if (blk_pc_request(rq)) | 1385 | else if (rq->cmd_type == REQ_TYPE_BLOCK_PC) |
1379 | return ide_cdrom_prep_pc(rq); | 1386 | return ide_cdrom_prep_pc(rq); |
1380 | 1387 | ||
1381 | return 0; | 1388 | return 0; |
@@ -1592,17 +1599,19 @@ static struct ide_driver ide_cdrom_driver = { | |||
1592 | 1599 | ||
1593 | static int idecd_open(struct block_device *bdev, fmode_t mode) | 1600 | static int idecd_open(struct block_device *bdev, fmode_t mode) |
1594 | { | 1601 | { |
1595 | struct cdrom_info *info = ide_cd_get(bdev->bd_disk); | 1602 | struct cdrom_info *info; |
1596 | int rc = -ENOMEM; | 1603 | int rc = -ENXIO; |
1597 | 1604 | ||
1605 | lock_kernel(); | ||
1606 | info = ide_cd_get(bdev->bd_disk); | ||
1598 | if (!info) | 1607 | if (!info) |
1599 | return -ENXIO; | 1608 | goto out; |
1600 | 1609 | ||
1601 | rc = cdrom_open(&info->devinfo, bdev, mode); | 1610 | rc = cdrom_open(&info->devinfo, bdev, mode); |
1602 | |||
1603 | if (rc < 0) | 1611 | if (rc < 0) |
1604 | ide_cd_put(info); | 1612 | ide_cd_put(info); |
1605 | 1613 | out: | |
1614 | unlock_kernel(); | ||
1606 | return rc; | 1615 | return rc; |
1607 | } | 1616 | } |
1608 | 1617 | ||
@@ -1610,9 +1619,11 @@ static int idecd_release(struct gendisk *disk, fmode_t mode) | |||
1610 | { | 1619 | { |
1611 | struct cdrom_info *info = ide_drv_g(disk, cdrom_info); | 1620 | struct cdrom_info *info = ide_drv_g(disk, cdrom_info); |
1612 | 1621 | ||
1622 | lock_kernel(); | ||
1613 | cdrom_release(&info->devinfo, mode); | 1623 | cdrom_release(&info->devinfo, mode); |
1614 | 1624 | ||
1615 | ide_cd_put(info); | 1625 | ide_cd_put(info); |
1626 | unlock_kernel(); | ||
1616 | 1627 | ||
1617 | return 0; | 1628 | return 0; |
1618 | } | 1629 | } |
@@ -1656,7 +1667,7 @@ static int idecd_get_spindown(struct cdrom_device_info *cdi, unsigned long arg) | |||
1656 | return 0; | 1667 | return 0; |
1657 | } | 1668 | } |
1658 | 1669 | ||
1659 | static int idecd_ioctl(struct block_device *bdev, fmode_t mode, | 1670 | static int idecd_locked_ioctl(struct block_device *bdev, fmode_t mode, |
1660 | unsigned int cmd, unsigned long arg) | 1671 | unsigned int cmd, unsigned long arg) |
1661 | { | 1672 | { |
1662 | struct cdrom_info *info = ide_drv_g(bdev->bd_disk, cdrom_info); | 1673 | struct cdrom_info *info = ide_drv_g(bdev->bd_disk, cdrom_info); |
@@ -1678,6 +1689,19 @@ static int idecd_ioctl(struct block_device *bdev, fmode_t mode, | |||
1678 | return err; | 1689 | return err; |
1679 | } | 1690 | } |
1680 | 1691 | ||
1692 | static int idecd_ioctl(struct block_device *bdev, fmode_t mode, | ||
1693 | unsigned int cmd, unsigned long arg) | ||
1694 | { | ||
1695 | int ret; | ||
1696 | |||
1697 | lock_kernel(); | ||
1698 | ret = idecd_locked_ioctl(bdev, mode, cmd, arg); | ||
1699 | unlock_kernel(); | ||
1700 | |||
1701 | return ret; | ||
1702 | } | ||
1703 | |||
1704 | |||
1681 | static int idecd_media_changed(struct gendisk *disk) | 1705 | static int idecd_media_changed(struct gendisk *disk) |
1682 | { | 1706 | { |
1683 | struct cdrom_info *info = ide_drv_g(disk, cdrom_info); | 1707 | struct cdrom_info *info = ide_drv_g(disk, cdrom_info); |
@@ -1698,7 +1722,7 @@ static const struct block_device_operations idecd_ops = { | |||
1698 | .owner = THIS_MODULE, | 1722 | .owner = THIS_MODULE, |
1699 | .open = idecd_open, | 1723 | .open = idecd_open, |
1700 | .release = idecd_release, | 1724 | .release = idecd_release, |
1701 | .locked_ioctl = idecd_ioctl, | 1725 | .ioctl = idecd_ioctl, |
1702 | .media_changed = idecd_media_changed, | 1726 | .media_changed = idecd_media_changed, |
1703 | .revalidate_disk = idecd_revalidate_disk | 1727 | .revalidate_disk = idecd_revalidate_disk |
1704 | }; | 1728 | }; |