Interrupt Polling

"Rodel Miguel" <[email protected]>
Newsgroups gmane.linux.drivers.prism54.devel,gmane.linux.drivers.prism54.user
Message-ID <[email protected]>
Hi!

    I am trying to port the driver on a uClinux/ARM7 platform.  My
device can't handle "too much interrupts", i.e., the network application
hangs on high data rates.  The prism54 module displays kernel bug at
isl38xx:401!  I would like to re-design the driver for my platform.  I
am currently using March 18 2004 version of the driver for 2.4 kernels.
I tried to "poll" the reg & ISL38XX_INT_IDENT_UPDATE condition of the
islpci_interrupt interrupt handler of islpci_dev.c, using a fixed count
(500) and re-reading the ISL38XX_INT_IDENT_REG and check if the register
is updated.  I am still having the same interrupt handling problem.
Could somebody help me to create a polling function for the prism54
driver to minimize calls to the interrupt handler routine?  Or should I
register the interrupt on a polling timer (fast_poll_add - from
asm/fast_timer.h) instead of using the interrupt request? Are there
groups porting the driver on MMU-less devices?  Could someone tell me if
they already did some optimization codes for the driver on embedded
linux systems? 

Here's the polling routine snippet I did on the driver but this does not
seem to work.  Please help!

i.e.:

int max_interrupt_work = 500;
/* check for each bit in the register separately */
	do { // rodel
                if (reg & ISL38XX_INT_IDENT_UPDATE) {
#if VERBOSE > SHOW_ERROR_MESSAGES
                        /* Queue has been updated */
                        DEBUG(SHOW_TRACING, "IRQ: Update flag \n");

                        DEBUG(SHOW_QUEUE_INDEXES,
                              "CB drv Qs: [%i][%i][%i][%i][%i][%i]\n",
                              le32_to_cpu(priv->control_block->
                                          driver_curr_frag[0]),
                              le32_to_cpu(priv->control_block->
                                          driver_curr_frag[1]),
                              le32_to_cpu(priv->control_block->
                                          driver_curr_frag[2]),
                              le32_to_cpu(priv->control_block->
                                          driver_curr_frag[3]),
                              le32_to_cpu(priv->control_block->
                                          driver_curr_frag[4]),
                              le32_to_cpu(priv->control_block->
                                          driver_curr_frag[5])
                            );

                        DEBUG(SHOW_QUEUE_INDEXES,
                              "CB dev Qs: [%i][%i][%i][%i][%i][%i]\n",
                              le32_to_cpu(priv->control_block->
                                          device_curr_frag[0]),
                              le32_to_cpu(priv->control_block->
                                          device_curr_frag[1]),
                              le32_to_cpu(priv->control_block->
                                          device_curr_frag[2]),
                              le32_to_cpu(priv->control_block->
                                          device_curr_frag[3]),
                              le32_to_cpu(priv->control_block->
                                          device_curr_frag[4]),
                              le32_to_cpu(priv->control_block->
                                          device_curr_frag[5])
                            );
#endif

                        /* cleanup the data low transmit queue */
                        islpci_eth_cleanup_transmit(priv,
priv->control_block);

                        /* device is in active state, update the
                         * powerstate flag if necessary */
                        powerstate = ISL38XX_PSM_ACTIVE_STATE;

                        /* check all three queues in priority order
                         * call the PIMFOR receive function until the
                         * queue is empty */
                        if (isl38xx_in_queue(priv->control_block,
                                                ISL38XX_CB_RX_MGMTQ) !=
0) {
#if VERBOSE > SHOW_ERROR_MESSAGES
                                DEBUG(SHOW_TRACING,
                                      "Received frame in Management
Queue\n");
#endif
                                islpci_mgt_receive(ndev);

                                islpci_mgt_cleanup_transmit(ndev);

                                /* Refill slots in receive queue */
                                islpci_mgmt_rx_fill(ndev);

                                /* no need to trigger the device, next
                                   islpci_mgt_transaction does it */
                        }

                        while (isl38xx_in_queue(priv->control_block,
                                                ISL38XX_CB_RX_DATA_LQ)
!= 0) {
#if VERBOSE > SHOW_ERROR_MESSAGES
                                DEBUG(SHOW_TRACING,
                                      "Received frame in Data Low Queue
\n");
#endif
                                islpci_eth_receive(priv);
                        }

                        /* check whether the data transmit queues were
full */
                        if (priv->data_low_tx_full) {
                                /* check whether the transmit is not
full anymore */
                                if (ISL38XX_CB_TX_QSIZE -
 
isl38xx_in_queue(priv->control_block,
 
ISL38XX_CB_TX_DATA_LQ) >=
                                    ISL38XX_MIN_QTHRESHOLD) {
                                        /* nope, the driver is ready for
more network frames */
                                        netif_wake_queue(priv->ndev);

                                        /* reset the full flag */
                                        priv->data_low_tx_full = 0;
                                }
                        }
                }

		/* rodel - trying to poll */
	      reg &= ~ISL38XX_INT_IDENT_UPDATE; 
      	reg |= readl(device + ISL38XX_INT_IDENT_REG);
      	isl38xx_w32_flush(device, ISL38XX_INT_IDENT_UPDATE,
ISL38XX_INT_ACK_REG);
      	max_interrupt_work--;
      } while(max_interrupt_work >= 0);

Regards,

Rodel
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.