?? pata_via.c
字號:
}static void via_set_piomode(struct ata_port *ap, struct ata_device *adev){ const struct via_isa_bridge *config = ap->host->private_data; int set_ast = (config->flags & VIA_BAD_AST) ? 0 : 1; int mode = config->flags & VIA_UDMA; static u8 tclock[5] = { 1, 1, 2, 3, 4 }; static u8 udma[5] = { 0, 33, 66, 100, 133 }; via_do_set_mode(ap, adev, adev->pio_mode, tclock[mode], set_ast, udma[mode]);}static void via_set_dmamode(struct ata_port *ap, struct ata_device *adev){ const struct via_isa_bridge *config = ap->host->private_data; int set_ast = (config->flags & VIA_BAD_AST) ? 0 : 1; int mode = config->flags & VIA_UDMA; static u8 tclock[5] = { 1, 1, 2, 3, 4 }; static u8 udma[5] = { 0, 33, 66, 100, 133 }; via_do_set_mode(ap, adev, adev->dma_mode, tclock[mode], set_ast, udma[mode]);}static struct scsi_host_template via_sht = { ATA_BMDMA_SHT(DRV_NAME),};static struct ata_port_operations via_port_ops = { .inherits = &ata_bmdma_port_ops, .cable_detect = via_cable_detect, .set_piomode = via_set_piomode, .set_dmamode = via_set_dmamode, .prereset = via_pre_reset,};static struct ata_port_operations via_port_ops_noirq = { .inherits = &via_port_ops, .sff_data_xfer = ata_sff_data_xfer_noirq,};/** * via_config_fifo - set up the FIFO * @pdev: PCI device * @flags: configuration flags * * Set the FIFO properties for this device if necessary. Used both on * set up and on and the resume path */static void via_config_fifo(struct pci_dev *pdev, unsigned int flags){ u8 enable; /* 0x40 low bits indicate enabled channels */ pci_read_config_byte(pdev, 0x40 , &enable); enable &= 3; if (flags & VIA_SET_FIFO) { static const u8 fifo_setting[4] = {0x00, 0x60, 0x00, 0x20}; u8 fifo; pci_read_config_byte(pdev, 0x43, &fifo); /* Clear PREQ# until DDACK# for errata */ if (flags & VIA_BAD_PREQ) fifo &= 0x7F; else fifo &= 0x9f; /* Turn on FIFO for enabled channels */ fifo |= fifo_setting[enable]; pci_write_config_byte(pdev, 0x43, fifo); }}/** * via_init_one - discovery callback * @pdev: PCI device * @id: PCI table info * * A VIA IDE interface has been discovered. Figure out what revision * and perform configuration work before handing it to the ATA layer */static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id){ /* Early VIA without UDMA support */ static const struct ata_port_info via_mwdma_info = { .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .port_ops = &via_port_ops }; /* Ditto with IRQ masking required */ static const struct ata_port_info via_mwdma_info_borked = { .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .port_ops = &via_port_ops_noirq, }; /* VIA UDMA 33 devices (and borked 66) */ static const struct ata_port_info via_udma33_info = { .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = ATA_UDMA2, .port_ops = &via_port_ops }; /* VIA UDMA 66 devices */ static const struct ata_port_info via_udma66_info = { .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = ATA_UDMA4, .port_ops = &via_port_ops }; /* VIA UDMA 100 devices */ static const struct ata_port_info via_udma100_info = { .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = ATA_UDMA5, .port_ops = &via_port_ops }; /* UDMA133 with bad AST (All current 133) */ static const struct ata_port_info via_udma133_info = { .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, .mwdma_mask = 0x07, .udma_mask = ATA_UDMA6, /* FIXME: should check north bridge */ .port_ops = &via_port_ops }; const struct ata_port_info *ppi[] = { NULL, NULL }; struct pci_dev *isa = NULL; const struct via_isa_bridge *config; static int printed_version; u8 enable; u32 timing; int rc; if (!printed_version++) dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); rc = pcim_enable_device(pdev); if (rc) return rc; /* To find out how the IDE will behave and what features we actually have to look at the bridge not the IDE controller */ for (config = via_isa_bridges; config->id; config++) if ((isa = pci_get_device(PCI_VENDOR_ID_VIA + !!(config->flags & VIA_BAD_ID), config->id, NULL))) { if (isa->revision >= config->rev_min && isa->revision <= config->rev_max) break; pci_dev_put(isa); } if (!config->id) { printk(KERN_WARNING "via: Unknown VIA SouthBridge, disabling.\n"); return -ENODEV; } pci_dev_put(isa); if (!(config->flags & VIA_NO_ENABLES)) { /* 0x40 low bits indicate enabled channels */ pci_read_config_byte(pdev, 0x40 , &enable); enable &= 3; if (enable == 0) return -ENODEV; } /* Initialise the FIFO for the enabled channels. */ via_config_fifo(pdev, config->flags); /* Clock set up */ switch(config->flags & VIA_UDMA) { case VIA_UDMA_NONE: if (config->flags & VIA_NO_UNMASK) ppi[0] = &via_mwdma_info_borked; else ppi[0] = &via_mwdma_info; break; case VIA_UDMA_33: ppi[0] = &via_udma33_info; break; case VIA_UDMA_66: ppi[0] = &via_udma66_info; /* The 66 MHz devices require we enable the clock */ pci_read_config_dword(pdev, 0x50, &timing); timing |= 0x80008; pci_write_config_dword(pdev, 0x50, timing); break; case VIA_UDMA_100: ppi[0] = &via_udma100_info; break; case VIA_UDMA_133: ppi[0] = &via_udma133_info; break; default: WARN_ON(1); return -ENODEV; } if (config->flags & VIA_BAD_CLK66) { /* Disable the 66MHz clock on problem devices */ pci_read_config_dword(pdev, 0x50, &timing); timing &= ~0x80008; pci_write_config_dword(pdev, 0x50, timing); } /* We have established the device type, now fire it up */ return ata_pci_sff_init_one(pdev, ppi, &via_sht, (void *)config);}#ifdef CONFIG_PM/** * via_reinit_one - reinit after resume * @pdev; PCI device * * Called when the VIA PATA device is resumed. We must then * reconfigure the fifo and other setup we may have altered. In * addition the kernel needs to have the resume methods on PCI * quirk supported. */static int via_reinit_one(struct pci_dev *pdev){ u32 timing; struct ata_host *host = dev_get_drvdata(&pdev->dev); const struct via_isa_bridge *config = host->private_data; int rc; rc = ata_pci_device_do_resume(pdev); if (rc) return rc; via_config_fifo(pdev, config->flags); if ((config->flags & VIA_UDMA) == VIA_UDMA_66) { /* The 66 MHz devices require we enable the clock */ pci_read_config_dword(pdev, 0x50, &timing); timing |= 0x80008; pci_write_config_dword(pdev, 0x50, timing); } if (config->flags & VIA_BAD_CLK66) { /* Disable the 66MHz clock on problem devices */ pci_read_config_dword(pdev, 0x50, &timing); timing &= ~0x80008; pci_write_config_dword(pdev, 0x50, timing); } ata_host_resume(host); return 0;}#endifstatic const struct pci_device_id via[] = { { PCI_VDEVICE(VIA, 0x0571), }, { PCI_VDEVICE(VIA, 0x0581), }, { PCI_VDEVICE(VIA, 0x1571), }, { PCI_VDEVICE(VIA, 0x3164), }, { PCI_VDEVICE(VIA, 0x5324), }, { },};static struct pci_driver via_pci_driver = { .name = DRV_NAME, .id_table = via, .probe = via_init_one, .remove = ata_pci_remove_one,#ifdef CONFIG_PM .suspend = ata_pci_device_suspend, .resume = via_reinit_one,#endif};static int __init via_init(void){ return pci_register_driver(&via_pci_driver);}static void __exit via_exit(void){ pci_unregister_driver(&via_pci_driver);}MODULE_AUTHOR("Alan Cox");MODULE_DESCRIPTION("low-level driver for VIA PATA");MODULE_LICENSE("GPL");MODULE_DEVICE_TABLE(pci, via);MODULE_VERSION(DRV_VERSION);module_init(via_init);module_exit(via_exit);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -