[Prism54-users] Interrupt Polling

Rodel Miguel rodel.miguel at eazix.com
Thu Aug 5 03:44:06 UTC 2004


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




More information about the Prism54-users mailing list