예제 #1
0
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;
}
예제 #2
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;
}
예제 #3
0
파일: ide-pnp.c 프로젝트: wxlong/Test
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;
}
예제 #4
0
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;
}
예제 #5
0
파일: rapide.c 프로젝트: sarnobat/knoppix
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;
}
예제 #6
0
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);
}
예제 #7
0
파일: ide-cs.c 프로젝트: sarnobat/knoppix
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);
}
예제 #8
0
파일: ide_arm.c 프로젝트: cilynx/dd-wrt
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);
}
예제 #9
0
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;
}
예제 #10
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);
    }
}
예제 #11
0
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);

}
예제 #12
0
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);
	}
}
예제 #13
0
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
	}
}
예제 #14
0
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    
}
예제 #15
0
/* 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);
}
예제 #16
0
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);
}
예제 #17
0
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);
	}
}
예제 #18
0
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;
}
예제 #19
0
파일: avila-ide.c 프로젝트: cilynx/dd-wrt
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;

}
예제 #20
0
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;
}
예제 #21
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;
    }
}
예제 #22
0
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);
    }
}
예제 #23
0
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;
}
예제 #24
0
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");	    
			}		      
		}
	}
}
예제 #25
0
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;
}