From 008bd5eab9f66a10bc4c60c3b9a3bee04de206fa Mon Sep 17 00:00:00 2001 From: Frank Mori Hess Date: Sat, 14 May 2005 17:17:22 +0000 Subject: [PATCH] be more careful about sending pci-1760 mailbox commands --- comedi/drivers/adv_pci_dio.c | 73 ++++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 29 deletions(-) diff --git a/comedi/drivers/adv_pci_dio.c b/comedi/drivers/adv_pci_dio.c index a86b47c7..73b4d93a 100644 --- a/comedi/drivers/adv_pci_dio.c +++ b/comedi/drivers/adv_pci_dio.c @@ -428,7 +428,7 @@ static int pci_dio_insn_bits_do_w(comedi_device *dev, comedi_subdevice *s, /* ============================================================================== */ -static int pci1760_mbxrequest(comedi_device *dev, +static int pci1760_unchecked_mbxrequest(comedi_device *dev, unsigned char *omb, unsigned char *imb, int repeats) { @@ -456,24 +456,39 @@ static int pci1760_mbxrequest(comedi_device *dev, return -ETIME; } +static int pci1760_clear_imb2(comedi_device *dev) +{ + unsigned char omb[4] = {0x0, 0x0, CMD_ClearIMB2, 0x0}; + unsigned char imb[4]; + /* check if imb2 is already clear */ + if(inb(dev->iobase + IMB2) == CMD_ClearIMB2) return 0; + return pci1760_unchecked_mbxrequest(dev, omb, imb, OMBCMD_RETRY); +} + +static int pci1760_mbxrequest(comedi_device *dev, + unsigned char *omb, unsigned char *imb) +{ + if(omb[2] == CMD_ClearIMB2) + { + comedi_error(dev, "bug! this function should not be used for CMD_ClearIMB2 command"); + return -EINVAL; + } + if(inb(dev->iobase + IMB2) == omb[2]) + { + int retval; + retval = pci1860_clear_imb2(dev); + if(retval < 0) return retval; + } + return pci1760_unchecked_mbxrequest(dev, omb, imb, OMBCMD_RETRY); +} + /* ============================================================================== */ static int pci1760_insn_bits_di(comedi_device *dev, comedi_subdevice *s, comedi_insn *insn, lsampl_t *data) { - int ret; - unsigned char omb[4]={ - 0x00, - 0x00, - CMD_ClearIMB2, - 0x00}; - unsigned char imb[4]; - - if (!(ret=pci1760_mbxrequest(dev, omb, imb, OMBCMD_RETRY))) - return ret; - - data[1]=imb[3]; + data[1]=inb(dev->iobase + IMB3); return 2; } @@ -496,7 +511,7 @@ static int pci1760_insn_bits_do(comedi_device *dev, comedi_subdevice *s, s->state &= ~data[0]; s->state |= (data[0]&data[1]); omb[0] = s->state; - if (!(ret=pci1760_mbxrequest(dev, omb, imb, OMBCMD_RETRY))) + if (!(ret=pci1760_mbxrequest(dev, omb, imb))) return ret; } data[1] = s->state; @@ -519,7 +534,7 @@ static int pci1760_insn_cnt_read(comedi_device *dev, comedi_subdevice *s, unsigned char imb[4]; for (n=0; nn; n++) { - if (!(ret=pci1760_mbxrequest(dev, omb, imb, OMBCMD_RETRY))) + if (!(ret=pci1760_mbxrequest(dev, omb, imb))) return ret; data[n] = (imb[1]<<8) + imb[0]; } @@ -544,20 +559,20 @@ static int pci1760_insn_cnt_write(comedi_device *dev, comedi_subdevice *s, unsigned char imb[4]; if (devpriv->CntResValue[chan] != (data[0]&0xffff)) { // Set reset value if different - if (!(ret=pci1760_mbxrequest(dev, omb, imb, OMBCMD_RETRY))) + if (!(ret=pci1760_mbxrequest(dev, omb, imb))) return ret; devpriv->CntResValue[chan] = data[0]&0xffff; } omb[0] = bitmask; // reset counter to it reset value omb[2] = CMD_ResetIDICounters; - if (!(ret=pci1760_mbxrequest(dev, omb, imb, OMBCMD_RETRY))) + if (!(ret=pci1760_mbxrequest(dev, omb, imb))) return ret; if (!(bitmask & devpriv->IDICntEnable)) { // start counter if it don't run omb[0] = bitmask; omb[2] = CMD_EnableIDICounters; - if (!(ret=pci1760_mbxrequest(dev, omb, imb, OMBCMD_RETRY))) + if (!(ret=pci1760_mbxrequest(dev, omb, imb))) return ret; devpriv->IDICntEnable |= bitmask; } @@ -581,28 +596,28 @@ static int pci1760_reset(comedi_device *dev) omb[0] = 0x00; omb[2] = CMD_SetRelaysOutput; // reset relay outputs - pci1760_mbxrequest(dev, omb, imb, OMBCMD_RETRY); + pci1760_mbxrequest(dev, omb, imb); omb[0] = 0x00; omb[2] = CMD_EnableIDICounters; // disable IDI up counters - pci1760_mbxrequest(dev, omb, imb, OMBCMD_RETRY); + pci1760_mbxrequest(dev, omb, imb); devpriv->IDICntEnable = 0; omb[0] = 0x00; omb[2] = CMD_OverflowIDICounters; // disable counters overflow interrupts - pci1760_mbxrequest(dev, omb, imb, OMBCMD_RETRY); + pci1760_mbxrequest(dev, omb, imb); devpriv->IDICntOverEnable = 0; omb[0] = 0x00; omb[2] = CMD_MatchIntIDICounters; // disable counters match value interrupts - pci1760_mbxrequest(dev, omb, imb, OMBCMD_RETRY); + pci1760_mbxrequest(dev, omb, imb); devpriv->IDICntMatchEnable = 0; omb[0] = 0x00; omb[1] = 0x80; for (i=0; i<8; i++) { // set IDI up counters match value omb[2] = CMD_SetIDI0CntMatchValue+i; - pci1760_mbxrequest(dev, omb, imb, OMBCMD_RETRY); + pci1760_mbxrequest(dev, omb, imb); devpriv->CntMatchValue[i] = 0x8000; } @@ -610,32 +625,32 @@ static int pci1760_reset(comedi_device *dev) omb[1] = 0x00; for (i=0; i<8; i++) { // set IDI up counters reset value omb[2] = CMD_SetIDI0CntResetValue+i; - pci1760_mbxrequest(dev, omb, imb, OMBCMD_RETRY); + pci1760_mbxrequest(dev, omb, imb); devpriv->CntResValue[i] = 0x0000; } omb[0] = 0xff; omb[2] = CMD_ResetIDICounters; // reset IDI up counters to reset values - pci1760_mbxrequest(dev, omb, imb, OMBCMD_RETRY); + pci1760_mbxrequest(dev, omb, imb); omb[0] = 0x00; omb[2] = CMD_EdgeIDICounters; // set IDI up counters count edge - pci1760_mbxrequest(dev, omb, imb, OMBCMD_RETRY); + pci1760_mbxrequest(dev, omb, imb); devpriv->IDICntEdge = 0x00; omb[0] = 0x00; omb[2] = CMD_EnableIDIFilters; // disable all digital in filters - pci1760_mbxrequest(dev, omb, imb, OMBCMD_RETRY); + pci1760_mbxrequest(dev, omb, imb); devpriv->IDIFiltersEn = 0x00; omb[0] = 0x00; omb[2] = CMD_EnableIDIPatternMatch; // disable pattern matching - pci1760_mbxrequest(dev, omb, imb, OMBCMD_RETRY); + pci1760_mbxrequest(dev, omb, imb); devpriv->IDIPatMatchEn = 0x00; omb[0] = 0x00; omb[2] = CMD_SetIDIPatternMatch; // set pattern match value - pci1760_mbxrequest(dev, omb, imb, OMBCMD_RETRY); + pci1760_mbxrequest(dev, omb, imb); devpriv->IDIPatMatchValue = 0x00; return 0; -- 2.26.2