[Prism54-devel] usb advances

Feyd feyd at seznam.cz
Mon Dec 20 09:55:37 UTC 2004


On Sun, 19 Dec 2004 10:44:13 +0100
Jean-Baptiste Note <jean-baptiste.note at wanadoo.fr> wrote:

> 
> > comment the lines resetting the USB device ; calling
> > usb_reset_device()
> > after the firmware upload never returns and causes a deadlock in the
> > module for some odd reason. Why should the USB be resetted ? Is it
> > to
> > mimic the Windows driver's behaviour ? It seems unnecessary, at
> > least
> > for my device.
> 
> Actually Feyd wrote this part of the driver, i only fixed some
> endianess problems, some control logic problems related to the
> interrupt handling, allowed the resubmission of some packets during
> firmware upload. So for the actual meaning of the code, we should
> ask him first, but i think that indeed the intent was to mimic the
> windows driver.

My device didn't work reliably without the reset. It was called after
the firmware request from userspace, not after the upload. Perhaps the
usb_rese_device() now takes a lock the probe() allready has. May be it
can be replaced by simple reinitialization of the device as ndiswrapper
seems to do, I often see the device not responding at the start followed
by second initialization sequence (including firmware upload) in the log.

The interrupt handling in the cvs is sure broken. I couldn't get the
device to send the ISL38XX_INT_IDENT_INIT, what was caused by using
vmalloced memory for firmware upload resulting in garbage being loaded,
but I thought that it is caused by wrong interrup routine, so I tried
many versions and a random one was checked in the cvs. From the logs
I think the correct procedure should be something like this:

do {
        /* wait for int pipe and get the received data */
        pending = p54u_wait_int(netdev);

        /* disable irqs */
	p54u_dev_writel(netdev, ISL38XX_INT_EN_REG, 0);

        /* ack the irqs, certain MASK at least 0x7fffffff, may be 0x00004004 */
        while((reg = p54u_dev_readl(netdev, ISL38XX_INT_IDENT_REG)) & MASK) {
                p54u_dev_writel(netdev, ISL38XX_INT_ACK_REG, reg); 
        }

        /* clear INTA */
        p54u_brg_writel(netdev, NET2280_IRQSTAT1, NET2280_PCI_INTA_INTERRUPT);

        /* enable irqs */
        p54u_dev_writel(netdev, ISL38XX_INT_EN_REG, 0x00004004);

} while(pending);

See the attached log and http://sweb.cz/feyd for other logs.

Feyd

-------------- next part --------------
[>submit time (ms), <complete time, +difference, :error], ordered by complete time
reset (shared by all logs):
[>1437 <1438 +1    :0] 0e -> 00000000: 0F 08 78 00 00 40              # reg = p54u_dev_readl(netdev, ISL38XX_CTRL_STAT_REG);
[>1438 <1439 +1    :0] 8e <- 00000000: DB 44 00 00                  
[>1439 <1440 +1    :0] 0e -> 00000000: 0F 08 78 00 00 40 DB 44 00 20  # p54u_dev_writel(netdev, ISL38XX_CTRL_STAT_REG, reg);
[>1440 <1441 +1    :0] 0e -> 00000000: 0F 08 78 00 00 40 DB 44 00 30  # p54u_dev_writel(netdev, ISL38XX_CTRL_STAT_REG, reg | ISL38XX_CTRL_STAT_RESET);
[>1441 <1442 +1    :0] 0e -> 00000000: 0F 08 78 00 00 40 DB 44 00 20  # p54u_dev_writel(netdev, ISL38XX_CTRL_STAT_REG, reg);
[>1442 <1443 +1    :0] 0e -> 00000000: 0F 08 18 00 00 40 04 40 00 00  # p54u_dev_writel(netdev, ISL38XX_INT_EN_REG, 0x00004004); # enable irqs
[>1443 <1444 +1    :0] 0d -> 00000000: 1F 00 2C 00 00 00 00 00 00 01  # p54u_brg_writel(netdev, NET2280_IRQSTAT1, NET2280_PCI_INTA_INTERRUPT); # clear INTA
[>1444 <1445 +1    :0] 0d -> 00000000: 1F 00 24 00 00 00 00 00 00 81  # p54u_brg_writel(netdev, NET2280_USBIRQENB1, NET2280_PCI_INTA_INTERRUPT_ENABLE | NET2280_USB_INTERRUPT_ENABLE);
[>1445 <1446 +1    :0] 0e -> 00000000: 0F 08 00 00 00 40 01 00 00 00  # p54u_dev_writel(netdev, ISL38XX_DEV_INT_REG, ISL38XX_DEV_INT_RESET); # reset the isl chip

