📄 cdu31a.c.txt
字号:
465 * how many more status bytes are coming.
466 *
467 * The result register can be read 10 bytes at a time, a wait for
468 * result ready to be asserted must be done between every 10 bytes.
469 */
470 if ((a & 0xf0) != 0x20)
471 {
472 if (b > 8)
473 {
474 for (i=0; i<8; i++)
475 {
476 *result_buffer = read_result_register();
477 result_buffer++;
478 (*result_size)++;
479 }
480 b = b - 8;
481
482 while (b > 10)
483 {
484 retry_count = SONY_READY_RETRIES;
485 while ((retry_count > 0) && (!is_result_ready()))
486 {
487 retry_count--;
488 }
489 if (!is_result_ready())
490 {
491 result_buffer[0] = 0x20;
492 result_buffer[1] = SONY_TIMEOUT_OP_ERR;
493 *result_size = 2;
494 return;
495 }
496
497 clear_result_ready();
498
499 for (i=0; i<10; i++)
500 {
501 *result_buffer = read_result_register();
502 result_buffer++;
503 (*result_size)++;
504 }
505 b = b - 10;
506 }
507
508 if (b > 0)
509 {
510 retry_count = SONY_READY_RETRIES;
511 while ((retry_count > 0) && (!is_result_ready()))
512 {
513 retry_count--;
514 }
515 if (!is_result_ready())
516 {
517 result_buffer[0] = 0x20;
518 result_buffer[1] = SONY_TIMEOUT_OP_ERR;
519 *result_size = 2;
520 return;
521 }
522 }
523 }
524
525 while (b > 0)
526 {
527 *result_buffer = read_result_register();
528 result_buffer++;
529 (*result_size)++;
530 b--;
531 }
532 }
533 }
534
535 /*
536 * Read in a 2048 byte block of data.
537 */
538 static void
539 read_data_block(unsigned char *data,
540 unsigned char *result_buffer,
541 unsigned int *result_size)
542 {
543 int i;
544 unsigned int retry_count;
545
546 for (i=0; i<2048; i++)
547 {
548 retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
549 while ((retry_count > jiffies) && (!is_data_requested()))
550 {
551 while (handle_sony_cd_attention())
552 ;
553
554 sony_sleep();
555 }
556 if (!is_data_requested())
557 {
558 result_buffer[0] = 0x20;
559 result_buffer[1] = SONY_TIMEOUT_OP_ERR;
560 *result_size = 2;
561 return;
562 }
563
564 *data = read_data_register();
565 data++;
566 }
567 }
568
569 /*
570 * This routine issues a read data command and gets the data. I don't
571 * really like the way this is done (I would prefer for do_sony_cmd() to
572 * handle it automatically) but I found that the drive returns status
573 * when it finishes reading (not when the host has read all the data)
574 * or after it gets an error. This means that the status can be
575 * received at any time and should be handled immediately (at least
576 * between every 2048 byte block) to check for errors, we can't wait
577 * until all the data is read.
578 *
579 * This routine returns the total number of sectors read. It will
580 * not return an error if it reads at least one sector successfully.
581 */
582 static unsigned int
583 get_data(unsigned char *orig_data,
584 unsigned char *params, /* 6 bytes with the MSF start address
585 and number of sectors to read. */
586 unsigned int orig_data_size,
587 unsigned char *result_buffer,
588 unsigned int *result_size)
589 {
590 unsigned int cur_offset;
591 unsigned int retry_count;
592 int result_read;
593 int num_retries;
594 unsigned int num_sectors_read = 0;
595 unsigned char *data = orig_data;
596 unsigned int data_size = orig_data_size;
597
598
599 cli();
600 while (sony_inuse)
601 {
602 interruptible_sleep_on(&sony_wait);
603 if (current->signal & ~current->blocked)
604 {
605 result_buffer[0] = 0x20;
606 result_buffer[1] = SONY_SIGNAL_OP_ERR;
607 *result_size = 2;
608 return 0;
609 }
610 }
611 sony_inuse = 1;
612 has_cd_task = current;
613 sti();
614
615 num_retries = 0;
616 retry_data_operation:
617 result_buffer[0] = 0;
618 result_buffer[1] = 0;
619
620 /*
621 * Clear any outstanding attentions and wait for the drive to
622 * complete any pending operations.
623 */
624 while (handle_sony_cd_attention())
625 ;
626
627 retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
628 while ((retry_count > jiffies) && (is_busy()))
629 {
630 sony_sleep();
631
632 while (handle_sony_cd_attention())
633 ;
634 }
635
636 if (is_busy())
637 {
638 result_buffer[0] = 0x20;
639 result_buffer[1] = SONY_TIMEOUT_OP_ERR;
640 *result_size = 2;
641 }
642 else
643 {
644 /* Issue the command */
645 clear_result_ready();
646 clear_param_reg();
647
648 write_params(params, 6);
649 write_cmd(SONY_READ_CMD);
650
651 /*
652 * Read the data from the drive one 2048 byte sector at a time. Handle
653 * any results received between sectors, if an error result is returned
654 * terminate the operation immediately.
655 */
656 cur_offset = 0;
657 result_read = 0;
658 while ((data_size > 0) && (result_buffer[0] == 0))
659 {
660 /* Wait for the drive to tell us we have something */
661 retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
662 while ((retry_count > jiffies) && (!(is_result_ready() || is_data_ready())))
663 {
664 while (handle_sony_cd_attention())
665 ;
666
667 sony_sleep();
668 }
669 if (!(is_result_ready() || is_data_ready()))
670 {
671 result_buffer[0] = 0x20;
672 result_buffer[1] = SONY_TIMEOUT_OP_ERR;
673 *result_size = 2;
674 }
675
676 /* Handle results first */
677 else if (is_result_ready())
678 {
679 result_read = 1;
680 get_result(result_buffer, result_size);
681 }
682 else /* Handle data next */
683 {
684 /*
685 * The drive has to be polled for status on a byte-by-byte basis
686 * to know if the data is ready. Yuck. I really wish I could use DMA.
687 */
688 clear_data_ready();
689 read_data_block(data, result_buffer, result_size);
690 data += 2048;
691 data_size -= 2048;
692 cur_offset = cur_offset + 2048;
693 num_sectors_read++;
694 }
695 }
696
697 /* Make sure the result has been read */
698 if (!result_read)
699 {
700 get_result(result_buffer, result_size);
701 }
702 }
703
704 if ( ((result_buffer[0] & 0x20) == 0x20)
705 && (result_buffer[1] != SONY_NOT_SPIN_ERR) /* No retry when not spin */
706 && (num_retries < MAX_CDU31A_RETRIES))
707 {
708 /*
709 * If an error occurs, go back and only read one sector at the
710 * given location. Hopefully the error occurred on an unused
711 * sector after the first one. It is hard to say which sector
712 * the error occurred on because the drive returns status before
713 * the data transfer is finished and doesn't say which sector.
714 */
715 data_size = 2048;
716 data = orig_data;
717 num_sectors_read = 0;
718 size_to_buf(1, ¶ms[3]);
719
720 num_retries++;
721 /* Issue a reset on an error (the second time), othersize just delay */
722 if (num_retries == 2)
723 {
724 restart_on_error();
725 }
726 else
727 {
728 current->state = TASK_INTERRUPTIBLE;
729 current->timeout = jiffies + 10;
730 schedule();
731 }
732
733 /* Restart the operation. */
734 goto retry_data_operation;
735 }
736
737 has_cd_task = NULL;
738 sony_inuse = 0;
739 wake_up_interruptible(&sony_wait);
740
741 return(num_sectors_read);
742 }
743
744
745 /*
746 * Do a command that does not involve data transfer. This routine must
747 * be re-entrant from the same task to support being called from the
748 * data operation code when an error occurs.
749 */
750 static void
751 do_sony_cd_cmd(unsigned char cmd,
752 unsigned char *params,
753 unsigned int num_params,
754 unsigned char *result_buffer,
755 unsigned int *result_size)
756 {
757 unsigned int retry_count;
758 int num_retries;
759 int recursive_call;
760
761
762 cli();
763 if (current != has_cd_task) /* Allow recursive calls to this routine */
764 {
765 while (sony_inuse)
766 {
767 interruptible_sleep_on(&sony_wait);
768 if (current->signal & ~current->blocked)
769 {
770 result_buffer[0] = 0x20;
771 result_buffer[1] = SONY_SIGNAL_OP_ERR;
772 *result_size = 2;
773 return;
774 }
775 }
776 sony_inuse = 1;
777 has_cd_task = current;
778 recursive_call = 0;
779 }
780 else
781 {
782 recursive_call = 1;
783 }
784 sti();
785
786 num_retries = 0;
787 retry_cd_operation:
788
789 while (handle_sony_cd_attention())
790 ;
791
792 retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
793 while ((retry_count > jiffies) && (is_busy()))
794 {
795 sony_sleep();
796
797 while (handle_sony_cd_attention())
798 ;
799 }
800 if (is_busy())
801 {
802 result_buffer[0] = 0x20;
803 result_buffer[1] = SONY_TIMEOUT_OP_ERR;
804 *result_size = 2;
805 }
806 else
807 {
808 clear_result_ready();
809 clear_param_reg();
810
811 write_params(params, num_params);
812 write_cmd(cmd);
813
814 get_result(result_buffer, result_size);
815 }
816
817 if ( ((result_buffer[0] & 0x20) == 0x20)
818 && (num_retries < MAX_CDU31A_RETRIES))
819 {
820 num_retries++;
821 current->state = TASK_INTERRUPTIBLE;
822 current->timeout = jiffies + 10; /* Wait .1 seconds on retries */
823 schedule();
824 goto retry_cd_operation;
825 }
826
827 if (!recursive_call)
828 {
829 has_cd_task = NULL;
830 sony_inuse = 0;
831 wake_up_interruptible(&sony_wait);
832 }
833 }
834
835
836 /*
837 * Handle an attention from the drive. This will return 1 if it found one
838 * or 0 if not (if one is found, the caller might want to call again).
839 *
840 * This routine counts the number of consecutive times it is called
841 * (since this is always called from a while loop until it returns
842 * a 0), and returns a 0 if it happens too many times. This will help
843 * prevent a lockup.
844 */
845 static int
846 handle_sony_cd_attention(void)
847 {
848 unsigned char atten_code;
849 static int num_consecutive_attentions = 0;
850
851
852 if (is_attention())
853 {
854 if (num_consecutive_attentions > CDU31A_MAX_CONSECUTIVE_ATTENTIONS)
855 {
856 printk("cdu31a: Too many consecutive attentions: %d\n",
857 num_consecutive_attentions);
858 num_consecutive_attentions = 0;
859 return(0);
860 }
861
862 clear_attention();
863 atten_code = read_result_register();
864
865 switch (atten_code)
866 {
867 /* Someone changed the CD. Mark it as changed */
868 case SONY_MECH_LOADED_ATTN:
869 sony_disc_changed = 1;
870 sony_toc_read = 0;
871 sony_audio_status = CDROM_AUDIO_NO_STATUS;
872 sony_first_block = -1;
873 sony_last_block = -1;
874 break;
875
876 case SONY_AUDIO_PLAY_DONE_ATTN:
877 sony_audio_status = CDROM_AUDIO_COMPLETED;
878 read_subcode();
879 break;
880
881 case SONY_EJECT_PUSHED_ATTN:
882 sony_audio_status = CDROM_AUDIO_INVALID;
883 break;
884
885 case SONY_LEAD_IN_ERR_ATTN:
886 case SONY_LEAD_OUT_ERR_ATTN:
887 case SONY_DATA_TRACK_ERR_ATTN:
888 case SONY_AUDIO_PLAYBACK_ERR_ATTN:
889 sony_audio_status = CDROM_AUDIO_ERROR;
890 break;
891 }
892
893 num_consecutive_attentions++;
894 return(1);
895 }
896
897 num_consecutive_attentions = 0;
898 return(0);
899 }
900
901
902 /* Convert from an integer 0-99 to BCD */
903 static inline unsigned int
904 int_to_bcd(unsigned int val)
905 {
906 int retval;
907
908
909 retval = (val / 10) << 4;
910 retval = retval | val % 10;
911 return(retval);
912 }
913
914
915 /* Convert from BCD to an integer from 0-99 */
916 static unsigned int
917 bcd_to_int(unsigned int bcd)
918 {
919 return((((bcd >> 4) & 0x0f) * 10) + (bcd & 0x0f));
920 }
921
922
923 /*
924 * Convert a logical sector value (like the OS would want to use for
925 * a block device) to an MSF format.
926 */
927 static void
928 log_to_msf(unsigned int log, unsigned char *msf)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -