Commit a0dbc715 authored by Martin Diehl's avatar Martin Diehl Committed by Stephen Hemminger

[IRDA]: vlsi_ir v0.5 update, 1/7.

* Kconfig: we depend on CONFIG_PCI
* update header compatibility stuff
* beautify C99-initializers for PCI IDs
* PCIDEV_NAME wrapper to abstract device name storage location
* cleanup of the pci shutdown path. Also fixing a possible NULL-pointer
  dereference when the driver is rmmod with the netdev still running.
parent 9d65ad2e
...@@ -319,7 +319,7 @@ config ALI_FIR ...@@ -319,7 +319,7 @@ config ALI_FIR
config VLSI_FIR config VLSI_FIR
tristate "VLSI 82C147 SIR/MIR/FIR (EXPERIMENTAL)" tristate "VLSI 82C147 SIR/MIR/FIR (EXPERIMENTAL)"
depends on EXPERIMENTAL && IRDA depends on EXPERIMENTAL && IRDA && PCI
help help
Say Y here if you want to build support for the VLSI 82C147 Say Y here if you want to build support for the VLSI 82C147
PCI-IrDA Controller. This controller is used by the HP OmniBook 800 PCI-IrDA Controller. This controller is used by the HP OmniBook 800
......
...@@ -55,14 +55,16 @@ MODULE_LICENSE("GPL"); ...@@ -55,14 +55,16 @@ MODULE_LICENSE("GPL");
static /* const */ char drivername[] = DRIVER_NAME; static /* const */ char drivername[] = DRIVER_NAME;
#define PCI_CLASS_WIRELESS_IRDA 0x0d00 static struct pci_device_id vlsi_irda_table [] = {
{
static struct pci_device_id vlsi_irda_table [] = { { .class = PCI_CLASS_WIRELESS_IRDA << 8,
.class_mask = PCI_CLASS_SUBCLASS_MASK << 8,
.class = PCI_CLASS_WIRELESS_IRDA << 8, .vendor = PCI_VENDOR_ID_VLSI,
.vendor = PCI_VENDOR_ID_VLSI, .device = PCI_DEVICE_ID_VLSI_82C147,
.device = PCI_DEVICE_ID_VLSI_82C147, .subvendor = PCI_ANY_ID,
}, { /* all zeroes */ } .subdevice = PCI_ANY_ID,
},
{ /* all zeroes */ }
}; };
MODULE_DEVICE_TABLE(pci, vlsi_irda_table); MODULE_DEVICE_TABLE(pci, vlsi_irda_table);
...@@ -164,7 +166,7 @@ static int vlsi_proc_pdev(struct pci_dev *pdev, char *buf, int len) ...@@ -164,7 +166,7 @@ static int vlsi_proc_pdev(struct pci_dev *pdev, char *buf, int len)
return 0; return 0;
out += sprintf(out, "\n%s (vid/did: %04x/%04x)\n", out += sprintf(out, "\n%s (vid/did: %04x/%04x)\n",
pci_name(pdev), (int)pdev->vendor, (int)pdev->device); PCIDEV_NAME(pdev), (int)pdev->vendor, (int)pdev->device);
out += sprintf(out, "pci-power-state: %u\n", (unsigned) pdev->current_state); out += sprintf(out, "pci-power-state: %u\n", (unsigned) pdev->current_state);
out += sprintf(out, "resources: irq=%u / io=0x%04x / dma_mask=0x%016Lx\n", out += sprintf(out, "resources: irq=%u / io=0x%04x / dma_mask=0x%016Lx\n",
pdev->irq, (unsigned)pci_resource_start(pdev, 0), (u64)pdev->dma_mask); pdev->irq, (unsigned)pci_resource_start(pdev, 0), (u64)pdev->dma_mask);
...@@ -1392,9 +1394,7 @@ static int vlsi_init_chip(struct pci_dev *pdev) ...@@ -1392,9 +1394,7 @@ static int vlsi_init_chip(struct pci_dev *pdev)
/* start the clock and clean the registers */ /* start the clock and clean the registers */
if (vlsi_start_clock(pdev)) { if (vlsi_start_clock(pdev)) {
printk(KERN_ERR "%s: no valid clock source\n", ERROR("%s: no valid clock source\n", __FUNCTION__);
__FUNCTION__);
pci_disable_device(pdev);
return -1; return -1;
} }
iobase = ndev->base_addr; iobase = ndev->base_addr;
...@@ -1455,7 +1455,10 @@ static int vlsi_start_hw(vlsi_irda_dev_t *idev) ...@@ -1455,7 +1455,10 @@ static int vlsi_start_hw(vlsi_irda_dev_t *idev)
pci_write_config_byte(pdev, VLSI_PCI_MSTRPAGE, MSTRPAGE_VALUE); pci_write_config_byte(pdev, VLSI_PCI_MSTRPAGE, MSTRPAGE_VALUE);
pci_set_master(pdev); pci_set_master(pdev);
vlsi_init_chip(pdev); if (vlsi_init_chip(pdev) < 0) {
pci_disable_device(pdev);
return -1;
}
vlsi_fill_rx(idev->rx_ring); vlsi_fill_rx(idev->rx_ring);
...@@ -1521,8 +1524,8 @@ static void vlsi_tx_timeout(struct net_device *ndev) ...@@ -1521,8 +1524,8 @@ static void vlsi_tx_timeout(struct net_device *ndev)
idev->new_baud = idev->baud; /* keep current baudrate */ idev->new_baud = idev->baud; /* keep current baudrate */
if (vlsi_start_hw(idev)) if (vlsi_start_hw(idev))
printk(KERN_CRIT "%s: failed to restart hw - %s(%s) unusable!\n", ERROR("%s: failed to restart hw - %s(%s) unusable!\n",
__FUNCTION__, pci_name(idev->pdev), ndev->name); __FUNCTION__, PCIDEV_NAME(idev->pdev), ndev->name);
else else
netif_start_queue(ndev); netif_start_queue(ndev);
} }
...@@ -1771,8 +1774,8 @@ vlsi_irda_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1771,8 +1774,8 @@ vlsi_irda_probe(struct pci_dev *pdev, const struct pci_device_id *id)
else else
pdev->current_state = 0; /* hw must be running now */ pdev->current_state = 0; /* hw must be running now */
printk(KERN_INFO "%s: IrDA PCI controller %s detected\n", MESSAGE("%s: IrDA PCI controller %s detected\n",
drivername, pci_name(pdev)); drivername, PCIDEV_NAME(pdev));
if ( !pci_resource_start(pdev,0) if ( !pci_resource_start(pdev,0)
|| !(pci_resource_flags(pdev,0) & IORESOURCE_IO) ) { || !(pci_resource_flags(pdev,0) & IORESOURCE_IO) ) {
...@@ -1854,8 +1857,6 @@ static void __devexit vlsi_irda_remove(struct pci_dev *pdev) ...@@ -1854,8 +1857,6 @@ static void __devexit vlsi_irda_remove(struct pci_dev *pdev)
idev = ndev->priv; idev = ndev->priv;
down(&idev->sem); down(&idev->sem);
pci_set_drvdata(pdev, NULL);
pci_disable_device(pdev);
if (idev->proc_entry) { if (idev->proc_entry) {
remove_proc_entry(ndev->name, vlsi_proc_root); remove_proc_entry(ndev->name, vlsi_proc_root);
idev->proc_entry = NULL; idev->proc_entry = NULL;
...@@ -1867,7 +1868,9 @@ static void __devexit vlsi_irda_remove(struct pci_dev *pdev) ...@@ -1867,7 +1868,9 @@ static void __devexit vlsi_irda_remove(struct pci_dev *pdev)
* ndev->destructor called (if present) when going to free * ndev->destructor called (if present) when going to free
*/ */
printk(KERN_INFO "%s: %s removed\n", drivername, pci_name(pdev)); pci_set_drvdata(pdev, NULL);
MESSAGE("%s: %s removed\n", drivername, PCIDEV_NAME(pdev));
} }
#ifdef CONFIG_PM #ifdef CONFIG_PM
...@@ -1882,8 +1885,8 @@ static void __devexit vlsi_irda_remove(struct pci_dev *pdev) ...@@ -1882,8 +1885,8 @@ static void __devexit vlsi_irda_remove(struct pci_dev *pdev)
static int vlsi_irda_save_state(struct pci_dev *pdev, u32 state) static int vlsi_irda_save_state(struct pci_dev *pdev, u32 state)
{ {
if (state < 1 || state > 3 ) { if (state < 1 || state > 3 ) {
printk( KERN_ERR "%s - %s: invalid pm state request: %u\n", ERROR("%s - %s: invalid pm state request: %u\n",
__FUNCTION__, pci_name(pdev), state); __FUNCTION__, PCIDEV_NAME(pdev), state);
return -1; return -1;
} }
return 0; return 0;
...@@ -1895,12 +1898,12 @@ static int vlsi_irda_suspend(struct pci_dev *pdev, u32 state) ...@@ -1895,12 +1898,12 @@ static int vlsi_irda_suspend(struct pci_dev *pdev, u32 state)
vlsi_irda_dev_t *idev; vlsi_irda_dev_t *idev;
if (state < 1 || state > 3 ) { if (state < 1 || state > 3 ) {
printk( KERN_ERR "%s - %s: invalid pm state request: %u\n", ERROR("%s - %s: invalid pm state request: %u\n",
__FUNCTION__, pci_name(pdev), state); __FUNCTION__, PCIDEV_NAME(pdev), state);
return 0; return 0;
} }
if (!ndev) { if (!ndev) {
printk(KERN_ERR "%s - %s: no netdevice \n", __FUNCTION__, pci_name(pdev)); ERROR("%s - %s: no netdevice \n", __FUNCTION__, PCIDEV_NAME(pdev));
return 0; return 0;
} }
idev = ndev->priv; idev = ndev->priv;
...@@ -1911,8 +1914,8 @@ static int vlsi_irda_suspend(struct pci_dev *pdev, u32 state) ...@@ -1911,8 +1914,8 @@ static int vlsi_irda_suspend(struct pci_dev *pdev, u32 state)
pdev->current_state = state; pdev->current_state = state;
} }
else else
printk(KERN_ERR "%s - %s: invalid suspend request %u -> %u\n", ERROR("%s - %s: invalid suspend request %u -> %u\n",
__FUNCTION__, pci_name(pdev), pdev->current_state, state); __FUNCTION__, PCIDEV_NAME(pdev), pdev->current_state, state);
up(&idev->sem); up(&idev->sem);
return 0; return 0;
} }
...@@ -1939,14 +1942,14 @@ static int vlsi_irda_resume(struct pci_dev *pdev) ...@@ -1939,14 +1942,14 @@ static int vlsi_irda_resume(struct pci_dev *pdev)
vlsi_irda_dev_t *idev; vlsi_irda_dev_t *idev;
if (!ndev) { if (!ndev) {
printk(KERN_ERR "%s - %s: no netdevice \n", __FUNCTION__, pci_name(pdev)); ERROR("%s - %s: no netdevice \n", __FUNCTION__, PCIDEV_NAME(pdev));
return 0; return 0;
} }
idev = ndev->priv; idev = ndev->priv;
down(&idev->sem); down(&idev->sem);
if (pdev->current_state == 0) { if (pdev->current_state == 0) {
up(&idev->sem); up(&idev->sem);
printk(KERN_ERR "%s - %s: already resumed\n", __FUNCTION__, pci_name(pdev)); WARNING("%s - %s: already resumed\n", __FUNCTION__, PCIDEV_NAME(pdev));
return 0; return 0;
} }
......
...@@ -27,18 +27,71 @@ ...@@ -27,18 +27,71 @@
#ifndef IRDA_VLSI_FIR_H #ifndef IRDA_VLSI_FIR_H
#define IRDA_VLSI_FIR_H #define IRDA_VLSI_FIR_H
/* /* ================================================================
* #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,xx) * compatibility stuff
* */
* missing pci-dma api call to give streaming dma buffer back to hw
* patch floating on lkml - probably present in 2.5.26 or later /* definitions not present in pci_ids.h */
* otherwise defining it as noop is ok, since the vlsi-ir is only
#ifndef PCI_CLASS_WIRELESS_IRDA
#define PCI_CLASS_WIRELESS_IRDA 0x0d00
#endif
#ifndef PCI_CLASS_SUBCLASS_MASK
#define PCI_CLASS_SUBCLASS_MASK 0xffff
#endif
/* missing pci-dma api call to give streaming dma buffer back to hw
* patch was floating on lkml around 2.5.2x and might be present later.
* Defining it this way is ok, since the vlsi-ir is only
* used on two oldish x86-based notebooks which are cache-coherent * used on two oldish x86-based notebooks which are cache-coherent
* (and flush_write_buffers also handles PPro errata and C3 OOstore)
*/ */
#define pci_dma_prep_single(dev, addr, size, direction) /* nothing */ #ifdef CONFIG_X86
/* #include <asm-i386/io.h>
* #endif #define pci_dma_prep_single(dev, addr, size, direction) flush_write_buffers()
#else
#error missing pci dma api call
#endif
/* in recent 2.5 interrupt handlers have non-void return value */
#ifndef IRQ_RETVAL
typedef void irqreturn_t;
#define IRQ_NONE
#define IRQ_HANDLED
#define IRQ_RETVAL(x)
#endif
/* some stuff need to check kernelversion. Not all 2.5 stuff was present
* in early 2.5.x - the test is merely to separate 2.4 from 2.5
*/ */
#include <linux/version.h>
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
/* PDE() introduced in 2.5.4 */
#ifdef CONFIG_PROC_FS
#define PDE(inode) ((inode)->u.generic_ip)
#endif
/* irda crc16 calculation exported in 2.5.42 */
#define irda_calc_crc16(fcs,buf,len) (GOOD_FCS)
/* we use this for unified pci device name access */
#define PCIDEV_NAME(pdev) ((pdev)->name)
#else /* 2.5 or later */
/* recent 2.5/2.6 stores pci device names at varying places ;-) */
#ifdef CONFIG_PCI_NAMES
/* human readable name */
#define PCIDEV_NAME(pdev) ((pdev)->pretty_name)
#else
/* whatever we get from the associated struct device - bus:slot:dev.fn id */
#define PCIDEV_NAME(pdev) (pci_name(pdev))
#endif
#endif
/* ================================================================ */ /* ================================================================ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment