[PATCH 2/2] introduced pcnet_dummy_reset()

Dmitry Podgorny pasis.ua at gmail.com
Thu May 19 14:48:11 EDT 2011


> Soft reset (S_RESET) resets value of CSR0 to default. The default
> value for CSR0 is 0x0004 (STOP bit is set) [2 p.23]. At first,
> assume we in word i/o mode and try to read 0x14. After this try to
> read 0x18 if CSR0 hasn't been set to default value.
> After S_RESET the controller will be in word i/o mode [1 p.101]. We
> need to perform 32bit write access to the i/o location at 0x10 to
> switch the controller to dword i/o mode [1 p.104]. Zero is safe
> value for this operation [1 p.104].
> DWIO bit of BCR18 indicates that the controller is working in dword
> mode, if it isn't set something wrong occurred.
> 
> [1] Am79C970A
> [2] PCnet Family Software Design Considerations
> ---
>  src/pcnet.c |   19 ++++++++++++++++++-
>  1 files changed, 18 insertions(+), 1 deletions(-)
> 
> diff --git a/src/pcnet.c b/src/pcnet.c
> index 480a67f..2372ec3 100644
> --- a/src/pcnet.c
> +++ b/src/pcnet.c
> @@ -182,6 +182,21 @@ static unsigned long pcnet_dummy_bcr_read32(void
> __iomem *ioaddr, return ioread32(ioaddr + PCNET_IO32_BDP) & 0xffff;
>  }
>  
> +/* resets the controller and switches to 32bit mode */
> +static int pcnet_dummy_reset(void __iomem *ioaddr)
> +{
> +	int err = 0;
> +	ioread16(ioaddr + PCNET_IO_RESET);
> +	if (pcnet_dummy_csr_read16(ioaddr, CSR0) != CSR0_STOP)
> +		ioread32(ioaddr + PCNET_IO32_RESET);
> +	iowrite32(0, ioaddr + PCNET_IO_RDP);
> +	if (!(pcnet_dummy_bcr_read32(ioaddr, BCR18) & BCR18_DWIO)) {
> +		printk(KERN_ERR DRV_NAME ": cannot switch controller
> to 32bit mode\n");
> +		err = -ENODEV;
> +	}
> +	return err;
> +}
> +
>  static int pcnet_dummy_open(struct net_device *ndev)
>  {
>  	return 0;
> @@ -236,7 +251,6 @@ static int __devinit
> pcnet_dummy_init_netdev(struct pci_dev *pdev, #endif /*
> HAVE_NET_DEVICE_OPS */ 
>  	/* registers net_device and returns err */
> -	/* TODO: reset the chip at the end */
>  
>  	return 0;
>  }
> @@ -272,6 +286,9 @@ static int __devinit pcnet_dummy_init_one(struct
> pci_dev *pdev, goto out_res;
>  	pci_set_drvdata(pdev, ndev);
>  
> +	if (pcnet_dummy_reset(ioaddr))
> +		goto out_res_unmap;
> +
>  	if (pcnet_dummy_init_netdev(pdev, (unsigned long)ioaddr))
>  		goto out_res_unmap;
>  

Приветствую после длительного перерыва.
Заметил следующую особенность: если перед выгрузкой модуля не
переключить контроллер в 16бит режим, то оригинальный драйвер pcnet32,
загруженный после pcnet-dummy, не обнаружит сетевую карту. Но он
сбросит контроллер в 16бит режим, после чего при повторной его загрузке
карточка обнаружится.
Поэтому выдвигаю предложение разбить функцию pcnet_dummy_reset() на
две: reset и switch_to_32, и вызывать reset в remove_one()
Есть ли замечания?

--
Best regards,
Dmitry Podgorny



More information about the Kernel-russian mailing list