@@ -95,11 +95,25 @@ static int mantis_ca_slot_reset(struct dvb_ca_en50221 *en50221, int slot)
struct mantis_pci *mantis = ca->ca_priv;
dprintk(MANTIS_DEBUG, 1, "Slot(%d): Slot RESET", slot);
+ mutex_lock(&mantis->int_stat_lock);
+ if (test_and_clear_bit(MANTIS_SBUF_OPDONE_BIT, &ca->hif_event)) {
+ dprintk(MANTIS_NOTICE, 1, "Slot(%d): Reset operation done before it started!", slot);
+ }
udelay(500); /* Wait.. */
mmwrite(0xda, MANTIS_PCMCIA_RESET); /* Leading edge assert */
udelay(500);
mmwrite(0x00, MANTIS_PCMCIA_RESET); /* Trailing edge deassert */
msleep(1000);
+
+ if (wait_event_timeout(ca->hif_opdone_wq,
+ test_and_clear_bit(MANTIS_SBUF_OPDONE_BIT, &ca->hif_event),
+ msecs_to_jiffies(500)) == -ERESTARTSYS) {
+
+ dprintk(MANTIS_ERROR, 1, "Slot(%d): Reset timeout!", slot);
+ } else {
+ dprintk(MANTIS_DEBUG, 1, "Slot(%d): Reset complete", slot);
+ }
+ mutex_unlock(&mantis->int_stat_lock);
dvb_ca_en50221_camready_irq(&ca->en50221, 0);
return 0;
@@ -161,7 +161,7 @@ struct mantis_pci {
/* A12 A13 A14 */
u32 gpio_status;
- u32 gpif_status;
+ volatile unsigned long gpif_status;
struct mantis_ca *mantis_ca;
struct mutex int_stat_lock;
@@ -20,6 +20,7 @@
#include <linux/kernel.h>
+#include <linux/atomic.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
@@ -87,10 +88,14 @@ static void mantis_hifevm_work(struct work_struct *work)
if (gpif_stat & MANTIS_SBUF_EMPTY)
dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer Empty", mantis->num);
- if (gpif_stat & MANTIS_SBUF_OPDONE) {
+ if (gpif_stat & MANTIS_SBUF_OPDONE)
dprintk(MANTIS_DEBUG, 1, "Event Mgr: Adapter(%d) Slot(0): Smart Buffer operation complete", mantis->num);
+
+ if (gpif_stat & MANTIS_SBUF_OPDONE) {
ca->sbuf_status = MANTIS_SBUF_DATA_AVAIL;
- ca->hif_event = MANTIS_SBUF_OPDONE;
+ if (test_and_set_bit(MANTIS_SBUF_OPDONE_BIT, &ca->hif_event)) {
+ dprintk(MANTIS_NOTICE, 1, "Operation done, but SBUF_OPDONE bit was already set!");
+ }
wake_up(&ca->hif_opdone_wq);
}
}
@@ -22,6 +22,7 @@
#include <linux/signal.h>
#include <linux/sched.h>
+#include <linux/atomic.h>
#include <linux/interrupt.h>
#include <asm/io.h>
@@ -45,25 +46,23 @@ static int mantis_hif_sbuf_opdone_wait(struct mantis_ca *ca)
int rc = 0;
if (wait_event_timeout(ca->hif_opdone_wq,
- ca->hif_event & MANTIS_SBUF_OPDONE,
+ test_and_clear_bit(MANTIS_SBUF_OPDONE_BIT, &ca->hif_event),
msecs_to_jiffies(500)) == -ERESTARTSYS) {
dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): Smart buffer operation timeout !", mantis->num);
rc = -EREMOTEIO;
}
dprintk(MANTIS_DEBUG, 1, "Smart Buffer Operation complete");
- ca->hif_event &= ~MANTIS_SBUF_OPDONE;
return rc;
}
static int mantis_hif_write_wait(struct mantis_ca *ca)
{
struct mantis_pci *mantis = ca->ca_priv;
- u32 opdone = 0, timeout = 0;
int rc = 0;
if (wait_event_timeout(ca->hif_write_wq,
- mantis->gpif_status & MANTIS_GPIF_WRACK,
+ test_and_clear_bit(MANTIS_GPIF_WRACK_BIT, &mantis->gpif_status),
msecs_to_jiffies(500)) == -ERESTARTSYS) {
dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): Write ACK timed out !", mantis->num);
@@ -81,7 +80,10 @@ static int mantis_hif_write_wait(struct mantis_ca *ca)
break;
}
}
- dprintk(MANTIS_DEBUG, 1, "HIF Write success");
+ if (mantis_hif_sbuf_opdone_wait(ca) != 0) {
+ dprintk(MANTIS_ERROR, 1, "Adapter(%d) Slot(0): Write operation timeout !", mantis->num);
+ rc = -ETIMEDOUT;
+ }
return rc;
}
@@ -94,6 +96,10 @@ int mantis_hif_read_mem(struct mantis_ca *ca, u32 addr)
dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF Mem Read of 0x%x", mantis->num, addr);
mutex_lock(&mantis->int_stat_lock);
+ if (test_and_clear_bit(MANTIS_SBUF_OPDONE_BIT, &ca->hif_event)) {
+ dprintk(MANTIS_NOTICE, 1, "Adapter(%d) Slot(0): Read operation done before it started!", mantis->num);
+ }
+
hif_addr &= ~MANTIS_GPIF_PCMCIAREG;
hif_addr &= ~MANTIS_GPIF_PCMCIAIOM;
hif_addr |= MANTIS_HIF_STATUS;
@@ -123,6 +129,9 @@ int mantis_hif_write_mem(struct mantis_ca *ca, u32 addr, u8 data)
dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF Mem Write", mantis->num);
mutex_lock(&mantis->int_stat_lock);
+ if (test_and_clear_bit(MANTIS_SBUF_OPDONE_BIT, &ca->hif_event)) {
+ dprintk(MANTIS_NOTICE, 1, "Adapter(%d) Slot(0): Write operation done before it started!", mantis->num);
+ }
hif_addr &= ~MANTIS_GPIF_HIFRDWRN;
hif_addr &= ~MANTIS_GPIF_PCMCIAREG;
hif_addr &= ~MANTIS_GPIF_PCMCIAIOM;
@@ -151,6 +160,9 @@ int mantis_hif_read_iom(struct mantis_ca *ca, u32 addr)
dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF I/O Read of 0x%x", mantis->num, addr);
mutex_lock(&mantis->int_stat_lock);
+ if (test_and_clear_bit(MANTIS_SBUF_OPDONE_BIT, &ca->hif_event)) {
+ dprintk(MANTIS_NOTICE, 1, "Adapter(%d) Slot(0): I/O read operation done before it started!", mantis->num);
+ }
hif_addr &= ~MANTIS_GPIF_PCMCIAREG;
hif_addr |= MANTIS_GPIF_PCMCIAIOM;
hif_addr |= MANTIS_HIF_STATUS;
@@ -181,6 +193,9 @@ int mantis_hif_write_iom(struct mantis_ca *ca, u32 addr, u8 data)
dprintk(MANTIS_DEBUG, 1, "Adapter(%d) Slot(0): Request HIF I/O Write", mantis->num);
mutex_lock(&mantis->int_stat_lock);
+ if (test_and_clear_bit(MANTIS_SBUF_OPDONE_BIT, &ca->hif_event)) {
+ dprintk(MANTIS_NOTICE, 1, "Adapter(%d) Slot(0): I/O write operation done before it started!", mantis->num);
+ }
hif_addr &= ~MANTIS_GPIF_PCMCIAREG;
hif_addr &= ~MANTIS_GPIF_HIFRDWRN;
hif_addr |= MANTIS_GPIF_PCMCIAIOM;
@@ -48,7 +48,7 @@ struct mantis_ca {
struct work_struct hif_evm_work;
- u32 hif_event;
+ volatile unsigned long hif_event;
wait_queue_head_t hif_opdone_wq;
wait_queue_head_t hif_brrdyw_wq;
wait_queue_head_t hif_data_wq;
@@ -152,11 +152,13 @@
#define MANTIS_GPIF_STATUS 0x9c
#define MANTIS_SBUF_KILLOP (0x01 << 15)
-#define MANTIS_SBUF_OPDONE (0x01 << 14)
+#define MANTIS_SBUF_OPDONE_BIT 14
+#define MANTIS_SBUF_OPDONE (0x01 << MANTIS_SBUF_OPDONE_BIT)
#define MANTIS_SBUF_EMPTY (0x01 << 13)
#define MANTIS_GPIF_DETSTAT (0x01 << 9)
#define MANTIS_GPIF_INTSTAT (0x01 << 8)
-#define MANTIS_GPIF_WRACK (0x01 << 7)
+#define MANTIS_GPIF_WRACK_BIT 7
+#define MANTIS_GPIF_WRACK (0x01 << MANTIS_GPIF_WRACK_BIT)
#define MANTIS_GPIF_BRRDY (0x01 << 6)
#define MANTIS_SBUF_OVFLW (0x01 << 5)
#define MANTIS_GPIF_OTHERR (0x01 << 4)