On Sun, 2006-01-08 at 02:45 +0100, Edgar Toernig wrote: > These patches are my collection of changes for the > dvb_bt8xx and especially the Pinnacle PCTV-Sat driver > for kernel version 2.6.15. The current 2.6.15 version > of the PCTV-Sat driver is non-functional. > > This message contains the complete patch, the following > six messages the broken down versions with details. > > [1/6] Clean up printks > [2/6] Fix relay handling. > [3/6] Remove op_sync_orin and irq_err_ignore > [4/6] Check msg_len in cx24110_send_diseqc_msg > [5/6] Change mode of module params to 0644 > [6/6] Misc cleanup and robustness tweaks I've tested these patches a bit (with a big bunch of twinhan VP1030A cards) and have so far found no regressions. Without this patch I got about 15 "irq FDSR" messages in the log for a 30 minute test. With this patch they are all gone. I read through part 6/6 (had to manually apply because of stupid mailer) and I didn't like how it was presented. It mixes potentially very important semantic changes (like how the pci accesses are done) with quite complex cosmetic changes like this: > - RISC_STATUS(((buf_pos / > - bt->block_bytes) + > - (bt->block_count - > - 1)) % > - bt->block_count) | bt-> > - line_bytes); > + RISC_STATUS(((buf_pos / bt->block_bytes) + > + bt->block_count - 1) % > + bt->block_count) | > + bt->line_bytes); These kinds of changes are in my opinion very difficult to check for whether they actually change anything or are only cleanup, and should belong in commits that have _only_ cleanup changes. Also, some people complain about lacking Signed-off-by: lines... Regards, Sigmund > > > Ciao, ET. > > --- > > Combined patch: > > bt8xx/bt878.c | 186 +++++++++++++++++++--------------------- > bt8xx/bt878.h | 19 +--- > bt8xx/dvb-bt8xx.c | 102 +++++++-------------- > bt8xx/dvb-bt8xx.h | 2 > dvb-core/dvb_frontend.c | 8 - > frontends/cx24110.c | 15 +++ > frontends/cx24110.h | 1 > 7 files changed, 151 insertions(+), 182 deletions(-) > > --- 0.1/drivers/media/dvb/frontends/cx24110.h Sat, 07 Jan 2006 00:06:16 +0100 froese (kernel-dvb/f/41_cx24110.h 1.1 644) > +++ 0.7/drivers/media/dvb/frontends/cx24110.h Sat, 07 Jan 2006 01:12:16 +0100 froese (kernel-dvb/f/41_cx24110.h 1.2 644) > @@ -35,6 +35,7 @@ > /* PLL maintenance */ > int (*pll_init)(struct dvb_frontend* fe); > int (*pll_set)(struct dvb_frontend* fe, struct dvb_frontend_parameters* params); > + int (*pll_sleep)(struct dvb_frontend* fe); > }; > > extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config, > --- 0.1/drivers/media/dvb/frontends/cx24110.c Sat, 07 Jan 2006 00:06:16 +0100 froese (kernel-dvb/f/42_cx24110.c 1.1 644) > +++ 0.7/drivers/media/dvb/frontends/cx24110.c Sat, 07 Jan 2006 20:21:12 +0100 froese (kernel-dvb/f/42_cx24110.c 1.4 644) > @@ -251,7 +251,7 @@ > static const u32 bands[]={5000000UL,15000000UL,90999000UL/2}; > int i; > > -dprintk("cx24110 debug: entering %s(%d)\n",__FUNCTION__,srate); > + dprintk("cx24110 debug: entering %s(%d)\n",__FUNCTION__,srate); > if (srate>90999000UL/2) > srate=90999000UL/2; > if (srate<500000) > @@ -372,6 +372,15 @@ > return 0; > } > > +static int cx24110_sleep(struct dvb_frontend *fe) > +{ > + struct cx24110_state *state = fe->demodulator_priv; > + > + if (state->config->pll_sleep) > + return state->config->pll_sleep(fe); > + return 0; > +} > + > static int cx24110_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage) > { > struct cx24110_state *state = fe->demodulator_priv; > @@ -419,6 +428,9 @@ > struct cx24110_state *state = fe->demodulator_priv; > unsigned long timeout; > > + if (cmd->msg_len < 3 || cmd->msg_len > 6) > + return -EINVAL; /* not implemented */ > + > for (i = 0; i < cmd->msg_len; i++) > cx24110_writereg(state, 0x79 + i, cmd->msg[i]); > > @@ -640,6 +652,7 @@ > .release = cx24110_release, > > .init = cx24110_initfe, > + .sleep = cx24110_sleep, > .set_frontend = cx24110_set_frontend, > .get_frontend = cx24110_get_frontend, > .read_status = cx24110_read_status, > --- 0.1/drivers/media/dvb/dvb-core/dvb_frontend.c Sat, 07 Jan 2006 00:06:16 +0100 froese (kernel-dvb/g/41_dvb_fronte 1.1 644) > +++ 0.7/drivers/media/dvb/dvb-core/dvb_frontend.c Sat, 07 Jan 2006 20:22:38 +0100 froese (kernel-dvb/g/41_dvb_fronte 1.2 644) > @@ -50,13 +50,13 @@ > > module_param_named(frontend_debug, dvb_frontend_debug, int, 0644); > MODULE_PARM_DESC(frontend_debug, "Turn on/off frontend core debugging (default:off)."); > -module_param(dvb_shutdown_timeout, int, 0444); > +module_param(dvb_shutdown_timeout, int, 0644); > MODULE_PARM_DESC(dvb_shutdown_timeout, "wait <shutdown_timeout> seconds after close() before suspending hardware"); > -module_param(dvb_force_auto_inversion, int, 0444); > +module_param(dvb_force_auto_inversion, int, 0644); > MODULE_PARM_DESC(dvb_force_auto_inversion, "0: normal (default), 1: INVERSION_AUTO forced always"); > -module_param(dvb_override_tune_delay, int, 0444); > +module_param(dvb_override_tune_delay, int, 0644); > MODULE_PARM_DESC(dvb_override_tune_delay, "0: normal (default), >0 => delay in milliseconds to wait for lock after a tune attempt"); > -module_param(dvb_powerdown_on_sleep, int, 0444); > +module_param(dvb_powerdown_on_sleep, int, 0644); > MODULE_PARM_DESC(dvb_powerdown_on_sleep, "0: do not power down, 1: turn LNB volatage off on sleep (default)"); > > #define dprintk if (dvb_frontend_debug) printk > --- 0.1/drivers/media/dvb/bt8xx/dvb-bt8xx.h Sat, 07 Jan 2006 00:06:16 +0100 froese (kernel-dvb/h/8_dvb-bt8xx. 1.1 644) > +++ 0.7/drivers/media/dvb/bt8xx/dvb-bt8xx.h Sat, 07 Jan 2006 02:03:06 +0100 froese (kernel-dvb/h/8_dvb-bt8xx. 1.2 644) > @@ -49,8 +49,6 @@ > struct dmx_frontend fe_hw; > struct dmx_frontend fe_mem; > u32 gpio_mode; > - u32 op_sync_orin; > - u32 irq_err_ignore; > struct i2c_adapter *i2c_adapter; > struct dvb_net dvbnet; > > --- 0.1/drivers/media/dvb/bt8xx/dvb-bt8xx.c Sat, 07 Jan 2006 00:06:16 +0100 froese (kernel-dvb/h/9_dvb-bt8xx. 1.1 644) > +++ 0.7/drivers/media/dvb/bt8xx/dvb-bt8xx.c Sat, 07 Jan 2006 02:03:06 +0100 froese (kernel-dvb/h/9_dvb-bt8xx. 1.4 644) > @@ -52,8 +52,6 @@ > { > struct dvb_bt8xx_card *card = (struct dvb_bt8xx_card *)data; > > - //printk("%d ", card->bt->finished_block); > - > while (card->bt->last_block != card->bt->finished_block) { > (card->bt->TS_Size ? dvb_dmx_swfilter_204 : dvb_dmx_swfilter) > (&card->demux, > @@ -80,8 +78,7 @@ > card->nfeeds++; > rc = card->nfeeds; > if (card->nfeeds == 1) > - bt878_start(card->bt, card->gpio_mode, > - card->op_sync_orin, card->irq_err_ignore); > + bt878_start(card->bt, card->gpio_mode); > up(&card->lock); > return rc; > } > @@ -198,7 +195,7 @@ > 0x00120000,0x00140000}; > > #define XTAL 1011100 /* Hz, really 1.0111 MHz and a /10 prescaler */ > - printk("cx24108 debug: entering SetTunerFreq, freq=%d\n",freq); > + dprintk("cx24108 debug: entering SetTunerFreq, freq=%d\n",freq); > > /* This is really the bit driving the tuner chip cx24108 */ > > @@ -209,7 +206,7 @@ > > /* decide which VCO to use for the input frequency */ > for(i=1;(i<sizeof(osci)/sizeof(osci[0]))&&(osci[i]<freq);i++); > - printk("cx24108 debug: select vco #%d (f=%d)\n",i,freq); > + dprintk("cx24108 debug: select vco #%d (f=%d)\n",i,freq); > band=bandsel[i]; > /* the gain values must be set by SetSymbolrate */ > /* compute the pll divider needed, from Conexant data sheet, > @@ -225,7 +222,7 @@ > ((a&0x1f)<<11); > /* everything is shifted left 11 bits to left-align the bits in the > 32bit word. Output to the tuner goes MSB-aligned, after all */ > - printk("cx24108 debug: pump=%d, n=%d, a=%d\n",pump,n,a); > + dprintk("cx24108 debug: pump=%d, n=%d, a=%d\n",pump,n,a); > cx24110_pll_write(fe,band); > /* set vga and vca to their widest-band settings, as a precaution. > SetSymbolrate might not be called to set this up */ > @@ -239,6 +236,18 @@ > > static int pinnsat_pll_init(struct dvb_frontend* fe) > { > + struct dvb_bt8xx_card *card = fe->dvb->priv; > + > + bttv_gpio_enable(card->bttv_nr, 1, 1); /* output */ > + bttv_write_gpio(card->bttv_nr, 1, 1); /* relay on */ > + return 0; > +} > + > +static int pinnsat_pll_sleep(struct dvb_frontend* fe) > +{ > + struct dvb_bt8xx_card *card = fe->dvb->priv; > + > + bttv_write_gpio(card->bttv_nr, 1, 0); /* relay off */ > return 0; > } > > @@ -246,6 +255,7 @@ > .demod_address = 0x55, > .pll_init = pinnsat_pll_init, > .pll_set = cx24108_pll_set, > + .pll_sleep = pinnsat_pll_sleep, > }; > > static int microtune_mt7202dtf_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) > @@ -615,7 +625,7 @@ > lgdt330x_reset(card); > card->fe = lgdt330x_attach(&tdvs_tua6034_config, card->i2c_adapter); > if (card->fe != NULL) > - dprintk ("dvb_bt8xx: lgdt330x detected\n"); > + dprintk("dvb_bt8xx: lgdt330x detected\n"); > break; > #endif > > @@ -667,7 +677,7 @@ > > /* DST is not a frontend, attaching the ASIC */ > if ((dst_attach(state, &card->dvb_adapter)) == NULL) { > - printk("%s: Could not find a Twinhan DST.\n", __FUNCTION__); > + printk(KERN_ERR "%s: Could not find a Twinhan DST.\n", __FUNCTION__); > break; > } > card->fe = &state->frontend; > @@ -688,14 +698,14 @@ > } > > if (card->fe == NULL) > - printk("dvb-bt8xx: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n", > + printk(KERN_ERR "dvb-bt8xx: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n", > card->bt->dev->vendor, > card->bt->dev->device, > card->bt->dev->subsystem_vendor, > card->bt->dev->subsystem_device); > else > if (dvb_register_frontend(&card->dvb_adapter, card->fe)) { > - printk("dvb-bt8xx: Frontend registration failed!\n"); > + printk(KERN_ERR "dvb-bt8xx: Frontend registration failed!\n"); > if (card->fe->ops->release) > card->fe->ops->release(card->fe); > card->fe = NULL; > @@ -707,7 +717,7 @@ > int result; > > if ((result = dvb_register_adapter(&card->dvb_adapter, card->card_name, THIS_MODULE)) < 0) { > - printk("dvb_bt8xx: dvb_register_adapter failed (errno = %d)\n", result); > + printk(KERN_ERR "dvb_bt8xx: dvb_register_adapter failed (errno = %d)\n", result); > return result; > } > card->dvb_adapter.priv = card; > @@ -726,7 +736,7 @@ > card->demux.write_to_decoder = NULL; > > if ((result = dvb_dmx_init(&card->demux)) < 0) { > - printk("dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result); > + printk(KERN_ERR "dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result); > > dvb_unregister_adapter(&card->dvb_adapter); > return result; > @@ -737,7 +747,7 @@ > card->dmxdev.capabilities = 0; > > if ((result = dvb_dmxdev_init(&card->dmxdev, &card->dvb_adapter)) < 0) { > - printk("dvb_bt8xx: dvb_dmxdev_init failed (errno = %d)\n", result); > + printk(KERN_ERR "dvb_bt8xx: dvb_dmxdev_init failed (errno = %d)\n", result); > > dvb_dmx_release(&card->demux); > dvb_unregister_adapter(&card->dvb_adapter); > @@ -747,7 +757,7 @@ > card->fe_hw.source = DMX_FRONTEND_0; > > if ((result = card->demux.dmx.add_frontend(&card->demux.dmx, &card->fe_hw)) < 0) { > - printk("dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result); > + printk(KERN_ERR "dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result); > > dvb_dmxdev_release(&card->dmxdev); > dvb_dmx_release(&card->demux); > @@ -758,7 +768,7 @@ > card->fe_mem.source = DMX_MEMORY_FE; > > if ((result = card->demux.dmx.add_frontend(&card->demux.dmx, &card->fe_mem)) < 0) { > - printk("dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result); > + printk(KERN_ERR "dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result); > > card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw); > dvb_dmxdev_release(&card->dmxdev); > @@ -768,7 +778,7 @@ > } > > if ((result = card->demux.dmx.connect_frontend(&card->demux.dmx, &card->fe_hw)) < 0) { > - printk("dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result); > + printk(KERN_ERR "dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result); > > card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_mem); > card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw); > @@ -805,73 +815,33 @@ > > switch(sub->core->type) { > case BTTV_BOARD_PINNACLESAT: > - card->gpio_mode = 0x0400c060; > - /* should be: BT878_A_GAIN=0,BT878_A_PWRDN,BT878_DA_DPM,BT878_DA_SBR, > - BT878_DA_IOM=1,BT878_DA_APP to enable serial highspeed mode. */ > - card->op_sync_orin = 0; > - card->irq_err_ignore = 0; > - break; > - > -#ifdef BTTV_BOARD_DVICO_DVBT_LITE > case BTTV_BOARD_DVICO_DVBT_LITE: > -#endif > - card->gpio_mode = 0x0400C060; > - card->op_sync_orin = 0; > - card->irq_err_ignore = 0; > - /* 26, 15, 14, 6, 5 > - * A_PWRDN DA_DPM DA_SBR DA_IOM_DA > - * DA_APP(parallel) */ > - break; > - > -#ifdef BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE > case BTTV_BOARD_DVICO_FUSIONHDTV_5_LITE: > -#endif > - card->gpio_mode = 0x0400c060; > - card->op_sync_orin = BT878_RISC_SYNC_MASK; > - card->irq_err_ignore = BT878_AFBUS | BT878_AFDSR; > + card->gpio_mode = 0x0400c060; /* high speed serial mode */ > break; > > -#ifdef BTTV_BOARD_TWINHAN_VP3021 > - case BTTV_BOARD_TWINHAN_VP3021: > -#else > case BTTV_BOARD_NEBULA_DIGITV: > -#endif > case BTTV_BOARD_AVDVBT_761: > - card->gpio_mode = (1 << 26) | (1 << 14) | (1 << 5); > - card->op_sync_orin = 0; > - card->irq_err_ignore = 0; > - /* A_PWRDN DA_SBR DA_APP (high speed serial) */ > - break; > - > case BTTV_BOARD_AVDVBT_771: //case 0x07711461: > - card->gpio_mode = 0x0400402B; > - card->op_sync_orin = BT878_RISC_SYNC_MASK; > - card->irq_err_ignore = 0; > - /* A_PWRDN DA_SBR DA_APP[0] PKTP=10 RISC_ENABLE FIFO_ENABLE*/ > + card->gpio_mode = 0x04004020; /* parallel mode */ > break; > > case BTTV_BOARD_TWINHAN_DST: > - card->gpio_mode = 0x2204f2c; > - card->op_sync_orin = BT878_RISC_SYNC_MASK; > - card->irq_err_ignore = BT878_APABORT | BT878_ARIPERR | > - BT878_APPERR | BT878_AFBUS; > + card->gpio_mode = 0x2204f20; > /* 25,21,14,11,10,9,8,3,2 then > * 0x33 = 5,4,1,0 > * A_SEL=SML, DA_MLB, DA_SBR, > - * DA_SDR=f, fifo trigger = 32 DWORDS > + * DA_SDR=f, > * IOM = 0 == audio A/D > * DPM = 0 == digital audio mode > * == async data parallel port > * then 0x33 (13 is set by start_capture) > * DA_APP = async data parallel port, > - * ACAP_EN = 1, > - * RISC+FIFO ENABLE */ > + */ > break; > > case BTTV_BOARD_PC_HDTV: > - card->gpio_mode = 0x0100EC7B; > - card->op_sync_orin = 0; > - card->irq_err_ignore = 0; > + card->gpio_mode = 0x0100EC60; > break; > > default: > @@ -884,15 +854,15 @@ > dprintk("dvb_bt8xx: identified card%d as %s\n", card->bttv_nr, card->card_name); > > if (!(bttv_pci_dev = bttv_get_pcidev(card->bttv_nr))) { > - printk("dvb_bt8xx: no pci device for card %d\n", card->bttv_nr); > + printk(KERN_ERR "dvb_bt8xx: no pci device for card %d\n", card->bttv_nr); > kfree(card); > return -EFAULT; > } > > if (!(card->bt = dvb_bt8xx_878_match(card->bttv_nr, bttv_pci_dev))) { > - printk("dvb_bt8xx: unable to determine DMA core of card %d,\n", > + printk(KERN_ERR "dvb_bt8xx: unable to determine DMA core of card %d,\n", > card->bttv_nr); > - printk("dvb_bt8xx: if you have the ALSA bt87x audio driver " > + printk(KERN_ERR "dvb_bt8xx: if you have the ALSA bt87x audio driver " > "installed, try removing it.\n"); > > kfree(card); > --- 0.1/drivers/media/dvb/bt8xx/bt878.h Sat, 07 Jan 2006 00:06:16 +0100 froese (kernel-dvb/h/15_bt878.h 1.1 644) > +++ 0.7/drivers/media/dvb/bt8xx/bt878.h Sun, 08 Jan 2006 01:45:15 +0100 froese (kernel-dvb/h/15_bt878.h 1.3 644) > @@ -28,7 +28,7 @@ > #include "bt848.h" > #include "bttv.h" > > -#define BT878_VERSION_CODE 0x000000 > +#define BT878_VERSION_CODE 0x000001 > > #define BT878_AINT_STAT 0x100 > #define BT878_ARISCS (0xf<<28) > @@ -75,19 +75,8 @@ > > #define BT878_ARISC_PC 0x120 > > -/* BT878 FUNCTION 0 REGISTERS */ > -#define BT878_GPIO_DMA_CTL 0x10c > - > -/* Interrupt register */ > -#define BT878_INT_STAT 0x100 > -#define BT878_INT_MASK 0x104 > -#define BT878_I2CRACK (1<<25) > -#define BT878_I2CDONE (1<<8) > - > #define BT878_MAX 4 > > -#define BT878_RISC_SYNC_MASK (1 << 15) > - > extern int bt878_num; > > struct bt878 { > @@ -119,14 +108,16 @@ > dma_addr_t risc_dma; > u32 risc_pos; > > + unsigned int errors; > + unsigned long error_expire; > + > struct tasklet_struct tasklet; > int shutdown; > }; > > extern struct bt878 bt878[BT878_MAX]; > > -void bt878_start(struct bt878 *bt, u32 controlreg, u32 op_sync_orin, > - u32 irq_err_ignore); > +void bt878_start(struct bt878 *bt, u32 controlreg); > void bt878_stop(struct bt878 *bt); > > #if defined(__powerpc__) /* big-endian */ > --- 0.1/drivers/media/dvb/bt8xx/bt878.c Sat, 07 Jan 2006 00:06:16 +0100 froese (kernel-dvb/h/16_bt878.c 1.1 644) > +++ 0.7/drivers/media/dvb/bt8xx/bt878.c Sun, 08 Jan 2006 01:45:15 +0100 froese (kernel-dvb/h/16_bt878.c 1.4 644) > @@ -78,7 +78,8 @@ > #if defined(dprintk) > #undef dprintk > #endif > -#define dprintk if(bt878_debug) printk > +#define dprintk(args...) do { if (bt878_debug) printk(KERN_DEBUG args); } \ > + while (0) > > static void bt878_mem_free(struct bt878 *bt) > { > @@ -142,9 +143,9 @@ > #define RISC_SYNC_VRO 0x0C > > #define RISC_FLUSH() bt->risc_pos = 0 > -#define RISC_INSTR(instr) bt->risc_cpu[bt->risc_pos++] = cpu_to_le32(instr) > +#define RISC_INSTR(instr) bt->risc_cpu[bt->risc_pos++] = cpu_to_le32((instr)) > > -static int bt878_make_risc(struct bt878 *bt) > +static int bt878_calc_line_size(struct bt878 *bt) > { > bt->block_bytes = bt->buf_size >> 4; > bt->block_count = 1 << 4; > @@ -157,35 +158,34 @@ > } > > if (bt->line_count > 255) { > - printk("bt878: buffer size error!\n"); > + printk(KERN_ERR "bt878: buffer size error!\n"); > return -EINVAL; > } > return 0; > } > > > -static void bt878_risc_program(struct bt878 *bt, u32 op_sync_orin) > +static void bt878_risc_program(struct bt878 *bt) > { > u32 buf_pos = 0; > u32 line; > > RISC_FLUSH(); > - RISC_INSTR(RISC_SYNC | RISC_SYNC_FM1 | op_sync_orin); > + RISC_INSTR(RISC_SYNC | RISC_SYNC_FM1 | RISC_SYNC_RESYNC); > RISC_INSTR(0); > > dprintk("bt878: risc len lines %u, bytes per line %u\n", > bt->line_count, bt->line_bytes); > for (line = 0; line < bt->line_count; line++) { > - // At the beginning of every block we issue an IRQ with previous (finished) block number set > + // At the beginning of every block we issue an IRQ with > + // previous (finished) block number set > if (!(buf_pos % bt->block_bytes)) > RISC_INSTR(RISC_WRITE | RISC_WR_SOL | RISC_WR_EOL | > RISC_IRQ | > - RISC_STATUS(((buf_pos / > - bt->block_bytes) + > - (bt->block_count - > - 1)) % > - bt->block_count) | bt-> > - line_bytes); > + RISC_STATUS(((buf_pos / bt->block_bytes) + > + bt->block_count - 1) % > + bt->block_count) | > + bt->line_bytes); > else > RISC_INSTR(RISC_WRITE | RISC_WR_SOL | RISC_WR_EOL | > bt->line_bytes); > @@ -193,7 +193,7 @@ > buf_pos += bt->line_bytes; > } > > - RISC_INSTR(RISC_SYNC | op_sync_orin | RISC_SYNC_VRO); > + RISC_INSTR(RISC_SYNC | RISC_SYNC_RESYNC | RISC_SYNC_VRO); > RISC_INSTR(0); > > RISC_INSTR(RISC_JUMP); > @@ -206,38 +206,31 @@ > /* Start/Stop grabbing funcs */ > /*****************************/ > > -void bt878_start(struct bt878 *bt, u32 controlreg, u32 op_sync_orin, > - u32 irq_err_ignore) > +void bt878_start(struct bt878 *bt, u32 controlreg) > { > u32 int_mask; > > dprintk("bt878 debug: bt878_start (ctl=%8.8x)\n", controlreg); > - /* complete the writing of the risc dma program now we have > - * the card specifics > - */ > - bt878_risc_program(bt, op_sync_orin); > + > controlreg &= ~0x1f; > - controlreg |= 0x1b; > + btwrite(controlreg, BT878_AGPIO_DMA_CTL); > > btwrite(bt->risc_dma, BT878_ARISC_START); > + bt->last_block = bt->block_count - 1; > > - /* original int mask had : > - * 6 2 8 4 0 > - * 1111 1111 1000 0000 0000 > - * SCERR|OCERR|PABORT|RIPERR|FDSR|FTRGT|FBUS|RISCI > - * Hacked for DST to: > - * SCERR | OCERR | FDSR | FTRGT | FBUS | RISCI > - */ > - int_mask = BT878_ASCERR | BT878_AOCERR | BT878_APABORT | > - BT878_ARIPERR | BT878_APPERR | BT878_AFDSR | BT878_AFTRGT | > - BT878_AFBUS | BT878_ARISCI; > - > - > - /* ignore pesky bits */ > - int_mask &= ~irq_err_ignore; > + bt->errors = 0; > > + int_mask = BT878_ARISCI; > + if (bt878_debug) > + int_mask |= BT878_ASCERR | BT878_AOCERR | > + BT878_APABORT | BT878_ARIPERR | BT878_APPERR | > + BT878_AFDSR | BT878_AFTRGT | BT878_AFBUS; > + btwrite(int_mask, BT878_AINT_STAT); > btwrite(int_mask, BT878_AINT_MASK); > - btwrite(controlreg, BT878_AGPIO_DMA_CTL); > + > + /* start dma (with fifo threshold at minimum) */ > + /* just in case with a read-modify-write to flush prior writes */ > + btor(0x13, BT878_AGPIO_DMA_CTL); > } > > void bt878_stop(struct bt878 *bt) > @@ -270,7 +263,7 @@ > > static irqreturn_t bt878_irq(int irq, void *dev_id, struct pt_regs *regs) > { > - u32 stat, astat, mask; > + u32 stat, astat; > int count; > struct bt878 *bt; > > @@ -279,63 +272,75 @@ > count = 0; > while (1) { > stat = btread(BT878_AINT_STAT); > - mask = btread(BT878_AINT_MASK); > - if (!(astat = (stat & mask))) > - return IRQ_NONE; /* this interrupt is not for me */ > -/* dprintk("bt878(%d) debug: irq count %d, stat 0x%8.8x, mask 0x%8.8x\n",bt->nr,count,stat,mask); */ > - btwrite(astat, BT878_AINT_STAT); /* try to clear interupt condition */ > + astat = stat & btread(BT878_AINT_MASK); > + if (!astat) > + break; /* not for us */ > > + btwrite(astat, BT878_AINT_STAT); /* ack interrupt */ > > + if (astat & BT878_ARISCI) { > + bt->finished_block = (stat & BT878_ARISCS) >> 28; > + tasklet_schedule(&bt->tasklet); > + } > if (astat & (BT878_ASCERR | BT878_AOCERR)) { > if (bt878_verbose) { > - printk("bt878(%d): irq%s%s risc_pc=%08x\n", > + printk(KERN_ERR > + "bt878(%d): irq%s%s risc_pc=%08x\n", > bt->nr, > - (astat & BT878_ASCERR) ? " SCERR" : > - "", > - (astat & BT878_AOCERR) ? " OCERR" : > - "", btread(BT878_ARISC_PC)); > + (astat & BT878_ASCERR) ? " SCERR" : "", > + (astat & BT878_AOCERR) ? " OCERR" : "", > + btread(BT878_ARISC_PC)); > } > } > if (astat & (BT878_APABORT | BT878_ARIPERR | BT878_APPERR)) { > if (bt878_verbose) { > - printk > - ("bt878(%d): irq%s%s%s risc_pc=%08x\n", > - bt->nr, > - (astat & BT878_APABORT) ? " PABORT" : > - "", > - (astat & BT878_ARIPERR) ? " RIPERR" : > - "", > - (astat & BT878_APPERR) ? " PPERR" : > - "", btread(BT878_ARISC_PC)); > + printk(KERN_ERR > + "bt878(%d): irq%s%s%s risc_pc=%08x\n", > + bt->nr, > + (astat & BT878_APABORT) ? " PABORT" : "", > + (astat & BT878_ARIPERR) ? " RIPERR" : "", > + (astat & BT878_APPERR) ? " PPERR" : "", > + btread(BT878_ARISC_PC)); > } > } > if (astat & (BT878_AFDSR | BT878_AFTRGT | BT878_AFBUS)) { > if (bt878_verbose) { > - printk > - ("bt878(%d): irq%s%s%s risc_pc=%08x\n", > - bt->nr, > - (astat & BT878_AFDSR) ? " FDSR" : "", > - (astat & BT878_AFTRGT) ? " FTRGT" : > - "", > - (astat & BT878_AFBUS) ? " FBUS" : "", > - btread(BT878_ARISC_PC)); > + printk(KERN_ERR > + "bt878(%d): irq%s%s%s risc_pc=%08x\n", > + bt->nr, > + (astat & BT878_AFDSR) ? " FDSR" : "", > + (astat & BT878_AFTRGT) ? " FTRGT" : "", > + (astat & BT878_AFBUS) ? " FBUS" : "", > + btread(BT878_ARISC_PC)); > } > } > - if (astat & BT878_ARISCI) { > - bt->finished_block = (stat & BT878_ARISCS) >> 28; > - tasklet_schedule(&bt->tasklet); > - break; > + if (astat & ~BT878_ARISCI) { > + if (time_after(jiffies, bt->error_expire)) > + bt->errors = 0; > + bt->error_expire = jiffies + 5*HZ; > + bt->errors++; > + if (bt->errors == 10 || bt->errors == 15) { > + printk(KERN_ERR "bt878(%d): too many errors, " > + "resetting dma\n", bt->nr); > + /* reset dma and set fifo-trigger to minimum */ > + btand(~0x1f, BT878_AGPIO_DMA_CTL); > + btor(0x13, BT878_AGPIO_DMA_CTL); > + } > + if (bt->errors == 20) { > + printk(KERN_ERR "bt878(%d): too many errors, " > + "shutting up\n", bt->nr); > + btwrite(BT878_ARISCI, BT878_AINT_MASK); > + } > } > count++; > - if (count > 20) { > + if (count > 30) { > btwrite(0, BT878_AINT_MASK); > - printk(KERN_ERR > - "bt878(%d): IRQ lockup, cleared int mask\n", > - bt->nr); > + printk(KERN_ERR "bt878(%d): IRQ lockup," > + " device disabled\n", bt->nr); > break; > } > } > - return IRQ_HANDLED; > + return IRQ_RETVAL(count); > } > > int > @@ -395,8 +400,7 @@ > unsigned int cmd; > #endif > > - printk(KERN_INFO "bt878: Bt878 AUDIO function found (%d).\n", > - bt878_num); > + printk(KERN_INFO "bt878: DVB interface found (%d).\n", bt878_num); > if (pci_enable_device(dev)) > return -EIO; > > @@ -437,42 +441,35 @@ > bt->bt878_mem = ioremap(bt->bt878_adr, 0x1000); > #endif > > - /* clear interrupt mask */ > - btwrite(0, BT848_INT_MASK); > + /* disable interrupts and dma */ > + btwrite(0, BT878_AINT_MASK); > + btwrite(0, BT878_AGPIO_DMA_CTL); > > result = request_irq(bt->irq, bt878_irq, > SA_SHIRQ | SA_INTERRUPT, "bt878", > (void *) bt); > - if (result == -EINVAL) { > - printk(KERN_ERR "bt878(%d): Bad irq number or handler\n", > - bt878_num); > - goto fail1; > - } > if (result == -EBUSY) { > printk(KERN_ERR > "bt878(%d): IRQ %d busy, change your PnP config in BIOS\n", > bt878_num, bt->irq); > goto fail1; > } > - if (result < 0) > + if (result < 0) { > + printk(KERN_ERR "bt878(%d): Bad irq number or handler (%d)\n", > + bt878_num, result); > goto fail1; > + } > > pci_set_master(dev); > pci_set_drvdata(dev, bt); > > -/* if(init_bt878(btv) < 0) { > - bt878_remove(dev); > - return -EIO; > - } > -*/ > - > if ((result = bt878_mem_alloc(bt))) { > - printk("bt878: failed to allocate memory!\n"); > + printk(KERN_ERR "bt878: failed to allocate memory!\n"); > goto fail2; > } > > - bt878_make_risc(bt); > - btwrite(0, BT878_AINT_MASK); > + bt878_calc_line_size(bt); > + bt878_risc_program(bt); > bt878_num++; > > return 0; > @@ -493,7 +490,7 @@ > struct bt878 *bt = pci_get_drvdata(pci_dev); > > if (bt878_verbose) > - printk("bt878(%d): unloading\n", bt->nr); > + printk(KERN_INFO "bt878(%d): unloading\n", bt->nr); > > /* turn off all capturing, DMA and IRQs */ > btand(~0x13, BT878_AGPIO_DMA_CTL); > @@ -504,7 +501,6 @@ > > /* disable PCI bus-mastering */ > pci_read_config_byte(bt->dev, PCI_COMMAND, &command); > - /* Should this be &=~ ?? */ > command &= ~PCI_COMMAND_MASTER; > pci_write_config_byte(bt->dev, PCI_COMMAND, command); > > @@ -553,7 +549,7 @@ > bt878_num = 0; > bt878_pci_driver_registered = 0; > > - printk(KERN_INFO "bt878: AUDIO driver version %d.%d.%d loaded\n", > + printk(KERN_INFO "bt878: DVB driver version %d.%d.%d loaded\n", > (BT878_VERSION_CODE >> 16) & 0xff, > (BT878_VERSION_CODE >> 8) & 0xff, > BT878_VERSION_CODE & 0xff); > > _______________________________________________ > > linux-dvb@xxxxxxxxxxx > http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb