/* * Something like this really should be in generic code, but isn't. */ 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; int index, i; for (index = 0; index < MAX_HWIFS; ++index) { hwif = ide_hwifs + index; if (hwif->io_ports[IDE_DATA_OFFSET] == port) goto found; } for (index = 0; index < MAX_HWIFS; ++index) { hwif = ide_hwifs + index; if (hwif->io_ports[IDE_DATA_OFFSET] == 0) goto found; } return NULL; found: for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { hwif->hw.io_ports[i] = port; hwif->io_ports[i] = port; port += sz; } hwif->hw.io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl; hwif->io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl; hwif->hw.irq = hwif->irq = irq; hwif->mmio = 1; default_hwif_mmiops(hwif); return hwif; }
static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif) { struct pci_dev *dev = to_pci_dev(hwif->dev); void *addr = pci_get_drvdata(dev); u8 ch = hwif->channel; struct ide_io_ports *io_ports = &hwif->io_ports; unsigned long base; /* * Fill in the basic hwif bits */ hwif->host_flags |= IDE_HFLAG_MMIO; default_hwif_mmiops(hwif); hwif->hwif_data = addr; /* * Now set up the hw. We have to do this ourselves as the * MMIO layout isn't the same as the standard port based I/O. */ memset(io_ports, 0, sizeof(*io_ports)); base = (unsigned long)addr; if (ch) base += 0xC0; else base += 0x80; /* * The buffered task file doesn't have status/control, so we * can't currently use it sanely since we want to use LBA48 mode. */ io_ports->data_addr = base; io_ports->error_addr = base + 1; io_ports->nsect_addr = base + 2; io_ports->lbal_addr = base + 3; io_ports->lbam_addr = base + 4; io_ports->lbah_addr = base + 5; io_ports->device_addr = base + 6; io_ports->status_addr = base + 7; io_ports->ctl_addr = base + 10; if (pdev_is_sata(dev)) { base = (unsigned long)addr; if (ch) base += 0x80; hwif->sata_scr[SATA_STATUS_OFFSET] = base + 0x104; hwif->sata_scr[SATA_ERROR_OFFSET] = base + 0x108; hwif->sata_scr[SATA_CONTROL_OFFSET] = base + 0x100; } hwif->irq = dev->irq; hwif->dma_base = (unsigned long)addr + (ch ? 0x08 : 0x00); hwif->mmio = 1; }
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; }
static void __devinit ide_init_sgiioc4(ide_hwif_t * hwif) { hwif->mmio = 2; hwif->autodma = 1; hwif->atapi_dma = 1; hwif->ultra_mask = 0x0; /* Disable Ultra DMA */ hwif->mwdma_mask = 0x2; /* Multimode-2 DMA */ hwif->swdma_mask = 0x2; hwif->tuneproc = NULL; /* Sets timing for PIO mode */ hwif->speedproc = NULL; /* Sets timing for DMA &/or PIO modes */ hwif->selectproc = NULL;/* Use the default routine to select drive */ hwif->reset_poll = NULL;/* No HBA specific reset_poll needed */ hwif->pre_reset = NULL; /* No HBA specific pre_set needed */ hwif->resetproc = &sgiioc4_resetproc;/* Reset DMA engine, clear interrupts */ hwif->intrproc = NULL; /* Enable or Disable interrupt from drive */ hwif->maskproc = &sgiioc4_maskproc; /* Mask on/off NIEN register */ hwif->quirkproc = NULL; hwif->busproc = NULL; hwif->dma_setup = &sgiioc4_ide_dma_setup; hwif->dma_start = &sgiioc4_ide_dma_start; hwif->ide_dma_end = &sgiioc4_ide_dma_end; hwif->ide_dma_check = &sgiioc4_ide_dma_check; hwif->ide_dma_on = &sgiioc4_ide_dma_on; hwif->ide_dma_off_quietly = &sgiioc4_ide_dma_off_quietly; hwif->ide_dma_test_irq = &sgiioc4_ide_dma_test_irq; hwif->ide_dma_host_on = &sgiioc4_ide_dma_host_on; hwif->ide_dma_host_off = &sgiioc4_ide_dma_host_off; hwif->ide_dma_lostirq = &sgiioc4_ide_dma_lostirq; hwif->ide_dma_timeout = &__ide_dma_timeout; /* * The IOC4 uses MMIO rather than Port IO. * It also needs special workarounds for INB. */ default_hwif_mmiops(hwif); hwif->INB = &sgiioc4_INB; }
/* * 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; int i; if (!SIBYTE_HAVE_IDE) return -ENODEV; /* Find an empty slot. */ for (i = 0; i < MAX_HWIFS; i++) if (!ide_hwifs[i].io_ports[IDE_DATA_OFFSET]) break; if (i >= MAX_HWIFS) { printk(KERN_ERR DRV_NAME ": no free slot for interface\n"); return -ENOMEM; } hwif = ide_hwifs + i; 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. */ default_hwif_mmiops(hwif); /* Prevent resource map manipulation. */ hwif->mmio = 2; hwif->noprobe = 0; for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) hwif->hw.io_ports[i] = (unsigned long)(base + ((0x1f0 + i) << 5)); hwif->hw.io_ports[IDE_CONTROL_OFFSET] = (unsigned long)(base + (0x3f6 << 5)); hwif->hw.irq = K_INT_GB_IDE; memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports)); hwif->irq = hwif->hw.irq; dev_set_drvdata(dev, hwif); return 0; }
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 __devinit sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d) { unsigned long cmd_base, dma_base, irqport; unsigned long bar0, cmd_phys_base, ctl; void __iomem *virt_base; ide_hwif_t *hwif; int h; /* * Find an empty HWIF; if none available, return -ENOMEM. */ for (h = 0; h < MAX_HWIFS; ++h) { hwif = &ide_hwifs[h]; if (hwif->chipset == ide_unknown) break; } if (h == MAX_HWIFS) { printk(KERN_ERR "%s: too many IDE interfaces, no room in table\n", d->name); return -ENOMEM; } /* Get the CmdBlk and CtrlBlk Base Registers */ bar0 = pci_resource_start(dev, 0); virt_base = ioremap(bar0, pci_resource_len(dev, 0)); if (virt_base == NULL) { printk(KERN_ERR "%s: Unable to remap BAR 0 address: 0x%lx\n", d->name, bar0); return -ENOMEM; } cmd_base = (unsigned long) virt_base + IOC4_CMD_OFFSET; ctl = (unsigned long) virt_base + IOC4_CTRL_OFFSET; irqport = (unsigned long) virt_base + IOC4_INTR_OFFSET; dma_base = pci_resource_start(dev, 0) + IOC4_DMA_OFFSET; cmd_phys_base = bar0 + IOC4_CMD_OFFSET; if (!request_mem_region(cmd_phys_base, IOC4_CMD_CTL_BLK_SIZE, hwif->name)) { printk(KERN_ERR "%s : %s -- ERROR, Addresses " "0x%p to 0x%p ALREADY in use\n", __FUNCTION__, hwif->name, (void *) cmd_phys_base, (void *) cmd_phys_base + IOC4_CMD_CTL_BLK_SIZE); return -ENOMEM; } if (hwif->io_ports[IDE_DATA_OFFSET] != cmd_base) { /* Initialize the IO registers */ sgiioc4_init_hwif_ports(&hwif->hw, cmd_base, ctl, irqport); memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof (hwif->io_ports)); hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET]; } hwif->irq = dev->irq; hwif->chipset = ide_pci; hwif->pci_dev = dev; hwif->channel = 0; /* Single Channel chip */ hwif->cds = (struct ide_pci_device_s *) d; hwif->gendev.parent = &dev->dev;/* setup proper ancestral information */ /* The IOC4 uses MMIO rather than Port IO. */ default_hwif_mmiops(hwif); /* Initializing chipset IRQ Registers */ writel(0x03, (void __iomem *)(irqport + IOC4_INTR_SET * 4)); ide_init_sgiioc4(hwif); if (dma_base) ide_dma_sgiioc4(hwif, dma_base); else printk(KERN_INFO "%s: %s Bus-Master DMA disabled\n", hwif->name, d->name); if (probe_hwif_init(hwif)) return -EIO; /* Create /proc/ide entries */ ide_proc_register_port(hwif); return 0; }
static void __init init_mmio_iops_siimage (ide_hwif_t *hwif) { struct pci_dev *dev = hwif->pci_dev; void *addr = pci_get_drvdata(dev); u8 ch = hwif->channel; hw_regs_t hw; unsigned long base; /* * Fill in the basic HWIF bits */ default_hwif_mmiops(hwif); hwif->hwif_data = addr; /* * Now set up the hw. We have to do this ourselves as * the MMIO layout isnt the same as the the standard port * based I/O */ memset(&hw, 0, sizeof(hw_regs_t)); hw.priv = addr; base = (unsigned long)addr; if(ch) base += 0xC0; else base += 0x80; /* * The buffered task file doesn't have status/control * so we can't currently use it sanely since we want to * use LBA48 mode. */ // base += 0x10; // hwif->addressing = 1; hw.io_ports[IDE_DATA_OFFSET] = base; hw.io_ports[IDE_ERROR_OFFSET] = base + 1; hw.io_ports[IDE_NSECTOR_OFFSET] = base + 2; hw.io_ports[IDE_SECTOR_OFFSET] = base + 3; hw.io_ports[IDE_LCYL_OFFSET] = base + 4; hw.io_ports[IDE_HCYL_OFFSET] = base + 5; hw.io_ports[IDE_SELECT_OFFSET] = base + 6; hw.io_ports[IDE_STATUS_OFFSET] = base + 7; hw.io_ports[IDE_CONTROL_OFFSET] = base + 10; hw.io_ports[IDE_IRQ_OFFSET] = 0; if (pdev_is_sata(dev)) { base = (unsigned long) addr; if(ch) base += 0x80; hw.sata_scr[SATA_STATUS_OFFSET] = base + 0x104; hw.sata_scr[SATA_ERROR_OFFSET] = base + 0x108; hw.sata_scr[SATA_CONTROL_OFFSET]= base + 0x100; hw.sata_misc[SATA_MISC_OFFSET] = base + 0x140; hw.sata_misc[SATA_PHY_OFFSET] = base + 0x144; hw.sata_misc[SATA_IEN_OFFSET] = base + 0x148; } hw.irq = hwif->pci_dev->irq; memcpy(&hwif->hw, &hw, sizeof(hw)); memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->hw.io_ports)); if (is_sata(hwif)) { memcpy(hwif->sata_scr, hwif->hw.sata_scr, sizeof(hwif->hw.sata_scr)); memcpy(hwif->sata_misc, hwif->hw.sata_misc, sizeof(hwif->hw.sata_misc)); } hwif->irq = hw.irq; base = (unsigned long) addr; #ifdef SIIMAGE_LARGE_DMA /* Watch the brackets - even Ken and Dennis get some language design wrong */ hwif->dma_base = base + (ch ? 0x18 : 0x10); hwif->dma_base2 = base + (ch ? 0x08 : 0x00); hwif->dma_prdtable = hwif->dma_base2 + 4; #else /* ! SIIMAGE_LARGE_DMA */ hwif->dma_base = base + (ch ? 0x08 : 0x00); hwif->dma_base2 = base + (ch ? 0x18 : 0x10); #endif /* SIIMAGE_LARGE_DMA */ hwif->mmio = 2; }
static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif) { struct pci_dev *dev = hwif->pci_dev; void *addr = pci_get_drvdata(dev); u8 ch = hwif->channel; hw_regs_t hw; unsigned long base; /* * Fill in the basic HWIF bits */ default_hwif_mmiops(hwif); hwif->hwif_data = addr; /* * Now set up the hw. We have to do this ourselves as * the MMIO layout isnt the same as the the standard port * based I/O */ memset(&hw, 0, sizeof(hw_regs_t)); base = (unsigned long)addr; if (ch) base += 0xC0; else base += 0x80; /* * The buffered task file doesn't have status/control * so we can't currently use it sanely since we want to * use LBA48 mode. */ hw.io_ports[IDE_DATA_OFFSET] = base; hw.io_ports[IDE_ERROR_OFFSET] = base + 1; hw.io_ports[IDE_NSECTOR_OFFSET] = base + 2; hw.io_ports[IDE_SECTOR_OFFSET] = base + 3; hw.io_ports[IDE_LCYL_OFFSET] = base + 4; hw.io_ports[IDE_HCYL_OFFSET] = base + 5; hw.io_ports[IDE_SELECT_OFFSET] = base + 6; hw.io_ports[IDE_STATUS_OFFSET] = base + 7; hw.io_ports[IDE_CONTROL_OFFSET] = base + 10; hw.io_ports[IDE_IRQ_OFFSET] = 0; if (pdev_is_sata(dev)) { base = (unsigned long)addr; if (ch) base += 0x80; hwif->sata_scr[SATA_STATUS_OFFSET] = base + 0x104; hwif->sata_scr[SATA_ERROR_OFFSET] = base + 0x108; hwif->sata_scr[SATA_CONTROL_OFFSET] = base + 0x100; hwif->sata_misc[SATA_MISC_OFFSET] = base + 0x140; hwif->sata_misc[SATA_PHY_OFFSET] = base + 0x144; hwif->sata_misc[SATA_IEN_OFFSET] = base + 0x148; } memcpy(hwif->io_ports, hw.io_ports, sizeof(hwif->io_ports)); hwif->irq = dev->irq; hwif->dma_base = (unsigned long)addr + (ch ? 0x08 : 0x00); hwif->mmio = 2; }
static int __devinit sgiioc4_ide_setup_pci_device(struct pci_dev *dev) { unsigned long cmd_base, irqport; unsigned long bar0, cmd_phys_base, ctl; void __iomem *virt_base; ide_hwif_t *hwif; u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; hw_regs_t hw; struct ide_port_info d = sgiioc4_port_info; /* Get the CmdBlk and CtrlBlk Base Registers */ bar0 = pci_resource_start(dev, 0); virt_base = ioremap(bar0, pci_resource_len(dev, 0)); if (virt_base == NULL) { printk(KERN_ERR "%s: Unable to remap BAR 0 address: 0x%lx\n", DRV_NAME, bar0); return -ENOMEM; } cmd_base = (unsigned long) virt_base + IOC4_CMD_OFFSET; ctl = (unsigned long) virt_base + IOC4_CTRL_OFFSET; irqport = (unsigned long) virt_base + IOC4_INTR_OFFSET; cmd_phys_base = bar0 + IOC4_CMD_OFFSET; if (!request_mem_region(cmd_phys_base, IOC4_CMD_CTL_BLK_SIZE, DRV_NAME)) { printk(KERN_ERR "%s : %s -- ERROR, Addresses " "0x%p to 0x%p ALREADY in use\n", __func__, DRV_NAME, (void *) cmd_phys_base, (void *) cmd_phys_base + IOC4_CMD_CTL_BLK_SIZE); return -ENOMEM; } /* Initialize the IO registers */ memset(&hw, 0, sizeof(hw)); sgiioc4_init_hwif_ports(&hw, cmd_base, ctl, irqport); hw.irq = dev->irq; hw.chipset = ide_pci; hw.dev = &dev->dev; hwif = ide_find_port_slot(&d); if (hwif == NULL) goto err; ide_init_port_hw(hwif, &hw); /* The IOC4 uses MMIO rather than Port IO. */ default_hwif_mmiops(hwif); /* Initializing chipset IRQ Registers */ writel(0x03, (void __iomem *)(irqport + IOC4_INTR_SET * 4)); hwif->INB = &sgiioc4_INB; idx[0] = hwif->index; if (ide_device_add(idx, &d)) return -EIO; return 0; err: release_mem_region(cmd_phys_base, IOC4_CMD_CTL_BLK_SIZE); iounmap(virt_base); return -ENOMEM; }
static int __init tcf_register(unsigned long dataport,int irq) { ide_hwif_t *hwif; //int i,ret; hwif = tscf_find_hwif(dataport); if (hwif) { //int i; memset(&hwif->hw, 0, sizeof(hw_regs_t)); /* * Ensure we're using MMIO */ default_hwif_mmiops(hwif); hwif->mmio = 1; hwif->io_ports[IDE_DATA_OFFSET] = (unsigned long)ioremap(TS7800_CF_DATA_PHYS_BASE,1); hwif->io_ports[IDE_ERROR_OFFSET] = (unsigned long)ioremap(TS7800_CF_CMD_PHYS_BASE,1); hwif->io_ports[IDE_NSECTOR_OFFSET] = (unsigned long)ioremap(TS7800_CF_CMD_PHYS_BASE + 0x1,1); hwif->io_ports[IDE_SECTOR_OFFSET] = (unsigned long)ioremap(TS7800_CF_CMD_PHYS_BASE + 0x2,1); hwif->io_ports[IDE_LCYL_OFFSET] = (unsigned long)ioremap(TS7800_CF_CMD_PHYS_BASE + 0x3,1); hwif->io_ports[IDE_HCYL_OFFSET] = (unsigned long)ioremap(TS7800_CF_CMD_PHYS_BASE + 0x4,1); hwif->io_ports[IDE_SELECT_OFFSET] = (unsigned long)ioremap(TS7800_CF_CMD_PHYS_BASE + 0x5,1); hwif->io_ports[IDE_STATUS_OFFSET] = (unsigned long)ioremap(TS7800_CF_CMD_PHYS_BASE + 0x6,1); hwif->io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ioremap(TS7800_CF_AUX_PHYS_BASE,1); /* * This is the dma channel number assigned to this IDE interface. Until * dma is enabled for this interface, we set it to NO_DMA. */ hwif->hw.dma = NO_DMA; hwif->dma = NO_DMA; hwif->hw.irq = irq; hwif->irq = irq; hwif->noprobe = 0; hwif->chipset = ide_generic; //hwif->chipset = ide_forced; probe_hwif_init(hwif); //ide_proc_register_port(hwif); create_proc_ide_interfaces(); //ide_register_hw(hwif,NULL); } printk("Technologic Systems TS-7800 IDE initialization - driver version 1.0, 12/27/07. \n"); return 0; }
static void __init init_mmio_iops_siimage (ide_hwif_t *hwif) { struct pci_dev *dev = hwif->pci_dev; unsigned long addr = (unsigned long) pci_get_drvdata(hwif->pci_dev); u8 ch = hwif->channel; // u16 i = 0; hw_regs_t hw; default_hwif_mmiops(hwif); memset(&hw, 0, sizeof(hw_regs_t)); #if 1 #ifdef SIIMAGE_BUFFERED_TASKFILE hw.io_ports[IDE_DATA_OFFSET] = DEVADDR((ch) ? 0xD0 : 0x90); hw.io_ports[IDE_ERROR_OFFSET] = DEVADDR((ch) ? 0xD1 : 0x91); hw.io_ports[IDE_NSECTOR_OFFSET] = DEVADDR((ch) ? 0xD2 : 0x92); hw.io_ports[IDE_SECTOR_OFFSET] = DEVADDR((ch) ? 0xD3 : 0x93); hw.io_ports[IDE_LCYL_OFFSET] = DEVADDR((ch) ? 0xD4 : 0x94); hw.io_ports[IDE_HCYL_OFFSET] = DEVADDR((ch) ? 0xD5 : 0x95); hw.io_ports[IDE_SELECT_OFFSET] = DEVADDR((ch) ? 0xD6 : 0x96); hw.io_ports[IDE_STATUS_OFFSET] = DEVADDR((ch) ? 0xD7 : 0x97); hw.io_ports[IDE_CONTROL_OFFSET] = DEVADDR((ch) ? 0xDA : 0x9A); #else /* ! SIIMAGE_BUFFERED_TASKFILE */ hw.io_ports[IDE_DATA_OFFSET] = DEVADDR((ch) ? 0xC0 : 0x80); hw.io_ports[IDE_ERROR_OFFSET] = DEVADDR((ch) ? 0xC1 : 0x81); hw.io_ports[IDE_NSECTOR_OFFSET] = DEVADDR((ch) ? 0xC2 : 0x82); hw.io_ports[IDE_SECTOR_OFFSET] = DEVADDR((ch) ? 0xC3 : 0x83); hw.io_ports[IDE_LCYL_OFFSET] = DEVADDR((ch) ? 0xC4 : 0x84); hw.io_ports[IDE_HCYL_OFFSET] = DEVADDR((ch) ? 0xC5 : 0x85); hw.io_ports[IDE_SELECT_OFFSET] = DEVADDR((ch) ? 0xC6 : 0x86); hw.io_ports[IDE_STATUS_OFFSET] = DEVADDR((ch) ? 0xC7 : 0x87); hw.io_ports[IDE_CONTROL_OFFSET] = DEVADDR((ch) ? 0xCA : 0x8A); #endif /* SIIMAGE_BUFFERED_TASKFILE */ #else #ifdef SIIMAGE_BUFFERED_TASKFILE for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) hw.io_ports[i] = DEVADDR((ch) ? 0xD0 : 0x90)|(i); hw.io_ports[IDE_CONTROL_OFFSET] = DEVADDR((ch) ? 0xDA : 0x9A); #else /* ! SIIMAGE_BUFFERED_TASKFILE */ for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) hw.io_ports[i] = DEVADDR((ch) ? 0xC0 : 0x80)|(i); hw.io_ports[IDE_CONTROL_OFFSET] = DEVADDR((ch) ? 0xCA : 0x8A); #endif /* SIIMAGE_BUFFERED_TASKFILE */ #endif #if 0 printk(KERN_DEBUG "%s: ", hwif->name); for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) printk("0x%08x ", DEVADDR((ch) ? 0xC0 : 0x80)|(i)); printk("0x%08x ", DEVADDR((ch) ? 0xCA : 0x8A)|(i)); #endif hw.io_ports[IDE_IRQ_OFFSET] = 0; if (dev->device == PCI_DEVICE_ID_SII_3112) { hw.sata_scr[SATA_STATUS_OFFSET] = DEVADDR((ch) ? 0x184 : 0x104); hw.sata_scr[SATA_ERROR_OFFSET] = DEVADDR((ch) ? 0x188 : 0x108); hw.sata_scr[SATA_CONTROL_OFFSET]= DEVADDR((ch) ? 0x180 : 0x100); hw.sata_misc[SATA_MISC_OFFSET] = DEVADDR((ch) ? 0x1C0 : 0x140); hw.sata_misc[SATA_PHY_OFFSET] = DEVADDR((ch) ? 0x1C4 : 0x144); hw.sata_misc[SATA_IEN_OFFSET] = DEVADDR((ch) ? 0x1C8 : 0x148); } hw.priv = (void *) addr; // hw.priv = pci_get_drvdata(hwif->pci_dev); hw.irq = hwif->pci_dev->irq; memcpy(&hwif->hw, &hw, sizeof(hw)); memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->hw.io_ports)); if (hwif->pci_dev->device == PCI_DEVICE_ID_SII_3112) { memcpy(hwif->sata_scr, hwif->hw.sata_scr, sizeof(hwif->hw.sata_scr)); memcpy(hwif->sata_misc, hwif->hw.sata_misc, sizeof(hwif->hw.sata_misc)); } #ifdef SIIMAGE_BUFFERED_TASKFILE hwif->addressing = 1; #endif /* SIIMAGE_BUFFERED_TASKFILE */ hwif->irq = hw.irq; hwif->hwif_data = pci_get_drvdata(hwif->pci_dev); #ifdef SIIMAGE_LARGE_DMA hwif->dma_base = DEVADDR((ch) ? 0x18 : 0x10); hwif->dma_base2 = DEVADDR((ch) ? 0x08 : 0x00); hwif->dma_prdtable = (hwif->dma_base2 + 4); #else /* ! SIIMAGE_LARGE_DMA */ hwif->dma_base = DEVADDR((ch) ? 0x08 : 0x00); hwif->dma_base2 = DEVADDR((ch) ? 0x18 : 0x10); #endif /* SIIMAGE_LARGE_DMA */ hwif->mmio = 2; }
/* * 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; }
static int __devinit palm_bk3710_probe(struct platform_device *pdev) { struct clk *clk; struct resource *mem, *irq; ide_hwif_t *hwif; unsigned long base, rate; int i; hw_regs_t hw; u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; clk = clk_get(&pdev->dev, "IDECLK"); if (IS_ERR(clk)) return -ENODEV; clk_enable(clk); rate = clk_get_rate(clk); ideclk_period = 1000000000UL / rate; /* Register the IDE interface with Linux ATA Interface */ memset(&hw, 0, sizeof(hw)); mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (mem == NULL) { printk(KERN_ERR "failed to get memory region resource\n"); return -ENODEV; } irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (irq == NULL) { printk(KERN_ERR "failed to get IRQ resource\n"); return -ENODEV; } if (request_mem_region(mem->start, mem->end - mem->start + 1, "palm_bk3710") == NULL) { printk(KERN_ERR "failed to request memory region\n"); return -EBUSY; } base = IO_ADDRESS(mem->start); /* Configure the Palm Chip controller */ palm_bk3710_chipinit((void __iomem *)base); for (i = 0; i < IDE_NR_PORTS - 2; i++) hw.io_ports[i] = base + IDE_PALM_ATA_PRI_REG_OFFSET + i; hw.io_ports[IDE_CONTROL_OFFSET] = base + IDE_PALM_ATA_PRI_CTL_OFFSET; hw.irq = irq->start; hw.chipset = ide_palm3710; hwif = ide_deprecated_find_port(hw.io_ports[IDE_DATA_OFFSET]); if (hwif == NULL) goto out; i = hwif->index; if (hwif->present) ide_unregister(i, 0, 1); else if (!hwif->hold) ide_init_port_data(hwif, i); ide_init_port_hw(hwif, &hw); hwif->fixup = NULL; hwif->tuneproc = &palm_bk3710_tune_drive; hwif->speedproc = &palm_bk3710_tune_chipset; hwif->mmio = 2; default_hwif_mmiops(hwif); if (rate >= 100000000) hwif->ultra_mask = 0x3f; /* UDMA Mode 5 */ else hwif->ultra_mask = 0x1f; /* UDMA Mode 4 */ hwif->mwdma_mask = 0x7; hwif->drives[0].autotune = 1; hwif->drives[1].autotune = 1; hwif->ide_dma_check = &palm_bk3710_config_drive_xfer_rate; hwif->udma_four = 1; if (!noautodma) hwif->autodma = 1; hwif->drives[0].autodma = hwif->drives[1].autodma = hwif->autodma; ide_setup_dma(hwif, base, 8); idx[0] = i; ide_device_add(idx); if (!hwif->present) goto out; return 0; out: printk(KERN_WARNING "Palm Chip BK3710 IDE Register Fail\n"); return -ENODEV; }