diff options
-rw-r--r-- | sound/sparc/dbri.c | 40 |
1 files changed, 17 insertions, 23 deletions
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c index 405c603717b6..0b8545ad3e9a 100644 --- a/sound/sparc/dbri.c +++ b/sound/sparc/dbri.c | |||
@@ -250,6 +250,7 @@ static struct { | |||
250 | #define DBRI_NO_STREAMS 2 | 250 | #define DBRI_NO_STREAMS 2 |
251 | 251 | ||
252 | /* One transmit/receive descriptor */ | 252 | /* One transmit/receive descriptor */ |
253 | /* When ba != 0 descriptor is used */ | ||
253 | struct dbri_mem { | 254 | struct dbri_mem { |
254 | volatile __u32 word1; | 255 | volatile __u32 word1; |
255 | __u32 ba; /* Transmit/Receive Buffer Address */ | 256 | __u32 ba; /* Transmit/Receive Buffer Address */ |
@@ -282,12 +283,6 @@ struct dbri_pipe { | |||
282 | volatile __u32 *recv_fixed_ptr; /* Ptr to receive fixed data */ | 283 | volatile __u32 *recv_fixed_ptr; /* Ptr to receive fixed data */ |
283 | }; | 284 | }; |
284 | 285 | ||
285 | struct dbri_desc { | ||
286 | int inuse; /* Boolean flag */ | ||
287 | int next; /* Index of next desc, or -1 */ | ||
288 | unsigned int len; | ||
289 | }; | ||
290 | |||
291 | /* Per stream (playback or record) information */ | 286 | /* Per stream (playback or record) information */ |
292 | struct dbri_streaminfo { | 287 | struct dbri_streaminfo { |
293 | struct snd_pcm_substream *substream; | 288 | struct snd_pcm_substream *substream; |
@@ -317,7 +312,7 @@ struct snd_dbri { | |||
317 | int wait_ackd; /* sequence of command buffers acknowledged */ | 312 | int wait_ackd; /* sequence of command buffers acknowledged */ |
318 | 313 | ||
319 | struct dbri_pipe pipes[DBRI_NO_PIPES]; /* DBRI's 32 data pipes */ | 314 | struct dbri_pipe pipes[DBRI_NO_PIPES]; /* DBRI's 32 data pipes */ |
320 | struct dbri_desc descs[DBRI_NO_DESCS]; | 315 | int next_desc[DBRI_NO_DESCS]; /* Index of next desc, or -1 */ |
321 | 316 | ||
322 | int chi_in_pipe; | 317 | int chi_in_pipe; |
323 | int chi_out_pipe; | 318 | int chi_out_pipe; |
@@ -803,8 +798,8 @@ static void reset_pipe(struct snd_dbri * dbri, int pipe) | |||
803 | 798 | ||
804 | desc = dbri->pipes[pipe].first_desc; | 799 | desc = dbri->pipes[pipe].first_desc; |
805 | while (desc != -1) { | 800 | while (desc != -1) { |
806 | dbri->descs[desc].inuse = 0; | 801 | dbri->dma->desc[desc].nda = dbri->dma->desc[desc].ba = 0; |
807 | desc = dbri->descs[desc].next; | 802 | desc = dbri->next_desc[desc]; |
808 | } | 803 | } |
809 | 804 | ||
810 | dbri->pipes[pipe].desc = -1; | 805 | dbri->pipes[pipe].desc = -1; |
@@ -1093,7 +1088,7 @@ static int setup_descs(struct snd_dbri * dbri, int streamno, unsigned int period | |||
1093 | int mylen; | 1088 | int mylen; |
1094 | 1089 | ||
1095 | for (; desc < DBRI_NO_DESCS; desc++) { | 1090 | for (; desc < DBRI_NO_DESCS; desc++) { |
1096 | if (!dbri->descs[desc].inuse) | 1091 | if (!dbri->dma->desc[desc].ba) |
1097 | break; | 1092 | break; |
1098 | } | 1093 | } |
1099 | if (desc == DBRI_NO_DESCS) { | 1094 | if (desc == DBRI_NO_DESCS) { |
@@ -1110,19 +1105,16 @@ static int setup_descs(struct snd_dbri * dbri, int streamno, unsigned int period | |||
1110 | mylen = period; | 1105 | mylen = period; |
1111 | } | 1106 | } |
1112 | 1107 | ||
1113 | dbri->descs[desc].inuse = 1; | 1108 | dbri->next_desc[desc] = -1; |
1114 | dbri->descs[desc].next = -1; | ||
1115 | dbri->dma->desc[desc].ba = dvma_buffer; | 1109 | dbri->dma->desc[desc].ba = dvma_buffer; |
1116 | dbri->dma->desc[desc].nda = 0; | 1110 | dbri->dma->desc[desc].nda = 0; |
1117 | 1111 | ||
1118 | if (streamno == DBRI_PLAY) { | 1112 | if (streamno == DBRI_PLAY) { |
1119 | dbri->descs[desc].len = mylen; | ||
1120 | dbri->dma->desc[desc].word1 = DBRI_TD_CNT(mylen); | 1113 | dbri->dma->desc[desc].word1 = DBRI_TD_CNT(mylen); |
1121 | dbri->dma->desc[desc].word4 = 0; | 1114 | dbri->dma->desc[desc].word4 = 0; |
1122 | if (first_desc != -1) | 1115 | if (first_desc != -1) |
1123 | dbri->dma->desc[desc].word1 |= DBRI_TD_M; | 1116 | dbri->dma->desc[desc].word1 |= DBRI_TD_M; |
1124 | } else { | 1117 | } else { |
1125 | dbri->descs[desc].len = 0; | ||
1126 | dbri->dma->desc[desc].word1 = 0; | 1118 | dbri->dma->desc[desc].word1 = 0; |
1127 | dbri->dma->desc[desc].word4 = | 1119 | dbri->dma->desc[desc].word4 = |
1128 | DBRI_RD_B | DBRI_RD_BCNT(mylen); | 1120 | DBRI_RD_B | DBRI_RD_BCNT(mylen); |
@@ -1131,7 +1123,7 @@ static int setup_descs(struct snd_dbri * dbri, int streamno, unsigned int period | |||
1131 | if (first_desc == -1) { | 1123 | if (first_desc == -1) { |
1132 | first_desc = desc; | 1124 | first_desc = desc; |
1133 | } else { | 1125 | } else { |
1134 | dbri->descs[last_desc].next = desc; | 1126 | dbri->next_desc[last_desc] = desc; |
1135 | dbri->dma->desc[last_desc].nda = | 1127 | dbri->dma->desc[last_desc].nda = |
1136 | dbri->dma_dvma + dbri_dma_off(desc, desc); | 1128 | dbri->dma_dvma + dbri_dma_off(desc, desc); |
1137 | } | 1129 | } |
@@ -1154,7 +1146,7 @@ static int setup_descs(struct snd_dbri * dbri, int streamno, unsigned int period | |||
1154 | dbri->pipes[info->pipe].first_desc = first_desc; | 1146 | dbri->pipes[info->pipe].first_desc = first_desc; |
1155 | dbri->pipes[info->pipe].desc = first_desc; | 1147 | dbri->pipes[info->pipe].desc = first_desc; |
1156 | 1148 | ||
1157 | for (desc = first_desc; desc != -1; desc = dbri->descs[desc].next) { | 1149 | for (desc = first_desc; desc != -1; desc = dbri->next_desc[desc]) { |
1158 | dprintk(D_DESC, "DESC %d: %08x %08x %08x %08x\n", | 1150 | dprintk(D_DESC, "DESC %d: %08x %08x %08x %08x\n", |
1159 | desc, | 1151 | desc, |
1160 | dbri->dma->desc[desc].word1, | 1152 | dbri->dma->desc[desc].word1, |
@@ -1747,6 +1739,7 @@ static void transmission_complete_intr(struct snd_dbri * dbri, int pipe) | |||
1747 | struct dbri_streaminfo *info; | 1739 | struct dbri_streaminfo *info; |
1748 | int td; | 1740 | int td; |
1749 | int status; | 1741 | int status; |
1742 | int len; | ||
1750 | 1743 | ||
1751 | info = &dbri->stream_info[DBRI_PLAY]; | 1744 | info = &dbri->stream_info[DBRI_PLAY]; |
1752 | 1745 | ||
@@ -1765,11 +1758,12 @@ static void transmission_complete_intr(struct snd_dbri * dbri, int pipe) | |||
1765 | dprintk(D_INT, "TD %d, status 0x%02x\n", td, status); | 1758 | dprintk(D_INT, "TD %d, status 0x%02x\n", td, status); |
1766 | 1759 | ||
1767 | dbri->dma->desc[td].word4 = 0; /* Reset it for next time. */ | 1760 | dbri->dma->desc[td].word4 = 0; /* Reset it for next time. */ |
1768 | info->offset += dbri->descs[td].len; | 1761 | len = DBRI_RD_CNT(dbri->dma->desc[td].word1); |
1769 | info->left -= dbri->descs[td].len; | 1762 | info->offset += len; |
1763 | info->left -= len; | ||
1770 | 1764 | ||
1771 | /* On the last TD, transmit them all again. */ | 1765 | /* On the last TD, transmit them all again. */ |
1772 | if (dbri->descs[td].next == -1) { | 1766 | if (dbri->next_desc[td] == -1) { |
1773 | if (info->left > 0) { | 1767 | if (info->left > 0) { |
1774 | printk(KERN_WARNING | 1768 | printk(KERN_WARNING |
1775 | "%d bytes left after last transfer.\n", | 1769 | "%d bytes left after last transfer.\n", |
@@ -1779,7 +1773,7 @@ static void transmission_complete_intr(struct snd_dbri * dbri, int pipe) | |||
1779 | tasklet_schedule(&xmit_descs_task); | 1773 | tasklet_schedule(&xmit_descs_task); |
1780 | } | 1774 | } |
1781 | 1775 | ||
1782 | td = dbri->descs[td].next; | 1776 | td = dbri->next_desc[td]; |
1783 | dbri->pipes[pipe].desc = td; | 1777 | dbri->pipes[pipe].desc = td; |
1784 | } | 1778 | } |
1785 | 1779 | ||
@@ -1803,8 +1797,8 @@ static void reception_complete_intr(struct snd_dbri * dbri, int pipe) | |||
1803 | return; | 1797 | return; |
1804 | } | 1798 | } |
1805 | 1799 | ||
1806 | dbri->descs[rd].inuse = 0; | 1800 | dbri->dma->desc[rd].ba = 0; |
1807 | dbri->pipes[pipe].desc = dbri->descs[rd].next; | 1801 | dbri->pipes[pipe].desc = dbri->next_desc[rd]; |
1808 | status = dbri->dma->desc[rd].word1; | 1802 | status = dbri->dma->desc[rd].word1; |
1809 | dbri->dma->desc[rd].word1 = 0; /* Reset it for next time. */ | 1803 | dbri->dma->desc[rd].word1 = 0; /* Reset it for next time. */ |
1810 | 1804 | ||
@@ -1818,7 +1812,7 @@ static void reception_complete_intr(struct snd_dbri * dbri, int pipe) | |||
1818 | rd, DBRI_RD_STATUS(status), DBRI_RD_CNT(status)); | 1812 | rd, DBRI_RD_STATUS(status), DBRI_RD_CNT(status)); |
1819 | 1813 | ||
1820 | /* On the last TD, transmit them all again. */ | 1814 | /* On the last TD, transmit them all again. */ |
1821 | if (dbri->descs[rd].next == -1) { | 1815 | if (dbri->next_desc[rd] == -1) { |
1822 | if (info->left > info->size) { | 1816 | if (info->left > info->size) { |
1823 | printk(KERN_WARNING | 1817 | printk(KERN_WARNING |
1824 | "%d bytes recorded in %d size buffer.\n", | 1818 | "%d bytes recorded in %d size buffer.\n", |