now the interesting part from ndiswrapper log:
[>1442 <1498 +57   :0] 8f <- 00000000: 00 00 00 01                    # int pipe returns nonzero
[>1499 <1499 +1    :0] 0e -> 00000000: 0F 08 18 00 00 40 00 00 00 00  # disable irqs             # p54u_dev_writel(netdev, ISL38XX_INT_EN_REG, 0x00000000);
[>1500 <1500 +1    :0] 0e -> 00000000: 0F 08 10 00 00 40              # read irq status          # reg = p54u_dev_readl(netdev, ISL38XX_INT_IDENT_REG);
[>1501 <1501 +1    :0] 8e <- 00000000: 04 40 00 80                  
[>1502 <1503 +1    :0] 0e -> 00000000: 0F 08 14 00 00 40 04 40 00 80  # ack irqs (including 0x80000000) # p54u_dev_writel(netdev, ISL38XX_INT_ACK_REG, reg);
[>1503 <1503 +1    :0] 0e -> 00000000: 0F 08 10 00 00 40              # read irq status          # reg = p54u_dev_readl(netdev, ISL38XX_INT_IDENT_REG);
[>1504 <1504 +1    :0] 8e <- 00000000: 00 00 00 80                    # (0x80000000 ignored)
[>1505 <1505 +1    :0] 0d -> 00000000: 1F 00 2C 00 00 00 00 00 00 01  # clear INTA               # p54u_brg_writel(netdev, NET2280_IRQSTAT1, NET2280_PCI_INTA_INTERRUPT);
[>1506 <1506 +1    :0] 0e -> 00000000: 0F 08 18 00 00 40 04 40 00 00  # enable irqs              # p54u_dev_writel(netdev, ISL38XX_INT_EN_REG, 0x00004004);
[>1507 <1508 +2    :0] 8f <- 00000000: 00 00 00 00                    # int pipe returns zero
[>1509 <1509 +1    :0] 0e -> 00000000: 0F 08 18 00 00 40 00 00 00 00  # disable irqs             # p54u_dev_writel(netdev, ISL38XX_INT_EN_REG, 0x00000000);
[>1510 <1510 +1    :0] 0e -> 00000000: 0F 08 10 00 00 40              # read irq status          # reg = p54u_dev_readl(netdev, ISL38XX_INT_IDENT_REG);
[>1511 <1511 +1    :0] 8e <- 00000000: 00 00 00 80                    # (0x80000000 ignored)
[>1512 <1512 +1    :0] 0d -> 00000000: 1F 00 2C 00 00 00 00 00 00 01  # clear INTA               # p54u_brg_writel(netdev, NET2280_IRQSTAT1, NET2280_PCI_INTA_INTERRUPT);
[>1513 <1513 +1    :0] 0e -> 00000000: 0F 08 18 00 00 40 04 40 00 00  # enable irqs              # p54u_dev_writel(netdev, ISL38XX_INT_EN_REG, 0x00004004);

from an usbsnoop log (ordered by submit time):
[IN  >852   <908   +56    ]     8f <- 00000000: 00 00 00 01                    # int pipe returns nonzero
[OUT >908   <908   +0     ]     0e -> 00000000: 0f 08 18 00 00 40 00 00 00 00  # disable irqs
[OUT >908   <908   +0     ]     0e -> 00000000: 0f 08 10 00 00 40              # read irq status
[IN  >909   <909   +0     ]     8e <- 00000000: 00 40 00 80
[OUT >909   <909   +0     ]     0e -> 00000000: 0f 08 14 00 00 40 00 40 00 80  # ack irqs
[OUT >909   <909   +0     ]     0e -> 00000000: 0f 08 10 00 00 40              # read irq status
[IN  >909   <909   +0     ]     8e <- 00000000: 04 00 00 00
[OUT >909   <909   +0     ]     0e -> 00000000: 0f 08 14 00 00 40 04 00 00 00  # ack irqs
[OUT >909   <910   +1     ]     0e -> 00000000: 0f 08 10 00 00 40              # read irq status
[IN  >910   <910   +0     ]     8e <- 00000000: 00 00 00 00
[OUT >910   <910   +0     ]     0d -> 00000000: 1f 00 2c 00 00 00 00 00 00 01  # clear INTA
[OUT >910   <910   +0     ]     0e -> 00000000: 0f 08 18 00 00 40 04 40 00 00  # enable irqs
[IN  >910   <911   +1     ]     8f <- 00000000: 00 00 00 00                    # int pipe return zero
[OUT >911   <911   +0     ]     0e -> 00000000: 0f 08 18 00 00 40 00 00 00 00  # disable irqs
[OUT >911   <911   +0     ]     0e -> 00000000: 0f 08 10 00 00 40              # read irq status
[IN  >911   <911   +0     ]     8e <- 00000000: 00 00 00 00
[OUT >911   <911   +0     ]     0d -> 00000000: 1f 00 2c 00 00 00 00 00 00 01  # clear INTA
[OUT >911   <912   +1     ]     0e -> 00000000: 0f 08 18 00 00 40 04 40 00 00  # enable irqs
[IN  >912   <26517 +25605 ]     8f <- NO DATA



More information about the Prism54-devel mailing list