[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