diff options
author | Andreas Mohr <andi@lisas.de> | 2006-03-28 05:56:14 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@suse.cz> | 2006-03-31 10:59:00 -0500 |
commit | 0b2dcd5d6a9a3e27fdd67053e526388f9f2ea33b (patch) | |
tree | d380fb45aa120b2499aa03753717f3ecbf0ad099 /sound/pci/maestro3.c | |
parent | a1e8d2da03b3a1017aab01d49666ec9b67927de5 (diff) |
[ALSA] maestro3.c: fix BUG, optimization
- fix brown-paper-bag locking bug (lock() / return / unlock())
- improve central function snd_m3_update_ptr()
(avoid expensive integer divisions)
- add cpu_relax() to busy-wait I/O loop as recommended
(does this require special macro support in ALSA for older kernels??)
- constify several structs
- spelling updates
Signed-off-by: Andreas Mohr <andi@lisas.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/maestro3.c')
-rw-r--r-- | sound/pci/maestro3.c | 57 |
1 files changed, 37 insertions, 20 deletions
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c index 44393e190929..9c90d901e6b9 100644 --- a/sound/pci/maestro3.c +++ b/sound/pci/maestro3.c | |||
@@ -831,8 +831,8 @@ struct snd_m3 { | |||
831 | struct snd_pcm *pcm; | 831 | struct snd_pcm *pcm; |
832 | 832 | ||
833 | struct pci_dev *pci; | 833 | struct pci_dev *pci; |
834 | struct m3_quirk *quirk; | 834 | const struct m3_quirk *quirk; |
835 | struct m3_hv_quirk *hv_quirk; | 835 | const struct m3_hv_quirk *hv_quirk; |
836 | 836 | ||
837 | int dacs_active; | 837 | int dacs_active; |
838 | int timer_users; | 838 | int timer_users; |
@@ -892,7 +892,7 @@ static struct pci_device_id snd_m3_ids[] = { | |||
892 | 892 | ||
893 | MODULE_DEVICE_TABLE(pci, snd_m3_ids); | 893 | MODULE_DEVICE_TABLE(pci, snd_m3_ids); |
894 | 894 | ||
895 | static struct m3_quirk m3_quirk_list[] = { | 895 | static const struct m3_quirk m3_quirk_list[] = { |
896 | /* panasonic CF-28 "toughbook" */ | 896 | /* panasonic CF-28 "toughbook" */ |
897 | { | 897 | { |
898 | .name = "Panasonic CF-28", | 898 | .name = "Panasonic CF-28", |
@@ -950,7 +950,7 @@ static struct m3_quirk m3_quirk_list[] = { | |||
950 | }; | 950 | }; |
951 | 951 | ||
952 | /* These values came from the Windows driver. */ | 952 | /* These values came from the Windows driver. */ |
953 | static struct m3_hv_quirk m3_hv_quirk_list[] = { | 953 | static const struct m3_hv_quirk m3_hv_quirk_list[] = { |
954 | /* Allegro chips */ | 954 | /* Allegro chips */ |
955 | { 0x125D, 0x1988, 0x0E11, 0x002E, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, | 955 | { 0x125D, 0x1988, 0x0E11, 0x002E, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, |
956 | { 0x125D, 0x1988, 0x0E11, 0x0094, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, | 956 | { 0x125D, 0x1988, 0x0E11, 0x0094, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, |
@@ -1361,7 +1361,7 @@ static void snd_m3_pcm_setup2(struct snd_m3 *chip, struct m3_dma *s, | |||
1361 | } | 1361 | } |
1362 | 1362 | ||
1363 | 1363 | ||
1364 | static struct play_vals { | 1364 | static const struct play_vals { |
1365 | u16 addr, val; | 1365 | u16 addr, val; |
1366 | } pv[] = { | 1366 | } pv[] = { |
1367 | {CDATA_LEFT_VOLUME, ARB_VOLUME}, | 1367 | {CDATA_LEFT_VOLUME, ARB_VOLUME}, |
@@ -1428,7 +1428,7 @@ snd_m3_playback_setup(struct snd_m3 *chip, struct m3_dma *s, | |||
1428 | /* | 1428 | /* |
1429 | * Native record driver | 1429 | * Native record driver |
1430 | */ | 1430 | */ |
1431 | static struct rec_vals { | 1431 | static const struct rec_vals { |
1432 | u16 addr, val; | 1432 | u16 addr, val; |
1433 | } rv[] = { | 1433 | } rv[] = { |
1434 | {CDATA_LEFT_VOLUME, ARB_VOLUME}, | 1434 | {CDATA_LEFT_VOLUME, ARB_VOLUME}, |
@@ -1598,12 +1598,26 @@ static void snd_m3_update_ptr(struct snd_m3 *chip, struct m3_dma *s) | |||
1598 | if (! s->running) | 1598 | if (! s->running) |
1599 | return; | 1599 | return; |
1600 | 1600 | ||
1601 | hwptr = snd_m3_get_pointer(chip, s, subs) % s->dma_size; | 1601 | hwptr = snd_m3_get_pointer(chip, s, subs); |
1602 | diff = (s->dma_size + hwptr - s->hwptr) % s->dma_size; | 1602 | |
1603 | /* try to avoid expensive modulo divisions */ | ||
1604 | if (hwptr >= s->dma_size) | ||
1605 | hwptr %= s->dma_size; | ||
1606 | |||
1607 | diff = s->dma_size + hwptr - s->hwptr; | ||
1608 | if (diff >= s->dma_size) | ||
1609 | diff %= s->dma_size; | ||
1610 | |||
1603 | s->hwptr = hwptr; | 1611 | s->hwptr = hwptr; |
1604 | s->count += diff; | 1612 | s->count += diff; |
1613 | |||
1605 | if (s->count >= (signed)s->period_size) { | 1614 | if (s->count >= (signed)s->period_size) { |
1606 | s->count %= s->period_size; | 1615 | |
1616 | if (s->count < 2 * (signed)s->period_size) | ||
1617 | s->count -= (signed)s->period_size; | ||
1618 | else | ||
1619 | s->count %= s->period_size; | ||
1620 | |||
1607 | spin_unlock(&chip->reg_lock); | 1621 | spin_unlock(&chip->reg_lock); |
1608 | snd_pcm_period_elapsed(subs); | 1622 | snd_pcm_period_elapsed(subs); |
1609 | spin_lock(&chip->reg_lock); | 1623 | spin_lock(&chip->reg_lock); |
@@ -1942,6 +1956,7 @@ static int snd_m3_ac97_wait(struct snd_m3 *chip) | |||
1942 | do { | 1956 | do { |
1943 | if (! (snd_m3_inb(chip, 0x30) & 1)) | 1957 | if (! (snd_m3_inb(chip, 0x30) & 1)) |
1944 | return 0; | 1958 | return 0; |
1959 | cpu_relax(); | ||
1945 | } while (i-- > 0); | 1960 | } while (i-- > 0); |
1946 | 1961 | ||
1947 | snd_printk(KERN_ERR "ac97 serial bus busy\n"); | 1962 | snd_printk(KERN_ERR "ac97 serial bus busy\n"); |
@@ -1953,16 +1968,18 @@ snd_m3_ac97_read(struct snd_ac97 *ac97, unsigned short reg) | |||
1953 | { | 1968 | { |
1954 | struct snd_m3 *chip = ac97->private_data; | 1969 | struct snd_m3 *chip = ac97->private_data; |
1955 | unsigned long flags; | 1970 | unsigned long flags; |
1956 | unsigned short data; | 1971 | unsigned short data = 0xffff; |
1957 | 1972 | ||
1958 | if (snd_m3_ac97_wait(chip)) | 1973 | if (snd_m3_ac97_wait(chip)) |
1959 | return 0xffff; | 1974 | goto fail; |
1960 | spin_lock_irqsave(&chip->ac97_lock, flags); | 1975 | spin_lock_irqsave(&chip->ac97_lock, flags); |
1961 | snd_m3_outb(chip, 0x80 | (reg & 0x7f), CODEC_COMMAND); | 1976 | snd_m3_outb(chip, 0x80 | (reg & 0x7f), CODEC_COMMAND); |
1962 | if (snd_m3_ac97_wait(chip)) | 1977 | if (snd_m3_ac97_wait(chip)) |
1963 | return 0xffff; | 1978 | goto fail_unlock; |
1964 | data = snd_m3_inw(chip, CODEC_DATA); | 1979 | data = snd_m3_inw(chip, CODEC_DATA); |
1980 | fail_unlock: | ||
1965 | spin_unlock_irqrestore(&chip->ac97_lock, flags); | 1981 | spin_unlock_irqrestore(&chip->ac97_lock, flags); |
1982 | fail: | ||
1966 | return data; | 1983 | return data; |
1967 | } | 1984 | } |
1968 | 1985 | ||
@@ -2121,7 +2138,7 @@ static int __devinit snd_m3_mixer(struct snd_m3 *chip) | |||
2121 | * DSP Code images | 2138 | * DSP Code images |
2122 | */ | 2139 | */ |
2123 | 2140 | ||
2124 | static u16 assp_kernel_image[] __devinitdata = { | 2141 | static const u16 assp_kernel_image[] __devinitdata = { |
2125 | 0x7980, 0x0030, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x00FB, 0x7980, 0x00DD, 0x7980, 0x03B4, | 2142 | 0x7980, 0x0030, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x00FB, 0x7980, 0x00DD, 0x7980, 0x03B4, |
2126 | 0x7980, 0x0332, 0x7980, 0x0287, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4, | 2143 | 0x7980, 0x0332, 0x7980, 0x0287, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4, |
2127 | 0x7980, 0x031A, 0x7980, 0x03B4, 0x7980, 0x022F, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4, | 2144 | 0x7980, 0x031A, 0x7980, 0x03B4, 0x7980, 0x022F, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4, |
@@ -2208,7 +2225,7 @@ static u16 assp_kernel_image[] __devinitdata = { | |||
2208 | * Mini sample rate converter code image | 2225 | * Mini sample rate converter code image |
2209 | * that is to be loaded at 0x400 on the DSP. | 2226 | * that is to be loaded at 0x400 on the DSP. |
2210 | */ | 2227 | */ |
2211 | static u16 assp_minisrc_image[] __devinitdata = { | 2228 | static const u16 assp_minisrc_image[] __devinitdata = { |
2212 | 2229 | ||
2213 | 0xBF80, 0x101E, 0x906E, 0x006E, 0x8B88, 0x6980, 0xEF88, 0x906F, 0x0D6F, 0x6900, 0xEB08, 0x0412, | 2230 | 0xBF80, 0x101E, 0x906E, 0x006E, 0x8B88, 0x6980, 0xEF88, 0x906F, 0x0D6F, 0x6900, 0xEB08, 0x0412, |
2214 | 0xBC20, 0x696E, 0xB801, 0x906E, 0x7980, 0x0403, 0xB90E, 0x8807, 0xBE43, 0xBF01, 0xBE47, 0xBE41, | 2231 | 0xBC20, 0x696E, 0xB801, 0x906E, 0x7980, 0x0403, 0xB90E, 0x8807, 0xBE43, 0xBF01, 0xBE47, 0xBE41, |
@@ -2251,7 +2268,7 @@ static u16 assp_minisrc_image[] __devinitdata = { | |||
2251 | */ | 2268 | */ |
2252 | 2269 | ||
2253 | #define MINISRC_LPF_LEN 10 | 2270 | #define MINISRC_LPF_LEN 10 |
2254 | static u16 minisrc_lpf[MINISRC_LPF_LEN] __devinitdata = { | 2271 | static const u16 minisrc_lpf[MINISRC_LPF_LEN] __devinitdata = { |
2255 | 0X0743, 0X1104, 0X0A4C, 0XF88D, 0X242C, | 2272 | 0X0743, 0X1104, 0X0A4C, 0XF88D, 0X242C, |
2256 | 0X1023, 0X1AA9, 0X0B60, 0XEFDD, 0X186F | 2273 | 0X1023, 0X1AA9, 0X0B60, 0XEFDD, 0X186F |
2257 | }; | 2274 | }; |
@@ -2358,7 +2375,7 @@ static int __devinit snd_m3_assp_client_init(struct snd_m3 *chip, struct m3_dma | |||
2358 | */ | 2375 | */ |
2359 | 2376 | ||
2360 | /* | 2377 | /* |
2361 | * align instance address to 256 bytes so that it's | 2378 | * align instance address to 256 bytes so that its |
2362 | * shifted list address is aligned. | 2379 | * shifted list address is aligned. |
2363 | * list address = (mem address >> 1) >> 7; | 2380 | * list address = (mem address >> 1) >> 7; |
2364 | */ | 2381 | */ |
@@ -2647,8 +2664,8 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci, | |||
2647 | { | 2664 | { |
2648 | struct snd_m3 *chip; | 2665 | struct snd_m3 *chip; |
2649 | int i, err; | 2666 | int i, err; |
2650 | struct m3_quirk *quirk; | 2667 | const struct m3_quirk *quirk; |
2651 | struct m3_hv_quirk *hv_quirk; | 2668 | const struct m3_hv_quirk *hv_quirk; |
2652 | static struct snd_device_ops ops = { | 2669 | static struct snd_device_ops ops = { |
2653 | .dev_free = snd_m3_dev_free, | 2670 | .dev_free = snd_m3_dev_free, |
2654 | }; | 2671 | }; |
@@ -2843,12 +2860,12 @@ snd_m3_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) | |||
2843 | } | 2860 | } |
2844 | 2861 | ||
2845 | #if 0 /* TODO: not supported yet */ | 2862 | #if 0 /* TODO: not supported yet */ |
2846 | /* TODO enable midi irq and i/o */ | 2863 | /* TODO enable MIDI IRQ and I/O */ |
2847 | err = snd_mpu401_uart_new(chip->card, 0, MPU401_HW_MPU401, | 2864 | err = snd_mpu401_uart_new(chip->card, 0, MPU401_HW_MPU401, |
2848 | chip->iobase + MPU401_DATA_PORT, 1, | 2865 | chip->iobase + MPU401_DATA_PORT, 1, |
2849 | chip->irq, 0, &chip->rmidi); | 2866 | chip->irq, 0, &chip->rmidi); |
2850 | if (err < 0) | 2867 | if (err < 0) |
2851 | printk(KERN_WARNING "maestro3: no midi support.\n"); | 2868 | printk(KERN_WARNING "maestro3: no MIDI support.\n"); |
2852 | #endif | 2869 | #endif |
2853 | 2870 | ||
2854 | pci_set_drvdata(pci, card); | 2871 | pci_set_drvdata(pci, card); |