|
Lines 726-731
Link Here
|
| 726 |
struct ioc_read_subchannel *args = |
726 |
struct ioc_read_subchannel *args = |
| 727 |
(struct ioc_read_subchannel *)addr; |
727 |
(struct ioc_read_subchannel *)addr; |
| 728 |
struct cd_sub_channel_info data; |
728 |
struct cd_sub_channel_info data; |
|
|
729 |
u_int8_t format; |
| 730 |
int i; |
| 729 |
int len = args->data_len; |
731 |
int len = args->data_len; |
| 730 |
int32_t abslba, rellba; |
732 |
int32_t abslba, rellba; |
| 731 |
int8_t ccb[16] = { ATAPI_READ_SUBCHANNEL, 0, 0x40, 1, 0, 0, 0, |
733 |
int8_t ccb[16] = { ATAPI_READ_SUBCHANNEL, 0, 0x40, 1, 0, 0, 0, |
|
Lines 738-768
Link Here
|
| 738 |
break; |
740 |
break; |
| 739 |
} |
741 |
} |
| 740 |
|
742 |
|
|
|
743 |
format=args->data_format; |
| 744 |
if ((format != CD_CURRENT_POSITION) && |
| 745 |
(format != CD_MEDIA_CATALOG) && (format != CD_TRACK_INFO)) { |
| 746 |
error = EINVAL; |
| 747 |
break; |
| 748 |
} |
| 749 |
|
| 741 |
if ((error = atapi_queue_cmd(cdp->atp, ccb, (caddr_t)&cdp->subchan, |
750 |
if ((error = atapi_queue_cmd(cdp->atp, ccb, (caddr_t)&cdp->subchan, |
| 742 |
sizeof(cdp->subchan), ATPR_F_READ, 10, |
751 |
sizeof(cdp->subchan), ATPR_F_READ, 10, |
| 743 |
NULL, NULL))) { |
752 |
NULL, NULL))) { |
| 744 |
break; |
753 |
break; |
| 745 |
} |
754 |
} |
| 746 |
abslba = cdp->subchan.abslba; |
755 |
|
| 747 |
rellba = cdp->subchan.rellba; |
756 |
/* |
| 748 |
if (args->address_format == CD_MSF_FORMAT) { |
757 |
* Ask for media catalogue or track info only if no audio play |
| 749 |
lba2msf(ntohl(abslba), |
758 |
* operation is in progress or the drive will return an error. |
| 750 |
&data.what.position.absaddr.msf.minute, |
759 |
*/ |
| 751 |
&data.what.position.absaddr.msf.second, |
760 |
|
| 752 |
&data.what.position.absaddr.msf.frame); |
761 |
if ((format == CD_MEDIA_CATALOG) || (format == CD_TRACK_INFO)) { |
| 753 |
lba2msf(ntohl(rellba), |
762 |
if (cdp->subchan.header.audio_status == 0x11) { |
| 754 |
&data.what.position.reladdr.msf.minute, |
763 |
error = EINVAL; |
| 755 |
&data.what.position.reladdr.msf.second, |
764 |
break; |
| 756 |
&data.what.position.reladdr.msf.frame); |
765 |
} |
| 757 |
} else { |
766 |
|
| 758 |
data.what.position.absaddr.lba = abslba; |
767 |
ccb[3] = format; |
| 759 |
data.what.position.reladdr.lba = rellba; |
768 |
if (format == CD_TRACK_INFO) |
|
|
769 |
ccb[6] = args->track; |
| 770 |
|
| 771 |
if ((error = atapi_queue_cmd(cdp->atp, ccb, |
| 772 |
(caddr_t)&cdp->subchan, |
| 773 |
sizeof(cdp->subchan), ATPR_F_READ, |
| 774 |
10, NULL, NULL))) { |
| 775 |
break; |
| 776 |
} |
| 777 |
} |
| 778 |
|
| 779 |
data.header.audio_status = cdp->subchan.header.audio_status; |
| 780 |
data.header.data_len[0] = cdp->subchan.header.data_length >> 8; |
| 781 |
data.header.data_len[1] = cdp->subchan.header.data_length & 255; |
| 782 |
|
| 783 |
switch (format) { |
| 784 |
case CD_CURRENT_POSITION: |
| 785 |
{ |
| 786 |
abslba = cdp->subchan.what.position.abslba; |
| 787 |
rellba = cdp->subchan.what.position.rellba; |
| 788 |
if (args->address_format == CD_MSF_FORMAT) { |
| 789 |
lba2msf(ntohl(abslba), |
| 790 |
&data.what.position.absaddr.msf.minute, |
| 791 |
&data.what.position.absaddr.msf.second, |
| 792 |
&data.what.position.absaddr.msf.frame); |
| 793 |
lba2msf(ntohl(rellba - 150), |
| 794 |
&data.what.position.reladdr.msf.minute, |
| 795 |
&data.what.position.reladdr.msf.second, |
| 796 |
&data.what.position.reladdr.msf.frame); |
| 797 |
} else { |
| 798 |
data.what.position.absaddr.lba = abslba; |
| 799 |
data.what.position.reladdr.lba = rellba; |
| 800 |
} |
| 801 |
data.what.position.data_format = |
| 802 |
cdp->subchan.what.position.data_format; |
| 803 |
data.what.position.control = |
| 804 |
cdp->subchan.what.position.control & 0xf; |
| 805 |
data.what.position.addr_type = |
| 806 |
cdp->subchan.what.position.control >> 4; |
| 807 |
data.what.position.track_number = |
| 808 |
cdp->subchan.what.position.track; |
| 809 |
data.what.position.index_number = |
| 810 |
cdp->subchan.what.position.indx; |
| 811 |
break; |
| 812 |
} |
| 813 |
|
| 814 |
case CD_MEDIA_CATALOG: |
| 815 |
{ |
| 816 |
data.what.media_catalog.data_format = |
| 817 |
cdp->subchan.what.media_catalog.data_format; |
| 818 |
data.what.media_catalog.mc_valid = |
| 819 |
cdp->subchan.what.media_catalog.mc_valid; |
| 820 |
for(i = 0; i < 15; i++) |
| 821 |
data.what.media_catalog.mc_number[i] = |
| 822 |
cdp->subchan.what.media_catalog.mc_number[i]; |
| 823 |
break; |
| 824 |
} |
| 825 |
|
| 826 |
case CD_TRACK_INFO: |
| 827 |
{ |
| 828 |
data.what.track_info.data_format = |
| 829 |
cdp->subchan.what.track_info.data_format; |
| 830 |
data.what.track_info.control = |
| 831 |
cdp->subchan.what.track_info.control & 0xf; |
| 832 |
data.what.track_info.addr_type = |
| 833 |
cdp->subchan.what.track_info.control >> 4; |
| 834 |
data.what.track_info.track_number = |
| 835 |
cdp->subchan.what.track_info.track; |
| 836 |
data.what.track_info.ti_valid = |
| 837 |
cdp->subchan.what.track_info.ti_valid; |
| 838 |
for(i = 0; i < 15; i++) |
| 839 |
data.what.track_info.ti_number[i] = |
| 840 |
cdp->subchan.what.track_info.ti_number[i]; |
| 841 |
break; |
| 842 |
|
| 843 |
} |
| 760 |
} |
844 |
} |
| 761 |
data.header.audio_status = cdp->subchan.audio_status; |
|
|
| 762 |
data.what.position.control = cdp->subchan.control & 0xf; |
| 763 |
data.what.position.addr_type = cdp->subchan.control >> 4; |
| 764 |
data.what.position.track_number = cdp->subchan.track; |
| 765 |
data.what.position.index_number = cdp->subchan.indx; |
| 766 |
error = copyout(&data, args->data, len); |
845 |
error = copyout(&data, args->data, len); |
| 767 |
break; |
846 |
break; |
| 768 |
} |
847 |
} |