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_init_hwif_ports(&hw, (ide_ioreg_t)(base + 0x10), (ide_ioreg_t)(base + 0x1e), NULL); hw.irq = dev->irq; hw.chipset = ide_pci; /* this enables IRQ sharing */ rc = ide_register_hw(&hw, &hwif); if (rc < 0) /* ide_register_hw likes to be invoked twice (buggy) */ rc = ide_register_hw(&hw, &hwif); if (rc < 0) { printk(KERN_ERR "delkin_cb: ide_register_hw failed (%d)\n", rc); pci_disable_device(dev); return -ENODEV; } MOD_INC_USE_COUNT; pci_set_drvdata(dev, hwif); hwif->pci_dev = dev; drive = &hwif->drives[0]; if (drive->present) { drive->id->csfo = 0; /* workaround for idedisk_open bug */ drive->io_32bit = 1; drive->unmask = 1; } return 0; }
static int __init pnpide_generic_init(struct pci_dev *dev, int enable) { hw_regs_t hw; int index; if (!enable) return 0; if (!(DEV_IO(dev, 0) && DEV_IO(dev, 1) && DEV_IRQ(dev, 0))) return 1; ide_setup_ports(&hw, (ide_ioreg_t) DEV_IO(dev, 0), generic_ide_offsets, (ide_ioreg_t) DEV_IO(dev, 1), 0, NULL, // generic_pnp_ide_iops, DEV_IRQ(dev, 0)); index = ide_register_hw(&hw, NULL); if (index != -1) { printk(KERN_INFO "ide%d: %s IDE interface\n", index, DEV_NAME(dev)); return 0; } return 1; }
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; ide_setup_ports(&hw, (unsigned long) pnp_port_start(dev, 0), generic_ide_offsets, (unsigned long) pnp_port_start(dev, 1), 0, NULL, // generic_pnp_ide_iops, pnp_irq(dev, 0)); 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 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 __devinit rapide_probe(struct expansion_card *ec, const struct ecard_id *id) { unsigned long port = ecard_address (ec, ECARD_MEMC, 0); hw_regs_t hw; int i, ret; memset(&hw, 0, sizeof(hw)); for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { hw.io_ports[i] = port; port += 1 << 4; } hw.io_ports[IDE_CONTROL_OFFSET] = port + 0x206; hw.irq = ec->irq; ret = ide_register_hw(&hw, NULL); if (ret) ecard_release(ec); /* * this locks the driver in-core - remove this * comment and the two lines below when we can * safely remove interfaces. */ else MOD_INC_USE_COUNT; return ret; }
int idecs_register (int arg1, int arg2, int irq) { hw_regs_t hw; ide_init_hwif_ports(&hw, (ide_ioreg_t) arg1, (ide_ioreg_t) arg2, NULL); hw.irq = irq; hw.chipset = ide_pci; /* this enables IRQ sharing w/ PCI irqs */ return ide_register_hw(&hw, NULL); }
static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq) { hw_regs_t hw; ide_init_hwif_ports(&hw, io, ctl, NULL); hw.irq = irq; hw.chipset = ide_pci; return ide_register_hw(&hw, NULL); }
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); }
int __init ipod_ide_register(void) { hw_regs_t hw; ide_ioreg_t reg; ide_hwif_t *hwifp; int i; int hw_ver = ipod_get_hw_version() >> 16; if (hw_ver > 0x3) { /* PP5020 */ outl(inl(0xc3000028) | (1 << 5), 0xc3000028); outl(inl(0xc3000028) & ~0x10000000, 0xc3000028); outl(0x10, 0xc3000000); outl(0x80002150, 0xc3000004); } else { /* PP5002 */ outl(inl(0xc0003024) | (1 << 7), 0xc0003024); outl(inl(0xc0003024) & ~(1<<2), 0xc0003024); outl(0x10, 0xc0003000); outl(0x80002150, 0xc0003004); } memset(&hw, 0, sizeof(hw)); if (hw_ver > 0x3) { reg = PP5020_IDE_PRIMARY_BASE; } else { reg = PP5002_IDE_PRIMARY_BASE; } for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { hw.io_ports[i] = reg; reg += 4; /* our registers are on word boundaries */ } if (hw_ver > 0x3) { hw.io_ports[IDE_CONTROL_OFFSET] = PP5020_IDE_PRIMARY_CONTROL; hw.irq = PP5020_IDE_IRQ; } else { hw.io_ports[IDE_CONTROL_OFFSET] = PP5002_IDE_PRIMARY_CONTROL; hw.irq = PP5002_IDE_IRQ; } ide_register_hw(&hw, &hwifp); return 0; }
void falconide_init(void) { if (MACH_IS_ATARI && ATARIHW_PRESENT(IDE)) { hw_regs_t hw; int index; ide_setup_ports(&hw, (ide_ioreg_t)ATA_HD_BASE, falconide_offsets, 0, 0, NULL, IRQ_MFP_IDE); index = ide_register_hw(&hw, NULL); if (index != -1) printk("ide%d: Falcon IDE interface\n", index); } }
void __init cpci405ide_init(void) { hw_regs_t hw; int index = -1; cpci405_ide_base_mapped = ioremap((unsigned long) CPCI405_HD_BASE, 0x200) - _IO_BASE; ide_setup_ports(&hw, (ide_ioreg_t)cpci405_ide_base_mapped, cpci405ide_offsets, 0, 0, NULL, CPCI405_IRQ_IDE); index = ide_register_hw(&hw, NULL); if (index != -1) printk("ide%d: CPCI405 IDE interface\n", index); }
void __init tx4938_ide_init(void) { hw_regs_t hw; int index; int offsets[IDE_NR_PORTS]; int i; unsigned long port; for (i = 0; i < 8; i++) offsets[i] = i; offsets[IDE_CONTROL_OFFSET] = 6; offsets[IDE_CONTROL_OFFSET] += 0x10000; tx4938_ide_irq = RBTX4938_IRQ_IOC_ATA; if ((tx4938_ccfgptr->pcfg & (TX4938_PCFG_ATA_SEL | TX4938_PCFG_NDF_SEL)) != TX4938_PCFG_ATA_SEL) return; for (i = 0; i < 8; i++) { /* check EBCCRn.ISA, EBCCRn.BSZ, EBCCRn.ME */ if ((tx4938_ebuscptr->cr[i] & 0x00f00008) == 0x00e00008) break; } if (i == 8) { printk(KERN_DEBUG "TX4938 ATA channel not found.\n"); return; } port = KSEG1ADDR((tx4938_ebuscptr->cr[i] >> 48) << 20) + 0x10000 - mips_io_port_base; memset(&hw, 0, sizeof(hw)); ide_setup_ports(&hw, port, offsets, 0, 0, 0, tx4938_ide_irq); index = ide_register_hw(&hw, NULL); if (index != -1) { ide_hwif_t *hwif = &ide_hwifs[index]; #ifdef __BIG_ENDIAN hwif->ata_input_data = tx4938_ata_input_data; hwif->ata_output_data = tx4938_ata_output_data; hwif->atapi_input_bytes = tx4938_atapi_input_bytes; hwif->atapi_output_bytes = tx4938_atapi_output_bytes; #endif printk("%s: TX4938 IDE interface\n", hwif->name); } }
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 } }
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 }
/* Set hwif for S3C2410/S3C2440, by www.100ask.net */ static void __init ide_s3c24xx_init(void) { int i; unsigned int oldval_bwscon; /* 用来保存BWSCON寄存器的值 */ unsigned long mapaddr0; unsigned long mapaddr1; unsigned long baseaddr[] = IDE_ARM_IOs; hw_regs_t hw; /* 设置BANK1/2: 总线宽度为16 */ oldval_bwscon = readl(S3C2410_BWSCON); writel((oldval_bwscon & ~((3<<4)|(3<<8))) \ | S3C2410_BWSCON_DW1_16 | S3C2410_BWSCON_WS1 | S3C2410_BWSCON_DW2_16 | S3C2410_BWSCON_WS2, S3C2410_BWSCON); /* 设置BANK1/2的时间参数 */ writel((S3C2410_BANKCON_Tacs4 | S3C2410_BANKCON_Tcos4 | S3C2410_BANKCON_Tacc14 | S3C2410_BANKCON_Tcoh4 | S3C2410_BANKCON_Tcah4 | S3C2410_BANKCON_Tacp6 | S3C2410_BANKCON_PMCnorm), S3C2410_BANKCON1); writel((S3C2410_BANKCON_Tacs4 | S3C2410_BANKCON_Tcos4 | S3C2410_BANKCON_Tacc14 | S3C2410_BANKCON_Tcoh4 | S3C2410_BANKCON_Tcah4 | S3C2410_BANKCON_Tacp6 | S3C2410_BANKCON_PMCnorm), S3C2410_BANKCON2); /* * 设置IDE接口的地址, ADDR3~1接到IDE接口的A02~00 * 注意:没有使用ADDR0,所以下面确定地址时,都左移1位 */ mapaddr0 = (unsigned long)ioremap(baseaddr[0], 16); mapaddr1 = (unsigned long)ioremap(baseaddr[1], 16); memset(&hw, 0, sizeof(hw)); for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) hw.io_ports[i] = mapaddr0 + (i<<1); hw.io_ports[IDE_CONTROL_OFFSET] = mapaddr1 + (6<<1); /* 设置中断引脚 */ hw.irq = s3c2410_gpio_getirq(IDE_ARM_IRQPIN); s3c2410_gpio_cfgpin(IDE_ARM_IRQPIN, S3C2410_GPIO_IRQ); set_irq_type(hw.irq, IRQF_TRIGGER_RISING); /* 注册IDE接口 */ ide_register_hw(&hw, 1, NULL); }
static inline int rapide_register(struct expansion_card *ec) { unsigned long port = ecard_address (ec, ECARD_MEMC, 0); hw_regs_t hw; int i; memset(&hw, 0, sizeof(hw)); for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { hw.io_ports[i] = (ide_ioreg_t)port; port += 1 << 4; } hw.io_ports[IDE_CONTROL_OFFSET] = port + 0x206; hw.irq = ec->irq; return ide_register_hw(&hw, NULL); }
void uclinux_ide_init(void) { hw_regs_t hw; ide_ioreg_t base; int index, i; ide_hwif_t* hwif; for (i = 0; ide_defaults[i].base != (ide_ioreg_t) -1; i++) { base = ide_defaults[i].base; memset(&hw, 0, sizeof(hw)); #ifdef CONFIG_COLDFIRE mcf_autovector(hw.irq); #endif hw.irq = ide_defaults[i].irq; ide_setup_ports(&hw, base, ide_offsets, 0, 0, ack_intr, /* ide_iops, */ ide_defaults[i].irq); index = ide_register_hw(&hw, &hwif); if (index != -1) { hwif->mmio = 1; /* not io(0) or mmio(1) */ #ifdef CONFIG_COLDFIRE hwif->OUTB = OUTB; hwif->OUTBSYNC = OUTBSYNC; hwif->OUTW = OUTW; hwif->OUTL = OUTL; hwif->OUTSW = OUTSW; hwif->OUTSL = OUTSL; hwif->INB = INB; hwif->INW = INW; hwif->INL = INL; hwif->INSW = INSW; hwif->INSL = INSL; DRIVER(&hwif->drives[0])->cleanup = uclinux_irq_remove; #endif } disable_irq(ide_defaults[i].irq); } }
static int __devinit rapide_probe(struct expansion_card *ec, const struct ecard_id *id) { unsigned long port = ecard_address (ec, ECARD_MEMC, 0); hw_regs_t hw; int i, ret; memset(&hw, 0, sizeof(hw)); for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { hw.io_ports[i] = port; port += 1 << 4; } hw.io_ports[IDE_CONTROL_OFFSET] = port + 0x206; hw.irq = ec->irq; ret = ide_register_hw(&hw, NULL); if (ret) ecard_release(ec); return ret; }
void __init avila_ide_init(void) { hw_regs_t hw; ide_hwif_t *hwif; unsigned char *avila_ide_iobase; int i; gpio_line_config(AVILA_IDE_INT, IXP4XX_GPIO_IN | IXP4XX_GPIO_STYLE_ACTIVE_HIGH); gpio_line_isr_clear(AVILA_IDE_INT); *IXP4XX_EXP_CS1 |= AVILA_IDE_CS1_BITS; avila_ide_iobase = ioremap(AVILA_IDE_BASE, 0x1000); memset(&hw, 0, sizeof(hw)); hw.irq = AVILA_IDE_IRQ; hw.dma = NO_DMA; for (i = 0; (i <= IDE_STATUS_OFFSET); i++) hw.io_ports[i] = (unsigned long)(avila_ide_iobase + i); hw.io_ports[IDE_CONTROL_OFFSET] = (unsigned long)(avila_ide_iobase + AVILA_IDE_CONTROL); printk("ide: Gateworks Avila IDE/CF driver v1.3b\n"); ide_register_hw(&hw, 1, &hwif); hwif->mmio = 2; hwif->OUTB = avila_ide_outb; hwif->OUTBSYNC = avila_ide_outbsync; hwif->OUTW = avila_ide_outw; hwif->OUTSW = avila_ide_outsw; hwif->INB = avila_ide_inb; hwif->INW = avila_ide_inw; hwif->INSW = avila_ide_insw; }
static int __init bastide_register(unsigned int base, unsigned int aux, int irq, ide_hwif_t **hwif) { hw_regs_t hw; int i; memset(&hw, 0, sizeof(hw)); base += BAST_IDE_CS; aux += BAST_IDE_CS; for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { hw.io_ports[i] = (unsigned long)base; base += 0x20; } hw.io_ports[IDE_CONTROL_OFFSET] = aux + (6 * 0x20); hw.irq = irq; ide_register_hw(&hw, NULL, 0, hwif); return 0; }
void q40ide_init(void) { int i; ide_hwif_t *hwif; int index; 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])); index = ide_register_hw(&hw, 1, &hwif); // **FIXME** if (index != -1) hwif->mmio = 1; } }
void __init gayle_init(void) { int a4000, i; if (!MACH_IS_AMIGA) return; 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; found: 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; int index; 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; ide_setup_ports(&hw, base, gayle_offsets, ctrlport, irqport, ack_intr, // &gayle_iops, IRQ_AMIGA_PORTS); index = ide_register_hw(&hw, &hwif); if (index != -1) { hwif->mmio = 2; switch (i) { case 0: printk("ide%d: Gayle IDE interface (A%d style)\n", index, a4000 ? 4000 : 1200); break; #ifdef CONFIG_BLK_DEV_IDEDOUBLER case 1: printk("ide%d: IDE doubler\n", index); break; #endif /* CONFIG_BLK_DEV_IDEDOUBLER */ } } else release_mem_region(res_start, res_n); } }
static inline int csb536_cf_init(void) { ide_hwif_t *hwif; ide_drive_t *drive; hw_regs_t hw; int cf_idx; dbg("CSB536 CF Probe\n"); dbg("Using CF_REGISTER_BASE 0x%08lx\n",CF_REGISTER_BASE); ide_setup_ports(&hw, CF_REGISTER_BASE, cfide_offsets, 0, 0, &csb536_ide_ack_intr, CF_RDYBSY_IRQ); /* Reset the CF card */ csb536_cf_reset(NULL); /* Dump the initial state of CF registers */ dbg("CF Config Option Reg(0x%08lx)=0x%02x\n",CF_CONFIG_OPTION_REG, inb(CF_CONFIG_OPTION_REG)); dbg("CF Config/Status Reg(0x%08lx)=0x%02x\n",CF_CONFIG_STATUS_REG, inb(CF_CONFIG_STATUS_REG)); dbg("CF Pin Replacement Reg(0x%08lx)=0x%02x\n",CF_PIN_REPLACEMENT_REG, inw(CF_PIN_REPLACEMENT_REG)); dbg("CF Socket and Copy Reg(0x%08lx)=0x%02x\n",CF_SOCKET_AND_COPY_REG, inb(CF_SOCKET_AND_COPY_REG)); /* Make sure that the CF card in is memory mapped mode by * writing 0x0000 to the Configuration Option Register. */ dbg("Using Memory Mapped Mode\n"); outb(0x00, CF_CONFIG_OPTION_REG); /* Dump the current state of CF registers */ dbg("CF Config Option Reg(0x%08lx)=0x%02x\n", CF_CONFIG_OPTION_REG, inb(CF_CONFIG_OPTION_REG)); dbg("CF Config/Status Reg(0x%08lx)=0x%02x\n", CF_CONFIG_STATUS_REG, inb(CF_CONFIG_STATUS_REG)); dbg("CF Pin Replacement Reg(0x%08lx)=0x%02x\n", CF_PIN_REPLACEMENT_REG, inb(CF_PIN_REPLACEMENT_REG)); dbg("CF Socket and Copy Reg(0x%08lx)=0x%02x\n", CF_SOCKET_AND_COPY_REG, inb(CF_SOCKET_AND_COPY_REG)); udelay(CF_MODE_DELAY); /* Register the hardware interface. NOTE: The CF hardware * must be completely initialized at this point because if * ide_register_hw() is called AFTER initialization of the built-in, * drivers it will also probe the CF interface. */ cf_idx = ide_register_hw(&hw, &hwif); if (cf_idx < 0) { err("Could not register CSB536 CompactFlash driver\n"); return -ENODEV; } dbg("Using ide_hwifs[%d]\n", cf_idx); /* Provide function pointers for special handling */ hwif->resetproc = csb536_cf_reset; /* We assume only one "drive," the master driver. * Probe only the master drive */ drive = &hwif->drives[0]; drive->noprobe = 0; hwif->drives[1].noprobe = 1; /* This is the signature for a CF card */ drive->removable = 1; drive->is_flash = 1; /* Dump all IDE registers */ dbg("CF DATA(0x%08lx) = 0x%04x\n", hwif->hw.io_ports[IDE_DATA_OFFSET], inw(hwif->hw.io_ports[IDE_DATA_OFFSET])); dbg("CF ERROR(0x%08lx) = 0x%02x\n", hwif->hw.io_ports[IDE_ERROR_OFFSET], inb(hwif->hw.io_ports[IDE_ERROR_OFFSET])); dbg("CF NSECTOR(0x%08lx) = 0x%02x\n", hwif->hw.io_ports[IDE_NSECTOR_OFFSET], inb(hwif->hw.io_ports[IDE_NSECTOR_OFFSET])); dbg("CF SECTOR(0x%08lx) = 0x%02x\n", hwif->hw.io_ports[IDE_SECTOR_OFFSET], inb(hwif->hw.io_ports[IDE_SECTOR_OFFSET])); dbg("CF LCYL(0x%08lx) = 0x%02x\n", hwif->hw.io_ports[IDE_LCYL_OFFSET], inb(hwif->hw.io_ports[IDE_LCYL_OFFSET])); dbg("CF HCYL(0x%08lx) = 0x%02x\n", hwif->hw.io_ports[IDE_HCYL_OFFSET], inb(hwif->hw.io_ports[IDE_HCYL_OFFSET])); dbg("CF SELECT(0x%08lx) = 0x%02x\n", hwif->hw.io_ports[IDE_SELECT_OFFSET], inb(hwif->hw.io_ports[IDE_SELECT_OFFSET])); dbg("CF STATUS(0x%08lx) = 0x%02x\n", hwif->hw.io_ports[IDE_STATUS_OFFSET], inb(hwif->hw.io_ports[IDE_STATUS_OFFSET])); dbg("CF CONTROL(0x%08lx) = 0x%02x\n", hwif->hw.io_ports[IDE_CONTROL_OFFSET], inb(hwif->hw.io_ports[IDE_CONTROL_OFFSET])); dbg("CF IRQ(0x%08lx) = 0x%02x\n", hwif->hw.io_ports[IDE_IRQ_OFFSET], inb(hwif->hw.io_ports[IDE_IRQ_OFFSET])); csb536_cf_memory(); /* Probe the hardware interface. NOTE: If ide_register_hw() is * called AFTER initialization of IDE built-in drivers, it will do * the following automatically. */ probe_hwif_init(hwif); create_proc_ide_interfaces(); return cf_idx; }
void __init buddha_init(void) { hw_regs_t hw; ide_hwif_t *hwif; int i, index; 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; 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); for(i=0;i<buddha_num_hwifs;i++) { if(type != BOARD_XSURF) { ide_setup_ports(&hw, (buddha_board+buddha_bases[i]), buddha_offsets, 0, (buddha_board+buddha_irqports[i]), buddha_ack_intr, // budda_iops, IRQ_AMIGA_PORTS); } else { ide_setup_ports(&hw, (buddha_board+xsurf_bases[i]), xsurf_offsets, 0, (buddha_board+xsurf_irqports[i]), xsurf_ack_intr, // xsurf_iops, IRQ_AMIGA_PORTS); } index = ide_register_hw(&hw, NULL, 1, &hwif); if (index != -1) { hwif->mmio = 1; printk("ide%d: ", index); switch(type) { case BOARD_BUDDHA: printk("Buddha"); break; case BOARD_CATWEASEL: printk("Catweasel"); break; case BOARD_XSURF: printk("X-Surf"); break; } printk(" IDE interface\n"); } } } }
int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device *bdev, unsigned int cmd, unsigned long arg) { unsigned long flags; ide_driver_t *drv; void __user *p = (void __user *)arg; int err = 0, (*setfunc)(ide_drive_t *, int); u8 *val; switch (cmd) { case HDIO_GET_32BIT: val = &drive->io_32bit; goto read_val; case HDIO_GET_KEEPSETTINGS: val = &drive->keep_settings; goto read_val; case HDIO_GET_UNMASKINTR: val = &drive->unmask; goto read_val; case HDIO_GET_DMA: val = &drive->using_dma; goto read_val; case HDIO_SET_32BIT: setfunc = set_io_32bit; goto set_val; case HDIO_SET_KEEPSETTINGS: setfunc = set_ksettings; goto set_val; case HDIO_SET_PIO_MODE: setfunc = set_pio_mode; goto set_val; case HDIO_SET_UNMASKINTR: setfunc = set_unmaskirq; goto set_val; case HDIO_SET_DMA: setfunc = set_using_dma; goto set_val; } switch (cmd) { case HDIO_OBSOLETE_IDENTITY: case HDIO_GET_IDENTITY: if (bdev != bdev->bd_contains) return -EINVAL; if (drive->id_read == 0) return -ENOMSG; if (copy_to_user(p, drive->id, (cmd == HDIO_GET_IDENTITY) ? sizeof(*drive->id) : 142)) return -EFAULT; return 0; case HDIO_GET_NICE: return put_user(drive->dsc_overlap << IDE_NICE_DSC_OVERLAP | drive->atapi_overlap << IDE_NICE_ATAPI_OVERLAP | drive->nice0 << IDE_NICE_0 | drive->nice1 << IDE_NICE_1 | drive->nice2 << IDE_NICE_2, (long __user *) arg); #ifdef CONFIG_IDE_TASK_IOCTL case HDIO_DRIVE_TASKFILE: if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) return -EACCES; switch(drive->media) { case ide_disk: return ide_taskfile_ioctl(drive, cmd, arg); default: return -ENOMSG; } #endif /* CONFIG_IDE_TASK_IOCTL */ case HDIO_DRIVE_CMD: if (!capable(CAP_SYS_RAWIO)) return -EACCES; return ide_cmd_ioctl(drive, cmd, arg); case HDIO_DRIVE_TASK: if (!capable(CAP_SYS_RAWIO)) return -EACCES; return ide_task_ioctl(drive, cmd, arg); case HDIO_SCAN_HWIF: { hw_regs_t hw; int args[3]; if (!capable(CAP_SYS_RAWIO)) return -EACCES; if (copy_from_user(args, p, 3 * sizeof(int))) return -EFAULT; memset(&hw, 0, sizeof(hw)); ide_init_hwif_ports(&hw, (unsigned long) args[0], (unsigned long) args[1], NULL); hw.irq = args[2]; if (ide_register_hw(&hw, 0, NULL) == -1) return -EIO; return 0; } case HDIO_UNREGISTER_HWIF: if (!capable(CAP_SYS_RAWIO)) return -EACCES; /* (arg > MAX_HWIFS) checked in function */ ide_unregister(arg); return 0; case HDIO_SET_NICE: if (!capable(CAP_SYS_ADMIN)) return -EACCES; if (arg != (arg & ((1 << IDE_NICE_DSC_OVERLAP) | (1 << IDE_NICE_1)))) return -EPERM; drive->dsc_overlap = (arg >> IDE_NICE_DSC_OVERLAP) & 1; drv = *(ide_driver_t **)bdev->bd_disk->private_data; if (drive->dsc_overlap && !drv->supports_dsc_overlap) { drive->dsc_overlap = 0; return -EPERM; } drive->nice1 = (arg >> IDE_NICE_1) & 1; return 0; case HDIO_DRIVE_RESET: { unsigned long flags; if (!capable(CAP_SYS_ADMIN)) return -EACCES; /* * Abort the current command on the * group if there is one, taking * care not to allow anything else * to be queued and to die on the * spot if we miss one somehow */ spin_lock_irqsave(&ide_lock, flags); if (HWGROUP(drive)->resetting) { spin_unlock_irqrestore(&ide_lock, flags); return -EBUSY; } ide_abort(drive, "drive reset"); BUG_ON(HWGROUP(drive)->handler); /* Ensure nothing gets queued after we drop the lock. Reset will clear the busy */ HWGROUP(drive)->busy = 1; spin_unlock_irqrestore(&ide_lock, flags); (void) ide_do_reset(drive); return 0; } case CDROMEJECT: case CDROMCLOSETRAY: return scsi_cmd_ioctl(file, bdev->bd_disk, cmd, p); case HDIO_GET_BUSSTATE: if (!capable(CAP_SYS_ADMIN)) return -EACCES; if (put_user(HWIF(drive)->bus_state, (long __user *)arg)) return -EFAULT; return 0; case HDIO_SET_BUSSTATE: if (!capable(CAP_SYS_ADMIN)) return -EACCES; if (HWIF(drive)->busproc) return HWIF(drive)->busproc(drive, (int)arg); return -EOPNOTSUPP; default: return -EINVAL; } read_val: down(&ide_setting_sem); spin_lock_irqsave(&ide_lock, flags); err = *val; spin_unlock_irqrestore(&ide_lock, flags); up(&ide_setting_sem); return err >= 0 ? put_user(err, (long __user *)arg) : err; set_val: if (bdev != bdev->bd_contains) err = -EINVAL; else { if (!capable(CAP_SYS_ADMIN)) err = -EACCES; else { down(&ide_setting_sem); err = setfunc(drive, arg); up(&ide_setting_sem); } } return err; }