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 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 __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 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 __init macide_init(void) { ide_hwif_t *hwif; ide_ack_intr_t *ack_intr; unsigned long base; int irq; hw_regs_t hw; if (!MACH_IS_MAC) return -ENODEV; switch (macintosh_config->ide_type) { case MAC_IDE_QUADRA: base = IDE_BASE; ack_intr = macide_ack_intr; irq = IRQ_NUBUS_F; break; case MAC_IDE_PB: base = IDE_BASE; ack_intr = macide_ack_intr; irq = IRQ_NUBUS_C; break; case MAC_IDE_BABOON: base = BABOON_BASE; ack_intr = NULL; irq = IRQ_BABOON_1; break; default: return -ENODEV; } printk(KERN_INFO "ide: Macintosh %s IDE controller\n", mac_ide_name[macintosh_config->ide_type - 1]); macide_setup_ports(&hw, base, irq, ack_intr); 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); ide_device_add(idx, NULL); } return 0; }
static ide_hwif_t * rapide_locate_hwif(void __iomem *base, void __iomem *ctrl, unsigned int sz, int irq) { unsigned long port = (unsigned long)base; ide_hwif_t *hwif = ide_find_port(port); int i; if (hwif == NULL) goto out; for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { hwif->io_ports[i] = port; port += sz; } hwif->io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl; hwif->irq = irq; hwif->mmio = 1; default_hwif_mmiops(hwif); out: return hwif; }
void q40ide_init(void) { int i; ide_hwif_t *hwif; const char *name; if (!MACH_IS_Q40) return ; for (i = 0; i < Q40IDE_NUM_HWIFS; i++) { hw_regs_t hw; name = q40_ide_names[i]; if (!request_region(pcide_bases[i], 8, name)) { printk("could not reserve ports %lx-%lx for %s\n", pcide_bases[i],pcide_bases[i]+8,name); continue; } if (!request_region(pcide_bases[i]+0x206, 1, name)) { printk("could not reserve port %lx for %s\n", pcide_bases[i]+0x206,name); release_region(pcide_bases[i], 8); continue; } q40_ide_setup_ports(&hw,(unsigned long) pcide_bases[i], (int *)pcide_offsets, pcide_bases[i]+0x206, 0, NULL, // m68kide_iops, q40ide_default_irq(pcide_bases[i])); hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]); if (hwif) { ide_init_port_data(hwif, hwif->index); ide_init_port_hw(hwif, &hw); hwif->mmio = 2; } } }
static int __devinit plat_ide_probe(struct platform_device *pdev) { struct resource *res_base, *res_alt, *res_irq; void __iomem *base, *alt_base; ide_hwif_t *hwif; struct pata_platform_info *pdata; u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; int ret = 0; int mmio = 0; hw_regs_t hw; pdata = pdev->dev.platform_data; /* get a pointer to the register memory */ res_base = platform_get_resource(pdev, IORESOURCE_IO, 0); res_alt = platform_get_resource(pdev, IORESOURCE_IO, 1); if (!res_base || !res_alt) { res_base = platform_get_resource(pdev, IORESOURCE_MEM, 0); res_alt = platform_get_resource(pdev, IORESOURCE_MEM, 1); if (!res_base || !res_alt) { ret = -ENOMEM; goto out; } mmio = 1; } res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!res_irq) { ret = -EINVAL; goto out; } if (mmio) { base = devm_ioremap(&pdev->dev, res_base->start, res_base->end - res_base->start + 1); alt_base = devm_ioremap(&pdev->dev, res_alt->start, res_alt->end - res_alt->start + 1); } else { base = devm_ioport_map(&pdev->dev, res_base->start, res_base->end - res_base->start + 1); alt_base = devm_ioport_map(&pdev->dev, res_alt->start, res_alt->end - res_alt->start + 1); } hwif = ide_find_port(); if (!hwif) { ret = -ENODEV; goto out; } memset(&hw, 0, sizeof(hw)); plat_ide_setup_ports(&hw, base, alt_base, pdata, res_irq->start); hw.dev = &pdev->dev; ide_init_port_hw(hwif, &hw); if (mmio) { hwif->host_flags = IDE_HFLAG_MMIO; default_hwif_mmiops(hwif); } idx[0] = hwif->index; ide_device_add(idx, NULL); platform_set_drvdata(pdev, hwif); return 0; out: return ret; }
static int __init gayle_init(void) { int a4000, i; u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; if (!MACH_IS_AMIGA) return -ENODEV; if ((a4000 = AMIGAHW_PRESENT(A4000_IDE)) || AMIGAHW_PRESENT(A1200_IDE)) goto found; #ifdef CONFIG_ZORRO if (zorro_find_device(ZORRO_PROD_MTEC_VIPER_MK_V_E_MATRIX_530_SCSI_IDE, NULL)) goto found; #endif return -ENODEV; found: printk(KERN_INFO "ide: Gayle IDE controller (A%d style%s)\n", a4000 ? 4000 : 1200, #ifdef CONFIG_BLK_DEV_IDEDOUBLER ide_doubler ? ", IDE doubler" : #endif ""); for (i = 0; i < GAYLE_NUM_PROBE_HWIFS; i++) { unsigned long base, ctrlport, irqport; ide_ack_intr_t *ack_intr; hw_regs_t hw; ide_hwif_t *hwif; unsigned long phys_base, res_start, res_n; if (a4000) { phys_base = GAYLE_BASE_4000; irqport = (unsigned long)ZTWO_VADDR(GAYLE_IRQ_4000); ack_intr = gayle_ack_intr_a4000; } else { phys_base = GAYLE_BASE_1200; irqport = (unsigned long)ZTWO_VADDR(GAYLE_IRQ_1200); ack_intr = gayle_ack_intr_a1200; } /* * FIXME: we now have selectable modes between mmio v/s iomio */ phys_base += i*GAYLE_NEXT_PORT; res_start = ((unsigned long)phys_base) & ~(GAYLE_NEXT_PORT-1); res_n = GAYLE_IDEREG_SIZE; if (!request_mem_region(res_start, res_n, "IDE")) continue; base = (unsigned long)ZTWO_VADDR(phys_base); ctrlport = GAYLE_HAS_CONTROL_REG ? (base + GAYLE_CONTROL) : 0; gayle_setup_ports(&hw, base, ctrlport, irqport, ack_intr); hwif = ide_find_port(); if (hwif) { u8 index = hwif->index; ide_init_port_hw(hwif, &hw); idx[i] = index; } else release_mem_region(res_start, res_n); } ide_device_add(idx, NULL); return 0; }
static int __init buddha_init(void) { hw_regs_t hw; ide_hwif_t *hwif; int i; struct zorro_dev *z = NULL; u_long buddha_board = 0; BuddhaType type; int buddha_num_hwifs; while ((z = zorro_find_device(ZORRO_WILDCARD, z))) { unsigned long board; u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_BUDDHA) { buddha_num_hwifs = BUDDHA_NUM_HWIFS; type=BOARD_BUDDHA; } else if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_CATWEASEL) { buddha_num_hwifs = CATWEASEL_NUM_HWIFS; type=BOARD_CATWEASEL; } else if (z->id == ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF) { buddha_num_hwifs = XSURF_NUM_HWIFS; type=BOARD_XSURF; } else continue; board = z->resource.start; /* * FIXME: we now have selectable mmio v/s iomio transports. */ if(type != BOARD_XSURF) { if (!request_mem_region(board+BUDDHA_BASE1, 0x800, "IDE")) continue; } else { if (!request_mem_region(board+XSURF_BASE1, 0x1000, "IDE")) continue; if (!request_mem_region(board+XSURF_BASE2, 0x1000, "IDE")) goto fail_base2; if (!request_mem_region(board+XSURF_IRQ1, 0x8, "IDE")) { release_mem_region(board+XSURF_BASE2, 0x1000); fail_base2: release_mem_region(board+XSURF_BASE1, 0x1000); continue; } } buddha_board = ZTWO_VADDR(board); /* write to BUDDHA_IRQ_MR to enable the board IRQ */ /* X-Surf doesn't have this. IRQs are always on */ if (type != BOARD_XSURF) z_writeb(0, buddha_board+BUDDHA_IRQ_MR); printk(KERN_INFO "ide: %s IDE controller\n", buddha_board_name[type]); for (i = 0; i < buddha_num_hwifs; i++) { unsigned long base, ctl, irq_port; ide_ack_intr_t *ack_intr; if (type != BOARD_XSURF) { base = buddha_board + buddha_bases[i]; ctl = base + BUDDHA_CONTROL; irq_port = buddha_board + buddha_irqports[i]; ack_intr = buddha_ack_intr; } else { base = buddha_board + xsurf_bases[i]; /* X-Surf has no CS1* (Control/AltStat) */ ctl = 0; irq_port = buddha_board + xsurf_irqports[i]; ack_intr = xsurf_ack_intr; } buddha_setup_ports(&hw, base, ctl, irq_port, ack_intr); hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]); if (hwif) { u8 index = hwif->index; ide_init_port_data(hwif, index); ide_init_port_hw(hwif, &hw); hwif->mmio = 1; idx[i] = index; } } ide_device_add(idx, NULL); } return 0; }
/* * swarm_ide_probe - if the board header indicates the existence of * Generic Bus IDE, allocate a HWIF for it. */ static int __devinit swarm_ide_probe(struct device *dev) { ide_hwif_t *hwif; u8 __iomem *base; phys_t offset, size; hw_regs_t hw; int i; u8 idx[] = { 0xff, 0xff, 0xff, 0xff }; if (!SIBYTE_HAVE_IDE) return -ENODEV; hwif = ide_find_port(); if (hwif == NULL) { printk(KERN_ERR DRV_NAME ": no free slot for interface\n"); return -ENOMEM; } base = ioremap(A_IO_EXT_BASE, 0x800); offset = __raw_readq(base + R_IO_EXT_REG(R_IO_EXT_START_ADDR, IDE_CS)); size = __raw_readq(base + R_IO_EXT_REG(R_IO_EXT_MULT_SIZE, IDE_CS)); iounmap(base); offset = G_IO_START_ADDR(offset) << S_IO_ADDRBASE; size = (G_IO_MULT_SIZE(size) + 1) << S_IO_REGSIZE; if (offset < A_PHYS_GENBUS || offset >= A_PHYS_GENBUS_END) { printk(KERN_INFO DRV_NAME ": IDE interface at GenBus disabled\n"); return -EBUSY; } printk(KERN_INFO DRV_NAME ": IDE interface at GenBus slot %i\n", IDE_CS); swarm_ide_resource.start = offset; swarm_ide_resource.end = offset + size - 1; if (request_resource(&iomem_resource, &swarm_ide_resource)) { printk(KERN_ERR DRV_NAME ": can't request I/O memory resource\n"); return -EBUSY; } base = ioremap(offset, size); /* Setup MMIO ops. */ hwif->host_flags = IDE_HFLAG_MMIO; default_hwif_mmiops(hwif); for (i = 0; i <= 7; i++) hw.io_ports_array[i] = (unsigned long)(base + ((0x1f0 + i) << 5)); hw.io_ports.ctl_addr = (unsigned long)(base + (0x3f6 << 5)); hw.irq = K_INT_GB_IDE; hw.chipset = ide_generic; ide_init_port_hw(hwif, &hw); idx[0] = hwif->index; ide_device_add(idx, NULL); dev_set_drvdata(dev, hwif); return 0; }