61 |
MODULE_DEVICE_TABLE(pci, snd_vortex_ids); |
MODULE_DEVICE_TABLE(pci, snd_vortex_ids); |
62 |
|
|
63 |
|
|
64 |
// chip-specific destructor |
// component-destructor |
65 |
// (see "PCI Resource Managements") |
// (see "Management of Cards and Components") |
66 |
static int snd_vortex_free(vortex_t *vortex) { |
static int snd_vortex_dev_free(snd_device_t *device) { |
67 |
|
vortex_t *vortex = snd_magic_cast(vortex_t, device->device_data, |
68 |
|
return -ENXIO); |
69 |
|
|
70 |
|
//FIXME: we do stuff here without checking |
71 |
vortex_gameport_unregister(vortex); |
vortex_gameport_unregister(vortex); |
72 |
vortex_core_shutdown(vortex); |
vortex_core_shutdown(vortex); |
73 |
// Take down PCI interface. |
// Take down PCI interface. |
76 |
pci_release_regions(vortex->pci_dev); |
pci_release_regions(vortex->pci_dev); |
77 |
pci_disable_device(vortex->pci_dev); |
pci_disable_device(vortex->pci_dev); |
78 |
snd_magic_kfree(vortex); |
snd_magic_kfree(vortex); |
|
return 0; |
|
|
} |
|
|
|
|
|
// component-destructor |
|
|
// (see "Management of Cards and Components") |
|
|
static int snd_vortex_dev_free(snd_device_t *device) { |
|
|
vortex_t *vortex = snd_magic_cast(vortex_t, device->device_data, |
|
|
return -ENXIO); |
|
79 |
|
|
80 |
return snd_vortex_free(vortex); |
return 0; |
81 |
} |
} |
82 |
|
|
83 |
// chip-specific constructor |
// chip-specific constructor |
122 |
// Get MMIO area. |
// Get MMIO area. |
123 |
if (!request_mem_region(pci_resource_start(pci, 0), |
if (!request_mem_region(pci_resource_start(pci, 0), |
124 |
pci_resource_len(pci, 0), CARD_NAME_SHORT)) { |
pci_resource_len(pci, 0), CARD_NAME_SHORT)) { |
|
snd_vortex_free(chip); |
|
125 |
printk(KERN_ERR "cannot allocate mmio area.\n"); |
printk(KERN_ERR "cannot allocate mmio area.\n"); |
126 |
return -EBUSY; |
err = -EBUSY; |
127 |
} |
goto regions_out; |
|
//chip->mmio = ioremap_nocache(pci_resource_start(pci,0), pci_resource_len(pci,0)); |
|
|
chip->mmio = ioremap(pci_resource_start(pci,0), pci_resource_len(pci,0)); |
|
|
if (!chip->mmio) { |
|
|
snd_vortex_free(chip); |
|
|
printk(KERN_ERR "MMIO area remap failed.\n"); |
|
|
return -EBUSY; |
|
128 |
} |
} |
129 |
// Get I/O ports. |
// Get I/O ports. |
130 |
if (check_region(pci_resource_start(pci, 1), 8)) { |
if (check_region(pci_resource_start(pci, 1), 8)) { |
|
snd_vortex_free(chip); |
|
131 |
printk(KERN_ERR "cannot allocate I/O port0.\n"); |
printk(KERN_ERR "cannot allocate I/O port0.\n"); |
132 |
return -EBUSY; |
err = -EBUSY; |
133 |
|
goto regions_out; |
134 |
} |
} |
135 |
chip->port0 = request_region(pci_resource_start(pci, 1), 8, CARD_NAME_SHORT); |
chip->port0 = request_region(pci_resource_start(pci, 1), 8, CARD_NAME_SHORT); |
136 |
|
|
137 |
if (check_region(pci_resource_start(pci, 2), 8)) { |
if (check_region(pci_resource_start(pci, 2), 8)) { |
|
snd_vortex_free(chip); |
|
138 |
printk(KERN_ERR "cannot allocate the I/O port1.\n"); |
printk(KERN_ERR "cannot allocate the I/O port1.\n"); |
139 |
return -EBUSY; |
err = -EBUSY; |
140 |
|
goto regions_out; |
141 |
} |
} |
142 |
chip->port1 = request_region(pci_resource_start(pci, 2), 8, CARD_NAME_SHORT); |
chip->port1 = request_region(pci_resource_start(pci, 2), 8, CARD_NAME_SHORT); |
143 |
|
|
144 |
|
|
145 |
|
//chip->mmio = ioremap_nocache(pci_resource_start(pci,0), pci_resource_len(pci,0)); |
146 |
|
chip->mmio = ioremap(pci_resource_start(pci,0), pci_resource_len(pci,0)); |
147 |
|
if (!chip->mmio) { |
148 |
|
printk(KERN_ERR "MMIO area remap failed.\n"); |
149 |
|
err = -EBUSY; |
150 |
|
goto ioremap_out; |
151 |
|
} |
152 |
|
|
153 |
/* Init audio core. |
/* Init audio core. |
154 |
* This must be done before we do request_irq otherwise we can get spurious |
* This must be done before we do request_irq otherwise we can get spurious |
155 |
* interupts that we do not handle properly and make a mess of things */ |
* interupts that we do not handle properly and make a mess of things */ |
157 |
|
|
158 |
if (request_irq(pci->irq, vortex_interrupt, SA_INTERRUPT | SA_SHIRQ, |
if (request_irq(pci->irq, vortex_interrupt, SA_INTERRUPT | SA_SHIRQ, |
159 |
CARD_NAME_SHORT, (void *) chip)) { |
CARD_NAME_SHORT, (void *) chip)) { |
|
snd_vortex_free(chip); |
|
160 |
printk(KERN_ERR "cannot grab irq\n"); |
printk(KERN_ERR "cannot grab irq\n"); |
161 |
return -EBUSY; |
err = -EBUSY; |
162 |
|
goto irq_out; |
163 |
} |
} |
164 |
chip->irq = pci->irq; |
chip->irq = pci->irq; |
165 |
vortex_enable_int(chip); |
vortex_enable_int(chip); |
170 |
|
|
171 |
// Register alsa root device. |
// Register alsa root device. |
172 |
if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { |
if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { |
173 |
snd_vortex_free(chip); |
goto alloc_out; |
|
return err; |
|
174 |
} |
} |
175 |
|
|
176 |
*rchip = chip; |
*rchip = chip; |
177 |
|
|
178 |
return 0; |
return 0; |
179 |
|
|
180 |
|
alloc_out: |
181 |
|
snd_magic_kfree(chip); |
182 |
|
irq_out: |
183 |
|
synchronize_irq(chip->irq); |
184 |
|
free_irq(chip->irq, chip); |
185 |
|
core_out: |
186 |
|
vortex_core_shutdown(chip); |
187 |
|
ioremap_out: |
188 |
|
//FIXME: the type of chip->mmio might need to be changed?? |
189 |
|
iounmap((void*)chip->mmio); |
190 |
|
regions_out: |
191 |
|
pci_release_regions(chip->pci_dev); |
192 |
|
pci_disable_device(chip->pci_dev); |
193 |
|
//FIXME: this not the right place to unregister the gameport |
194 |
|
vortex_gameport_unregister(chip); |
195 |
|
return err; |
196 |
|
|
197 |
} |
} |
198 |
|
|
199 |
// constructor -- see "Constructor" sub-section |
// constructor -- see "Constructor" sub-section |