static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq, struct pcmcia_device *handle) { ide_hwif_t *hwif; hw_regs_t hw; int i; u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; memset(&hw, 0, sizeof(hw)); ide_std_init_ports(&hw, io, ctl); hw.irq = irq; hw.chipset = ide_pci; hw.dev = &handle->dev; hwif = ide_deprecated_find_port(hw.io_ports[IDE_DATA_OFFSET]); if (hwif == NULL) return -1; i = hwif->index; if (hwif->present) ide_unregister(i, 0, 0); else if (!hwif->hold) ide_init_port_data(hwif, i); ide_init_port_hw(hwif, &hw); hwif->quirkproc = &ide_undecoded_slave; idx[0] = i; ide_device_add(idx, NULL); return hwif->present ? i : -1; }
static int __init ide_4drives_init(void) { unsigned long base = 0x1f0, ctl = 0x3f6; struct ide_hw hw, *hws[] = { &hw, &hw }; if (probe_4drives == 0) return -ENODEV; if (!request_region(base, 8, DRV_NAME)) { // printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX not free.\n", ; return -EBUSY; } if (!request_region(ctl, 1, DRV_NAME)) { // printk(KERN_ERR "%s: I/O resource 0x%lX not free.\n", ; release_region(base, 8); return -EBUSY; } memset(&hw, 0, sizeof(hw)); ide_std_init_ports(&hw, base, ctl); hw.irq = 14; return ide_host_add(&ide_4drives_port_info, hws, 2, NULL); }
static int idepnp_probe(struct pnp_dev * dev, const struct pnp_device_id *dev_id) { hw_regs_t hw; ide_hwif_t *hwif; int index; if (!(pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) && pnp_irq_valid(dev, 0))) return -1; memset(&hw, 0, sizeof(hw)); ide_std_init_ports(&hw, pnp_port_start(dev, 0), pnp_port_start(dev, 1)); hw.irq = pnp_irq(dev, 0); hw.dma = NO_DMA; index = ide_register_hw(&hw, &hwif); if (index != -1) { printk(KERN_INFO "ide%d: generic PnP IDE interface\n", index); pnp_set_drvdata(dev,hwif); return 0; } return -1; }
static int __init ide_arm_init(void) { unsigned long base = IDE_ARM_IO, ctl = IDE_ARM_IO + 0x206; hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; if (!request_region(base, 8, DRV_NAME)) { printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX not free.\n", DRV_NAME, base, base + 7); return -EBUSY; } if (!request_region(ctl, 1, DRV_NAME)) { printk(KERN_ERR "%s: I/O resource 0x%lX not free.\n", DRV_NAME, ctl); release_region(base, 8); return -EBUSY; } memset(&hw, 0, sizeof(hw)); ide_std_init_ports(&hw, base, ctl); hw.irq = IDE_ARM_IRQ; hw.chipset = ide_generic; return ide_host_add(NULL, hws, NULL); }
static ide_hwif_t *idecs_register(unsigned long io, unsigned long ctl, unsigned long irq, struct pcmcia_device *handle) { ide_hwif_t *hwif; hw_regs_t hw; int i; u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; if (!request_region(io, 8, DRV_NAME)) { printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX not free.\n", DRV_NAME, io, io + 7); return NULL; } if (!request_region(ctl, 1, DRV_NAME)) { printk(KERN_ERR "%s: I/O resource 0x%lX not free.\n", DRV_NAME, ctl); release_region(io, 8); return NULL; } memset(&hw, 0, sizeof(hw)); ide_std_init_ports(&hw, io, ctl); hw.irq = irq; hw.chipset = ide_pci; hw.dev = &handle->dev; hwif = ide_find_port(); if (hwif == NULL) goto out_release; i = hwif->index; ide_init_port_data(hwif, i); ide_init_port_hw(hwif, &hw); hwif->port_ops = &idecs_port_ops; idx[0] = i; ide_device_add(idx, NULL); if (hwif->present) return hwif; /* retry registration in case device is still spinning up */ for (i = 0; i < 10; i++) { msleep(100); ide_port_scan(hwif); if (hwif->present) return hwif; } return hwif; out_release: release_region(ctl, 1); release_region(io, 8); return NULL; }
static int __init ide_generic_init(void) { struct ide_hw hw, *hws[] = { &hw }; unsigned long io_addr; int i, rc = 0, primary = 0, secondary = 0; ide_generic_check_pci_legacy_iobases(&primary, &secondary); if (!probe_mask) { printk(KERN_INFO DRV_NAME ": please use \"probe_mask=0x3f\" " "module parameter for probing all legacy ISA IDE ports\n"); if (primary == 0) probe_mask |= 0x1; if (secondary == 0) probe_mask |= 0x2; } else printk(KERN_INFO DRV_NAME ": enforcing probing of I/O ports " "upon user request\n"); for (i = 0; i < ARRAY_SIZE(legacy_bases); i++) { io_addr = legacy_bases[i]; if ((probe_mask & (1 << i)) && io_addr) { if (!request_region(io_addr, 8, DRV_NAME)) { printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX " "not free.\n", DRV_NAME, io_addr, io_addr + 7); rc = -EBUSY; continue; } if (!request_region(io_addr + 0x206, 1, DRV_NAME)) { printk(KERN_ERR "%s: I/O resource 0x%lX " "not free.\n", DRV_NAME, io_addr + 0x206); release_region(io_addr, 8); rc = -EBUSY; continue; } memset(&hw, 0, sizeof(hw)); ide_std_init_ports(&hw, io_addr, io_addr + 0x206); #ifdef CONFIG_IA64 hw.irq = isa_irq_to_vector(legacy_irqs[i]); #else hw.irq = legacy_irqs[i]; #endif rc = ide_host_add(&ide_generic_port_info, hws, 1, NULL); if (rc) { release_region(io_addr + 0x206, 1); release_region(io_addr, 8); } } } return rc; }
static int __init tx4938ide_probe(struct platform_device *pdev) { struct ide_hw hw, *hws[] = { &hw }; struct ide_host *host; struct resource *res; struct tx4938ide_platform_info *pdata = pdev->dev.platform_data; int irq, ret, i; unsigned long mapbase, mapctl; struct ide_port_info d = tx4938ide_port_info; irq = platform_get_irq(pdev, 0); if (irq < 0) return -ENODEV; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) return -ENODEV; if (!devm_request_mem_region(&pdev->dev, res->start, resource_size(res), "tx4938ide")) return -EBUSY; mapbase = (unsigned long)devm_ioremap(&pdev->dev, res->start, 8 << pdata->ioport_shift); mapctl = (unsigned long)devm_ioremap(&pdev->dev, res->start + 0x10000 + (6 << pdata->ioport_shift), 1 << pdata->ioport_shift); if (!mapbase || !mapctl) return -EBUSY; memset(&hw, 0, sizeof(hw)); if (pdata->ioport_shift) { unsigned long port = mapbase; unsigned long ctl = mapctl; hw.io_ports_array[0] = port; #ifdef __BIG_ENDIAN port++; ctl++; #endif for (i = 1; i <= 7; i++) hw.io_ports_array[i] = port + (i << pdata->ioport_shift); hw.io_ports.ctl_addr = ctl; } else ide_std_init_ports(&hw, mapbase, mapctl); hw.irq = irq; hw.dev = &pdev->dev; pr_info("TX4938 IDE interface (base %#lx, ctl %#lx, irq %d)\n", mapbase, mapctl, hw.irq); if (pdata->gbus_clock) tx4938ide_tune_ebusc(pdata->ebus_ch, pdata->gbus_clock, 0); else d.port_ops = NULL; ret = ide_host_add(&d, hws, 1, &host); if (!ret) platform_set_drvdata(pdev, host); return ret; }
void __init ide_arm_init(void) { hw_regs_t hw; memset(&hw, 0, sizeof(hw)); ide_std_init_ports(&hw, IDE_ARM_IO, IDE_ARM_IO + 0x206); hw.irq = IDE_ARM_IRQ; ide_register_hw(&hw, 1, NULL); }
static int __devinit delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id) { unsigned long base; hw_regs_t hw; ide_hwif_t *hwif = NULL; int i, rc; u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; rc = pci_enable_device(dev); if (rc) { printk(KERN_ERR "delkin_cb: pci_enable_device failed (%d)\n", rc); return rc; } rc = pci_request_regions(dev, "delkin_cb"); if (rc) { printk(KERN_ERR "delkin_cb: pci_request_regions failed (%d)\n", rc); pci_disable_device(dev); return rc; } base = pci_resource_start(dev, 0); outb(0x02, base + 0x1e); /* set nIEN to block interrupts */ inb(base + 0x17); /* read status to clear interrupts */ for (i = 0; i < sizeof(setup); ++i) { if (setup[i]) outb(setup[i], base + i); } memset(&hw, 0, sizeof(hw)); ide_std_init_ports(&hw, base + 0x10, base + 0x1e); hw.irq = dev->irq; hw.dev = &dev->dev; hw.chipset = ide_pci; /* this enables IRQ sharing */ hwif = ide_find_port(); if (hwif == NULL) goto out_disable; i = hwif->index; ide_init_port_data(hwif, i); ide_init_port_hw(hwif, &hw); idx[0] = i; ide_device_add(idx, &delkin_cb_port_info); pci_set_drvdata(dev, hwif); return 0; out_disable: pci_release_regions(dev); pci_disable_device(dev); return -ENODEV; }
static int __init ide_4drives_init(void) { ide_hwif_t *hwif, *mate; unsigned long base = 0x1f0, ctl = 0x3f6; u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; hw_regs_t hw; if (probe_4drives == 0) return -ENODEV; if (!request_region(base, 8, DRV_NAME)) { printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX not free.\n", DRV_NAME, base, base + 7); return -EBUSY; } if (!request_region(ctl, 1, DRV_NAME)) { printk(KERN_ERR "%s: I/O resource 0x%lX not free.\n", DRV_NAME, ctl); release_region(base, 8); return -EBUSY; } memset(&hw, 0, sizeof(hw)); ide_std_init_ports(&hw, base, ctl); hw.irq = 14; hw.chipset = ide_4drives; hwif = ide_find_port(); if (hwif) { ide_init_port_hw(hwif, &hw); idx[0] = hwif->index; } mate = ide_find_port(); if (mate) { ide_init_port_hw(mate, &hw); mate->drives[0].select.all ^= 0x20; mate->drives[1].select.all ^= 0x20; idx[1] = mate->index; if (hwif) { hwif->mate = mate; mate->mate = hwif; hwif->serialized = mate->serialized = 1; } } ide_device_add(idx, NULL); return 0; }
static struct ide_host *idecs_register(unsigned long io, unsigned long ctl, unsigned long irq, struct pcmcia_device *handle) { struct ide_host *host; ide_hwif_t *hwif; int i, rc; hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; if (!request_region(io, 8, DRV_NAME)) { printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX not free.\n", DRV_NAME, io, io + 7); return NULL; } if (!request_region(ctl, 1, DRV_NAME)) { printk(KERN_ERR "%s: I/O resource 0x%lX not free.\n", DRV_NAME, ctl); release_region(io, 8); return NULL; } memset(&hw, 0, sizeof(hw)); ide_std_init_ports(&hw, io, ctl); hw.irq = irq; hw.chipset = ide_pci; hw.dev = &handle->dev; rc = ide_host_add(&idecs_port_info, hws, &host); if (rc) goto out_release; hwif = host->ports[0]; if (hwif->present) return host; /* retry registration in case device is still spinning up */ for (i = 0; i < 10; i++) { msleep(100); ide_port_scan(hwif); if (hwif->present) return host; } return host; out_release: release_region(ctl, 1); release_region(io, 8); return NULL; }
static int idepnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) { hw_regs_t hw; ide_hwif_t *hwif; unsigned long base, ctl; if (!(pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) && pnp_irq_valid(dev, 0))) return -1; base = pnp_port_start(dev, 0); ctl = pnp_port_start(dev, 1); if (!request_region(base, 8, DRV_NAME)) { printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX not free.\n", DRV_NAME, base, base + 7); return -EBUSY; } if (!request_region(ctl, 1, DRV_NAME)) { printk(KERN_ERR "%s: I/O resource 0x%lX not free.\n", DRV_NAME, ctl); release_region(base, 8); return -EBUSY; } memset(&hw, 0, sizeof(hw)); ide_std_init_ports(&hw, base, ctl); hw.irq = pnp_irq(dev, 0); hw.chipset = ide_generic; hwif = ide_find_port(); if (hwif) { u8 index = hwif->index; u8 idx[4] = { index, 0xff, 0xff, 0xff }; ide_init_port_data(hwif, index); ide_init_port_hw(hwif, &hw); printk(KERN_INFO "ide%d: generic PnP IDE interface\n", index); pnp_set_drvdata(dev, hwif); ide_device_add(idx, NULL); return 0; } release_region(ctl, 1); release_region(base, 8); return -1; }
static int __devinit delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id) { unsigned long base; hw_regs_t hw; ide_hwif_t *hwif = NULL; ide_drive_t *drive; int i, rc; rc = pci_enable_device(dev); if (rc) { printk(KERN_ERR "delkin_cb: pci_enable_device failed (%d)\n", rc); return rc; } rc = pci_request_regions(dev, "delkin_cb"); if (rc) { printk(KERN_ERR "delkin_cb: pci_request_regions failed (%d)\n", rc); pci_disable_device(dev); return rc; } base = pci_resource_start(dev, 0); outb(0x02, base + 0x1e); /* set nIEN to block interrupts */ inb(base + 0x17); /* read status to clear interrupts */ for (i = 0; i < sizeof(setup); ++i) { if (setup[i]) outb(setup[i], base + i); } pci_release_regions(dev); /* IDE layer handles regions itself */ memset(&hw, 0, sizeof(hw)); ide_std_init_ports(&hw, base + 0x10, base + 0x1e); hw.irq = dev->irq; hw.chipset = ide_pci; /* this enables IRQ sharing */ rc = ide_register_hw_with_fixup(&hw, &hwif, ide_undecoded_slave); if (rc < 0) { printk(KERN_ERR "delkin_cb: ide_register_hw failed (%d)\n", rc); pci_disable_device(dev); return -ENODEV; } pci_set_drvdata(dev, hwif); hwif->pci_dev = dev; drive = &hwif->drives[0]; if (drive->present) { drive->io_32bit = 1; drive->unmask = 1; } return 0; }
static int idepnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) { struct ide_host *host; unsigned long base, ctl; int rc; struct ide_hw hw, *hws[] = { &hw }; #ifdef CONFIG_DEBUG_PRINTK printk(KERN_INFO DRV_NAME ": generic PnP IDE interface\n"); #else ; #endif if (!(pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) && pnp_irq_valid(dev, 0))) return -1; base = pnp_port_start(dev, 0); ctl = pnp_port_start(dev, 1); if (!request_region(base, 8, DRV_NAME)) { printk(KERN_ERR "%s: I/O resource 0x%lX-0x%lX not free.\n", DRV_NAME, base, base + 7); return -EBUSY; } if (!request_region(ctl, 1, DRV_NAME)) { printk(KERN_ERR "%s: I/O resource 0x%lX not free.\n", DRV_NAME, ctl); release_region(base, 8); return -EBUSY; } memset(&hw, 0, sizeof(hw)); ide_std_init_ports(&hw, base, ctl); hw.irq = pnp_irq(dev, 0); rc = ide_host_add(&ide_pnp_port_info, hws, 1, &host); if (rc) goto out; pnp_set_drvdata(dev, host); return 0; out: release_region(ctl, 1); release_region(base, 8); return rc; }
void __init ide_arm_init(void) { #ifdef CONFIG_ARCH_S3C2410 if (IDE_ARM_HOST) { ide_s3c24xx_init(); } #else if (IDE_ARM_HOST) { hw_regs_t hw; memset(&hw, 0, sizeof(hw)); ide_std_init_ports(&hw, IDE_ARM_IO, IDE_ARM_IO + 0x206); hw.irq = IDE_ARM_IRQ; ide_register_hw(&hw, 1, NULL); } #endif }
void __init ide_arm_init(void) { if (IDE_ARM_HOST) { hw_regs_t hw; memset(&hw, 0, sizeof(hw)); #ifdef CONFIG_BLK_DEV_IDE_EP93XX //#include <asm/arch/ide.h> old_ide_init_default_hwifs(); //ide_init_default_hwifs(); #else ide_std_init_ports(&hw, IDE_ARM_IO, IDE_ARM_IO + 0x206); hw.irq = IDE_ARM_IRQ; ide_register_hw(&hw, NULL); #endif } }
static int __devinit delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id) { struct ide_host *host; unsigned long base; int rc; hw_regs_t hw, *hws[] = { &hw, NULL, NULL, NULL }; rc = pci_enable_device(dev); if (rc) { printk(KERN_ERR "delkin_cb: pci_enable_device failed (%d)\n", rc); return rc; } rc = pci_request_regions(dev, "delkin_cb"); if (rc) { printk(KERN_ERR "delkin_cb: pci_request_regions failed (%d)\n", rc); pci_disable_device(dev); return rc; } base = pci_resource_start(dev, 0); delkin_cb_init_chipset(dev); memset(&hw, 0, sizeof(hw)); ide_std_init_ports(&hw, base + 0x10, base + 0x1e); hw.irq = dev->irq; hw.dev = &dev->dev; hw.chipset = ide_pci; /* this enables IRQ sharing */ rc = ide_host_add(&delkin_cb_port_info, hws, &host); if (rc) goto out_disable; pci_set_drvdata(dev, host); return 0; out_disable: pci_release_regions(dev); pci_disable_device(dev); return rc; }
/* * probe function, mainly used to get the taskfile base address and * configure the hardware information for the IDE framework */ static int __init emxx_cfi_probe(struct platform_device *pdev) { int ret; emxx_cfi_push = 0; emxx_cfi_burst_mode = CFI_BURST_MODE_3 << 3; #ifdef CONFIG_MACH_EMEV if ((system_rev & EMXX_REV_MASK) == EMXX_REV_ES1) emxx_cfi_burst_mode = CFI_BURST_MODE_0 << 3; #endif /* CONFIG_MACH_EMEV */ memset(&emxx_cfi_hw, 0, sizeof(emxx_cfi_hw)); ide_std_init_ports(&emxx_cfi_hw, EMXX_CFI_TASK_FILE, EMXX_CFI_CTL_MODE + 6); emxx_cfi_hw.irq = INT_CFI; emxx_cfi_hw.dev = &pdev->dev; emxx_cfi_hw.chipset = ide_generic; /* Setting pin */ emxx_cfi_init_pin(); #ifdef CONFIG_MACH_EMEV if ((system_rev & EMXX_REV_MASK) != EMXX_REV_ES1) #endif /* CONFIG_MACH_EMEV */ emxx_cfi_disable(); emxx_cfi_workqueue = create_singlethread_workqueue(DRV_NAME); INIT_DELAYED_WORK(&emxx_cfi_detect_work, emxx_cfi_detect_check); set_irq_type(INT_GPIO_101, IRQ_TYPE_EDGE_BOTH); ret = request_irq(INT_GPIO_101, emxx_cfi_detect, IRQF_DISABLED, DRV_NAME, NULL); queue_delayed_work(emxx_cfi_workqueue, &emxx_cfi_detect_work, msecs_to_jiffies(100)); return 0; }
/* * Probe for a cmd640 chipset, and initialize it if found. */ static int __init cmd640x_init(void) { int second_port_cmd640 = 0, rc; const char *bus_type, *port2; u8 b, cfr; hw_regs_t hw[2], *hws[] = { NULL, NULL, NULL, NULL }; if (cmd640_vlb && probe_for_cmd640_vlb()) { bus_type = "VLB"; } else { cmd640_vlb = 0; /* Find out what kind of PCI probing is supported otherwise Justin Gibbs will sulk.. */ if (pci_conf1() && probe_for_cmd640_pci1()) bus_type = "PCI (type1)"; else if (pci_conf2() && probe_for_cmd640_pci2()) bus_type = "PCI (type2)"; else return 0; } /* * Undocumented magic (there is no 0x5b reg in specs) */ put_cmd640_reg(0x5b, 0xbd); if (get_cmd640_reg(0x5b) != 0xbd) { printk(KERN_ERR "ide: cmd640 init failed: wrong value in reg 0x5b\n"); return 0; } put_cmd640_reg(0x5b, 0); #ifdef CMD640_DUMP_REGS cmd640_dump_regs(); #endif /* * Documented magic begins here */ cfr = get_cmd640_reg(CFR); cmd640_chip_version = cfr & CFR_DEVREV; if (cmd640_chip_version == 0) { printk("ide: bad cmd640 revision: %d\n", cmd640_chip_version); return 0; } rc = cmd640x_init_one(0x1f0, 0x3f6); if (rc) return rc; rc = cmd640x_init_one(0x170, 0x376); if (rc) { release_region(0x3f6, 1); release_region(0x1f0, 8); return rc; } memset(&hw, 0, sizeof(hw)); ide_std_init_ports(&hw[0], 0x1f0, 0x3f6); hw[0].irq = 14; hw[0].chipset = ide_cmd640; ide_std_init_ports(&hw[1], 0x170, 0x376); hw[1].irq = 15; hw[1].chipset = ide_cmd640; printk(KERN_INFO "cmd640: buggy cmd640%c interface on %s, config=0x%02x" "\n", 'a' + cmd640_chip_version - 1, bus_type, cfr); /* * Initialize data for primary port */ hws[0] = &hw[0]; /* * Ensure compatibility by always using the slowest timings * for access to the drive's command register block, * and reset the prefetch burstsize to default (512 bytes). * * Maybe we need a way to NOT do these on *some* systems? */ put_cmd640_reg(CMDTIM, 0); put_cmd640_reg(BRST, 0x40); b = get_cmd640_reg(CNTRL); /* * Try to enable the secondary interface, if not already enabled */ if (secondary_port_responding()) { if ((b & CNTRL_ENA_2ND)) { second_port_cmd640 = 1; port2 = "okay"; } else if (cmd640_vlb) { second_port_cmd640 = 1; port2 = "alive"; } else port2 = "not cmd640"; } else { put_cmd640_reg(CNTRL, b ^ CNTRL_ENA_2ND); /* toggle the bit */ if (secondary_port_responding()) { second_port_cmd640 = 1; port2 = "enabled"; } else { put_cmd640_reg(CNTRL, b); /* restore original setting */ port2 = "not responding"; } } /* * Initialize data for secondary cmd640 port, if enabled */ if (second_port_cmd640) hws[1] = &hw[1]; printk(KERN_INFO "cmd640: %sserialized, secondary interface %s\n", second_port_cmd640 ? "" : "not ", port2); #ifdef CMD640_DUMP_REGS cmd640_dump_regs(); #endif return ide_host_add(&cmd640_port_info, hws, NULL); }
static int __init cmd640x_init(void) { int second_port_cmd640 = 0, rc; const char *bus_type, *port2; u8 b, cfr; struct ide_hw hw[2], *hws[2]; if (cmd640_vlb && probe_for_cmd640_vlb()) { bus_type = "VLB"; } else { cmd640_vlb = 0; /* */ if (pci_conf1() && probe_for_cmd640_pci1()) bus_type = "PCI (type1)"; else if (pci_conf2() && probe_for_cmd640_pci2()) bus_type = "PCI (type2)"; else return 0; } /* */ put_cmd640_reg(0x5b, 0xbd); if (get_cmd640_reg(0x5b) != 0xbd) { printk(KERN_ERR "ide: cmd640 init failed: wrong value in reg 0x5b\n"); return 0; } put_cmd640_reg(0x5b, 0); #ifdef CMD640_DUMP_REGS cmd640_dump_regs(); #endif /* */ cfr = get_cmd640_reg(CFR); cmd640_chip_version = cfr & CFR_DEVREV; if (cmd640_chip_version == 0) { printk("ide: bad cmd640 revision: %d\n", cmd640_chip_version); return 0; } rc = cmd640x_init_one(0x1f0, 0x3f6); if (rc) return rc; rc = cmd640x_init_one(0x170, 0x376); if (rc) { release_region(0x3f6, 1); release_region(0x1f0, 8); return rc; } memset(&hw, 0, sizeof(hw)); ide_std_init_ports(&hw[0], 0x1f0, 0x3f6); hw[0].irq = 14; ide_std_init_ports(&hw[1], 0x170, 0x376); hw[1].irq = 15; printk(KERN_INFO "cmd640: buggy cmd640%c interface on %s, config=0x%02x" "\n", 'a' + cmd640_chip_version - 1, bus_type, cfr); /* */ hws[0] = &hw[0]; /* */ put_cmd640_reg(CMDTIM, 0); put_cmd640_reg(BRST, 0x40); b = get_cmd640_reg(CNTRL); /* */ if (secondary_port_responding()) { if ((b & CNTRL_ENA_2ND)) { second_port_cmd640 = 1; port2 = "okay"; } else if (cmd640_vlb) { second_port_cmd640 = 1; port2 = "alive"; } else port2 = "not cmd640"; } else { put_cmd640_reg(CNTRL, b ^ CNTRL_ENA_2ND); /* */ if (secondary_port_responding()) { second_port_cmd640 = 1; port2 = "enabled"; } else { put_cmd640_reg(CNTRL, b); /* */ port2 = "not responding"; } } /* */ if (second_port_cmd640) hws[1] = &hw[1]; printk(KERN_INFO "cmd640: %sserialized, secondary interface %s\n", second_port_cmd640 ? "" : "not ", port2); #ifdef CMD640_DUMP_REGS cmd640_dump_regs(); #endif return ide_host_add(&cmd640_port_info, hws, second_port_cmd640 ? 2 : 1, NULL); }
static int __init at91_ide_probe(struct platform_device *pdev) { int ret; struct ide_hw hw, *hws[] = { &hw }; struct ide_host *host; struct resource *res; unsigned long tf_base = 0, ctl_base = 0; struct at91_cf_data *board = pdev->dev.platform_data; if (!board) return -ENODEV; if (board->det_pin && at91_get_gpio_value(board->det_pin) != 0) { perr("no device detected\n"); return -ENODEV; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { perr("can't get memory resource\n"); return -ENODEV; } if (!devm_request_mem_region(&pdev->dev, res->start + TASK_FILE, REGS_SIZE, "ide") || !devm_request_mem_region(&pdev->dev, res->start + ALT_MODE, REGS_SIZE, "alt")) { perr("memory resources in use\n"); return -EBUSY; } pdbg("chipselect %u irq %u res %08lx\n", board->chipselect, board->irq_pin, (unsigned long) res->start); tf_base = (unsigned long) devm_ioremap(&pdev->dev, res->start + TASK_FILE, REGS_SIZE); ctl_base = (unsigned long) devm_ioremap(&pdev->dev, res->start + ALT_MODE, REGS_SIZE); if (!tf_base || !ctl_base) { perr("can't map memory regions\n"); return -EBUSY; } memset(&hw, 0, sizeof(hw)); if (board->flags & AT91_IDE_SWAP_A0_A2) { hw.io_ports.data_addr = tf_base + 0; hw.io_ports.error_addr = tf_base + 4; hw.io_ports.nsect_addr = tf_base + 2; hw.io_ports.lbal_addr = tf_base + 6; hw.io_ports.lbam_addr = tf_base + 1; hw.io_ports.lbah_addr = tf_base + 5; hw.io_ports.device_addr = tf_base + 3; hw.io_ports.command_addr = tf_base + 7; hw.io_ports.ctl_addr = ctl_base + 3; } else ide_std_init_ports(&hw, tf_base, ctl_base + 6); hw.irq = board->irq_pin; hw.dev = &pdev->dev; host = ide_host_alloc(&at91_ide_port_info, hws, 1); if (!host) { perr("failed to allocate ide host\n"); return -ENOMEM; } /* setup Static Memory Controller - PIO 0 as default */ apply_timings(board->chipselect, 0, ide_timing_find_mode(XFER_PIO_0), 0); /* with GPIO interrupt we have to do quirks in handler */ if (board->irq_pin >= PIN_BASE) host->irq_handler = at91_irq_handler; host->ports[0]->select_data = board->chipselect; ret = ide_host_register(host, &at91_ide_port_info, hws); if (ret) { perr("failed to register ide host\n"); goto err_free_host; } platform_set_drvdata(pdev, host); return 0; err_free_host: ide_host_free(host); return ret; }