aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/sparc/dbri.c40
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 */
253struct dbri_mem { 254struct 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
285struct 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 */
292struct dbri_streaminfo { 287struct 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",