/* URB stuff for streaming */ static void dvb_usb_urb_complete(struct urb *urb, struct pt_regs *ptregs) { struct dvb_usb_device *d = urb->context; int ptype = usb_pipetype(urb->pipe); int i; u8 *b; deb_ts("'%s' urb completed. feedcount: %d, status: %d, length: %d/%d, pack_num: %d, errors: %d\n", ptype == PIPE_ISOCHRONOUS ? "isoc" : "bulk", d->feedcount, urb->status,urb->actual_length,urb->transfer_buffer_length, urb->number_of_packets,urb->error_count); switch (urb->status) { case 0: /* success */ case -ETIMEDOUT: /* NAK */ break; case -ECONNRESET: /* kill */ case -ENOENT: case -ESHUTDOWN: return; default: /* error */ deb_ts("urb completition error %d.", urb->status); break; } if (d->feedcount > 0) { if (d->state & DVB_USB_STATE_DVB) { switch (ptype) { case PIPE_ISOCHRONOUS: b = (u8 *) urb->transfer_buffer; for (i = 0; i < urb->number_of_packets; i++) { if (urb->iso_frame_desc[i].status != 0) deb_ts("iso frame descriptor has an error: %d\n",urb->iso_frame_desc[i].status); else if (urb->iso_frame_desc[i].actual_length > 0) { dvb_dmx_swfilter(&d->demux,b + urb->iso_frame_desc[i].offset, urb->iso_frame_desc[i].actual_length); } urb->iso_frame_desc[i].status = 0; urb->iso_frame_desc[i].actual_length = 0; } debug_dump(b,20,deb_ts); break; case PIPE_BULK: if (urb->actual_length > 0) dvb_dmx_swfilter(&d->demux, (u8 *) urb->transfer_buffer,urb->actual_length); break; default: err("unkown endpoint type in completition handler."); return; } } } usb_submit_urb(urb,GFP_ATOMIC); }
static inline int em28xx_dvb_urb_data_copy(struct em28xx *dev, struct urb *urb) { int xfer_bulk, num_packets, i; if (!dev) return 0; if (dev->disconnected) return 0; if (urb->status < 0) print_err_status(dev, -1, urb->status); xfer_bulk = usb_pipebulk(urb->pipe); if (xfer_bulk) /* bulk */ num_packets = 1; else /* isoc */ num_packets = urb->number_of_packets; for (i = 0; i < num_packets; i++) { if (xfer_bulk) { if (urb->status < 0) { print_err_status(dev, i, urb->status); if (urb->status != -EPROTO) continue; } if (!urb->actual_length) continue; dvb_dmx_swfilter(&dev->dvb->demux, urb->transfer_buffer, urb->actual_length); } else { if (urb->iso_frame_desc[i].status < 0) { print_err_status(dev, i, urb->iso_frame_desc[i].status); if (urb->iso_frame_desc[i].status != -EPROTO) continue; } if (!urb->iso_frame_desc[i].actual_length) continue; dvb_dmx_swfilter(&dev->dvb->demux, urb->transfer_buffer + urb->iso_frame_desc[i].offset, urb->iso_frame_desc[i].actual_length); } } return 0; }
static inline int dvb_isoc_copy(struct em28xx *dev, struct urb *urb) { int i; if (!dev) return 0; if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED)) return 0; if (urb->status < 0) { print_err_status(dev, -1, urb->status); if (urb->status == -ENOENT) return 0; } for (i = 0; i < urb->number_of_packets; i++) { int status = urb->iso_frame_desc[i].status; if (status < 0) { print_err_status(dev, i, status); if (urb->iso_frame_desc[i].status != -EPROTO) continue; } dvb_dmx_swfilter(&dev->dvb->demux, urb->transfer_buffer + urb->iso_frame_desc[i].offset, urb->iso_frame_desc[i].actual_length); } return 0; }
static void tm6000_urb_received(struct urb *urb) { int ret; struct tm6000_core *dev = urb->context; switch (urb->status) { case 0: case -ETIMEDOUT: break; case -ENOENT: case -ECONNRESET: case -ESHUTDOWN: return; default: print_err_status(dev, 0, urb->status); } if (urb->actual_length > 0) dvb_dmx_swfilter(&dev->dvb->demux, urb->transfer_buffer, urb->actual_length); if (dev->dvb->streams > 0) { ret = usb_submit_urb(urb, GFP_ATOMIC); if (ret < 0) { printk(KERN_ERR "tm6000: error %s\n", __func__); kfree(urb->transfer_buffer); usb_free_urb(urb); } } }
static int pvr2_dvb_feed_func(struct pvr2_dvb_adapter *adap) { int ret; unsigned int count; struct pvr2_buffer *bp; struct pvr2_stream *stream; pvr2_trace(PVR2_TRACE_DVB_FEED, "dvb feed thread started"); set_freezable(); stream = adap->channel.stream->stream; for (;;) { if (kthread_should_stop()) break; /* */ try_to_freeze(); bp = pvr2_stream_get_ready_buffer(stream); if (bp != NULL) { count = pvr2_buffer_get_count(bp); if (count) { dvb_dmx_swfilter( &adap->demux, adap->buffer_storage[ pvr2_buffer_get_id(bp)], count); } else { ret = pvr2_buffer_get_status(bp); if (ret < 0) break; } ret = pvr2_buffer_queue(bp); if (ret < 0) break; /* */ continue; } /* */ ret = wait_event_interruptible( adap->buffer_wait_data, (pvr2_stream_get_ready_count(stream) > 0) || kthread_should_stop()); if (ret < 0) break; } /* */ pvr2_trace(PVR2_TRACE_DVB_FEED, "dvb feed thread stopped"); return 0; }
static int pvr2_dvb_feed_func(struct pvr2_dvb_adapter *adap) { int ret; unsigned int count; struct pvr2_buffer *bp; struct pvr2_stream *stream; pvr2_trace(PVR2_TRACE_DVB_FEED, "dvb feed thread started"); set_freezable(); stream = adap->channel.stream->stream; for (;;) { if (kthread_should_stop()) break; /* Not sure about this... */ try_to_freeze(); bp = pvr2_stream_get_ready_buffer(stream); if (bp != NULL) { count = pvr2_buffer_get_count(bp); if (count) { dvb_dmx_swfilter( &adap->demux, adap->buffer_storage[ pvr2_buffer_get_id(bp)], count); } else { ret = pvr2_buffer_get_status(bp); if (ret < 0) break; } ret = pvr2_buffer_queue(bp); if (ret < 0) break; /* Since we know we did something to a buffer, just go back and try again. No point in blocking unless we really ran out of buffers to process. */ continue; } /* Wait until more buffers become available or we're told not to wait any longer. */ ret = wait_event_interruptible( adap->buffer_wait_data, (pvr2_stream_get_ready_count(stream) > 0) || kthread_should_stop()); if (ret < 0) break; } /* If we get here and ret is < 0, then an error has occurred. Probably would be a good idea to communicate that to DVB core... */ pvr2_trace(PVR2_TRACE_DVB_FEED, "dvb feed thread stopped"); return 0; }
void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags) { struct ngene_channel *chan = priv; if (chan->users > 0) dvb_dmx_swfilter(&chan->demux, buf, len); return NULL; }
static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) { struct smsdvb_client_t *client = (struct smsdvb_client_t *) context; struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *)(((u8 *) cb->p) + cb->offset); switch (phdr->msgType) { case MSG_SMS_DVBT_BDA_DATA: dvb_dmx_swfilter(&client->demux, (u8 *)(phdr + 1), cb->size - sizeof(struct SmsMsgHdr_ST)); break; case MSG_SMS_RF_TUNE_RES: complete(&client->tune_done); break; case MSG_SMS_GET_STATISTICS_RES: { struct SmsMsgStatisticsInfo_ST *p = (struct SmsMsgStatisticsInfo_ST *)(phdr + 1); if (p->Stat.IsDemodLocked) { client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; client->fe_snr = p->Stat.SNR; client->fe_ber = p->Stat.BER; client->fe_unc = p->Stat.BERErrorCount; if (p->Stat.InBandPwr < -95) client->fe_signal_strength = 0; else if (p->Stat.InBandPwr > -29) client->fe_signal_strength = 100; else client->fe_signal_strength = (p->Stat.InBandPwr + 95) * 3 / 2; } else { client->fe_status = 0; client->fe_snr = client->fe_ber = client->fe_unc = client->fe_signal_strength = 0; } complete(&client->stat_done); break; } } smscore_putbuffer(client->coredev, cb); return 0; }
static void dvb_urb_irq(struct urb *urb) { struct pd_dvb_adapter *pd_dvb = urb->context; int len = urb->transfer_buffer_length; struct dvb_demux *demux = &pd_dvb->demux; s32 ret; if (!pd_dvb->is_streaming || urb->status) { if (urb->status == -EPROTO) goto resend; return; } if (urb->actual_length == len) dvb_dmx_swfilter(demux, urb->transfer_buffer, len); else if (urb->actual_length == len - 4) { int offset; u8 *buf = urb->transfer_buffer; /* * The packet size is 512, * last packet contains 456 bytes tsp data */ for (offset = 456; offset < len; offset += 512) { if (!strncmp(buf + offset, "DVHS", 4)) { dvb_dmx_swfilter(demux, buf, offset); if (len > offset + 52 + 4) { /*16 bytes trailer + 36 bytes padding */ buf += offset + 52; len -= offset + 52 + 4; dvb_dmx_swfilter(demux, buf, len); } break; } } } resend: ret = usb_submit_urb(urb, GFP_ATOMIC); if (ret) log(" usb_submit_urb failed: error %d", ret); }
static int videobuf_dvb_thread(void *data) { struct videobuf_dvb *dvb = data; struct videobuf_buffer *buf; unsigned long flags; int err; void *outp; dprintk("dvb thread started\n"); set_freezable(); videobuf_read_start(&dvb->dvbq); for (;;) { /* fetch next buffer */ buf = list_entry(dvb->dvbq.stream.next, struct videobuf_buffer, stream); list_del(&buf->stream); err = videobuf_waiton(buf,0,1); /* no more feeds left or stop_feed() asked us to quit */ if (0 == dvb->nfeeds) break; if (kthread_should_stop()) break; try_to_freeze(); /* feed buffer data to demux */ outp = videobuf_queue_to_vmalloc (&dvb->dvbq, buf); if (buf->state == VIDEOBUF_DONE) dvb_dmx_swfilter(&dvb->demux, outp, buf->size); /* requeue buffer */ list_add_tail(&buf->stream,&dvb->dvbq.stream); spin_lock_irqsave(dvb->dvbq.irqlock,flags); dvb->dvbq.ops->buf_queue(&dvb->dvbq,buf); spin_unlock_irqrestore(dvb->dvbq.irqlock,flags); } videobuf_read_stop(&dvb->dvbq); dprintk("dvb thread stopped\n"); /* Hmm, linux becomes *very* unhappy without this ... */ while (!kthread_should_stop()) { set_current_state(TASK_INTERRUPTIBLE); schedule(); } return 0; }
void as102_urb_stream_irq(struct urb *urb) { struct as102_dev_t *as102_dev = urb->context; if (urb->actual_length > 0) { dvb_dmx_swfilter(&as102_dev->dvb_dmx, urb->transfer_buffer, urb->actual_length); } else { if (urb->actual_length == 0) memset(urb->transfer_buffer, 0, AS102_USB_BUF_SIZE); } /* is not stopped, re-submit urb */ if (as102_dev->streaming) as102_submit_urb_stream(as102_dev, urb); }
static void cx18_mdl_send_to_dvb(struct cx18_stream *s, struct cx18_mdl *mdl) { struct cx18_buffer *buf; if (s->dvb == NULL || !s->dvb->enabled || mdl->bytesused == 0) return; if (list_is_singular(&mdl->buf_list)) { buf = list_first_entry(&mdl->buf_list, struct cx18_buffer, list); if (buf->bytesused) dvb_dmx_swfilter(&s->dvb->demux, buf->buf, buf->bytesused); return; }
static void cx18_mdl_send_to_dvb(struct cx18_stream *s, struct cx18_mdl *mdl) { struct cx18_buffer *buf; if (s->dvb == NULL || !s->dvb->enabled || mdl->bytesused == 0) return; /* We ignore mdl and buf readpos accounting here - it doesn't matter */ /* The likely case */ if (list_is_singular(&mdl->buf_list)) { buf = list_first_entry(&mdl->buf_list, struct cx18_buffer, list); if (buf->bytesused) dvb_dmx_swfilter(&s->dvb->demux, buf->buf, buf->bytesused); return; }
void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags) { struct ngene_channel *chan = priv; struct ngene *dev = chan->dev; if (flags & DF_SWAP32) swap_buffer(buf, len); if (dev->ci.en && chan->number == 2) { while (len >= 188) { if (memcmp(buf, fill_ts, sizeof fill_ts) != 0) { if (dvb_ringbuffer_free(&dev->tsin_rbuf) >= 188) { dvb_ringbuffer_write(&dev->tsin_rbuf, buf, 188); wake_up(&dev->tsin_rbuf.queue); #ifdef DEBUG_CI_XFER ok++; #endif } #ifdef DEBUG_CI_XFER else overflow++; #endif } #ifdef DEBUG_CI_XFER else stripped++; if (ok % 100 == 0 && overflow) printk(KERN_WARNING "%s: ok %u overflow %u dropped %u\n", __func__, ok, overflow, stripped); #endif buf += 188; len -= 188; } return NULL; } if (chan->users > 0) dvb_dmx_swfilter(&chan->demux, buf, len); return NULL; }
static void tm6000_urb_received(struct urb *urb) { int ret; struct tm6000_core *dev = urb->context; if (urb->status != 0) print_err_status(dev, 0, urb->status); else if (urb->actual_length > 0) dvb_dmx_swfilter(&dev->dvb->demux, urb->transfer_buffer, urb->actual_length); if (dev->dvb->streams > 0) { ret = usb_submit_urb(urb, GFP_ATOMIC); if (ret < 0) { printk(KERN_ERR "tm6000: error %s\n", __func__); kfree(urb->transfer_buffer); usb_free_urb(urb); } } }
void as102_urb_stream_irq(struct urb *urb) #endif { struct as102_dev_t *as102_dev = urb->context; if (urb->actual_length > 0) { #if defined(CONFIG_DVB_CORE) || defined(CONFIG_DVB_CORE_MODULE) dvb_dmx_swfilter(&as102_dev->dvb_dmx, urb->transfer_buffer, urb->actual_length); #else /* do nothing ? */ #endif } else { if (urb->actual_length == 0) memset(urb->transfer_buffer, 0, AS102_USB_BUF_SIZE); } /* is not stopped, re-submit urb */ if (as102_dev->streaming) as102_submit_urb_stream(as102_dev, urb); }
static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) { struct smsdvb_client_t *client = (struct smsdvb_client_t *) context; struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) (((u8 *) cb->p) + cb->offset); u32 *pMsgData = (u32 *) (phdr + 1); /*u32 MsgDataLen = phdr->msgLength - sizeof(struct SmsMsgHdr_ST);*/ bool is_status_update = false; smsendian_handle_rx_message((struct SmsMsgData_ST *) phdr); switch (phdr->msgType) { case MSG_SMS_DVBT_BDA_DATA: dvb_dmx_swfilter(&client->demux, (u8 *) (phdr + 1), cb->size - sizeof(struct SmsMsgHdr_ST)); break; case MSG_SMS_ISDBT_TUNE_RES: sms_info("MSG_SMS_ISDBT_TUNE_RES"); case MSG_SMS_RF_TUNE_RES: complete(&client->tune_done); break; case MSG_SMS_SIGNAL_DETECTED_IND: sms_info("MSG_SMS_SIGNAL_DETECTED_IND"); client->sms_stat_dvb.ReceptionData.IsDemodLocked = true; is_status_update = true; break; case MSG_SMS_NO_SIGNAL_IND: sms_info("MSG_SMS_NO_SIGNAL_IND"); client->sms_stat_dvb.ReceptionData.IsDemodLocked = false; is_status_update = true; break; case MSG_SMS_TRANSMISSION_IND: { sms_info("MSG_SMS_TRANSMISSION_IND"); memcpy(&client->sms_stat_dvb.TransmissionData, pMsgData, sizeof(struct TRANSMISSION_STATISTICS_S)); /* Mo need to correct guard interval * (as opposed to old statistics message). */ CORRECT_STAT_BANDWIDTH(client->sms_stat_dvb.TransmissionData); CORRECT_STAT_TRANSMISSON_MODE( client->sms_stat_dvb.TransmissionData); is_status_update = true; break; } case MSG_SMS_HO_PER_SLICES_IND: { struct RECEPTION_STATISTICS_S *pReceptionData = &client->sms_stat_dvb.ReceptionData; struct SRVM_SIGNAL_STATUS_S SignalStatusData; /*sms_info("MSG_SMS_HO_PER_SLICES_IND");*/ SignalStatusData.result = pMsgData[0]; SignalStatusData.snr = pMsgData[1]; SignalStatusData.inBandPower = (s32) pMsgData[2]; SignalStatusData.tsPackets = pMsgData[3]; SignalStatusData.etsPackets = pMsgData[4]; SignalStatusData.constellation = pMsgData[5]; SignalStatusData.hpCode = pMsgData[6]; SignalStatusData.tpsSrvIndLP = pMsgData[7] & 0x03; SignalStatusData.tpsSrvIndHP = pMsgData[8] & 0x03; SignalStatusData.cellId = pMsgData[9] & 0xFFFF; SignalStatusData.reason = pMsgData[10]; SignalStatusData.requestId = pMsgData[11]; pReceptionData->IsRfLocked = pMsgData[16]; pReceptionData->IsDemodLocked = pMsgData[17]; pReceptionData->ModemState = pMsgData[12]; pReceptionData->SNR = pMsgData[1]; pReceptionData->BER = pMsgData[13]; pReceptionData->RSSI = pMsgData[14]; CORRECT_STAT_RSSI(client->sms_stat_dvb.ReceptionData); pReceptionData->InBandPwr = (s32) pMsgData[2]; pReceptionData->CarrierOffset = (s32) pMsgData[15]; pReceptionData->TotalTSPackets = pMsgData[3]; pReceptionData->ErrorTSPackets = pMsgData[4]; /* TS PER */ if ((SignalStatusData.tsPackets + SignalStatusData.etsPackets) > 0) { pReceptionData->TS_PER = (SignalStatusData.etsPackets * 100) / (SignalStatusData.tsPackets + SignalStatusData.etsPackets); } else { pReceptionData->TS_PER = 0; } pReceptionData->BERBitCount = pMsgData[18]; pReceptionData->BERErrorCount = pMsgData[19]; pReceptionData->MRC_SNR = pMsgData[20]; pReceptionData->MRC_InBandPwr = pMsgData[21]; pReceptionData->MRC_RSSI = pMsgData[22]; is_status_update = true; break; } case MSG_SMS_GET_STATISTICS_EX_RES: { struct RECEPTION_STATISTICS_S *pReceptionData = &client->sms_stat_dvb.ReceptionData; struct SMSHOSTLIB_STATISTICS_ISDBT_S *pStatsIsdbt; struct SRVM_SIGNAL_STATUS_S SignalStatusData; /*sms_info("MSG_SMS_GET_STATISTICS_EX_RES");*/ pMsgData++; pStatsIsdbt = (struct SMSHOSTLIB_STATISTICS_ISDBT_S*)pMsgData; /* sms_info("%d layers detected", pStatsIsdbt->NumOfLayers); sms_info("InBandPwr = %d dBm", pStatsIsdbt->InBandPwr); sms_info("SNR = %d dB", pStatsIsdbt->SNR); sms_info("RSSI = %d dBm", pStatsIsdbt->RSSI); */ /* update signal status */ SignalStatusData.snr = pStatsIsdbt->SNR; SignalStatusData.tsPackets = pStatsIsdbt->LayerInfo[0].TotalTSPackets; SignalStatusData.etsPackets = pStatsIsdbt->LayerInfo[0].ErrorTSPackets; SignalStatusData.constellation = pStatsIsdbt->LayerInfo[0].Constellation; SignalStatusData.inBandPower = pStatsIsdbt->InBandPwr; /* update reception data */ pReceptionData->IsRfLocked = pStatsIsdbt->IsRfLocked; pReceptionData->IsDemodLocked = pStatsIsdbt->IsDemodLocked; pReceptionData->ModemState = pStatsIsdbt->ModemState; pReceptionData->SNR = pStatsIsdbt->SNR; pReceptionData->BER = pStatsIsdbt->LayerInfo[0].BER; pReceptionData->BERErrorCount = pStatsIsdbt->LayerInfo[0].BERErrorCount; pReceptionData->BERBitCount = pStatsIsdbt->LayerInfo[0].BERBitCount; pReceptionData->RSSI = pStatsIsdbt->RSSI; CORRECT_STAT_RSSI(client->sms_stat_dvb.ReceptionData); pReceptionData->InBandPwr = pStatsIsdbt->InBandPwr; pReceptionData->CarrierOffset = pStatsIsdbt->CarrierOffset; pReceptionData->ErrorTSPackets = pStatsIsdbt->LayerInfo[0].ErrorTSPackets; pReceptionData->TotalTSPackets = pStatsIsdbt->LayerInfo[0].TotalTSPackets; /* TS PER */ if ((SignalStatusData.tsPackets + SignalStatusData.etsPackets) > 0) { pReceptionData->TS_PER = (SignalStatusData.etsPackets * 100) / (SignalStatusData.tsPackets + SignalStatusData.etsPackets); } else { pReceptionData->TS_PER = 0; } /* pReceptionData->MRC_SNR = pReceptionData->MRC_InBandPwr = pReceptionData->MRC_RSSI = */ client->last_sample_time = jiffies_to_msecs(jiffies); is_status_update = true; complete(&client->get_stats_done); break; } } smscore_putbuffer(client->coredev, cb); if (is_status_update) { /* sms_info("client->fe_status = %d",client->fe_status); sms_info("--- TransmissionData ---"); sms_info(" Frequency %d", client->sms_stat_dvb.TransmissionData.Frequency); sms_info(" Constellation %d", client->sms_stat_dvb.TransmissionData.Constellation); sms_info(" IsDemodLocked %d", client->sms_stat_dvb.TransmissionData.IsDemodLocked); sms_info("--- ReceptionData ---"); sms_info(" IsDemodLocked %d", client->sms_stat_dvb.ReceptionData.IsDemodLocked); sms_info(" BER %d", client->sms_stat_dvb.ReceptionData.BER); sms_info(" ErrorTSPackets %d", client->sms_stat_dvb.ReceptionData.ErrorTSPackets); sms_info(" InBandPwr %d", client->sms_stat_dvb.ReceptionData.InBandPwr); sms_info(" IsRfLocked %d", client->sms_stat_dvb.ReceptionData.IsRfLocked); sms_info(" RSSI %d", client->sms_stat_dvb.ReceptionData.RSSI); sms_info(" SNR %d", client->sms_stat_dvb.ReceptionData.SNR); */ if (client->sms_stat_dvb.ReceptionData.IsDemodLocked) { client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; sms_board_dvb3_event(client, DVB3_EVENT_FE_LOCK); if (client->sms_stat_dvb.ReceptionData.ErrorTSPackets == 0) sms_board_dvb3_event(client, DVB3_EVENT_UNC_OK); else sms_board_dvb3_event(client, DVB3_EVENT_UNC_ERR); } else { /*client->fe_status = (phdr->msgType == MSG_SMS_NO_SIGNAL_IND) ? 0 : FE_HAS_SIGNAL;*/ client->fe_status = 0; sms_board_dvb3_event(client, DVB3_EVENT_FE_UNLOCK); } } return 0; }
static void dvb_usb_data_complete(struct usb_data_stream *stream, u8 *buf, size_t len) { struct dvb_usb_adapter *adap = stream->user_priv; dvb_dmx_swfilter(&adap->demux, buf, len); }
/* these methods are necessary to achieve the long-term-goal of hiding the * struct flexcop_device from the bus-parts */ void flexcop_pass_dmx_data(struct flexcop_device *fc, u8 *buf, u32 len) { dvb_dmx_swfilter(&fc->demux, buf, len); }
static void dvb_usb_data_complete(struct usb_data_stream *stream, u8 *buffer, size_t length) { struct dvb_usb_adapter *adap = stream->user_priv; if (adap->feedcount > 0 && adap->state & DVB_USB_ADAP_STATE_DVB) dvb_dmx_swfilter(&adap->demux, buffer, length); }
static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb) { struct smsdvb_client_t *client = (struct smsdvb_client_t *) context; struct sms_msg_hdr *phdr = (struct sms_msg_hdr *) (((u8 *) cb->p) + cb->offset); void *p = phdr + 1; struct dvb_frontend *fe = &client->frontend; struct dtv_frontend_properties *c = &fe->dtv_property_cache; bool is_status_update = false; switch (phdr->msg_type) { case MSG_SMS_DVBT_BDA_DATA: /* * Only feed data to dvb demux if are there any feed listening * to it and if the device has tuned */ if (client->feed_users && client->has_tuned) dvb_dmx_swfilter(&client->demux, p, cb->size - sizeof(struct sms_msg_hdr)); break; case MSG_SMS_RF_TUNE_RES: case MSG_SMS_ISDBT_TUNE_RES: complete(&client->tune_done); break; case MSG_SMS_SIGNAL_DETECTED_IND: client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; is_status_update = true; break; case MSG_SMS_NO_SIGNAL_IND: client->fe_status = 0; is_status_update = true; break; case MSG_SMS_TRANSMISSION_IND: smsdvb_update_tx_params(client, p); is_status_update = true; break; case MSG_SMS_HO_PER_SLICES_IND: smsdvb_update_per_slices(client, p); is_status_update = true; break; case MSG_SMS_GET_STATISTICS_RES: switch (smscore_get_device_mode(client->coredev)) { case DEVICE_MODE_ISDBT: case DEVICE_MODE_ISDBT_BDA: smsdvb_update_isdbt_stats(client, p); break; default: /* Skip sms_msg_statistics_info:request_result field */ smsdvb_update_dvb_stats(client, p + sizeof(u32)); } is_status_update = true; break; /* Only for ISDB-T */ case MSG_SMS_GET_STATISTICS_EX_RES: /* Skip sms_msg_statistics_info:request_result field? */ smsdvb_update_isdbt_stats_ex(client, p + sizeof(u32)); is_status_update = true; break; default: pr_debug("message not handled\n"); } smscore_putbuffer(client->coredev, cb); if (is_status_update) { if (client->fe_status & FE_HAS_LOCK) { sms_board_dvb3_event(client, DVB3_EVENT_FE_LOCK); if (client->last_per == c->block_error.stat[0].uvalue) sms_board_dvb3_event(client, DVB3_EVENT_UNC_OK); else sms_board_dvb3_event(client, DVB3_EVENT_UNC_ERR); client->has_tuned = true; } else { smsdvb_stats_not_ready(fe); client->has_tuned = false; sms_board_dvb3_event(client, DVB3_EVENT_FE_UNLOCK); } complete(&client->stats_done); } return 0; }
static void epu_dma_done(struct cx18 *cx, struct cx18_epu_work_order *order) { u32 handle, mdl_ack_count, id; struct cx18_mailbox *mb; struct cx18_mdl_ack *mdl_ack; struct cx18_stream *s; struct cx18_buffer *buf; int i; mb = &order->mb; handle = mb->args[0]; s = cx18_handle_to_stream(cx, handle); if (s == NULL) { CX18_WARN("Got DMA done notification for unknown/inactive" " handle %d, %s mailbox seq no %d\n", handle, (order->flags & CX18_F_EWO_MB_STALE_UPON_RECEIPT) ? "stale" : "good", mb->request); return; } mdl_ack_count = mb->args[2]; mdl_ack = order->mdl_ack; for (i = 0; i < mdl_ack_count; i++, mdl_ack++) { id = mdl_ack->id; /* * Simple integrity check for processing a stale (and possibly * inconsistent mailbox): make sure the buffer id is in the * valid range for the stream. * * We go through the trouble of dealing with stale mailboxes * because most of the time, the mailbox data is still valid and * unchanged (and in practice the firmware ping-pongs the * two mdl_ack buffers so mdl_acks are not stale). * * There are occasions when we get a half changed mailbox, * which this check catches for a handle & id mismatch. If the * handle and id do correspond, the worst case is that we * completely lost the old buffer, but pick up the new buffer * early (but the new mdl_ack is guaranteed to be good in this * case as the firmware wouldn't point us to a new mdl_ack until * it's filled in). * * cx18_queue_get buf() will detect the lost buffers * and send them back to q_free for fw rotation eventually. */ if ((order->flags & CX18_F_EWO_MB_STALE_UPON_RECEIPT) && !(id >= s->mdl_offset && id < (s->mdl_offset + s->buffers))) { CX18_WARN("Fell behind! Ignoring stale mailbox with " " inconsistent data. Lost buffer for mailbox " "seq no %d\n", mb->request); break; } buf = cx18_queue_get_buf(s, id, mdl_ack->data_used); CX18_DEBUG_HI_DMA("DMA DONE for %s (buffer %d)\n", s->name, id); if (buf == NULL) { CX18_WARN("Could not find buf %d for stream %s\n", id, s->name); /* Put as many buffers as possible back into fw use */ cx18_stream_load_fw_queue(s); continue; } if (s->type == CX18_ENC_STREAM_TYPE_TS && s->dvb.enabled) { CX18_DEBUG_HI_DMA("TS recv bytesused = %d\n", buf->bytesused); dvb_dmx_swfilter(&s->dvb.demux, buf->buf, buf->bytesused); } /* Put as many buffers as possible back into fw use */ cx18_stream_load_fw_queue(s); /* Put back TS buffer, since it was removed from all queues */ if (s->type == CX18_ENC_STREAM_TYPE_TS) cx18_stream_put_buf_fw(s, buf); } wake_up(&cx->dma_waitq); if (s->id != -1) wake_up(&s->waitq); }