Commit 27762b2c authored by Takashi Iwai's avatar Takashi Iwai

Merge branch 'fix/misc' into topic/usb

parents 7b7b9042 29aac005
...@@ -307,7 +307,7 @@ struct ak4113 { ...@@ -307,7 +307,7 @@ struct ak4113 {
int snd_ak4113_create(struct snd_card *card, ak4113_read_t *read, int snd_ak4113_create(struct snd_card *card, ak4113_read_t *read,
ak4113_write_t *write, ak4113_write_t *write,
const unsigned char pgm[AK4113_WRITABLE_REGS], const unsigned char *pgm,
void *private_data, struct ak4113 **r_ak4113); void *private_data, struct ak4113 **r_ak4113);
void snd_ak4113_reg_write(struct ak4113 *ak4113, unsigned char reg, void snd_ak4113_reg_write(struct ak4113 *ak4113, unsigned char reg,
unsigned char mask, unsigned char val); unsigned char mask, unsigned char val);
......
...@@ -148,6 +148,9 @@ static void pcm_debug_name(struct snd_pcm_substream *substream, ...@@ -148,6 +148,9 @@ static void pcm_debug_name(struct snd_pcm_substream *substream,
#define xrun_debug(substream, mask) \ #define xrun_debug(substream, mask) \
((substream)->pstr->xrun_debug & (mask)) ((substream)->pstr->xrun_debug & (mask))
#else
#define xrun_debug(substream, mask) 0
#endif
#define dump_stack_on_xrun(substream) do { \ #define dump_stack_on_xrun(substream) do { \
if (xrun_debug(substream, XRUN_DEBUG_STACK)) \ if (xrun_debug(substream, XRUN_DEBUG_STACK)) \
...@@ -169,6 +172,7 @@ static void xrun(struct snd_pcm_substream *substream) ...@@ -169,6 +172,7 @@ static void xrun(struct snd_pcm_substream *substream)
} }
} }
#ifdef CONFIG_SND_PCM_XRUN_DEBUG
#define hw_ptr_error(substream, fmt, args...) \ #define hw_ptr_error(substream, fmt, args...) \
do { \ do { \
if (xrun_debug(substream, XRUN_DEBUG_BASIC)) { \ if (xrun_debug(substream, XRUN_DEBUG_BASIC)) { \
...@@ -255,8 +259,6 @@ static void xrun_log_show(struct snd_pcm_substream *substream) ...@@ -255,8 +259,6 @@ static void xrun_log_show(struct snd_pcm_substream *substream)
#else /* ! CONFIG_SND_PCM_XRUN_DEBUG */ #else /* ! CONFIG_SND_PCM_XRUN_DEBUG */
#define xrun_debug(substream, mask) 0
#define xrun(substream) do { } while (0)
#define hw_ptr_error(substream, fmt, args...) do { } while (0) #define hw_ptr_error(substream, fmt, args...) do { } while (0)
#define xrun_log(substream, pos) do { } while (0) #define xrun_log(substream, pos) do { } while (0)
#define xrun_log_show(substream) do { } while (0) #define xrun_log_show(substream) do { } while (0)
......
...@@ -70,7 +70,7 @@ static int snd_ak4113_dev_free(struct snd_device *device) ...@@ -70,7 +70,7 @@ static int snd_ak4113_dev_free(struct snd_device *device)
} }
int snd_ak4113_create(struct snd_card *card, ak4113_read_t *read, int snd_ak4113_create(struct snd_card *card, ak4113_read_t *read,
ak4113_write_t *write, const unsigned char pgm[5], ak4113_write_t *write, const unsigned char *pgm,
void *private_data, struct ak4113 **r_ak4113) void *private_data, struct ak4113 **r_ak4113)
{ {
struct ak4113 *chip; struct ak4113 *chip;
......
...@@ -1852,12 +1852,14 @@ static unsigned int ad1981_jacks_blacklist[] = { ...@@ -1852,12 +1852,14 @@ static unsigned int ad1981_jacks_blacklist[] = {
0x10140523, /* Thinkpad R40 */ 0x10140523, /* Thinkpad R40 */
0x10140534, /* Thinkpad X31 */ 0x10140534, /* Thinkpad X31 */
0x10140537, /* Thinkpad T41p */ 0x10140537, /* Thinkpad T41p */
0x1014053e, /* Thinkpad R40e */
0x10140554, /* Thinkpad T42p/R50p */ 0x10140554, /* Thinkpad T42p/R50p */
0x10140567, /* Thinkpad T43p 2668-G7U */ 0x10140567, /* Thinkpad T43p 2668-G7U */
0x10140581, /* Thinkpad X41-2527 */ 0x10140581, /* Thinkpad X41-2527 */
0x10280160, /* Dell Dimension 2400 */ 0x10280160, /* Dell Dimension 2400 */
0x104380b0, /* Asus A7V8X-MX */ 0x104380b0, /* Asus A7V8X-MX */
0x11790241, /* Toshiba Satellite A-15 S127 */ 0x11790241, /* Toshiba Satellite A-15 S127 */
0x1179ff10, /* Toshiba P500 */
0x144dc01a, /* Samsung NP-X20C004/SEG */ 0x144dc01a, /* Samsung NP-X20C004/SEG */
0 /* end */ 0 /* end */
}; };
......
...@@ -941,13 +941,21 @@ static snd_pcm_uframes_t snd_cmipci_pcm_pointer(struct cmipci *cm, struct cmipci ...@@ -941,13 +941,21 @@ static snd_pcm_uframes_t snd_cmipci_pcm_pointer(struct cmipci *cm, struct cmipci
struct snd_pcm_substream *substream) struct snd_pcm_substream *substream)
{ {
size_t ptr; size_t ptr;
unsigned int reg; unsigned int reg, rem, tries;
if (!rec->running) if (!rec->running)
return 0; return 0;
#if 1 // this seems better.. #if 1 // this seems better..
reg = rec->ch ? CM_REG_CH1_FRAME2 : CM_REG_CH0_FRAME2; reg = rec->ch ? CM_REG_CH1_FRAME2 : CM_REG_CH0_FRAME2;
ptr = rec->dma_size - (snd_cmipci_read_w(cm, reg) + 1); for (tries = 0; tries < 3; tries++) {
ptr >>= rec->shift; rem = snd_cmipci_read_w(cm, reg);
if (rem < rec->dma_size)
goto ok;
}
printk(KERN_ERR "cmipci: invalid PCM pointer: %#x\n", rem);
return SNDRV_PCM_POS_XRUN;
ok:
ptr = (rec->dma_size - (rem + 1)) >> rec->shift;
#else #else
reg = rec->ch ? CM_REG_CH1_FRAME1 : CM_REG_CH0_FRAME1; reg = rec->ch ? CM_REG_CH1_FRAME1 : CM_REG_CH0_FRAME1;
ptr = snd_cmipci_read(cm, reg) - rec->offset; ptr = snd_cmipci_read(cm, reg) - rec->offset;
......
...@@ -2184,10 +2184,9 @@ static int __devinit snd_echo_probe(struct pci_dev *pci, ...@@ -2184,10 +2184,9 @@ static int __devinit snd_echo_probe(struct pci_dev *pci,
goto ctl_error; goto ctl_error;
#endif #endif
if ((err = snd_card_register(card)) < 0) { err = snd_card_register(card);
snd_card_free(card); if (err < 0)
goto ctl_error; goto ctl_error;
}
snd_printk(KERN_INFO "Card registered: %s\n", card->longname); snd_printk(KERN_INFO "Card registered: %s\n", card->longname);
pci_set_drvdata(pci, chip); pci_set_drvdata(pci, chip);
......
...@@ -1161,13 +1161,15 @@ static long snd_mixart_BA0_read(struct snd_info_entry *entry, void *file_private ...@@ -1161,13 +1161,15 @@ static long snd_mixart_BA0_read(struct snd_info_entry *entry, void *file_private
unsigned long count, unsigned long pos) unsigned long count, unsigned long pos)
{ {
struct mixart_mgr *mgr = entry->private_data; struct mixart_mgr *mgr = entry->private_data;
unsigned long maxsize;
count = count & ~3; /* make sure the read size is a multiple of 4 bytes */ if (pos >= MIXART_BA0_SIZE)
if(count <= 0)
return 0; return 0;
if(pos + count > MIXART_BA0_SIZE) maxsize = MIXART_BA0_SIZE - pos;
count = (long)(MIXART_BA0_SIZE - pos); if (count > maxsize)
if(copy_to_user_fromio(buf, MIXART_MEM( mgr, pos ), count)) count = maxsize;
count = count & ~3; /* make sure the read size is a multiple of 4 bytes */
if (copy_to_user_fromio(buf, MIXART_MEM(mgr, pos), count))
return -EFAULT; return -EFAULT;
return count; return count;
} }
...@@ -1180,13 +1182,15 @@ static long snd_mixart_BA1_read(struct snd_info_entry *entry, void *file_private ...@@ -1180,13 +1182,15 @@ static long snd_mixart_BA1_read(struct snd_info_entry *entry, void *file_private
unsigned long count, unsigned long pos) unsigned long count, unsigned long pos)
{ {
struct mixart_mgr *mgr = entry->private_data; struct mixart_mgr *mgr = entry->private_data;
unsigned long maxsize;
count = count & ~3; /* make sure the read size is a multiple of 4 bytes */ if (pos > MIXART_BA1_SIZE)
if(count <= 0)
return 0; return 0;
if(pos + count > MIXART_BA1_SIZE) maxsize = MIXART_BA1_SIZE - pos;
count = (long)(MIXART_BA1_SIZE - pos); if (count > maxsize)
if(copy_to_user_fromio(buf, MIXART_REG( mgr, pos ), count)) count = maxsize;
count = count & ~3; /* make sure the read size is a multiple of 4 bytes */
if (copy_to_user_fromio(buf, MIXART_REG(mgr, pos), count))
return -EFAULT; return -EFAULT;
return count; return count;
} }
......
...@@ -987,6 +987,8 @@ static void snd_usbmidi_output_drain(struct snd_rawmidi_substream *substream) ...@@ -987,6 +987,8 @@ static void snd_usbmidi_output_drain(struct snd_rawmidi_substream *substream)
DEFINE_WAIT(wait); DEFINE_WAIT(wait);
long timeout = msecs_to_jiffies(50); long timeout = msecs_to_jiffies(50);
if (ep->umidi->disconnected)
return;
/* /*
* The substream buffer is empty, but some data might still be in the * The substream buffer is empty, but some data might still be in the
* currently active URBs, so we have to wait for those to complete. * currently active URBs, so we have to wait for those to complete.
...@@ -1124,14 +1126,21 @@ static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi* umidi, ...@@ -1124,14 +1126,21 @@ static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi* umidi,
* Frees an output endpoint. * Frees an output endpoint.
* May be called when ep hasn't been initialized completely. * May be called when ep hasn't been initialized completely.
*/ */
static void snd_usbmidi_out_endpoint_delete(struct snd_usb_midi_out_endpoint* ep) static void snd_usbmidi_out_endpoint_clear(struct snd_usb_midi_out_endpoint *ep)
{ {
unsigned int i; unsigned int i;
for (i = 0; i < OUTPUT_URBS; ++i) for (i = 0; i < OUTPUT_URBS; ++i)
if (ep->urbs[i].urb) if (ep->urbs[i].urb) {
free_urb_and_buffer(ep->umidi, ep->urbs[i].urb, free_urb_and_buffer(ep->umidi, ep->urbs[i].urb,
ep->max_transfer); ep->max_transfer);
ep->urbs[i].urb = NULL;
}
}
static void snd_usbmidi_out_endpoint_delete(struct snd_usb_midi_out_endpoint *ep)
{
snd_usbmidi_out_endpoint_clear(ep);
kfree(ep); kfree(ep);
} }
...@@ -1263,15 +1272,18 @@ void snd_usbmidi_disconnect(struct list_head* p) ...@@ -1263,15 +1272,18 @@ void snd_usbmidi_disconnect(struct list_head* p)
usb_kill_urb(ep->out->urbs[j].urb); usb_kill_urb(ep->out->urbs[j].urb);
if (umidi->usb_protocol_ops->finish_out_endpoint) if (umidi->usb_protocol_ops->finish_out_endpoint)
umidi->usb_protocol_ops->finish_out_endpoint(ep->out); umidi->usb_protocol_ops->finish_out_endpoint(ep->out);
ep->out->active_urbs = 0;
if (ep->out->drain_urbs) {
ep->out->drain_urbs = 0;
wake_up(&ep->out->drain_wait);
}
} }
if (ep->in) if (ep->in)
for (j = 0; j < INPUT_URBS; ++j) for (j = 0; j < INPUT_URBS; ++j)
usb_kill_urb(ep->in->urbs[j]); usb_kill_urb(ep->in->urbs[j]);
/* free endpoints here; later call can result in Oops */ /* free endpoints here; later call can result in Oops */
if (ep->out) { if (ep->out)
snd_usbmidi_out_endpoint_delete(ep->out); snd_usbmidi_out_endpoint_clear(ep->out);
ep->out = NULL;
}
if (ep->in) { if (ep->in) {
snd_usbmidi_in_endpoint_delete(ep->in); snd_usbmidi_in_endpoint_delete(ep->in);
ep->in = NULL; ep->in = NULL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment