extractedLnx/linux-2.6.38/drivers/staging/easycap/easycap_sound.c_easysnd_complete.c
void
easysnd_complete(struct urb *purb)
{
struct easycap *peasycap;
struct data_buffer *paudio_buffer;
__u8 *p1, *p2;
__s16 s16;
int i, j, more, much, leap, rc;
#if defined(UPSAMPLE)
int k;
__s16 oldaudio, newaudio, delta;
#endif /*UPSAMPLE*/
JOT(16, "\n");
if (NULL == purb) {
SAY("ERROR: purb is NULL\n");
return;
}
peasycap = purb->context;
if (NULL == peasycap) {
SAY("ERROR: peasycap is NULL\n");
return;
}
if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) {
SAY("ERROR: bad peasycap\n");
return;
}
much = 0;
if (peasycap->audio_idle) {
JOM(16, "%i=audio_idle %i=audio_isoc_streaming\n", \
peasycap->audio_idle, peasycap->audio_isoc_streaming);
if (peasycap->audio_isoc_streaming) {
rc = usb_submit_urb(purb, GFP_ATOMIC);
if (0 != rc) {
if (-ENODEV != rc)
SAM("ERROR: while %i=audio_idle, " \
"usb_submit_urb() failed with rc:\n", \
peasycap->audio_idle);
switch (rc) {
case -ENOMEM: {
SAM("-ENOMEM\n");
break;
}
case -ENODEV: {
break;
}
case -ENXIO: {
SAM("-ENXIO\n");
break;
}
case -EINVAL: {
SAM("-EINVAL\n");
break;
}
case -EAGAIN: {
SAM("-EAGAIN\n");
break;
}
case -EFBIG: {
SAM("-EFBIG\n");
break;
}
case -EPIPE: {
SAM("-EPIPE\n");
break;
}
case -EMSGSIZE: {
SAM("-EMSGSIZE\n");
break;
}
case -ENOSPC: {
SAM("-ENOSPC\n");
break;
}
default: {
SAM("unknown error: 0x%08X\n", rc);
break;
}
}
}
}
return;
}
/*---------------------------------------------------------------------------*/
if (purb->status) {
if ((-ESHUTDOWN == purb->status) || (-ENOENT == purb->status)) {
JOM(16, "urb status -ESHUTDOWN or -ENOENT\n");
return;
}
SAM("ERROR: non-zero urb status:\n");
switch (purb->status) {
case -EINPROGRESS: {
SAM("-EINPROGRESS\n");
break;
}
case -ENOSR: {
SAM("-ENOSR\n");
break;
}
case -EPIPE: {
SAM("-EPIPE\n");
break;
}
case -EOVERFLOW: {
SAM("-EOVERFLOW\n");
break;
}
case -EPROTO: {
SAM("-EPROTO\n");
break;
}
case -EILSEQ: {
SAM("-EILSEQ\n");
break;
}
case -ETIMEDOUT: {
SAM("-ETIMEDOUT\n");
break;
}
case -EMSGSIZE: {
SAM("-EMSGSIZE\n");
break;
}
case -EOPNOTSUPP: {
SAM("-EOPNOTSUPP\n");
break;
}
case -EPFNOSUPPORT: {
SAM("-EPFNOSUPPORT\n");
break;
}
case -EAFNOSUPPORT: {
SAM("-EAFNOSUPPORT\n");
break;
}
case -EADDRINUSE: {
SAM("-EADDRINUSE\n");
break;
}
case -EADDRNOTAVAIL: {
SAM("-EADDRNOTAVAIL\n");
break;
}
case -ENOBUFS: {
SAM("-ENOBUFS\n");
break;
}
case -EISCONN: {
SAM("-EISCONN\n");
break;
}
case -ENOTCONN: {
SAM("-ENOTCONN\n");
break;
}
case -ESHUTDOWN: {
SAM("-ESHUTDOWN\n");
break;
}
case -ENOENT: {
SAM("-ENOENT\n");
break;
}
case -ECONNRESET: {
SAM("-ECONNRESET\n");
break;
}
case -ENOSPC: {
SAM("ENOSPC\n");
break;
}
default: {
SAM("unknown error code 0x%08X\n", purb->status);
break;
}
}
/*---------------------------------------------------------------------------*/
/*
* RESUBMIT THIS URB AFTER AN ERROR
*
* (THIS IS DUPLICATE CODE TO REDUCE INDENTATION OF THE NO-ERROR PATH)
*/
/*---------------------------------------------------------------------------*/
if (peasycap->audio_isoc_streaming) {
rc = usb_submit_urb(purb, GFP_ATOMIC);
if (0 != rc) {
SAM("ERROR: while %i=audio_idle, usb_submit_urb() "
"failed with rc:\n", peasycap->audio_idle);
switch (rc) {
case -ENOMEM: {
SAM("-ENOMEM\n");
break;
}
case -ENODEV: {
SAM("-ENODEV\n");
break;
}
case -ENXIO: {
SAM("-ENXIO\n");
break;
}
case -EINVAL: {
SAM("-EINVAL\n");
break;
}
case -EAGAIN: {
SAM("-EAGAIN\n");
break;
}
case -EFBIG: {
SAM("-EFBIG\n");
break;
}
case -EPIPE: {
SAM("-EPIPE\n");
break;
}
case -EMSGSIZE: {
SAM("-EMSGSIZE\n");
break;
}
default: {
SAM("0x%08X\n", rc); break;
}
}
}
}
return;
}
/*---------------------------------------------------------------------------*/
/*
* PROCEED HERE WHEN NO ERROR
*/
/*---------------------------------------------------------------------------*/
#if defined(UPSAMPLE)
oldaudio = peasycap->oldaudio;
#endif /*UPSAMPLE*/
for (i = 0; i < purb->number_of_packets; i++) {
switch (purb->iso_frame_desc[i].status) {
case 0: {
break;
}
case -ENOENT: {
SAM("-ENOENT\n");
break;
}
case -EINPROGRESS: {
SAM("-EINPROGRESS\n");
break;
}
case -EPROTO: {
SAM("-EPROTO\n");
break;
}
case -EILSEQ: {
SAM("-EILSEQ\n");
break;
}
case -ETIME: {
SAM("-ETIME\n");
break;
}
case -ETIMEDOUT: {
SAM("-ETIMEDOUT\n");
break;
}
case -EPIPE: {
SAM("-EPIPE\n");
break;
}
case -ECOMM: {
SAM("-ECOMM\n");
break;
}
case -ENOSR: {
SAM("-ENOSR\n");
break;
}
case -EOVERFLOW: {
SAM("-EOVERFLOW\n");
break;
}
case -EREMOTEIO: {
SAM("-EREMOTEIO\n");
break;
}
case -ENODEV: {
SAM("-ENODEV\n");
break;
}
case -EXDEV: {
SAM("-EXDEV\n");
break;
}
case -EINVAL: {
SAM("-EINVAL\n");
break;
}
case -ECONNRESET: {
SAM("-ECONNRESET\n");
break;
}
case -ENOSPC: {
SAM("-ENOSPC\n");
break;
}
case -ESHUTDOWN: {
SAM("-ESHUTDOWN\n");
break;
}
default: {
SAM("unknown error:0x%08X\n", purb->iso_frame_desc[i].status);
break;
}
}
if (!purb->iso_frame_desc[i].status) {
more = purb->iso_frame_desc[i].actual_length;
#if defined(TESTTONE)
if (!more)
more = purb->iso_frame_desc[i].length;
#endif
if (!more)
peasycap->audio_mt++;
else {
if (peasycap->audio_mt) {
JOM(16, "%4i empty audio urb frames\n", \
peasycap->audio_mt);
peasycap->audio_mt = 0;
}
p1 = (__u8 *)(purb->transfer_buffer + \
purb->iso_frame_desc[i].offset);
leap = 0;
p1 += leap;
more -= leap;
/*---------------------------------------------------------------------------*/
/*
* COPY more BYTES FROM ISOC BUFFER TO AUDIO BUFFER,
* CONVERTING 8-BIT MONO TO 16-BIT SIGNED LITTLE-ENDIAN SAMPLES IF NECESSARY
*/
/*---------------------------------------------------------------------------*/
while (more) {
if (0 > more) {
SAM("easysnd_complete: MISTAKE: " \
"more is negative\n");
return;
}
if (peasycap->audio_buffer_page_many <= \
peasycap->audio_fill) {
SAM("ERROR: bad " \
"peasycap->audio_fill\n");
return;
}
paudio_buffer = &peasycap->audio_buffer\
[peasycap->audio_fill];
if (PAGE_SIZE < (paudio_buffer->pto - \
paudio_buffer->pgo)) {
SAM("ERROR: bad paudio_buffer->pto\n");
return;
}
if (PAGE_SIZE == (paudio_buffer->pto - \
paudio_buffer->pgo)) {
#if defined(TESTTONE)
easysnd_testtone(peasycap, \
peasycap->audio_fill);
#endif /*TESTTONE*/
paudio_buffer->pto = \
paudio_buffer->pgo;
(peasycap->audio_fill)++;
if (peasycap->\
audio_buffer_page_many <= \
peasycap->audio_fill)
peasycap->audio_fill = 0;
JOM(12, "bumped peasycap->" \
"audio_fill to %i\n", \
peasycap->audio_fill);
paudio_buffer = &peasycap->\
audio_buffer\
[peasycap->audio_fill];
paudio_buffer->pto = \
paudio_buffer->pgo;
if (!(peasycap->audio_fill % \
peasycap->\
audio_pages_per_fragment)) {
JOM(12, "wakeup call on wq_" \
"audio, %i=frag reading %i" \
"=fragment fill\n", \
(peasycap->audio_read / \
peasycap->\
audio_pages_per_fragment), \
(peasycap->audio_fill / \
peasycap->\
audio_pages_per_fragment));
wake_up_interruptible\
(&(peasycap->wq_audio));
}
}
much = PAGE_SIZE - (int)(paudio_buffer->pto -\
paudio_buffer->pgo);
if (false == peasycap->microphone) {
if (much > more)
much = more;
memcpy(paudio_buffer->pto, p1, much);
p1 += much;
more -= much;
} else {
#if defined(UPSAMPLE)
if (much % 16)
JOM(8, "MISTAKE? much" \
" is not divisible by 16\n");
if (much > (16 * \
more))
much = 16 * \
more;
p2 = (__u8 *)paudio_buffer->pto;
for (j = 0; j < (much/16); j++) {
newaudio = ((int) *p1) - 128;
newaudio = 128 * \
newaudio;
delta = (newaudio - oldaudio) \
/ 4;
s16 = oldaudio + delta;
for (k = 0; k < 4; k++) {
*p2 = (0x00FF & s16);
*(p2 + 1) = (0xFF00 & \
s16) >> 8;
p2 += 2;
*p2 = (0x00FF & s16);
*(p2 + 1) = (0xFF00 & \
s16) >> 8;
p2 += 2;
s16 += delta;
}
p1++;
more--;
oldaudio = s16;
}
#else
if (much > (2 * more))
much = 2 * more;
p2 = (__u8 *)paudio_buffer->pto;
for (j = 0; j < (much / 2); j++) {
s16 = ((int) *p1) - 128;
s16 = 128 * \
s16;
*p2 = (0x00FF & s16);
*(p2 + 1) = (0xFF00 & s16) >> \
8;
p1++; p2 += 2;
more--;
}
#endif /*UPSAMPLE*/
}
(paudio_buffer->pto) += much;
}
}
} else {
JOM(12, "discarding audio samples because " \
"%i=purb->iso_frame_desc[i].status\n", \
purb->iso_frame_desc[i].status);
}
#if defined(UPSAMPLE)
peasycap->oldaudio = oldaudio;
#endif /*UPSAMPLE*/
}
/*---------------------------------------------------------------------------*/
/*
* RESUBMIT THIS URB AFTER NO ERROR
*/
/*---------------------------------------------------------------------------*/
if (peasycap->audio_isoc_streaming) {
rc = usb_submit_urb(purb, GFP_ATOMIC);
if (0 != rc) {
if (-ENODEV != rc) {
SAM("ERROR: while %i=audio_idle, " \
"usb_submit_urb() failed " \
"with rc:\n", peasycap->audio_idle);
}
switch (rc) {
case -ENOMEM: {
SAM("-ENOMEM\n");
break;
}
case -ENODEV: {
break;
}
case -ENXIO: {
SAM("-ENXIO\n");
break;
}
case -EINVAL: {
SAM("-EINVAL\n");
break;
}
case -EAGAIN: {
SAM("-EAGAIN\n");
break;
}
case -EFBIG: {
SAM("-EFBIG\n");
break;
}
case -EPIPE: {
SAM("-EPIPE\n");
break;
}
case -EMSGSIZE: {
SAM("-EMSGSIZE\n");
break;
}
case -ENOSPC: {
SAM("-ENOSPC\n");
break;
}
default: {
SAM("unknown error: 0x%08X\n", rc);
break;
}
}
}
}
return;
}
Generated by GNU enscript 1.6.4.