0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042 #include "aic7xxx_osm.h"
0043 #include "aic7xxx_pci.h"
0044
0045
0046
0047 #define ID(x) ID_C(x, PCI_CLASS_STORAGE_SCSI)
0048
0049 static const struct pci_device_id ahc_linux_pci_id_table[] = {
0050
0051 ID(ID_AHA_2902_04_10_15_20C_30C),
0052
0053 ID(ID_AHA_2930CU),
0054 ID(ID_AHA_1480A & ID_DEV_VENDOR_MASK),
0055 ID(ID_AHA_2940AU_0 & ID_DEV_VENDOR_MASK),
0056 ID(ID_AHA_2940AU_CN & ID_DEV_VENDOR_MASK),
0057 ID(ID_AHA_2930C_VAR & ID_DEV_VENDOR_MASK),
0058
0059 ID(ID_AHA_2940),
0060 ID(ID_AHA_3940),
0061 ID(ID_AHA_398X),
0062 ID(ID_AHA_2944),
0063 ID(ID_AHA_3944),
0064 ID(ID_AHA_4944),
0065
0066 ID(ID_AHA_2940U & ID_DEV_VENDOR_MASK),
0067 ID(ID_AHA_3940U & ID_DEV_VENDOR_MASK),
0068 ID(ID_AHA_2944U & ID_DEV_VENDOR_MASK),
0069 ID(ID_AHA_3944U & ID_DEV_VENDOR_MASK),
0070 ID(ID_AHA_398XU & ID_DEV_VENDOR_MASK),
0071 ID(ID_AHA_4944U & ID_DEV_VENDOR_MASK),
0072 ID(ID_AHA_2930U & ID_DEV_VENDOR_MASK),
0073 ID(ID_AHA_2940U_PRO & ID_DEV_VENDOR_MASK),
0074 ID(ID_AHA_2940U_CN & ID_DEV_VENDOR_MASK),
0075
0076 ID(ID_AHA_2930U2),
0077 ID(ID_AHA_2940U2B),
0078 ID(ID_AHA_2940U2_OEM),
0079 ID(ID_AHA_2940U2),
0080 ID(ID_AHA_2950U2B),
0081 ID16(ID_AIC7890_ARO & ID_AIC7895_ARO_MASK),
0082 ID(ID_AAA_131U2),
0083
0084 ID(ID_AHA_29160),
0085 ID(ID_AHA_29160_CPQ),
0086 ID(ID_AHA_29160N),
0087 ID(ID_AHA_29160C),
0088 ID(ID_AHA_29160B),
0089 ID(ID_AHA_19160B),
0090 ID(ID_AIC7892_ARO),
0091
0092 ID(ID_AHA_2940U_DUAL),
0093 ID(ID_AHA_3940AU),
0094 ID(ID_AHA_3944AU),
0095 ID(ID_AIC7895_ARO),
0096 ID(ID_AHA_3950U2B_0),
0097 ID(ID_AHA_3950U2B_1),
0098 ID(ID_AHA_3950U2D_0),
0099 ID(ID_AHA_3950U2D_1),
0100 ID(ID_AIC7896_ARO),
0101
0102 ID(ID_AHA_3960D),
0103 ID(ID_AHA_3960D_CPQ),
0104 ID(ID_AIC7899_ARO),
0105
0106 ID(ID_AIC7850 & ID_DEV_VENDOR_MASK),
0107 ID(ID_AIC7855 & ID_DEV_VENDOR_MASK),
0108 ID(ID_AIC7859 & ID_DEV_VENDOR_MASK),
0109 ID(ID_AIC7860 & ID_DEV_VENDOR_MASK),
0110 ID(ID_AIC7870 & ID_DEV_VENDOR_MASK),
0111 ID(ID_AIC7880 & ID_DEV_VENDOR_MASK),
0112 ID16(ID_AIC7890 & ID_9005_GENERIC_MASK),
0113 ID16(ID_AIC7892 & ID_9005_GENERIC_MASK),
0114 ID(ID_AIC7895 & ID_DEV_VENDOR_MASK),
0115 ID16(ID_AIC7896 & ID_9005_GENERIC_MASK),
0116 ID16(ID_AIC7899 & ID_9005_GENERIC_MASK),
0117 ID(ID_AIC7810 & ID_DEV_VENDOR_MASK),
0118 ID(ID_AIC7815 & ID_DEV_VENDOR_MASK),
0119 { 0 }
0120 };
0121
0122 MODULE_DEVICE_TABLE(pci, ahc_linux_pci_id_table);
0123
0124 static int __maybe_unused
0125 ahc_linux_pci_dev_suspend(struct device *dev)
0126 {
0127 struct ahc_softc *ahc = dev_get_drvdata(dev);
0128
0129 return ahc_suspend(ahc);
0130 }
0131
0132 static int __maybe_unused
0133 ahc_linux_pci_dev_resume(struct device *dev)
0134 {
0135 struct ahc_softc *ahc = dev_get_drvdata(dev);
0136
0137 ahc_pci_resume(ahc);
0138
0139 return (ahc_resume(ahc));
0140 }
0141
0142 static void
0143 ahc_linux_pci_dev_remove(struct pci_dev *pdev)
0144 {
0145 struct ahc_softc *ahc = pci_get_drvdata(pdev);
0146 u_long s;
0147
0148 if (ahc->platform_data && ahc->platform_data->host)
0149 scsi_remove_host(ahc->platform_data->host);
0150
0151 ahc_lock(ahc, &s);
0152 ahc_intr_enable(ahc, FALSE);
0153 ahc_unlock(ahc, &s);
0154 ahc_free(ahc);
0155 }
0156
0157 static void
0158 ahc_linux_pci_inherit_flags(struct ahc_softc *ahc)
0159 {
0160 struct pci_dev *pdev = ahc->dev_softc, *master_pdev;
0161 unsigned int master_devfn = PCI_DEVFN(PCI_SLOT(pdev->devfn), 0);
0162
0163 master_pdev = pci_get_slot(pdev->bus, master_devfn);
0164 if (master_pdev) {
0165 struct ahc_softc *master = pci_get_drvdata(master_pdev);
0166 if (master) {
0167 ahc->flags &= ~AHC_BIOS_ENABLED;
0168 ahc->flags |= master->flags & AHC_BIOS_ENABLED;
0169
0170 ahc->flags &= ~AHC_PRIMARY_CHANNEL;
0171 ahc->flags |= master->flags & AHC_PRIMARY_CHANNEL;
0172 } else
0173 printk(KERN_ERR "aic7xxx: no multichannel peer found!\n");
0174 pci_dev_put(master_pdev);
0175 }
0176 }
0177
0178 static int
0179 ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
0180 {
0181 char buf[80];
0182 const uint64_t mask_39bit = 0x7FFFFFFFFFULL;
0183 struct ahc_softc *ahc;
0184 ahc_dev_softc_t pci;
0185 const struct ahc_pci_identity *entry;
0186 char *name;
0187 int error;
0188 struct device *dev = &pdev->dev;
0189
0190 pci = pdev;
0191 entry = ahc_find_pci_device(pci);
0192 if (entry == NULL)
0193 return (-ENODEV);
0194
0195
0196
0197
0198
0199
0200 sprintf(buf, "ahc_pci:%d:%d:%d",
0201 ahc_get_pci_bus(pci),
0202 ahc_get_pci_slot(pci),
0203 ahc_get_pci_function(pci));
0204 name = kstrdup(buf, GFP_ATOMIC);
0205 if (name == NULL)
0206 return (-ENOMEM);
0207 ahc = ahc_alloc(NULL, name);
0208 if (ahc == NULL)
0209 return (-ENOMEM);
0210 if (pci_enable_device(pdev)) {
0211 ahc_free(ahc);
0212 return (-ENODEV);
0213 }
0214 pci_set_master(pdev);
0215
0216 if (sizeof(dma_addr_t) > 4
0217 && ahc->features & AHC_LARGE_SCBS
0218 && dma_set_mask(dev, mask_39bit) == 0
0219 && dma_get_required_mask(dev) > DMA_BIT_MASK(32)) {
0220 ahc->flags |= AHC_39BIT_ADDRESSING;
0221 } else {
0222 if (dma_set_mask(dev, DMA_BIT_MASK(32))) {
0223 ahc_free(ahc);
0224 printk(KERN_WARNING "aic7xxx: No suitable DMA available.\n");
0225 return (-ENODEV);
0226 }
0227 }
0228 ahc->dev_softc = pci;
0229 ahc->dev = &pci->dev;
0230 error = ahc_pci_config(ahc, entry);
0231 if (error != 0) {
0232 ahc_free(ahc);
0233 return (-error);
0234 }
0235
0236
0237
0238
0239
0240 if ((ahc->features & AHC_MULTI_FUNC) && PCI_FUNC(pdev->devfn) != 0)
0241 ahc_linux_pci_inherit_flags(ahc);
0242
0243 pci_set_drvdata(pdev, ahc);
0244 ahc_linux_register_host(ahc, &aic7xxx_driver_template);
0245 return (0);
0246 }
0247
0248
0249 uint32_t
0250 ahc_pci_read_config(ahc_dev_softc_t pci, int reg, int width)
0251 {
0252 switch (width) {
0253 case 1:
0254 {
0255 uint8_t retval;
0256
0257 pci_read_config_byte(pci, reg, &retval);
0258 return (retval);
0259 }
0260 case 2:
0261 {
0262 uint16_t retval;
0263 pci_read_config_word(pci, reg, &retval);
0264 return (retval);
0265 }
0266 case 4:
0267 {
0268 uint32_t retval;
0269 pci_read_config_dword(pci, reg, &retval);
0270 return (retval);
0271 }
0272 default:
0273 panic("ahc_pci_read_config: Read size too big");
0274
0275 return (0);
0276 }
0277 }
0278
0279 void
0280 ahc_pci_write_config(ahc_dev_softc_t pci, int reg, uint32_t value, int width)
0281 {
0282 switch (width) {
0283 case 1:
0284 pci_write_config_byte(pci, reg, value);
0285 break;
0286 case 2:
0287 pci_write_config_word(pci, reg, value);
0288 break;
0289 case 4:
0290 pci_write_config_dword(pci, reg, value);
0291 break;
0292 default:
0293 panic("ahc_pci_write_config: Write size too big");
0294
0295 }
0296 }
0297
0298 static SIMPLE_DEV_PM_OPS(ahc_linux_pci_dev_pm_ops,
0299 ahc_linux_pci_dev_suspend,
0300 ahc_linux_pci_dev_resume);
0301
0302 static struct pci_driver aic7xxx_pci_driver = {
0303 .name = "aic7xxx",
0304 .probe = ahc_linux_pci_dev_probe,
0305 .driver.pm = &ahc_linux_pci_dev_pm_ops,
0306 .remove = ahc_linux_pci_dev_remove,
0307 .id_table = ahc_linux_pci_id_table
0308 };
0309
0310 int
0311 ahc_linux_pci_init(void)
0312 {
0313 return pci_register_driver(&aic7xxx_pci_driver);
0314 }
0315
0316 void
0317 ahc_linux_pci_exit(void)
0318 {
0319 pci_unregister_driver(&aic7xxx_pci_driver);
0320 }
0321
0322 static int
0323 ahc_linux_pci_reserve_io_region(struct ahc_softc *ahc, resource_size_t *base)
0324 {
0325 if (aic7xxx_allow_memio == 0)
0326 return (ENOMEM);
0327
0328 *base = pci_resource_start(ahc->dev_softc, 0);
0329 if (*base == 0)
0330 return (ENOMEM);
0331 if (!request_region(*base, 256, "aic7xxx"))
0332 return (ENOMEM);
0333 return (0);
0334 }
0335
0336 static int
0337 ahc_linux_pci_reserve_mem_region(struct ahc_softc *ahc,
0338 resource_size_t *bus_addr,
0339 uint8_t __iomem **maddr)
0340 {
0341 resource_size_t start;
0342 int error;
0343
0344 error = 0;
0345 start = pci_resource_start(ahc->dev_softc, 1);
0346 if (start != 0) {
0347 *bus_addr = start;
0348 if (!request_mem_region(start, 0x1000, "aic7xxx"))
0349 error = ENOMEM;
0350 if (error == 0) {
0351 *maddr = ioremap(start, 256);
0352 if (*maddr == NULL) {
0353 error = ENOMEM;
0354 release_mem_region(start, 0x1000);
0355 }
0356 }
0357 } else
0358 error = ENOMEM;
0359 return (error);
0360 }
0361
0362 int
0363 ahc_pci_map_registers(struct ahc_softc *ahc)
0364 {
0365 uint32_t command;
0366 resource_size_t base;
0367 uint8_t __iomem *maddr;
0368 int error;
0369
0370
0371
0372
0373 command = ahc_pci_read_config(ahc->dev_softc, PCIR_COMMAND, 4);
0374 command &= ~(PCIM_CMD_PORTEN|PCIM_CMD_MEMEN);
0375 base = 0;
0376 maddr = NULL;
0377 error = ahc_linux_pci_reserve_mem_region(ahc, &base, &maddr);
0378 if (error == 0) {
0379 ahc->platform_data->mem_busaddr = base;
0380 ahc->tag = BUS_SPACE_MEMIO;
0381 ahc->bsh.maddr = maddr;
0382 ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND,
0383 command | PCIM_CMD_MEMEN, 4);
0384
0385
0386
0387
0388
0389 if (ahc_pci_test_register_access(ahc) != 0) {
0390
0391 printk("aic7xxx: PCI Device %d:%d:%d "
0392 "failed memory mapped test. Using PIO.\n",
0393 ahc_get_pci_bus(ahc->dev_softc),
0394 ahc_get_pci_slot(ahc->dev_softc),
0395 ahc_get_pci_function(ahc->dev_softc));
0396 iounmap(maddr);
0397 release_mem_region(ahc->platform_data->mem_busaddr,
0398 0x1000);
0399 ahc->bsh.maddr = NULL;
0400 maddr = NULL;
0401 } else
0402 command |= PCIM_CMD_MEMEN;
0403 } else {
0404 printk("aic7xxx: PCI%d:%d:%d MEM region 0x%llx "
0405 "unavailable. Cannot memory map device.\n",
0406 ahc_get_pci_bus(ahc->dev_softc),
0407 ahc_get_pci_slot(ahc->dev_softc),
0408 ahc_get_pci_function(ahc->dev_softc),
0409 (unsigned long long)base);
0410 }
0411
0412
0413
0414
0415 if (maddr == NULL) {
0416
0417 error = ahc_linux_pci_reserve_io_region(ahc, &base);
0418 if (error == 0) {
0419 ahc->tag = BUS_SPACE_PIO;
0420 ahc->bsh.ioport = (u_long)base;
0421 command |= PCIM_CMD_PORTEN;
0422 } else {
0423 printk("aic7xxx: PCI%d:%d:%d IO region 0x%llx[0..255] "
0424 "unavailable. Cannot map device.\n",
0425 ahc_get_pci_bus(ahc->dev_softc),
0426 ahc_get_pci_slot(ahc->dev_softc),
0427 ahc_get_pci_function(ahc->dev_softc),
0428 (unsigned long long)base);
0429 }
0430 }
0431 ahc_pci_write_config(ahc->dev_softc, PCIR_COMMAND, command, 4);
0432 return (error);
0433 }
0434
0435 int
0436 ahc_pci_map_int(struct ahc_softc *ahc)
0437 {
0438 int error;
0439
0440 error = request_irq(ahc->dev_softc->irq, ahc_linux_isr,
0441 IRQF_SHARED, "aic7xxx", ahc);
0442 if (error == 0)
0443 ahc->platform_data->irq = ahc->dev_softc->irq;
0444
0445 return (-error);
0446 }
0447