Sparse found a bug: while ((kv_buf + kv_len - 1) == '\0') should have been while (kv_buf[kv_len - 1] == '\0') We fix it by a better implementation without a temporary copy. Also fix sparse warnings of 0 instead of NULL and signedness mismatches. Signed-off-by: Stefan Richter <stefanr at s5r6.in-berlin.de> --- drivers/media/dvb/firesat/avc_api.c | 14 +++++++------- drivers/media/dvb/firesat/avc_api.h | 6 +++--- drivers/media/dvb/firesat/firesat_1394.c | 23 +++++++---------------- drivers/media/dvb/firesat/firesat_dvb.c | 2 +- 4 files changed, 18 insertions(+), 27 deletions(-) Index: linux/drivers/media/dvb/firesat/firesat_1394.c =================================================================== --- linux.orig/drivers/media/dvb/firesat/firesat_1394.c +++ linux/drivers/media/dvb/firesat/firesat_1394.c @@ -146,8 +146,8 @@ static int firesat_probe(struct device * struct firesat *firesat; unsigned long flags; int kv_len; + void *kv_str; int i; - char *kv_buf; int err = -ENOMEM; firesat = kzalloc(sizeof(*firesat), GFP_KERNEL); @@ -169,20 +169,12 @@ static int firesat_probe(struct device * /* Reading device model from ROM */ kv_len = (ud->model_name_kv->value.leaf.len - 2) * sizeof(quadlet_t); - kv_buf = kmalloc((sizeof(quadlet_t) * kv_len), GFP_KERNEL); - if (!kv_buf) - goto fail_free; - memcpy(kv_buf, CSR1212_TEXTUAL_DESCRIPTOR_LEAF_DATA(ud->model_name_kv), - kv_len); - while ((kv_buf + kv_len - 1) == '\0') - kv_len--; - kv_buf[kv_len++] = '\0'; - + kv_str = CSR1212_TEXTUAL_DESCRIPTOR_LEAF_DATA(ud->model_name_kv); for (i = ARRAY_SIZE(firedtv_model_names); --i;) - if (strcmp(kv_buf, firedtv_model_names[i]) == 0) + if (strlen(firedtv_model_names[i]) <= kv_len && + strncmp(kv_str, firedtv_model_names[i], kv_len) == 0) break; firesat->type = i; - kfree(kv_buf); INIT_LIST_HEAD(&firesat->list); spin_lock_irqsave(&firesat_list_lock, flags); @@ -191,20 +183,19 @@ static int firesat_probe(struct device * err = AVCIdentifySubunit(firesat); if (err) - goto fail_unlist; + goto fail; err = firesat_dvbdev_init(firesat, dev); if (err) - goto fail_unlist; + goto fail; AVCRegisterRemoteControl(firesat); return 0; -fail_unlist: +fail: spin_lock_irqsave(&firesat_list_lock, flags); list_del(&firesat->list); spin_unlock_irqrestore(&firesat_list_lock, flags); -fail_free: kfree(firesat); return err; } Index: linux/drivers/media/dvb/firesat/firesat_dvb.c =================================================================== --- linux.orig/drivers/media/dvb/firesat/firesat_dvb.c +++ linux/drivers/media/dvb/firesat/firesat_dvb.c @@ -173,7 +173,7 @@ int firesat_stop_feed(struct dvb_demux_f return -EINVAL; demux->pids[dvbdmxfeed->pes_type] |= 0x8000; - demux->pesfilter[dvbdmxfeed->pes_type] = 0; + demux->pesfilter[dvbdmxfeed->pes_type] = NULL; } if (!(dvbdmxfeed->ts_type & TS_DECODER && Index: linux/drivers/media/dvb/firesat/avc_api.c =================================================================== --- linux.orig/drivers/media/dvb/firesat/avc_api.c +++ linux/drivers/media/dvb/firesat/avc_api.c @@ -880,7 +880,7 @@ static int get_ca_object_length(AVCRspFr return RspFrm->operand[7]; } -int avc_ca_app_info(struct firesat *firesat, char *app_info, int *length) +int avc_ca_app_info(struct firesat *firesat, char *app_info, unsigned int *len) { AVCCmdFrm CmdFrm; AVCRspFrm RspFrm; @@ -912,12 +912,12 @@ int avc_ca_app_info(struct firesat *fire app_info[3] = 6 + RspFrm.operand[pos + 4]; app_info[4] = 0x01; memcpy(&app_info[5], &RspFrm.operand[pos], 5 + RspFrm.operand[pos + 4]); - *length = app_info[3] + 4; + *len = app_info[3] + 4; return 0; } -int avc_ca_info(struct firesat *firesat, char *app_info, int *length) +int avc_ca_info(struct firesat *firesat, char *app_info, unsigned int *len) { AVCCmdFrm CmdFrm; AVCRspFrm RspFrm; @@ -948,7 +948,7 @@ int avc_ca_info(struct firesat *firesat, app_info[3] = 2; app_info[4] = app_info[5]; app_info[5] = app_info[6]; - *length = app_info[3] + 4; + *len = app_info[3] + 4; return 0; } @@ -1178,7 +1178,7 @@ int avc_ca_enter_menu(struct firesat *fi return 0; } -int avc_ca_get_mmi(struct firesat *firesat, char *mmi_object, int *length) +int avc_ca_get_mmi(struct firesat *firesat, char *mmi_object, unsigned int *len) { AVCCmdFrm CmdFrm; AVCRspFrm RspFrm; @@ -1203,8 +1203,8 @@ int avc_ca_get_mmi(struct firesat *fires if(AVCWrite(firesat,&CmdFrm,&RspFrm) < 0) return -EIO; - *length = get_ca_object_length(&RspFrm); - memcpy(mmi_object, &RspFrm.operand[get_ca_object_pos(&RspFrm)], *length); + *len = get_ca_object_length(&RspFrm); + memcpy(mmi_object, &RspFrm.operand[get_ca_object_pos(&RspFrm)], *len); return 0; } Index: linux/drivers/media/dvb/firesat/avc_api.h =================================================================== --- linux.orig/drivers/media/dvb/firesat/avc_api.h +++ linux/drivers/media/dvb/firesat/avc_api.h @@ -434,12 +434,12 @@ int AVCLNBControl(struct firesat *firesa void avc_remote_ctrl_work(struct work_struct *work); int AVCRegisterRemoteControl(struct firesat *firesat); int AVCTuner_Host2Ca(struct firesat *firesat); -int avc_ca_app_info(struct firesat *firesat, char *app_info, int *length); -int avc_ca_info(struct firesat *firesat, char *app_info, int *length); +int avc_ca_app_info(struct firesat *firesat, char *app_info, unsigned int *len); +int avc_ca_info(struct firesat *firesat, char *app_info, unsigned int *len); int avc_ca_reset(struct firesat *firesat); int avc_ca_pmt(struct firesat *firesat, char *app_info, int length); int avc_ca_get_time_date(struct firesat *firesat, int *interval); int avc_ca_enter_menu(struct firesat *firesat); -int avc_ca_get_mmi(struct firesat *firesat, char *mmi_object, int *length); +int avc_ca_get_mmi(struct firesat *firesat, char *mmi_object, unsigned int *len); #endif /* _AVC_API_H */ -- Stefan Richter -=====-==--- =--= ===-= http://arcgraph.de/sr/